Codeception waitForElement方法等效于什么?

时间:2018-06-19 13:28:51

标签: testing codeception end-to-end cypress

Codeception::waitForElement

我正在从基于PHP的测试框架重写一些测试。我在检测由Ajax POST请求获取的新DOM元素时遇到问题。

当我使用时:

cy.wait(timeout);

我能够填充根据Ajax请求加载的文本输入,但这是一种反模式。

我还尝试了以下解决方案:https://github.com/cypress-io/cypress/issues/937#issuecomment-345786498-在我的情况下不起作用。

2 个答案:

答案 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