我正在从基于PHP的测试框架重写一些测试。我在检测由Ajax POST请求获取的新DOM元素时遇到问题。
当我使用时:
cy.wait(timeout);
我能够填充根据Ajax请求加载的文本输入,但这是一种反模式。
我还尝试了以下解决方案:https://github.com/cypress-io/cypress/issues/937#issuecomment-345786498-在我的情况下不起作用。
答案 0 :(得分:3)
您可以简单地使用cy.get()
来等待某些DOM
元素的呈现。赛普拉斯将重试,直到timeout
为止:
cy.get('.request-button').click()
cy.get('.some-new-element', {timeout: 10000})
// Cypress waits up to 10 seconds for element to appear
cy.get('.new-button').click()
// continue with test knowing the DOM has
...
那么您将遇到一个更大的问题,因为无论如何您都需要使用选择器对元素执行操作。
在这种情况下,可以使用cy.contains()
对文本嵌套在元素内的任何位置进行声明:
cy.contains('.common-class', 'new text', {timeout:10000})
您无法执行此操作:
cy.get('.common-class).contains('new text')
因为在成功完成DOM
之后,赛普拉斯将不会再次查询cy.get()
,所以只看已经找到的.common-class
DOM node
进行更改。< / p>
答案 1 :(得分:0)
我也需要这个,所以以为我会写一个custom Cypress command
在Condeception source code中,我无法查明waitForElement
的来源,但是该库是在搜索azu/wait-for-element.js中打开的。
它有一个非常简单的实现,因此这是我对赛普拉斯命令的翻译,除了没有删除赛普拉斯的Promise逻辑外,其余代码基本相同。
我无法确切地说出是否是一种好的做法,但它似乎可以解决我到目前为止进行的一些粗略测试。
/cypress/support/wait-for-element.command.js
Cypress.Commands.add('waitForElement', (selector, timeout) => {
var timeoutOption = timeout || 2000;// 2s
var loopTime = 100;
var tryCount = 0;
var limitCount = timeoutOption / loopTime;
var limitCountOption = (limitCount < 1) ? 1 : limitCount;
function tryCheck(resolve, reject) {
if (tryCount < limitCountOption) {
cy.get(selector).then(element => {
if (element != null) {
return element
}
setTimeout(function () {
tryCheck(resolve, reject);
}, loopTime);
})
} else {
throw "Not found element match the selector:" + selector
}
tryCount++;
}
return tryCheck();
})
/cypress/support/commands.js
require('./wait-for-element.command.js')
...
/cypress/integration/my-tests.spec.js
cy.waitForElement('div#theid.aclass', 3000).then(x=> console.log(x))
// the .then() is not required, is just for initial checking via console