Reputation: 574
I have dynamically loading iframe in a application.
I'm catching a frame through this code:
Cypress.Commands.add('getIframe', (iframeLocator: string): void => {
cy.wait(10000)
cy.get(iframeLocator)
.its('0.contentDocument').should('not.be.empty')
.its('body').should('be.visible')
.then(cy.wrap)
})
The problem is that - without explicit timeout cy.wait(10000)
conditions not.be.empty
and be.visible
are passing fine, while there is no content of iframe on the page yet.
How to catch iframe without explicit wait ?
Upvotes: 0
Views: 5897
Reputation: 31944
There are a couple of things that can stop <iframe>
code working, including cypress-iframe
.
<iframe src="https://example.com"
loading="lazy"
width="600"
height="400"></iframe>
Standardized lazy-loading of iframes defers offscreen iframes from being loaded until the user scrolls near them. This saves data, speeds up the loading of other parts of the page, and reduces memory usage.
.should('not.be.empty')
check<body>
element is changed when proper page is available, negating .its('body').should('be.visible')
checkThese are the additional steps I use
// when iframe has attribute loading="lazy"
cy.get(iframeLocator).scrollIntoView() // start loading
cy.get(iframeLocator)
.its('0.contentDocument').should('not.be.empty')
.its('body')
.as('body') // alias this command chain
cy.get('@body') // repeats above chain when <body> detached from DOM (replaced)
.should('be.visible')
.should('not.be.empty')
.then(cy.wrap)
.find('div#some-content', {timeout:10000})
Upvotes: 2
Reputation: 10555
An iframe may have "iframe is loading" default, so not.be.empty
or be.visible
are false checks.
Try content check and make sure <body>
query is retried
Cypress.Commands.add('getIframe', (iframeLocator: string): void => {
cy.get(iframeLocator)
.its('0.contentDocument').should('not.be.empty')
.its('body h1').should('contain', 'IFrame title') // retry body
.then(cy.wrap)
})
Upvotes: 1
Reputation: 18634
You can use the cypress-iframe plugin for this. After installing you can use the frameLoaded
method.
// This will verify that the iframe is loaded to any page other than 'about:blank'
cy.frameLoaded()
// This will verify that the iframe is loaded to any url containing the given path part
cy.frameLoaded({ url: 'https://google.com' })
cy.frameLoaded({ url: '/join' })
cy.frameLoaded({ url: '?some=query' })
cy.frameLoaded({ url: '#/hash/path' })
// You can also give it a selector to check that a specific iframe has loaded
cy.frameLoaded('#my-frame')
cy.frameLoaded('#my-frame', { url: '/join' })
Upvotes: 0