英文:
How to select an item which renders a drop-down list of items that match a search
问题
我正在尝试选择一个项目,该项目会呈现与搜索匹配的项目的下拉列表。
在打开下拉列表后,我选择正确的项目。id
值会更改,因此不能使用它们。
这是 Cypress 中的脚本:
cy.get('input[placeholder="Search Something"]').type('Your search query').type('{enter}');
cy.contains('div span', 'XXXXX XXX').click();
或
cy.get('div[role="listbox"]')
.contains('span', 'XXX XXX')
.should('exist')
.click();
以下是页面的检查:
<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>
以下是页面中下拉列表的抽取:
<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>
欢迎任何解决方案。
英文:
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.
答案1
得分: 2
这是一个 HeadlessUi
组件,它使用 div
元素构建组件,如代码示例所示。
避免更改 id
要访问测试所需的部分,您可以使用 [role="listbox"]
和 [role="option"]
,这相当于普通 HTML5 中的 <select>
和 <option>
。
使用正确的命令序列
列表框和选项之间的关系是父子关系,因此建议使用 get().find()
而不是 get().contains()
。
按照您所做的方式,"subject"(查询的元素)是 listbox
而不是 option
,并且单击父级 listbox
不会选择 option
。
cy.get('[role="listbox"]')
.find('[role="option"]:contains("XXX XXX")') // 要小心括号和引号
.click();
英文:
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 recommend get().find()
.
The way you have done it, the "subject" (the queried element) is the listbox
instead of the option
, and click the parent listbox
doesn't make an option
selection.
cy.get('[role="listbox"]')
.find('[role="option"]:contains("XXX XXX")') // be careful with brackets and quote marks
.click();
答案2
得分: 0
以下是我从自己的代码中改编的用于Mantine下拉框的函数。它应该可以在你的测试规范中作为一个简单的函数调用。
Cypress.Commands.add('selecter', (selectSelector, value) => {
cy.get(selectSelector).scrollIntoView();
cy.get(selectSelector).click({ force: true });
const options = () =>
cy.get('listbox').find('option');
if (typeof value === 'string') {
// 如果给定的值是一个字符串,选择具有该标签的选项
return options()
.contains(value, { matchCase: false })
.click({ force: true });
}
if (typeof value === 'number') {
// 否则,如果它是一个数字,选择该索引处的选项
return options()
.eq(value)
.click({ force: true });
}
throw new Error(
`value should be a string or number, but was '${value}' (${typeof value}).`,
);
});
希望这对你有所帮助。
英文:
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.
Cypress.Commands.add('selecter', (selectSelector, value) => {
cy.get(selectSelector).scrollIntoView();
cy.get(selectSelector).click({ force: true });
const options = () =>
cy.get('listbox').find('option');
if (typeof value === 'string') {
// If the given value is a string, select the option with that label
return options()
.contains(value, { matchCase: false })
.click({ force: true });
}
if (typeof value === 'number') {
// Else if it's a number, select the option at that index
return options()
.eq(value)
.click({ force: true });
}
throw new Error(
`value should be a string or number, but was '${value}' (${typeof value}).`,
);
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论