如何使用赛普拉斯检查可能不存在的元素

How to check for an element that may not exist using Cypress

我正在编写 Cypress 测试以登录网站。有 usernamepassword 字段以及一个 Submit 按钮。大多数登录都很简单,但有时会先出现一个警告对话框,必须将其关闭。

我试过这个:

cy.get('#login-username').type('username');
cy.get('#login-password').type(`password{enter}`);

// Check for a possible warning dialog and dismiss it
if (cy.get('.warning')) {
  cy.get('#warn-dialog-submit').click();
}

效果很好,但如果未出现警告则测试失败:

CypressError: Timed out retrying: Expected to find element: '.warning', but never found it.

然后我尝试了这个,但失败了,因为警告出现的速度不够快,所以 Cypress.$ 没有找到任何东西:

cy.get('#login-username').type('username');
cy.get('#login-password').type(`password{enter}`);

// Check for a possible warning dialog and dismiss it
if (Cypress.$('.warning').length > 0) {
  cy.get('#warn-dialog-submit').click();
}

检查元素是否存在的正确方法是什么?我需要类似 cy.get() 的东西,如果找不到该元素,它不会抱怨。

尝试对 DOM 元素进行条件测试有多种缺点,赛普拉斯也有多种解决方法。 Conditional Testing.

中的赛普拉斯文档对所有这些内容进行了深入解释

由于有多种方法可以完成您想要做的事情,我建议您通读整个文档并确定最适合您的应用程序和测试需求的方法。

export function clickIfExist(element) {
    cy.get('body').then((body) => {
        if (body.find(element).length > 0) {
            cy.get(element).click();
        }
    });
}

我是用纯js搞定的

cy.get('body').then((jqBodyWrapper) => {

               if (jqBodyWrapper[0].querySelector('.pager-last a')) {
                   cy.get('.pager-last a').then(jqWrapper => {
                       // hardcoded due to similarities found on page

                       const splitLink = jqWrapper[0].href.split("2C");
                       AMOUNT_OF_PAGES_TO_BE_RETRIEVED = Number(splitLink[splitLink.length - 1]) + 1;
                   })
               } else {
                   AMOUNT_OF_PAGES_TO_BE_RETRIEVED = 1;
               }
           });

我正在尝试检查正文中是否存在元素

cy.get('body').then((jqBodyWrapper) => {

用纯js的querySelector

if (jqBodyWrapper[0].querySelector('.pager-last a')) {

然后我开火 cy.get

cy.get('.pager-last a').then(jqWrapper => {

hasClass() 或 CSS 选择器 has() 是 jQuery 中的一个内置方法,它检查具有指定 class 名称的元素是否存在或不是。然后,您可以 return 一个布尔值来执行断言控制。

Cypress.Commands.add('isExistElement', selector => {
  cy.get('body').then(($el) => {
    if ($el.has(selector)) {
      return true
    } else {
      return false
    }
  })
});

然后可以用TypeScript文件(index.d.ts)文件做成一个特殊的cypress方法,可以是chainable的形式

declare namespace Cypress {
    interface Chainable {
        isExistElement(cssSelector: string): Cypress.Chainable<boolean>
    }
}

如下例所示:

  shouldSeeCreateTicketTab() {
    cy.isExistElement(homePageSelector.createTicketTab).should("be.true");
  }
export const getEl = name => cy.get(`[data-cy="${name}"]`)

export const checkIfElementPresent = (visibleEl, text) => {
   cy.document().then((doc) => {
     if(doc.querySelectorAll(`[data-cy=${visibleEl}]`).length){
      getEl(visibleEl).should('have.text', text)

      return ;
   }
getEl(visibleEl).should('not.exist')})}