Last active
January 9, 2024 19:18
-
-
Save loranmutafov/0aef48884f3ec05edeb95aa1e0d06a17 to your computer and use it in GitHub Desktop.
Cypress command to wait for iframes to load
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Will check if an iframe is ready for DOM manipulation. Just listening for the | |
* load event will only work if the iframe is not already loaded. If so, it is | |
* necessary to observe the readyState. The issue here is that Chrome initialises | |
* iframes with "about:blank" and sets their readyState to complete. So it is | |
* also necessary to check if it's the readyState of the correct target document. | |
* | |
* Some hints taken and adapted from: | |
* https://stackoverflow.com/questions/17158932/how-to-detect-when-an-iframe-has-already-been-loaded/36155560 | |
* | |
* @param $iframe - The iframe element | |
*/ | |
const isIframeLoaded = $iframe => { | |
const contentWindow = $iframe.contentWindow; | |
const src = $iframe.attributes.src; | |
const href = contentWindow.location.href; | |
if (contentWindow.document.readyState === 'complete') { | |
return href !== 'about:blank' || src === 'about:blank' || src === ''; | |
} | |
return false; | |
}; | |
/** | |
* Wait for iframe to load, and call callback | |
* | |
* Some hints taken and adapted from: | |
* https://gitlab.com/kgroat/cypress-iframe/-/blob/master/src/index.ts | |
*/ | |
Cypress.Commands.add('iframe', { prevSubject: 'element' }, $iframes => new Cypress.Promise(resolve => { | |
const loaded = []; | |
$iframes.each((_, $iframe) => { | |
loaded.push( | |
new Promise(subResolve => { | |
if (isIframeLoaded($iframe)) { | |
subResolve($iframe.contentDocument.body); | |
} else { | |
Cypress.$($iframe).on('load.appearHere', () => { | |
if (isIframeLoaded($iframe)) { | |
subResolve($iframe.contentDocument.body); | |
Cypress.$($iframe).off('load.appearHere'); | |
} | |
}); | |
} | |
}) | |
); | |
}); | |
return Promise.all(loaded).then(resolve); | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment