2

I've successfully implemented the Semantic-UI Dropdown to display a list of companies. Now I'm trying to build Jest / React Testing Library tests for it. To accomplish this, I built this Mock Request:

beforeEach(() => {
  request.get = jest.fn(() => Promise.resolve({
    companies: [
      {"company_id": 1, "company_name": "ABC"},
      {"company_id": 2, "company_name": "DEF"}
    ]
  }));
});

Based on a console.log I added to my component code, this appears to work as expected.

Here's an abridged example of my instance of this element:

<div id="companyId" data-testid="companies-dropdown" role="combobox">
  <input autocomplete="companyId" class="search" type="text">
  <div class="default text" "role="alert">Ex. ABC Corp</div>
  <div role="listbox">
    <div role="option"><span class="text">ABC</span></div>
    <div role="option"><span class="text">DEF</span></div>
  </div>
</div>

Where I'm struggling is to correctly wait in my test for the Dropdown to get populated:

it('Should populate the Search and Select Company dropdown with 2 companies', async () => {
  const { getByTestId, getByText, getByRole } = displayModal();
  const listBox = await waitForElement(() => getByRole('listbox'));
});

The error message is: Unable to find an accessible element with the role "listbox"

I also tried this alternate approach but got the same error message:

const listBox = await waitForElement(() => within(getByTestId('companies-dropdown')).getByRole('listbox'));

Might anyone have any ideas what I'm doing wrong?

robertwerner_sf
  • 1,091
  • 4
  • 21
  • 35

1 Answers1

1

I happened to see this while I was searching something else. But in your case, you are using wrong role. I achieved my use case with the following:

  • First focus the input element of the div to open dropdown. I use the input element:
    • userEvent.click(getByLabelText('Company'))
    • The above can be replaced by using data-testid or with role 'combobox'
  • Get all the roles for the select options:
    • getAllByRole('option')

const companyAbc = getAllByRole('option').find(ele => ele.textContent === 'ABC') userEvent.click(companyAbc); // verify your onChange event

In your async case:

const companyAbc = await findAllByRole('option').find(ele => ele.textContent === 'ABC') userEvent.click(companyAbc); // verify your onChange event

SemanticReact also has onSearchChange event that you can use to trigger for every input search if that's the use case.

Karthik R
  • 5,523
  • 2
  • 18
  • 30