nightwatch icon indicating copy to clipboard operation
nightwatch copied to clipboard

Testing library command feature | findByRole(expectedRole, { name: 'The name' })

Open Terence625 opened this issue 1 year ago • 1 comments

Description

In testing library, getByRole / findByRole has a very useful command: findByRole(expectedRole, { name: 'The name' }). For example: findByRole('button', { name: 'Submit' }), this can find all the button elements then find the button with Submit text. According to testing library doc, this is the recommended way to query for a single element

If you only query for a single element with getByText('The name') it's oftentimes better to use getByRole(expectedRole, { name: 'The name' })

Currently cannot achieve this feature in nightwatch as discussed in discord (https://discord.com/channels/618399631038218240/1140931333556813855/1141711243929985124):

await browser.findByRole('button').findByText('Submit')
// ^ will first find all the 'button' elements, pick the first one of those and then try to find an element with text 'Submit' in the child elements of the first 'button' element.

await browser.findAllByRole('button').findByText('Submit')
// ^ not possible, because chaining can only be done on a single element, and not on a collection of elements
// the correct syntax for above would be:
await browser.findAllByRole('button').nth(i).findByText('Submit')
// which still won't do the job (we need to insert something for 'i' and the chained findByText would still try to look through the child elements of the chosen 'button' element).

Suggested solution

Add options name in findByRole command, according to testing library doc: https://testing-library.com/docs/queries/byrole/. Definition to accessible name: https://www.tpgi.com/what-is-an-accessible-name/ It'll be nice to have description option too: https://www.w3.org/TR/accname-1.1/, but I haven't had use case for this yet

Alternatives / Workarounds

I was suggested the workaround

const buttonElems = await browser.element.findAllByRole('button');

for (const buttonElem of buttonElems) {
  const buttonText = await buttonElem.getText();
  if (buttonText === 'Submit') {
    await buttonElem.click();
    break;
  }
}

And I can still use the old-fashion way find the element css selector

Additional Information

No response

Terence625 avatar Aug 18 '23 00:08 Terence625

Thank you for setting this as an enhancement. One of the product folk will triage this again to help see when we can fit this in an upcoming sprint.

github-actions[bot] avatar Aug 18 '23 00:08 github-actions[bot]