Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selectOptions` doesn't work when 'option' contains nested elements #546

Closed
escapiststupor opened this issue Jan 14, 2021 · 1 comment
Closed

Comments

@escapiststupor
Copy link

  • @testing-library/user-event version: 12.6.0
  • Testing Framework and version: RTL 11.2.3
  • DOM Environment: @testing-library/jest-dom@5.11.9

Relevant code or config

test('native', () => {
  render(
    <select data-testid="select">
      <option data-testid="val1" value="1">
        <span>A</span>
      </option>
      <option data-testid="val2" value="2">
        <span>B</span>
      </option>
      <option data-testid="val3" value="3">
        <span>C</span>
      </option>
    </select>,
  )

  userEvent.selectOptions(screen.getByTestId('select'), screen.getByText('A')) // like this won't pass

  expect(screen.getByTestId('val1').selected).toBe(true)
  expect(screen.getByTestId('val2').selected).toBe(false)
  expect(screen.getByTestId('val3').selected).toBe(false)
})

gives Unable to find an element with the text: A. 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.

However, if you remove the span element enclosing those options, it will work.

Reproduction repository: codesandbox here

Problem description: it checks for .value and .innerHTML but for nested components .innerHTML gives nothing meaningful, see https://github.com/testing-library/user-event/blob/master/src/select-options.js#L23

Suggested solution: I believe using innerText will be helpful in this situation but not sure this is the correct way to go. I found out this because I was testing a Mui Select component and unfortunately they wrap the <li role='option'><span>nested option</span></li>. Although this PR is a nice addition for a11y supported selections, it's somehow frustrating to find out that I can't use this API to test out Mui Select component. (There is an example in the codesandbox link.)

@ph-fritsche
Copy link
Member

Elements inside <option> are not permissible per spec.

As for Material-UI selects: They are no selects. The listbox and option are not even in the DOM before clicking the select (that is role="button").
You can test selecting an option though:

test('Mui select', () => {
  render(<SimpleSelect/>)

  const muiSelect = screen.getByLabelText('Age')
  userEvent.click(muiSelect)

  // you could also getByText but this one is recommended here
  userEvent.click(screen.getByRole('option', {name: /Ten/}))

  // you could also set a data-testid on the input per inputProps
  expect(muiSelect.nextSibling).toHaveValue('10')
})

I'm closing this because:
userEvent.selectOptions is the wrong API for the tested component.
screen.getByText (which this feature suggestion is aimed at) is the wrong API for accessible elements per the docs. It is also located at testing-library/dom.

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

No branches or pull requests

2 participants