【问题标题】:Exit from while loop with if/else in Cypress在 Cypress 中使用 if/else 退出 while 循环
【发布时间】:2021-06-16 00:59:55
【问题描述】:

我正在编写一个测试用例,需要我重新加载页面N 次数,并比较其标题的值,如果该值不存在,则中断 while 循环而不会出现上升错误。

下面是一个演示程序,类似于我想要实现的那个。

/// <reference types='cypress' />

it("Visiting Google",function(){
    var webUrl = 'https://html5test.com/'
    cy.visit(webUrl)
    var loop_iter = 0
    while(loop_iter < 5)
    {
        cy.get('body:nth-child(2) div:nth-child(2) div.header h1:nth-child(1) > em:nth-child(2)').then(($text_data) =>{
            if($text_data.text().contains('HTML123'))
            {
                cy.log(" --> ITERATION = ",loop_iter)
                cy.reload()
            }
            else
            {
                cy.log("Unknown website")
                loop_iter = 10
            }
        })
        loop_iter += 1
    }
})

我需要一种方法在执行 else 部分时从 while 循环中中断,而不会出现任何错误。

if 条件为 false 时返回 AssertionError,这种情况下应该执行 else 部分。

【问题讨论】:

  • 你需要使用递归,至少Cypress给出的通用模式是这样的。
  • 看看cypress-recurse。你的“commandsFn”是() =&gt; cy.title(),“checkFn”是($text_data) =&gt; $text_data.includes('HTML')。我还不确定在哪里适合cy.reload()
  • 这是一个演示示例,我真的很想使用const $val = cy.get() 并比较 $val 是否包含字符串,如果失败则应该退出 while
  • 您应该修改问题以表明您真正想要的是什么。 while 循环也不起作用,有很多关于它的信息(一些链接在这里)。

标签: javascript jquery testing automation cypress


【解决方案1】:

cy.title() 是异步的(证明是,您需要使用.then()),因此,整个while 循环甚至在第一个.then() 触发之前就结束了。这就是异步的工作原理。

你需要另一种方法:

it("Visiting Google", async function () {
    var webUrl = 'https://html5test.com/'
    cy.visit(webUrl)

    for (let i = 0; i < 5; i++) { // You can't await in a 'while' loop

        const $text_data = await cy.title();

        if ($text_data.includes('HTML')) {
            cy.log(" --> ITERATION = ", i)
            cy.reload()
        }
        else {
            cy.log("Unknown website")
            break;
        }
    }
})

【讨论】:

  • 如果我使用'const $text_data = cy.get(element)',那么if语句在false时抛出AssertionError,这种情况需要执行else块
  • 我没有写$text_data = cy.title(),我写了$text_data = await cy.title()。有很大的不同。第一个返回未解决的 Promise,第二个返回您寻求的值。
  • 仅仅因为它有一个.then() 函数并不能使它成为一个Promise。 cy.title() 返回一个不适用于 await 的 Chainable。
  • text_data.includes('HTML') if case 抛出错误
【解决方案2】:

请查看示例食谱Page reloads。它使用 cmets 中建议的递归。

这是您适应该模式的代码,

it('reload until "HTML" disappears', () => {

  // our utility function
  const checkAndReload = (recurse_level = 0) => {

    cy.title().then(title => {
      if (title.includes('HTML') && recurse_level < 5) {

        cy.log(" --> ITERATION = ", recurse_level)
        cy.wait(500, { log: false })           // just breathe here
        cy.reload()                            // reload
        checkAndReload(recurse_level + 1)      // check again

      } else {
        cy.log("Unknown website") 
      }
    })
  }

  cy.visit('https://html5test.com/')      // start the test by visiting the page
  checkAndReload()                        // and kicking off the first check
})

【讨论】:

    猜你喜欢
    • 2022-09-23
    • 2023-03-22
    • 2021-08-31
    • 2015-11-08
    • 1970-01-01
    • 2015-11-13
    • 2020-08-14
    • 2015-04-07
    • 1970-01-01
    相关资源
    最近更新 更多