赛普拉斯包含忽略元素

Cypress contains ignore elements

我想使用 cypress 查找可点击的元素。可点击元素始终包含文本“登录”并且位于容器 div 内。但是,问题是我不知道可点击元素是使用 <button><a> 还是 <input type="submit">.

建模的

我的HTML有时是这样的:

<nav>
  <button>Wrong Login Button</button>
</nav>
<div class='container'>
  ...
  <div>
    <h2>Login</h2>
    ...
    <button>Login</button>
  </div>
</div>

有时像这个例子:

<div class='container'>
  ...
  <div>
    <h2>Login</h2>
    ...
    <div>
        <div>
          <a>Login</a>
        </div>
    </div>
  </div>
</div>

有时是 <button>,有时是 <a><input type="submit">。有时还有更多嵌套的 div 在那里。

如何使用 cypress 找到可点击元素(按钮、a 或提交)元素?

我只想找到可点击的元素,所以如果有标题为“登录”的文本,应该忽略它。

这几乎就是答案:

cy.get('.container').contains('Login')

但是,我不知何故需要忽略除(按钮、a 和输入[type=submit])之外的所有元素。因为否则它将 return

Login

我需要这样的东西:

cy.get('.container').find('button OR a OR input[type=submit]').contains('Login')  

我想写一个可以用作下面示例的自定义命令:

cy.get('.container').findClickable('Login')

实施可能类似于以下示例:

Cypress.Commands.add('findClickable', {prevSubject: ['element']}, (
    subject: Cypress.Chainable<HTMLElement>,
    text: string,
    options?: Partial<Cypress.Loggable & Cypress.Timeoutable & Cypress.Withinable & Cypress.Shadow>,
) => {
  const buttons = cy.wrap(subject).find('button').contains(text)
  const links = cy.wrap(subject).find('a').contains(text)
  const submits = cy.wrap(subject).find('input[type=submit]').contains(text)

  if (buttons.length + links.length + submits.length !== 1) {
    throw new DOMException(
        `Didn't find exactly one element. Found ${buttons.length} buttons, ${links.length} links, and ${submits.length} submits.`)
  }

  if (buttons.length === 1)
    return buttons[0]
  else if (links.length === 1)
    return links[0]
  else
    return submits[0]
})

我知道上面的代码由于多种原因无法运行。首先,没有 .length 属性,其次,由于第一个 find('buttons') 方法超时,cypress 会失败。

有谁知道如何正确执行自定义命令?

您可以结合选择器和文本使用 withincontains 命令。

cy.get('.container').within(() => {
  cy.contains('button', 'Login').click()
  cy.get('input[type=submit]').click()
  cy.contains('Login').click()
})

对于多重登录,首先我们检查按钮是启用还是禁用,然后我们点击它。

cy.contains('Login').each(($ele) => {
  if($ele.is(":enabled")){
    cy.wrap($ele).click()
  }
})

你也可以,这是对上述代码段进行了更优化的代码。

cy.contains('Login').filter(':enabled').click()

用逗号分隔时可以搜索多个选择器:

cy.get('button, a, input[type=submit]')

因此,搜索所有可点击元素,然后筛选包含所需文本的可点击元素。

Cypress.Commands.add('findClickable', {prevSubject: ['element']}, (
    subject: Cypress.Chainable<HTMLElement>,
    text: string,
    _options?: Partial<Cypress.Loggable & Cypress.Timeoutable & Cypress.Withinable & Cypress.Shadow>,
) =>
  cy.wrap(subject)
      .find('button, a, input[type=submit]')
      .filter(':contains(' + text + ')'),
)

用法:

cy.get('.container').findClickable('Login')