1

我有一个要求,一旦我注册用户注册,我的 ID 就会在后端生成,并且网页几乎在 30 秒到 120 秒之间显示该 ID。

所以当我使用:

cy.get('header > p').invoke('text').then('text' => {
    cy.log("User Id: " + text)
})

注册完成后我可能没有它,所以我需要每隔 10 秒左右等待一次循环检查,直到用户 ID 显示为选择器“header > p”的一部分

尝试了不同的循环逻辑等,包括。等待并检查,但由于请求的异步性质,变量范围对我不起作用,因此尝试了 cy.wrap('false').as('found') 然后尝试在 cy.get(this .found),但是一旦我需要将其链接到.then。

那么有没有一种简单的方法可以使用 command.js 来存储全局变量值?我可以在其中更新

while(!variableFound) {
cy.get('header > p').invoke('text').then('text' => {
    cy.log("User Id: " + text)
    if(text.length > 0) {
        variableFound = true
    } else {
        variableFound = false
    }
})
}

最后从论坛尝试了以下代码,即使用户 ID 在 header>p 标记内可用,它仍然无法识别。

    let found = false
    let count=0
    while (!found) {

        const nonExistent = Cypress.$('header > p')

        // this is always evaluating to 0 even when p is become available and contains has the text
        cy.log("Length: " + nonExistent.length) 

        if (!nonExistent.length) {                                
            cy.visit("/profile/")                
            found = false
            count=count+1
            cy.wait(5000)
            cy.visit("/dashboard/")

            if(count==18) {
                found = true
                cy.log('Element not found after 18 attempts.Exit from loop!!!')
            }
        } else {
            found = true
            cy.get('header > p').invoke('text').then((useridtext) => {
                cy.log("User Id: " + useridtext)
            })
        }
    }

真诚感谢任何建议。非常感谢。

4

2 回答 2

2

问题不在于所有命令链都像您预期的那样应用自动重试机制。

所以cy.get('header > p').invoke('text')重试第一部分(寻找元素),但只要元素存在,它就会抓取当时拥有的任何文本。

cy.contains()命令更适合重试,直到元素和正确的内容都存在。

由于它最多可能需要 120 秒,因此您必须延长重试超时。

参考cy.contains(),第 4 个模式.contains(selector, content, options)

一些想法,

如果您知道将发送什么用户 ID

如果您总是得到一个已知的用户 ID,或者您是否可以存根调用并返回一个值进行测试,请执行此操作。

cy.contains('header > p', 'expectedUserId', { timeout: 120000 })
  .invoke('text')
  .then(text => cy.log("User Id: " + text) )

如果您只知道将发送的用户 ID 的一般形式

如果您不知道确切的用户 ID,但知道它的形式(例如总是一个数字),请使用正则表达式。

cy.contains('header > p', /\d+/, { timeout: 120000 })
  .invoke('text')
  .then(text => cy.log("User Id: " + text) )

如果您知道在用户 ID 到达之前该元素将为空

对非空内容使用正则表达式。

cy.contains('header > p', /.+/, { timeout: 120000 })
  .invoke('text')
  .then(text => cy.log("User Id: " + text) )
于 2020-02-17T23:12:40.217 回答
1

感谢@RichardMatsen 和 Arnon Axelrod,下面是适用于我的递归函数。

/* Recursive function */
function getEnvironment() {
    function getEnvironmentInternal(retires) {
        if (retires == 0) {
            throw "text didn't appear after the specified retires";
        }
        return cy.get('header > p').invoke('text').then(text => {
            if(text) {
                 return cy.wrap(text);
            }

            cy.wait(10000);
            cy.reload();
            return getEnvironmentInternal(retires-1);
        });
    }
    return getEnvironmentInternal(12);
 }

/* Usage */
getEnvironment().then(text => {
    cy.log("User Id: " + text);
});

截至 2020 年 11 月,此问题可以通过Test Retries解决。

于 2020-02-18T23:21:05.760 回答