Cypress-wait-until - дождаться изменения атрибута элемента - PullRequest
0 голосов
/ 14 июля 2020

Я тестирую приложение, у которого есть кнопка, которая вызывает изменение значения в другом элементе на экране без перезагрузки страницы. Однако это изменение значения может быть почти мгновенным или занять несколько секунд. Очевидно, я не хочу использовать какое-то произвольное ожидание, и я не хочу использовать (жесткое) утверждение - это может привести к остановке теста с ошибкой, которая не является ошибкой ... поэтому я ' мы смотрели на cypress-wait-until (https://www.npmjs.com/package/cypress-wait-until). Я написал различные варианты в следующих строках:

    waitForElemToChange(elem) {
        elem.invoke('attr', val').then((initialVal) => {
        cy.waitUntil(() => elem.invoke('attr', 'value').then((val) => val != initialVal))
    }

Но пока ничего не помогло - большинство попыток приводили к ошибке «Тайм-аут повторной попытки: cy.invoke ()», потому что ваша тема: null. Вы не можете вызывать какие-либо функции, такие как attr, для нулевого значения. "

Но это тот же субъект, который только что вернул значение в предыдущей строке ??

Ответы [ 2 ]

3 голосов
/ 15 июля 2020

Это выглядит слишком сложно. Я бы подошел к нему, дождавшись initialValue, а затем ожидая другого значения.

cy.get('input').should('have.value', 'myInitialValue');     // wait for initial value
cy.get('input').should('not.have.value', 'myInitialValue'); // wait for it to change

.should() будет повторять утверждение в течение 4 секунд.

Если через 'несколько секунд 'вы имеете в виду больше 4, вы можете добавить параметр тайм-аута, который лучше, чем произвольное ожидание, потому что он будет продолжен, как только утверждение пройдет.

Я предполагаю, что ваш элемент является вводом, поскольку вы доступ к val не text.

1 голос
/ 15 июля 2020

Я просмотрел вашу функцию и думаю, что есть несколько проблем с ее использованием. Это может быть проблема, связанная с кипарисом, или ожидание плагина.

Во-первых, в вашем коде, я думаю, с помощью elem вы пытаетесь передать что-то вроде cy.get ("path ") Проблема в том, что когда вы впервые вызываете elem и пытаетесь повторно использовать elem , он становится нулевым. Поэтому, если вы ожидаете, что cy.get ('path') запустится дважды, этого не произойдет.

Во-вторых, по какой-то причине в вашем ожидании до

cy.waitUntil(() => elem.invoke('attr', 'value').then((val) => val != initialVal))

//This part becomes true all the time.
elem.invoke('attr', 'value').then((val) => val != initialVal))

В-третьих,

invoke('attr', 'value')

не будет захватывать изменяющиеся атрибуты объекта. Обратите внимание, что эти наблюдения получены в результате того, что вы пытались сделать. Необходимо дополнительное исследование, чтобы выяснить точное поведение функций.

Учитывая приведенные выше факты, я внес несколько изменений в код.

  • Основное обновление изменений: передача пути CSS вместо объекта кипариса ( elem )
  • с использованием операций селектора запросов js для получения изменяющегося значения (чтобы получить начальное значение, мы можем использовать invoke)

Пример 1: Получение нового значения внутри waitUntil и проверка изменения переменной

const CheckElementChange = (path) => {
    //get the initial value of your object
    cy.get(path).invoke('attr', 'value').then($initialVal => {
        //It's better if you can do your click operation here

        //Wait untill the element changes
        cy.waitUntil(() =>
        cy.get(path).then($newVal => 
            $newVal[0].value !== $initialVal),
            //optional timeouts and error messages
            {
                errorMsg: "was expeting some other Value but got : " + $initialVal,
                timeout: 10000, 
                interval: 500 
              }
        ).then(() => {
            cy.log("Foudn a difference in values")
        })
})
}

Пример 2: переместите waitUntill после извлечения нового значения и дождитесь newVal! == initialVal , чтобы быть истинным

const CheckElementChangew = (path) => {
    //get the initial value of your object
    cy.get(path).invoke('attr', 'value').then($initialVal => {
        //It's better if you can do your click operation here

        //Wait untill the element changes
        cy.get(path).then($newVal => {
            cy.waitUntil(() => $newVal[0].value !== $initialVal, {
                //optional timeouts and error messages
                errorMsg: "was expeting some other Value but got : " + $initialVal,
                timeout: 10000, 
                interval: 500 
              }).then(() => {
                cy.log("Foudn a difference in values")
            })
        })
    })
}

Использование:

it('test',() => {
    CheckElementChange2("#fname");
})

Примечание. Если вы ожидаете, что значение изменится при щелчке мышью, если изменение значения не имеет временного интервала несколько секунд, лучше, если вы сможете сделать щелчок после извлечения начального значения (как указано в кодах выше)

...