Skip to content

fix: use an option's label attribute for toHaveDisplayValue - #734

Open
wahidrizka wants to merge 1 commit into
testing-library:mainfrom
wahidrizka:fix/display-value-option-label
Open

fix: use an option's label attribute for toHaveDisplayValue#734
wahidrizka wants to merge 1 commit into
testing-library:mainfrom
wahidrizka:fix/display-value-option-label

Conversation

@wahidrizka

Copy link
Copy Markdown

What

toHaveDisplayValue reads option.textContent for <select> elements. When an option carries a label attribute, that attribute is what the browser renders, so the matcher reports the wrong value:

<select data-testid="dropdown">
  <option value="apple" label="Apple"></option>
</select>
expect(screen.getByTestId('dropdown')).toHaveDisplayValue('Apple')
// Expected: ["Apple"]
// Received: [""]

The README already promises "the displayed value (the one the end user will see)", so the docs were right and the implementation was not.

Closes #507.

Fix

.map(option => option.getAttribute('label') || option.textContent)

Per the HTML spec, an option's label is the label content attribute if there is one and its value is not the empty string, otherwise the option's text. || covers all three cases: attribute absent (getAttribute returns null), attribute present but empty (''), and attribute present with a value.

That empty-string case is why I did not use hasAttribute('label'), which the issue suggests: <option label="">Apple</option> renders as Apple, not as an empty string. There is a test covering it.

Tests

Two added to src/__tests__/to-have-display-value.js, one per branch of that rule. The first fails on main and passes with the change; the second passes either way and exists to keep a naive fix from regressing it.

I ran the whole suite before and after: 94 tests fail on main unchanged (pre-existing snapshot colour mismatches in unrelated files) and exactly the same 94 fail afterwards, with 4 more passing. eslint and prettier --check are clean on both touched files.

The matcher promises the value the end user sees, but it read only
option.textContent. An option that carries a label attribute renders
that label instead, so <option value="apple" label="Apple"></option>
reported an empty display value.

Falls back to the option text when the label attribute is missing or
empty, which is how the HTML spec defines an option's label.

Closes testing-library#507
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

toHaveDisplayValue does not use consider label attribute on option elements

1 participant