Cypress 并不总是执行点击元素
Cypress does not always executes click on element
我正在自动化 Google 计算器。
有时赛普拉斯无法执行点击按钮。
测试单击按钮(0 到 9)并执行一些简单的数学运算。
并且有 30% 的机会它无法点击元素并且测试将失败。
出现问题时我也录了视频
我的项目位于:
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 - 测试
视频
对我来说,这段代码有效:
在你的点击方法中添加:{ force: true }
它会强制点击。
同时添加:cy.wait(150)
到 beforeEach 或 before click where your test fails.
这只是解决方法,不是解决方案。
我也看到了这个选择:
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
表示忽略字母大小写。
我正在自动化 Google 计算器。 有时赛普拉斯无法执行点击按钮。 测试单击按钮(0 到 9)并执行一些简单的数学运算。 并且有 30% 的机会它无法点击元素并且测试将失败。
出现问题时我也录了视频
我的项目位于: 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 - 测试 视频
对我来说,这段代码有效:
在你的点击方法中添加:{ force: true }
它会强制点击。
同时添加:cy.wait(150)
到 beforeEach 或 before click where your test fails.
这只是解决方法,不是解决方案。
我也看到了这个选择:
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
表示忽略字母大小写。