2

I have some code that tries to catch elements inside an iframe but I just keep getting thrown back an error

it('Send Medication',function(){
       cy.get('.aut-iframe') 
       .should(iframe => expect(iframe.contents().find('body')).to.exist)
       .then(iframe => cy.wrap(iframe.contents().find('body')))
       .within({}, $iframe => {
            cy.get('.pending-medication-check-box').click({force:true})

This is the error that I get:

enter image description here

enter image description here

Lastly, this is the iframe info:

enter image description here

Bruno Rodriguez
  • 65
  • 1
  • 1
  • 8
  • 2
    `` is part of the Cypress test runner, so you cannot use Cypress test commands to access it - why do you want to? If you have another iframe that is actually part of the app, you need to change the selector in the test. – Fody Oct 20 '21 at 19:13
  • you are exactly right, Fody, after doing some more digging I noticed that the actual iframe I needed was embedded deep within the one I was originally trying to use – Bruno Rodriguez Oct 20 '21 at 19:15

5 Answers5

5

I would assume you are just missing retries for fetching the iframe until the body is loaded. Simple get and should combo doesn't wait for this to happen. Official docs state you should use .its('body') when working with iframes, so try something like this:

cy.get('.aut-iframe').its('body').then((body) => { cy.wrap(body).should('...') }

Reference: https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/#header

Zaista
  • 1,272
  • 8
  • 18
4
  1. Install the cypress-iframe plugin.

  2. After installation write import 'cypress-iframe'; under cypress/support/commands.js

  3. Then finally your code should look like:

cy.frameLoaded('.aut-iframe')
cy.iframe('.aut-iframe')
  .find('.pending-medication-check-box')
  .should('be.visible')
  .click()
Alapan Das
  • 17,144
  • 3
  • 29
  • 52
2

First in your command file add this:

Cypress.Commands.add('getIframe', () => {
return cy
    .get('.aut-iframe')
    .its('0.contentDocument.body').should('not.be.empty')      
    .then(cy.wrap)
})

Then in your test you can use the command above in this way:

cy.getIframe()
  .get('.pending-medication-check-box').click({force:true})
Vict01
  • 300
  • 1
  • 10
0

If the iframe is pulling content from a different chromeWebSecurity: false in your cypress.conf.json file otherwise it will fail to find the contentDocument of the iframe.

PS this may not necessarily be your issue, but I've seen a lot of people with this problem so sharing the solution is always worthwhile.

RichardODonoghue
  • 266
  • 1
  • 2
  • 7
0

After many attempts here's what worked for me. Managed to pinpoint the credit card number field which is 1 out of 3, hence the index in the code. Hope, it helps someone else as well. NOTE: 3 input fields have the same locator piece but a different index.

Cypress.Commands.add("populateCardInformationForm", (creditCardDetails) => {
  cy.log("Going to populateCardInformationForm()");
  // Populate Name on card
  cy.get('#name-on-card')
  .scrollIntoView()
  .should('be.visible')
  .type(creditCardDetails.nameOnCard);
  // Populate Credit Card number
  const getIframeBody1 = () => {
    return cy
      .get('iframe[name*="privateStripeFrame"]')
      .eq(0)
      .its("0.contentDocument.body")
      .should("not.be.empty")
      .then(cy.wrap);
  };
  getIframeBody1().find('input[class^="InputElement"]').type(creditCardDetails.cardNumber);
});
Eve
  • 1
  • 1