【问题标题】:Cypress does not always executes click on element赛普拉斯并不总是执行点击元素
【发布时间】:2018-12-17 16:37:12
【问题描述】:

我正在自动化 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) 之后仍然遇到同样的问题。

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

项目结构为:

  • cypress/PageObject.js - 声明所有元素的地方。
  • cypress/support/commands.js - 创建函数点击的位置和 验证价值得到更新。
  • cypress/integration/functional/delete.spec.js - 测试在 视频

【问题讨论】:

标签: javascript testing automated-tests cypress


【解决方案1】:

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

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

另外添加:cy.wait(150)beforeEach点击测试失败的地方之前

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

Link to Cypress Issue

我也看到了这个替代方案:

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

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

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

【讨论】:

  • 另外添加:cy.wait(150):这绝不是一个好主意。 Cypress 基于异步意识形态,通过查询元素变得可见等情况,等待应该是隐式的。
  • 我同意,但在我的具体情况下,没有其他任何工作。还有一个帖子,多人有相同类型的问题。现在我没有找到更好的解决方案。答案中附有网址。
  • 投了反对票,因为:1. cy.wait() 永远不是解决方案 2. force:true 不保证点击成功
  • @PraveenPandey 当您投反对票时,请提出更好的解决方案。 Cypress 是一个相当新的工具,有时糟糕的解决方案总比没有解决方案好。
  • 在 DOM 中显示的控件、单击事件调度和另一个渲染再次弹跳之间可能存在竞争。浏览器在这方面并不完美。我在本地无头运行中经历了 100% 的通过,然后在机器速度较慢的 CI 管道中失败了 95%。单击按钮。最好有一个理想且坚固的等待点,但有时等待会让您畅通无阻。 +1
【解决方案2】:

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

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

赛普拉斯建议在底层 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')
})

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 不知道为什么这被否决了,但这是让我的脚本始终如一地工作的唯一答案
    • 这对我也有用,由于某种原因,它需要在 .click() 之前使用 .trigger('mouseover').
    • 鼠标悬停会导致隐式等待。 :/ 允许渲染在点击调度之前解决。可能实际上与 wait() 解决方案没有什么不同,只是实现不同:)
    • 在我的情况下,不管你 cy.wait() 有多少时间。它没有用。这是我唯一可行的解​​决方案。
    【解决方案4】:

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

    TLDR: @jpvantuyl 所说的,cypress 在 onclick 事件出现之前点击了按钮。 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
    

    【讨论】:

      【解决方案5】:

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

      之前:

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

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

      修复:

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

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

      【讨论】:

        【解决方案6】:

        这里是 2022 年,并使用 cypress 版本进行了测试:

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

        我的解决方案:

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

        说明:

        就我而言,我需要更深入地观察正在发生的事情。我首先将click 操作固定为这样:

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

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

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

        所以我只是通过以下方式简化了点击:

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

        它奏效了?

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

        【讨论】:

        • 在这里感谢您的贡献!这解决了我遇到的问题。
        • @marcacyr 很高兴这对您有所帮助 :)
        • 实际上(2021 年 11 月)这是使单个按钮单击 15 次的唯一方法(例如,在显示月份的日历中单击下一步)。所有其他方式都会错过一次或多次点击!
        【解决方案7】:

        FWIW:我在选择 Google 地方信息地址后提交/导航时遇到问题。我相信我的组件没有重新呈现邮政地址选择。

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-01
            • 1970-01-01
            相关资源
            最近更新 更多