cypress-example-recipes
cypress-example-recipes copied to clipboard
Add example of testing confirms and alerts triggered from within an iframe
The iframes have to be of the same origin and the alert/confirm triggered by something other than onload
of the iframe for the examples to work.
Confirm
index.html
<html>
<body>
<iframe id="iframe" width="300" height="200" src="iframe.html"></iframe>
</body>
</html>
iframe.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Stubbing Iframe Window Confirm</title>
</head>
<body>
<h1>My Iframe</h1>
<input type="button" onclick="return confirmSubmit(this);">
<script>
function confirmSubmit() {
if (confirm('Are you sure you want to submit your application?')) {
console.log('CONFIRMED')
}
}
</script>
</body>
</html>
spec.js
it('confirms in iframe', () => {
cy.visit('index.html')
cy.get('iframe').then(($iframe) => {
const $body = $iframe.contents().find('body')
const $win = $iframe[0].contentWindow
cy.stub($win, 'confirm').as('windowConfirm')
cy.wrap($body)
.find('input').click().should(function () {
expect(this.windowConfirm).to.be.calledWith('Are you sure you want to submit your application?')
})
})
})

Alert
index.html
<!DOCTYPE html>
<html lang="en">
<body>
<iframe id="iframe" width="300" height="200"
src="iframe.html">
</iframe>
</body>
</html>
iframe.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Stubbing Iframe Window Alert</title>
</head>
<body>
<h1>My Iframe</h1>
<button id="alert">Alert</button>
<script>
var btn = document.getElementById('alert')
btn.addEventListener('click', function (event) {
window.alert("Hello world!")
})
</script>
</body>
</html>
it('alerts in iframe', () => {
cy.visit('index.html')
cy.get('iframe').then(($iframe) => {
const $body = $iframe.contents().find('body')
const $win = $iframe[0].contentWindow
cy.stub($win, 'alert').as('windowAlert')
cy.wrap($body)
.find('#alert').click().should(function () {
expect(this.windowAlert).to.be.calledWith('Hello world!')
})
})
})

Thanks! Do you know of a way to dismiss the confirm within the iframe, as if OK or Cancel was clicked?
That is what the code above should do. This only works for iframe of the same origin of the main application under test though.
Thank you very much. It looks like I'm able to stub the javascript function that calls confirm, but not the confirm itself. In my example, things are a little complicated, as I have an application with many nested iframes, and, I am using these instructions to open the application in a child window: https://glebbahmutov.com/blog/cypress-using-child-window/
Thanks!
@jennifer-shehane I came across a situation where the code block you have mentioned above not working. I suspect the issue in my case is that the alert() was invoked inside a document ready again inside an internal same origin iframe which is not the top,
$(document).ready(function() { if(${!empty no_valid_licence}){ alert('Warning: some warning here'); } }
what my test has is,
cy.get('iframe#adminBody').then(($iframe) => {
const $body = $iframe.contents().find('body')
const $win = $iframe[0].contentWindow
cy.stub($win, 'alert').as('windowAlert')
cy.wrap($body).find('a:contains(\'cypress-client-23\')').click()
})
cy.get('@windowAlert').should('have.been.calledOnce')
Wonder if I missed anything but the only way I could pass this point in my test was to change the app side to fire the alert on the top iframe of the application using something like, parent.window.alert('Warning: some warning here'); which then automatically handle by cypress.
And the above test block works smoothly when I stub a alert happen inside the same iframe but not inside document.ready, which is thee main reason I was inclined that this perhaps need a work out to correctly add the stub to the window instance.
Any input on this would be highly appreciated.
Are there any workarounds to handle these dialogs if the iframes are from different origins?
How to handle alerts if it is triggered from nested iframe. Any example would be much appreciated.