Cypress 并不总是执行点击元素

Cypress does not always executes click on element

我正在自动化 Google 计算器。 有时赛普拉斯无法执行点击按钮。 测试单击按钮(0 到 9)并执行一些简单的数学运算。 并且有 30% 的机会它无法点击元素并且测试将失败。

出现问题时我也录了视频

Video here

我的项目位于: https://github.com/afiliptsov/test-project

To run the test run : "npm run test:e2e:functional"

我尝试使用不同的定位器。最初我只使用 ID ex(#cwbt15) 但在我做了更具体的定位器之后 (#cwbt15 > .cwbtpl > .cwbts) 并且仍然有同样的问题。

有谁知道为什么会发生这种情况以及如何避免这种行为?

项目结构为:

对我来说,这段代码有效:

在你的点击方法中添加:{ force: true }它会强制点击。

同时添加:cy.wait(150)beforeEachbefore click where your test fails.

这只是解决方法,不是解决方案。

Link to Cypress Issue

我也看到了这个选择:

cy.get('#query-btn').invoke('width').should('be.gt', 0)

cy.get('#query-btn').invoke('width').should('be. greaterThan', 0)

但我没有成功。也许对某人有用!

这可能是因为应用程序通过 JavaScript 将行为附加到按钮。当该脚本需要很长时间执行时,它允许 Cypress 在 OnClick 事件出现之前 单击按钮

参见:https://www.cypress.io/blog/2018/02/05/when-can-the-test-start/

Cypress 建议在底层 JS 就位时进行跟踪,例如:

function waitForAppStart() {
  // keeps rechecking "appHasStarted" variable
  return new Cypress.Promise((resolve, reject) => {
    const isReady = () => {
      if (appHasStarted) {
        return resolve()
      }
      setTimeout(isReady, 0)
    }
    isReady()
  })
}
it('greets', () => {
  cy.visit('app.html', {
    onBeforeLoad: spyOnAddEventListener
  }).then(waitForAppStart)
  // all other assertion will run only when
  // the application has started
  cy.get('#name').type('Cypress{enter}')
  cy.contains('#answer', 'Cypress')
})

https://github.com/cypress-io/cypress/issues/2928帮了我。

cy.get('[data-qa="select_workers-list"]'.contains('+ New Worker').trigger('mouseover').click();

谁发现了这个问题,官方的处理方法在这里描述:https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/

TLDR: @jpvantuyl 所说的,赛普拉斯在 onclick 事件出现之前点击了按钮。 lib cypress-pipe 将添加一个 .pipe 方法,如果后跟 .should 将重试一个函数,直到条件为真或超时。

示例:

cy
  .get(numbers.result.idLocator)
  .pipe($el => $el.click()) // try this
  .pipe(
    // next line will make assertions on the element returned by this pipe
    () => cy.get(calculatorScreen.resultOutput.idLocator)
  )
  .should("contain", "0"); // until this happens or times out

在 none 以上对我有用并经过数小时的搜索后,我刚刚从一位同事那里学到了一些东西。简直让我大吃一惊。只需添加另一个 .click()...

之前:

cy.contains('some string').click(); 

在左侧的 Cypress 菜单中单击操作,您会看到指示器表明它单击了正确的部分,但没有任何反应。在浏览器中手动操作并且有效。

修复:

cy.contains('some string').click().click();

突然间,字符串被点击,测试进入下一页

此处为 2022 并使用赛普拉斯版本进行了测试:

  • "6.x.x""7.x.x""8.x.x""9.x.x"

我的解决方案:

cy.get("YOUR_SELECTOR").trigger("click");

解释:

就我而言,我需要更深入地观察正在发生的事情。我开始像这样固定 click 动作:

然后查看控制台,您应该会看到如下内容:

现在点击行 Mouse Events,它应该显示一个 table:

所以基本上,当 Cypress 执行 click 函数时,它会触发所有这些事件,但不知何故我的组件的行为方式是在 click event 被触发的那一刻分离。

所以我只是简化了点击操作:

cy.get("YOUR_SELECTOR").trigger("click");

它奏效了

希望这能解决您的问题,或者至少能帮助您调试并了解问题所在。

FWIW:在 Google Places 地址选择后,我遇到了问题 submitting/navigating。我相信我的组件没有重新呈现 post-地址选择。

为了解决我的问题,在选择地址后,我选择了一个随机文本元素,点击它(无操作),然后点击我的继续按钮,它工作正常。

我将我的应用程序从呈现为 SPA 切换为使用 SSR(基本上从我的 svelte.config 中删除了 ssr: false),这开始使我的 Cypress 测试失败。还原修复了我的测试设置。

我不知道为什么,但这对我有用:

cy.get('[role="button"][aria-haspopup="listbox"]').trigger('mouseover').wait(1000).click().click({force:true});

在我的例子中,我必须确保按钮可见(或未禁用),然后鼠标悬停,然后单击:

 cy.contains(/activate/i)
  .should('be.visible')
  .trigger('mouseover')
  .click({ force: true });

PS。 /***/i 表示忽略字母大小写。