I’m attempting to select an item which renders a drop-down list of items that match a search.
I select the correct item once the drop-down list has been opened. The id
values changes so they cannot be used.
This is the script in Cypress:
cy.get('input[placeholder="Search Something"]').type('Your search query').type('{enter}');
cy.contains('div span', 'XXXXX XXX').click();
or
cy.get('div[role="listbox"]')
.contains('span', 'XXX XXX')
.should('exist')
.click();
Below is the inspection from the page:
<div
class="w-full"
id="headlessui-combobox-button-137"
tabindex="-1"
aria-haspopup="listbox"
aria-expanded="true"
data-headlessui-state="open"
aria-controls="headlessui-combobox-options-139"
>
<input
placeholder="Search Subscribers"
class="w-full inputFocus px-4 rounded-3xl text-ever-green font-beatrice font-normal transition-colors focus:border-cornflower-blue focus:outline-none outline-none placeholder:text-slate-gray h-smButtonHeight text-sm border-2 border-duck-egg-blue"
id="headlessui-combobox-input-138"
role="combobox"
type="text"
aria-expanded="true"
aria-autocomplete="list"
data-headlessui-state="open"
value="Prod"
aria-controls="headlessui-combobox-options-139"
aria-activedescendant="headlessui-combobox-option-156"
>
</div>
Below is the extract from the page the drop down:
<div
class="absolute z-10 w-full mt-2 overflow-auto text-base bg-white rounded-md shadow-dropdown max-h-60 focus:outline-none sm:text-sm left-0 right-0 mx-auto p-0"
aria-labelledby="headlessui-combobox-button-137"
role="listbox"
aria-multiselectable="true"
id="headlessui-combobox-options-139"
data-headlessui-state="open"
>
<div
class="relative h-full max-h-60 p-2 overflow-y-auto"
role="none"
>
<div
class="relative"
style="height: 32px;"
role="none"
>
<div
class="absolute top-0 left-0 w-full"
id="headlessui-combobox-option-156"
role="option"
tabindex="-1"
aria-selected="true"
data-headlessui-state="active selected"
style="transform: translateY(0px);"
>
<span
class="cursor-pointer flex items-center gap-x-2 py-1.5 px-4.5 font-medium text-sm transition-colors lg:truncate text-cornflower-blue bg-ice-blue"
>
<span
class="w-1/2 xl:w-1/3 inline-block text-xs">+1 251 230 8828
</span>
<span
class="w-1/2 xl:w-1/3 inline-block text-xs"
>
<div class="text-ever-green">Prod 701</div>
</span>
<span class="w-1/3 hidden xl:inline-block text-xs">
<div>
Any solutions welcomed.
2
Answers
Here is a function which I have adapted from my own for Mantine dropdown boxes. It should be able to be called simply as a function within your test specs.
This is a
HeadlessUi
component that constructs components from divs, as shown in the code sample.Avoiding changing ids
To access the parts needed for testing, you can use
[role="listbox"]
and[role="option"]
, which would be the equivalent to<select>
and<option>
in plain HTML5.Using the correct command sequence
The relationship between listbox and options is parent-child, so instead of
get().contains()
I recommendget().find()
.The way you have done it, the "subject" (the queried element) is the
listbox
instead of theoption
, and click the parentlistbox
doesn’t make anoption
selection.