繁体   English   中英

赛普拉斯:如果找不到任何元素,我可以防止赛普拉斯 cy.get 失败吗?

[英]Cypress: Can I prevent Cypress cy.get from failing if no elements are found?

我正在使用 Cypress cy.get来抓取元素,但如果没有,我的测试就会失败。 我不希望它失败。 我希望它继续。 测试只是简单地列出那里的项目,如果有的话。

const listItemTitle = '[data-cy-component=list-item-title]';
cy.get(listItemTitle).each(($el, index, $list) => {
  cy.wrap($el).then(($span) => {
    const spanText = $span.text();
    cy.log(`index: ` + index + ' ' + spanText);
  });
});

我本以为,如果那里没有元素——这段代码仍然可以,但事实并非如此。 当我运行它时,出现此错误: CypressError: Timed out retrying: Expected to find element: '[data-cy-component=list-item-title]', but never found it.

它在存在元素的地方工作正常。 如果没有找到元素,我想 go on & 做一个不同的测试。

这是我尝试过的一个实验:

let count: number = Cypress.$(listItemTitle).length;
cy.log('before:' + count);
cy.get(actionsBarActionsAdd).click();
cy.get(singlePickerSearch).type('Assets' + '{enter}');
cy.get(listItemCheckboxTitle)
  .first()
  .click();
cy.toast({
  type: 'Success',
});
count = Cypress.$(listItemTitle).length;
cy.log('after:' + count);
cy.get(listItemTitle).each(($li, index, $lis) => {
  cy.log('interface no. ' + (index + 1) + ' of ' + $lis.length);
  cy.wrap($li).click();
});

这是结果:

18 LOG        before:0
19 GET       [data-cy-component-key="actions-add"] input
20 CLICK
21 GET       [data-cy-component=single-picker-search] input
22 TYPE      Assets{enter}
23 GET       [data-cy-component="list-item-checkbox-title"]
24 FIRST
25 CLICK
26 GET       .iziToast    toast2
27 ASSERT    expected [ <div.iziToast.iziToast-opening.fadeInUp.iziToast-theme- 
alloy.iziToast-color-green.iziToast-animateInside>, 1 more... ] to have class iziToast-color-green
28 LOG       after:0
29 GET       [data-cy-component=list-item-title]
30 LOG       interface no. 1 of 1

最终表明Cypress.$(listItemTitle).length不计算带有选择器的元素数:listItemTitle。

更新:

通过放置cy.wait(1000) 在执行 Add 之后(在我的实验中)——让 DOM 有时间更新——找到了新元素。 使用更具体的选择器,不需要等待

您可以通过Cypress.$使用 jquery 来检查是否存在。

const listItemTitle = '[data-cy-component=list-item-title]';
if (Cypress.$(listItemTitle).length > 0) {
  cy.get(listItemTitle).each(($el, index, $list) => {
    cy.wrap($el).then(($span) => {
    const spanText = $span.text();
    cy.log(`index: ` + index + ' ' + spanText);
    });
  });
}

赛普拉斯 12 的更新

执行此操作的理想方法是使用 Gleb Bahmutov 的cypress-if ,但由于 Cypress 版本 12 的更改,它目前已被阻止。

这个问题正在处理中,但与此同时,这里有一个 hack on .should()执行重试检查,但在没有元素出现时不会失败 - 基于@M.Justin 的方法。

let start = Date.now()

const commandRetry = ($subject, {assert, timeout}) => {
  const elapsed = Date.now() - start
  console.log(elapsed, assert($subject))
  if (elapsed < timeout && !assert($subject)) {
    const err = new Error('Retry')
    err.isDefaultAssertionErr = true
    throw err
  }
}

cy.get('li')
  .should($subject => commandRetry($subject, { 
    assert: ($subject) => $subject.length > 0, 
    timeout: 3000 
  }))
  .should("have.length.gte", 0)
  .then($subject => cy.log(`Found ${$subject.length} items`))

下面是我用来测试的web页面。 它最初没有<li>元素,两秒后添加一个。

您可以看到测试在控制台中重试断言,并在2 秒后通过。

如果您注释掉页面上的脚本,因此没有添加<li> ,您会看到测试运行了4 秒但没有失败。

如果这两种情况都会记录正确的元素计数。

<ul></ul>
<script>
  setTimeout(() => {
    const ul = document.querySelector('ul')
    const li = document.createElement('li')
    li.innerText = 'A list item'
    ul.appendChild(li)
  }, 2000)
</script>

您可以使用cy.get(".field").should("have.length", 0)

以下检索项目,即使没有:

cy.get(listItemTitle).should("have.length.gte", 0)

请注意,如果页面可能仍在加载项目,这不会等待项目存在,因此这可能会在元素尚未存在之前返回。 当您知道这些项目已经加载时,使用它应该是安全的。

这种模式很容易导致有问题的测试,因此请注意何时以及如何使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM