Interop with jest and react testing library

Hello, anyone have a link or repo so i can see how to test my react app written in rescript, i’ll appreciate a lot

well not much luck with this, there is a pr pending approve here: https://github.com/wyze/bs-react-testing-library/pull/40 i hope @sacarr can finish up all the pending things in order to delivery his awesome pr

for now, currently i writing my tests in typescript, i share my config because jest dont work out the box with rescript, you need to tune up your package.json like this

{
  ...
  "jest": {
    "moduleNameMapper": {
// change when running jest all the import like rescript/lib/es6/curry.js to rescript/lib/js/curry.js
// jest does not support es6 dialect for node_modules packages !!
      "rescript/lib/es6/(.*)": "<rootDir>/node_modules/rescript/lib/js/$1"
    },
    "transformIgnorePatterns": [
  // put here all your rescript packages to force jest to transpile to commonjs dialect
      "/node_modules/(?!(@ryyppy|rescript-logger|@rescript)/)"
    ]
  }
}

In my business, we worked on bindings of jest and react-testing-library We did a few iterations before having something satisfactory.
We wanted to use jest.fn(), MSW , waitFor (from react-testing-library) … It wasn’t easy to make good bindings and keep a good typeafety and DX.
If you are interested, I can provide you with our bindings with some examples. Everything is not perfect yet but there is already a good base

Here is an example of what it looks like in use:

open Jest
open ReactTestingLibrary

// ... some code

let {
  setupNodeGraphQLServer,
  graphQLCtxData,
  listen,
  resetHandlers,
  close,
  graphQLLink,
  use,
} = module(MSW)

let gatewayLink = graphQLLink("http://localhost/graphql")
let server = setupNodeGraphQLServer([
  gatewayLink->MSWHelpers.apolloQueryExn(module(Query), (_, send, ctx) =>
    send(
      ctx->graphQLCtxData({
        xx: mockXx(...),
      }),
    )
  ),
])

beforeAllAsync((. ()) => server->listen(MSW.listenOptions(~onUnhandledRequest=#warn, ())))
afterEachAsync((. ()) => server->resetHandlers)
afterAllAsync((. ()) => server->close)

itFuture("should ... ", () => {
  let spy = fn1(.)
  <Provider spy> <Xxxx /> </Provider>->render->ignore

  let xxInput = screen->getByRoleExn("combobox")
  expect(xxInput)->toBeVisible
  expect(xxInput->placeholder)->toBe("Select xxx")
  expect(screen->queryByRole("dialog"))->toBeNone

  xxInput->FireEvent.focus

  let dialog = screen->getByRoleExn("dialog")
  expect(dialog)->toBeVisible
  expect(dialog)->toHaveTextContent("Loading..")

  futureWaitFor(() => {
    expect(dialog)->toHaveTextContent("mock-name-a")
    expect(dialog)->toHaveTextContent("mock-name-b")

    let firstOption = screen->getByTextExn("mock-name-a")
    let secondOption = screen->getByTextExn("mock-name-b")
    expect(firstOption)->toBeVisible
    expect(secondOption)->toBeVisible
    expect(spy)->toHaveBeenCalledTimes(1)
    expect(spy->mock->calls1)->toStrictEqual([
      {
        xx: None,
      },
    ])
    spy->mockClear

    // etc ...
  })
  // ->futureFlatMapWaitFor(...)
})
1 Like