如果没有找到元素,我可以防止赛普拉斯cy.get失败吗?



我正在使用赛普拉斯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.

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

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

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的更改,它目前被阻止了。

这个问题正在处理中,但与此同时,这里有一个关于.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`))

下面是我用来测试它的网页。它最初没有<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)

我有一个类似的情况:如果没有找到元素,我希望测试成功,但如果有元素,我需要用 should.我遇到了这个问题,根据贾斯汀先生的回答,我想出了以下内容:

        cy.get('td:eq(0) i').should("have.length.gte", 0).then (($hits) => {
            cy.log ('number of hits: ' + $hits.length)
            if ($hits.length == 0) {
                cy.log ('no hits OK');
                cy.wrap (true);
            }
            else {
                cy.log ('hits. test hits....');
                // this is only an example
                cy.wrap($hits).should('have.css',
                            'color').and('equal', 'rgb(170, 181, 0)');
            
            }
        });

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

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

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

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

我们可以使用此解决方案在 DOM 中查找可选元素。

我将其添加为常量函数。

`export const optionalFindingElement = (element: string) => {
  return Cypress.$(element).length;
};
`

然后像这样使用它:

`Given('There are not assets generated by cypress in the kanban', () => {
  const assetNumber = optionalFindingElement('[data-fx-name="assetName"]');
  if (assetNumber > 0) {
   // Do something if the element was found
  } else {
 // Do something if the element was not found
}
});

'

干杯!

相关内容

  • 没有找到相关文章

最新更新