选择一个项目,该项目会呈现出与搜索匹配的项目的下拉列表。

huangapple go评论60阅读模式
英文:

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(&#39;input[placeholder=&quot;Search Something&quot;]&#39;).type(&#39;Your search query&#39;).type(&#39;{enter}&#39;);
cy.contains(&#39;div span&#39;, &#39;XXXXX XXX&#39;).click();

or 

cy.get(&#39;div[role=&quot;listbox&quot;]&#39;)
  .contains(&#39;span&#39;, &#39;XXX XXX&#39;)
  .should(&#39;exist&#39;)
  .click();

Below is the inspection from the page:

&lt;div 
  class=&quot;w-full&quot; 
  id=&quot;headlessui-combobox-button-137&quot; 
  tabindex=&quot;-1&quot; 
  aria-haspopup=&quot;listbox&quot; 
  aria-expanded=&quot;true&quot; 
  data-headlessui-state=&quot;open&quot; 
  aria-controls=&quot;headlessui-combobox-options-139&quot;
&gt;
    &lt;input 
      placeholder=&quot;Search Subscribers&quot;  
      class=&quot;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&quot;  
      id=&quot;headlessui-combobox-input-138&quot;  
      role=&quot;combobox&quot;  
      type=&quot;text&quot;  
      aria-expanded=&quot;true&quot;  
      aria-autocomplete=&quot;list&quot;  
      data-headlessui-state=&quot;open&quot;  
      value=&quot;Prod&quot;  
      aria-controls=&quot;headlessui-combobox-options-139&quot;  
      aria-activedescendant=&quot;headlessui-combobox-option-156&quot;
    &gt;
&lt;/div&gt;

Below is the extract from the page the drop down:

&lt;div 
  class=&quot;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&quot;  
  aria-labelledby=&quot;headlessui-combobox-button-137&quot;  
  role=&quot;listbox&quot;  
  aria-multiselectable=&quot;true&quot;  
  id=&quot;headlessui-combobox-options-139&quot;  
  data-headlessui-state=&quot;open&quot;
&gt;
    &lt;div  
      class=&quot;relative h-full max-h-60 p-2 overflow-y-auto&quot;   
      role=&quot;none&quot;
    &gt;
        &lt;div   
          class=&quot;relative&quot;    
          style=&quot;height: 32px;&quot;    
          role=&quot;none&quot;   
        &gt;   
        &lt;div    
          class=&quot;absolute top-0 left-0 w-full&quot;     
          id=&quot;headlessui-combobox-option-156&quot;     
          role=&quot;option&quot;     
          tabindex=&quot;-1&quot;     
          aria-selected=&quot;true&quot;     
          data-headlessui-state=&quot;active selected&quot;     
          style=&quot;transform: translateY(0px);&quot;    
        &gt;    
          &lt;span     
            class=&quot;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&quot;   
          &gt;   
              &lt;span    
                class=&quot;w-1/2 xl:w-1/3 inline-block text-xs&quot;&gt;+1 251 230 8828   
              &lt;/span&gt;   
              &lt;span    
                class=&quot;w-1/2 xl:w-1/3 inline-block text-xs&quot;   
              &gt;   
                  &lt;div class=&quot;text-ever-green&quot;&gt;Prod 701&lt;/div&gt;
              &lt;/span&gt;
              &lt;span class=&quot;w-1/3 hidden xl:inline-block text-xs&quot;&gt; 
                  &lt;div&gt; 

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=&quot;listbox&quot;] and [role=&quot;option&quot;], which would be the equivalent to &lt;select&gt; and &lt;option&gt; 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(&#39;[role=&quot;listbox&quot;]&#39;)
  .find(&#39;[role=&quot;option&quot;]:contains(&quot;XXX XXX&quot;)&#39;)  // 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(&#39;selecter&#39;, (selectSelector, value) =&gt; {
  cy.get(selectSelector).scrollIntoView();
  cy.get(selectSelector).click({ force: true });

  const options = () =&gt;
    cy.get(&#39;listbox&#39;).find(&#39;option&#39;);
  if (typeof value === &#39;string&#39;) {
    // 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 === &#39;number&#39;) {
    // Else if it&#39;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 &#39;${value}&#39; (${typeof value}).`,
  );
});

huangapple
  • 本文由 发表于 2023年6月12日 18:30:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76455762.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定