CodeceptJS icon indicating copy to clipboard operation
CodeceptJS copied to clipboard

Please support @testing-library

Open dantman opened this issue 2 years ago • 0 comments

What are you trying to achieve?

I want to write my tests using accessibility roles instead of hardcoding implementation details about how the html of my application is implemented. i.e. When I say in my test to "Click on the button with the label Login", it should not matter to the test whether the button is a <button>Login</button> or a <div role="button" aria-label="Login">...</div> and should behave the same either way.

This is a best practice supported by @testing-library which has libraries for nearly every test runner that CodeceptJS supports and also by Playwright using the role= selector or using playwright-testing-library.

What is stopping you from doing this now?

Even though almost every test runner has an associated testing-library for locating an element using whatever Selector or element object the test runner natively understands. Codecept's helpers do not accept these native elements and only accept Codecept's own Locator syntax. As a result it's not possible to use any @testing-library with Codecept JS' helpers.

Possible solutions?

A) Natively support @testing-library

New strict selectors like role could be added for each of @testing-library's selectors (ByRole, ByLabelText, ByPlaceholderText, ByText, ByDisplayValue, ByAltText, ByTitle, ByTestId) and the findElement of each helpers module can use the related testing library as an optional peerDep if it is installed by the user.

B) Allow the user to specify a selector function that uses the helper's native API

Each helpers module could support an additional explicit selector with the test runner's own name that takes a user function that expects the user to return the test runner's own native Selector/element.

For example in TestCafe the following

I.click({ testcafe: () => new Selector('div')});
await within({ testcafe: () => new Selector('div')}, () => {
  I.click({ testcafe: (container) => container.find('button')});
});

This would allow any special locators or 3rd party library supporting a test runner to be used with Codecept. So the user could use this to use the related @testing-library library directly.

This is a little verbose of course. But that can easily be solved by writing custom functions to create the strict selector, e.g. By.role('button', /Login/i).

dantman avatar Jun 18 '22 02:06 dantman