javascripttestingiframeautomated-testscypress

Rendering iFrame in Cypress


Can anyone help me render the iFrame for the following page in Cypress.

https://testnewpage.digitaldisbursements.org/

<iframe
  frameborder="0"
  title="Payment method selection section."
  src="https://staging-content.digitaldisbursements.com/latest/index.html"
  style="border: none; width: 100%; height: 355px; overflow: hidden"
></iframe>

Solution

  • It appears to me that no amount of waiting for the frame to load works for this page. The payment options never appear.

    BUT, if you open the address in a new window the logos and payment buttons do appear.

    This suggests you could try testing it in a new window - the approach is a little experimental but working.
    See Unable to load a specific URL with Cypress for reference.

    Here is a working test.

    it('Should render the iframe', {timeout:20_000}, () => {
      cy.visit('http://testnewpage.digitaldisbursements.org/')
    
      cy.openWindow('http://testnewpage.digitaldisbursements.org/')
    
      const paymentMethods = [
        {imgSrc: 'virtual_mc3.png', caption: 'GET A PREPAID MASTERCARD'},    
        {imgSrc: 'paypal.png', caption: 'USE PAYPAL'},    
        {imgSrc: 'venmo.png', caption: 'USE VENMO'},    
        {imgSrc: 'zelle.png', caption: 'USE ZELLE'},    
        {imgSrc: 'virtual_mc3.png', caption: 'GET A PREPAID MASTERCARD'},   
      ]
    
      cy.get('iframe')
        .its('0.contentDocument')
        .find('body')
        .should('exist')
        .and('not.be.null')
        .within($body => {
          cy.get('#payment')
            .find('.MuiGrid-item')
            .each((paymentMethod, i) => {
    
              cy.wrap(paymentMethod)      // check the logo
                .find('button img')      // 1st button on card
                .should('have.attr', 'src')
                .and('contain', paymentMethods[i].imgSrc)
    
              cy.wrap(paymentMethod)     // check the button caption
                .find('button').eq(1)   // 2nd button on card
                .should('contain', paymentMethods[i].caption)
             })
    
        })
    })
    

    It uses the cy.openWindow() developed by Gleb Bahmutov here Cypress using child window with some adjustments.

    Cypress.Commands.add('openWindow', (url, features) => {
      const w = Cypress.config('viewportWidth')
      const h = Cypress.config('viewportHeight')
      if (!features) {
        features = `width=${w}, height=${h}`
      }
      console.log('openWindow %s "%s"', url, features)
    
      return new Promise(resolve => {
        if (window.top.aut) {
          console.log('window exists already')
          window.top.aut.close()
        }
        // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
        window.top.aut = window.top.open(url, 'aut', features)
    
        // letting page enough time to load and set "document.domain = localhost"
        // so we can access it
        setTimeout(() => {
          cy.state('document', window.top.aut.document)
          cy.state('window', window.top.aut)
          resolve()
        }, 10_000)
      })
    })
    

    Also, some setting needed in cypress.config.js

    const { defineConfig } = require("cypress");
    
    module.exports = defineConfig({
      e2e: {
        setupNodeEvents(on, config) {
        },
        chromeWebSecurity: false,
        modifyObstructiveCode: false,
      },
    })