Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example of testing confirms and alerts triggered from within an iframe #410

Closed
jennifer-shehane opened this issue Jan 29, 2020 · 6 comments

Comments

@jennifer-shehane
Copy link
Member

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?')
      })
  })
})

Screen Shot 2020-01-29 at 1 59 15 PM

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!')
      })
  })
})

Screen Shot 2020-01-16 at 11 35 04 AM

@isaacsobczak
Copy link

isaacsobczak commented Feb 28, 2020

Thanks! Do you know of a way to dismiss the confirm within the iframe, as if OK or Cancel was clicked?

@jennifer-shehane
Copy link
Member Author

That is what the code above should do. This only works for iframe of the same origin of the main application under test though.

@isaacsobczak
Copy link

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!

@supun-hettigoda
Copy link

supun-hettigoda commented Mar 11, 2021

@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.

@mmitchell3590
Copy link

Are there any workarounds to handle these dialogs if the iframes are from different origins?

@kavitha24
Copy link

How to handle alerts if it is triggered from nested iframe. Any example would be much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants