英文:
Trying to choose any non-disabled option from a select element
问题
以下是您要的翻译部分:
"我有一个包含多个子记录的父记录,所有这些记录都在ViewParentWithChildren和EditParentWithChildren屏幕上一起显示。我想编写一个Cypress测试,向现有的父记录添加新的子记录。每个子记录当然都在一个<tr>中。
问题是,<select>元素中有许多<option disabled>无效选项。我需要选择一个有效且已启用的选项,但事先不知道该选项的名称/值是什么。我不关心它们是什么,我只需要选择任何非禁用的选项。
我尝试了一个标准的方法:
cy.contains('button', /Add Another Child Record/i).click();
cy.get('[name=child_id_name][value=""]')  // 新添加的子记录在必填字段中没有内容
      .parents('tr')
      .within(tr => {
        cy.get('input[name=child_id_name]').type(randomAlpha());
        cy.get('input[name=description]').type(randomAlpha());
        cy.get('select[name=type]').select(?????);  // 待办事项
      });
Cypress只允许通过名称、值或索引选择<option>。尝试直接选择有效的<option>是不起作用的,这是设计上的限制。"
英文:
I have a parent record with multiple child records, all shown together on the ViewParentWithChildren and EditParentWithChildren screens.  I want to write a cypress test that adds a new child record to an existing parent record. Each child record is in a <tr> of course.
The problem is, the <select> element has many <option disabled> invalid options in it. I need to select a valid, enabled one, and I don't know ahead of time what the names/values in that option are going to be.  I don't care what they are, I just need to select any non-disabled option.
I try a standard-ish:
cy.contains('button', /Add Another Child Record/i).click();
cy.get('[name=child_id_name][value=""]')  // newly added has nothing in the required field
      .parents('tr')
      .within(tr => {
        cy.get('input[name=child_id_name]').type(randomAlpha());
        cy.get('input[name=description]').type(randomAlpha());
        cy.get('select[name=type]').select(?????);  // TODO
      });
Cypress only allows selecting an <option> via name, value, or index. Attempting to .select a valid <option> directly doesn't work, by design.
答案1
得分: 1
以下是翻译好的部分:
示例页面用于POC
<select>
  <option value="1" disabled>three</option>
  <option value="2">two</option>
  <option value="3" disabled>three</option>
  <option value="4">four</option>
</select>
方法1:首先暴露<select>
cy.get('select')
  .should('have.value', '2')  // 默认情况下,选择的值是第一个已启用的
  .then($select => {
    cy.wrap($select)
      .find('option:enabled:last')
      .then($lastEnabledOption => {
        cy.wrap($select).select($lastEnabledOption.val())
      })
  })
  .should('have.value', '4')  // 检查新值
方法2:使用jQuery设置选定属性
cy.get('select')
  .should('have.value', '2')          // 初始值
  .find('option:enabled:last')
  .invoke('attr', 'selected', true)
cy.get('select')
  .should('have.value', '4')          // 新值
英文:
Here's a couple of other ways you may or may not find easier
Example page for POC
<select>
  <option value="1" disabled>three</option>
  <option value="2">two</option>
  <option value="3" disabled>three</option>
  <option value="4">four</option>
</select>
Method 1: Expose the <select> first
cy.get('select')
  .should('have.value', '2')  // by default the selected value is the first enabled
  .then($select => {
    cy.wrap($select)
      .find('option:enabled:last')
      .then($lastEnabledOption => {
        cy.wrap($select).select($lastEnabledOption.val())
      })
  })
  .should('have.value', '4')  // check new value
Method 2: Set the selected attribute with jQuery
cy.get('select')
  .should('have.value', '2')          // initial value
  .find('option:enabled:last')
  .invoke('attr', 'selected', true)
cy.get('select')
  .should('have.value', '4')          // new value
答案2
得分: 0
这个解决方案有点反其道而行。首先从选择中获取所有非禁用选项,然后进入其中之一,然后再返回到选择,将.text()提供给.select。
cy.contains('button', /Add Another Child Record/i).click();
cy.get('[name=child_id_name][value=""]')  // 新添加的字段在必填字段中没有内容
      .parents('tr')
      .within(tr => {
        cy.get('input[name=child_id_name]').type(randomAlpha());
        cy.get('input[name=description]').type(randomAlpha());
        cy.get('select[name=type] option:not([disabled])') // 获取所有非禁用选项
          .last() // 第一个选项通常为空,用于取消选择,所以选择最后一个
          .within(option => {
            cy.root().closest('select').select(option.text());
          });
      });
英文:
The solution was kind of inside-out. Get all non-disabled options from that select first, then go within one of them, and "escape hatch" back out again to the select, feeding the .text() to the .select
cy.contains('button', /Add Another Child Record/i).click();
cy.get('[name=child_id_name][value=""]')  // newly added has nothing in the required field
      .parents('tr')
      .within(tr => {
        cy.get('input[name=child_id_name]').type(randomAlpha());
        cy.get('input[name=description]').type(randomAlpha());
        cy.get('select[name=type] option:not([disabled])') // get all its non-disabled options
          .last() // the first option is usually blank for un-selecting, so, .last
          .within(option => {
            cy.root().closest('select').select(option.text());
          });
      });
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论