Cypress: Как подождать, а затем прочитать внутренний текст элемента, который появится только где-то между 30 и 120 секундами. - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть требование, согласно которому, когда я регистрируюсь для регистрации пользователя, мой идентификатор генерируется в бэкэнде, и веб-страница показывает этот идентификатор спустя примерно от 30 до 120 секунд.

Так что, когда я использую:

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

, у меня может не быть его сразу после завершения регистрации, поэтому мне нужно подождать в проверке oop каждые 10 секунд или около того пока идентификатор пользователя не отобразится как часть селектора 'header> p'

Пробовал разные циклические логики и т. д. c., вкл. подожди и проверь, но из-за асинхронной c природы запросов переменная область видимости у меня не работает, поэтому попробовал cy.wrap ('false'). as ('found') и затем попытался использовать это в cy. get (this.found), но как только мне понадобится связать это в .then.

Так есть ли простой способ сохранить значение глобальной переменной с помощью команды. 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
    }
})
}

Наконец-то попробовал следующий код из форума, даже когда идентификатор пользователя доступен внутри заголовка> тег 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)
            })
        }
    }

Любой совет искренне ценится. Большое спасибо.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Благодаря @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);
});
1 голос
/ 18 февраля 2020

Проблема не во всех цепочках команд: автоматический c механизм повторных попыток , как и следовало ожидать.

Так что cy.get('header > p').invoke('text') повторяет первую часть (ищет элемент), но как только элемент присутствует, он захватывает любой текст, который у него есть в то время.

Команда cy.contains() лучше повторить, пока не будет присутствовать и элемент, и нужное содержимое.

Поскольку это может занять до 120 секунд, необходимо увеличить время ожидания повторной попытки.

Ref cy.contains () , 4-й шаблон .contains(selector, content, options).

Некоторые Идеи

Если вы знаете, какой идентификатор пользователя будет отправлен значение для тестирования.

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

Если вам известна только общая форма идентификатора пользователя, который будет отправлен

Используйте регулярное выражение если вы не знаете точный идентификатор пользователя, но знаете его форму (например, всегда число).

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

Если вы знаете элемент будет пустым до получения идентификатора пользователя

Используйте регулярное выражение для непустого содержимого.

cy.contains('header > p', /.+/, { timeout: 120000 })
  .invoke('text')
  .then(text => cy.log("User Id: " + text) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...