testing-library / dom-testing-library

🐙 Simple and complete DOM testing utilities that encourage good testing practices.
https://testing-library.com/dom
MIT License
3.26k stars 466 forks source link

ByRole: Constrain API further #1202

Closed eps1lon closed 1 year ago

eps1lon commented 1 year ago

Describe the feature you'd like:

As part of https://gist.github.com/bvaughn/d3c8b8842faf2ac2439bb11773a19cec I'm revisiting a lot of selector APIs from different libraries.

The API of ByRole stood out with regard to role selection and its options.

Suggested implementation:

  1. Constraint role to string
  2. ~match fallback roles (e.g. byRole('none') === byRole('presentation') in <div role="none presentation" />~ Leaving for now. Not so clear what's the best default here
  3. Remove exact option
  4. Remove normalizer option

Describe alternatives you've considered:

Document concrete use cases (motivated by real-world tests). If you have some, please let me know.

Teachability, Documentation, Adoption, Migration Strategy:

We can document fallback role matching in a footnote. I expect that most queries will not be concerned with fallback roles.

Constraining the API makes teaching this query easier.

eps1lon commented 1 year ago

Not dropping the queryFallbacks for now. Not clear to me if we should restrict that and what the best default would be.

MatanBobi commented 1 year ago

@eps1lon can we close this issue? I think that all of the points were covered as part of #1211.

eps1lon commented 1 year ago

Closed in https://github.com/testing-library/dom-testing-library/pull/1211 Released in @testing-library/dom@9.0.0

charliematters commented 1 year ago

Sorry to dig up a closed issue, but we've just upgraded to the version with this fix in, and this query no longer works. Maybe we're abusing it and there's a better way, but I can't find any suggestions from the docs? We use this to wait for a modal with a given string to appear

 const modal = await screen.findByRole(
    (content, element) => {
      return (
        content === 'dialog' &&
        within(element as HTMLElement).queryByText(title) !== null
      )
    }

Just in case anyone else has something like this, we've reverted to the lower-level:

const modal = await waitFor(() => {
    const foundModal = screen
      .getAllByRole('dialog')
      .find((dialog) => within(dialog).queryByText(title) !== null)

    if (!foundModal) {
      throw new Error(`Cannot find Modal with "${title}"`)
    }

    return foundModal
  })