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

Posted

技术标签:

【中文标题】如何使用赛普拉斯检查可能不存在的元素【英文标题】:How to check for an element that may not exist using Cypress 【发布时间】:2018-05-26 04:36:25 【问题描述】:

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

我试过了:

cy.get('#login-username').type('username');
cy.get('#login-password').type(`passwordenter`);

// 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(`passwordenter`);

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

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

【问题讨论】:

【参考方案1】:
export function clickIfExist(element) 
    cy.get('body').then((body) => 
        if (body.find(element).length > 0) 
            cy.get(element).click();
        
    );

【讨论】:

【参考方案2】:

尝试对 DOM 元素进行条件测试有很多缺点,赛普拉斯也有各种变通方法。所有这些都在Conditional Testing 的赛普拉斯文档中进行了深入解释。

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

【讨论】:

谢谢。我有一种感觉,我错误地处理了这个问题。我现在“获取”body 元素(它必须存在),然后测试它下面是否有警告对话框。工作正常。 @CharlesAnderson 你能分享你的测试代码吗?我需要做同样的事情 cy.get('body').then((body) => if (body.find('.warning').length > 0) cy.get('#warn-dialog-submit').click(); ); 如何接受这个答案?有进行条件测试的有效用例(例如服务器渲染的 DOM)。这个答案只不过是一记耳光并链接到文档。【参考方案3】:
 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'))

【讨论】:

【参考方案4】:

我是用纯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;
                
            );

我正在尝试检查 body 上是否存在元素

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

用一个纯js的querySelector

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

然后我启动我的 cy.get

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

【讨论】:

【参考方案5】:

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

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");
  

【讨论】:

以上是关于如何使用赛普拉斯检查可能不存在的元素的主要内容,如果未能解决你的问题,请参考以下文章

使用赛普拉斯,我将如何编写一个简单的测试来检查页面上是不是存在徽标图像

如何检查在赛普拉斯 e2e 测试中元素是不是永远不可见?

如何使用赛普拉斯测试文件输入?

赛普拉斯:测试元素是不是不存在

赛普拉斯 - 检查按钮是不是存在,如果存在则单击它

如何让赛普拉斯只处理可见元素?