testing-library / testing-library/dom-testing-library

*ByDisplayValue is not finding an input after it changes

Open
#1,232 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
3.3k
Forks
474
PR merge metrics
No merged PRs in 30d

Description

  • @testing-library/jest-dom version: 5.16.5
  • react and react-dom version: 16.13.1
  • jest version: 27.0.1
  • node version: 14.21.1
Relevant code or config:
  it.only('should format typed value', () => {
    renderComponent({ maximumAmount: '100' }); // this is a custom method that renders an input with default values
    await userEvent.tripleClick(screen.getByDisplayValue('0.00'));
    await userEvent.keyboard('55.7');
    await userEvent.tab(); // on blur, the component reformats its value to '55.70'
    expect(screen.getByDisplayValue('55.7')).toBeInTheDocument();   // this works (it shouldn't)
    expect(screen.getByDisplayValue('55.70')).toBeInTheDocument(); // this doesn't work (it should)
  });
What you did:

I'm testing an internally built component that's based on a DOM input. One of it's functions is to format a number according to currency after a blur. E.g. if you type '55.7' and tab out, it will change its value to '55.70'. The field is first rendered with the value '0.00'.

What happened:

The first getByDisplayValue('0.00') works, and that allows us to send events to the element.
But after we type '55.7' and tab out, neither getByDisplayValue('55.70') nor findByDisplayValue('55.70') can find the element. When they fail, here is the output:

Unable to find an element with the display value: 55.70.

Ignored nodes: comments, script, style
<body>
  <div>
    <div>
      <div
        class="idsTSTextField moneyText TextFieldWrapper"
        style="width: 12rem;"
      >
        <label
          class="TFLabelWrapper"
          for="idsTxtField1"
        >
          <span
            class="idsT body-3 intuit light"
            theme="intuit"
          />
          <div
            class="TFInputWrapper"
          >
            <input
              aria-invalid="false"
              aria-label="Money Text"
              class="idsF TFInput intuit light TFNoErrorText TFNotDisabled TFInputHideArrows"
              id="idsTxtField1"
              type="number"
              value="55.70"
              width="12rem"
            />
          </div>
        </label>
        <div
          class=""
        />
      </div>
    </div>
  </div>
</body>

You can see that the input has the value '55.70' as expected.

In a browser with real user events, the input properly shows '55.70'. And in this unit test, the input ends with the correct value, as you can see by the output above.

Instead, getByDisplayValue('55.7') and findByDisplayValue('55.7') both work, i.e. with the typed value instead of the re-formatted value after blur.

Reproduction:

I'm hoping there's an easy answer... 🙄

Problem description:

We can't unit test this part of our component's behavior.

Suggested solution:

Hope for the best?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the reported interaction with the shown React input: query the initial 0.00 value, type 55.7, tab to trigger reformatting, and compare the displayed value with the DOM output. Trace the display-value query behavior for number inputs, then add a regression test showing that 55.70 is found after blur while the old value is not.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.