Skip to content

Throw better error message by findByRole query #970

Closed
@vinaymahamuni

Description

@vinaymahamuni

Describe the feature you'd like:

Currently if findByRole query doesn't find the element for given role and name, it throws error with message TestingLibraryElementError: Unable to find role="button"

Test to verify above behavior

it("Doesn't tell where it failed", async () => {
  render(<button>Click me</button>)
  
  await screen.findByRole('button', { name: 'submit' })
  await screen.findByRole('button', { name: 'Click me' })
})

In above test, I don't get feedback for which name the findByRole query failed.

For same scenario, if getByRole query is used, it gives the name as well
TestingLibraryElementError: Unable to find an accessible element with the role "button" and name "submit"

This helps in debugging. Specially when it fails on CI.

Suggested implementation:

I looked the code. This behavior happen for all the queries which internally use runWithExpensiveErrorDiagnosticsDisabled function to run callback. In src/queries/role.js there is getMissingError function. In that there is one condition applied which tries to avoid expensive error diagnostics. This condition applies to findByRole function as well. I agree with decision. But I think that adding only namehint to the error string won't hit the performance.

Describe alternatives you've considered:

Currently, I try to figure out where error might have occur using line number printed in stacktrace. But that is very difficult as I am using typescript + snowpack+ web test runner which runs test on browser and I don't get easy access to generated js files

Teachability, Documentation, Adoption, Migration Strategy:

we can easily extract out function returning namehint and reuse it in first if condition

const getNameHint = (name) => {
  let nameHint = ''
  if (name === undefined) {
    nameHint = ''
  } else if (typeof name === 'string') {
    nameHint = ` and name "${name}"`
  } else {
    nameHint = ` and name \`${name}\``
  }
  return nameHint
}

const getMissingError = (
  container,
  role,
  {hidden = getConfig().defaultHidden, name} = {},
) => {
  if (getConfig()._disableExpensiveErrorDiagnostics) {
    return `Unable to find role="${role}${getNameHint(name)}"`
  }
  ...
  ...
  ...
  ...
  ...
  ...
  ...
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions