The question is published on by Tutorial Guruji team.
I’m trying to interact with some elements inside an iframe with cypress. If I use the approach in https://bparkerproductions.com/how-to-interact-with-iframes-using-cypress-io/ for only one element per test, everything is fine.
# 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')
However, I want to look for multiple elements, click on them, and check if they are rendered correctly, but if I assign the iframe contents to a variable and reuse it to locate another element (for example, a button), cypress tries to locate the second element (for example, a menu) from the first element (the button, which is doomed to fail, because the button does not contain the menu).
# landing_page.spec.js let iframeContent = cy.get('iframe').iframe() iframeContent.find('#happybutton').should('be.visible') iframeContent.find('#myMenu').should('be.visible')
I tried using different variables, or calling directly cy.get('iframe').iframe()
, every time I wanted to interact with different elements, but cypress gets trapped in an infinite loop and the test never ends (but no errors or warnings are produced).
Does anybody knows a way to avoid this infinite loop? As I want to reproduce a sequence of steps to build a test case, it is not possible to isolate each interaction in a different test.
Or does anybody knows of a framework that is more suitable for working with iframes?
Answer
Thanks to Marion’s answer I found a way to refactor my code, so now it works!
Note: the iframe()
function was left untouched
# 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') })