Skip to content

Sub-optimal error message when using text matcher functions #732

Open
@murphyke

Description

@murphyke

When using a text matcher function with, e.g. screen.getByText, the TestingLibraryElementError message is not accurate and possibly not helpful, in that it says that the source code of the function is the "text" (pattern) being matched against.

I realize that this is low priority, because a) in some cases the matcher function will contain hard-coded comparison parameters, and b) if the comparison parameters happen to be hidden in outer-scope variables, the user can just look up the test case to see what the actual pattern or match parameters were.

The "not accurate" part would be relatively easy to fix in that the library could detect when the matcher is a function and use a more appropriate error message. (Aside: maybe it would be helpful if the current error message contained a link to a discussion of how to write a matcher function to match across elements).

The "possibly not helpful" part is true if the function doesn't contain literal comparison parameters (pattern, etc), so that the function source code doesn't reveal the pattern(s) used. The documentation could mention the possibility of using a custom toString method on such custom matcher functions.

Versions:

  • @testing-library/dom version: 7.21.4, indirectly via @testing-library/react 10.4.7
  • Testing Framework and version: jest 24.9.0 via react-scripts 3.4.1
  • DOM Environment: jsdom 16.3.0

Relevant code or config:

function getByTextAcrossElements(stringOrRegexp) {
  return screen.getByText((content, element) => {
    // ...
  });
}

What you did:

expect(
  getByTextAcrossElements(
    new RegExp(`ICD-10 Diagnosis.*${finalExpected}`, 'i')
  )
).toBeTruthy();

What happened:

TestingLibraryElementError: Unable to find an element with the text: (content, element) => {
  ...
  }. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Suggested solution

I discussed this above. In the case of my example above, using a custom toString might look like this:

export function getByTextAcrossElements(stringOrRegexp) {
  function _getByTextAcrossElements(content, element) {
    // ...
  };
  _getByTextAcrossElements.toString = () => `_getByTextAcrossElements, using pattern \`${stringOrRegexp}\``;
  return screen.getByText(_getByTextAcrossElements);
}

Metadata

Metadata

Assignees

Labels

documentationAn update needs to be made to documentation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions