#javascript #testing #iframe #automated-tests #cypress
#javascript #тестирование #iframe — фрейм #автоматизированные тесты #cypress
Вопрос:
Я пытаюсь взаимодействовать с некоторыми элементами внутри iframe с помощью cypress. Если я использую подход в https://bparkerproductions.com/how-to-interact-with-iframes-using-cypress-io / только для одного элемента в тесте все в порядке.
# commands.js
Cypress.Commands.add(
'iframe',
{ prevSubject: 'element' },
($iframe) => {
return new Cypress.Promise(resolve => {
$iframe.on('load', () => {
resolve($iframe.contents().find('body'))
})
})
})
# landing_page.spec.js
cy.get('iframe').iframe().find('#happybutton').should('be.visible')
Однако я хочу найти несколько элементов, щелкнуть по ним и проверить, правильно ли они отображаются, но если я присвою содержимое iframe переменной и повторно использую его для поиска другого элемента (например, кнопки), cypress попытается найти второй элемент (например, меню) из первого элемента (кнопка, которая обречена на неудачу, потому что кнопка не содержит меню).
# landing_page.spec.js
let iframeContent = cy.get('iframe').iframe()
iframeContent.find('#happybutton').should('be.visible')
iframeContent.find('#myMenu').should('be.visible')
Я пытался использовать разные переменные или вызывать напрямую cy.get('iframe').iframe()
каждый раз, когда хотел взаимодействовать с разными элементами, но cypress попадает в бесконечный цикл, и тест никогда не заканчивается (но никаких ошибок или предупреждений не выдается).
Кто-нибудь знает способ избежать этого бесконечного цикла? Поскольку я хочу воспроизвести последовательность шагов для создания тестового примера, невозможно изолировать каждое взаимодействие в другом тесте.
Или кто-нибудь знает фреймворк, который больше подходит для работы с фреймами?
Комментарии:
1. Взгляните на cypress-iframe , который использует вложенность для выполнения нескольких команд.
Ответ №1:
Проблема $iframe.on('load',
в том, что срабатывает только один раз, поэтому вы не можете вызвать cy.get('iframe').iframe()
дважды, что фактически и делают обе .find()
команды.
let iframeContent = cy.get('iframe').iframe()
не сохраняет тело iframe, оно хранит «цепочку», которая обрабатывается как функция или средство получения.
«Бесконечный цикл» — это Cypress, ожидающий вызова promise resolve() во второй раз, чего никогда не происходит.
Таким образом, вы можете вложить команды следующим образом
cy.get('iframe').iframe().then(body => {
cy.wrap(body).find('#happybutton').should('be.visible')
cy.wrap(body).find('#myMenu').should('be.visible')
});
или вы можете улучшить команду, добавив тег при срабатывании события загрузки
Cypress.Commands.add('iframe', { prevSubject: 'element' }, ($iframe) => {
return $iframe._hasloaded
? $iframe.contents().find('body')
: new Cypress.Promise(resolve => {
$iframe.on('load', () => {
$iframe._hasloaded = true;
resolve($iframe.contents().find('body'))
})
})
})
Ответ №2:
Благодаря ответу Марион я нашел способ реорганизовать свой код, так что теперь он работает! Примечание: iframe()
функция была оставлена нетронутой
# commands.js
Cypress.Commands.add(
'iframe',
{ prevSubject: 'element' },
($iframe) => {
return new Cypress.Promise(resolve => {
$iframe.on('load', () => {
resolve($iframe.contents().find('body'))
})
})
})
# landing_page.spec.js
cy.get('iframe').iframe().as('iframeContent')
cy.get('@iframeContent').then((iframeContent) => {
cy.get(iframeContent).find('#happybutton').click()
cy.get(iframeContent).find('#myMenu')
cy.get(iframeContent).find('#anotherElement').should('be.visible')
})
Комментарии:
1. Хорошо, это работает, но
.as('iframeContent')
прямое следованиеcy.get('@iframeContent')
просто изнашивает кончики пальцев.
Ответ №3:
Приведенные выше ответы указали мне правильное направление. Опустив фразу ‘then’ и первый cy.get(‘@iframeContent’), решение Semiramis можно немного упростить и упростить для понимания следующим образом:
cy.get('iframe').iframe().as('iframeContent')
cy.get('@iframeContent').find('#happybutton').click()
cy.get('@iframeContent').find('#myMenu')
cy.get('@iframeContent').find('#anotherElement').should('be.visible')
Для новичков Cypress (таких, как я): переменные и псевдонимы Cypress