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 Iframe Switching API's #685

Closed
brian-mann opened this issue Sep 23, 2017 · 28 comments
Closed

Add Iframe Switching API's #685

brian-mann opened this issue Sep 23, 2017 · 28 comments
Assignees
Labels
type: duplicate This issue or pull request already exists

Comments

@brian-mann
Copy link
Member

brian-mann commented Sep 23, 2017

UPDATE

As of 0.20.0 it's possible to run cy.* commands on iframe elements as documented here: #136 (comment)

However you still can't "easily" switch to iframe context which prevents you from using commands like cy.get()

What users want

  • To be able to "switch" into <iframe> and then utilize all the regular cy.* commands within this context.

What we need to do

  • Add new cy commands to switch into iframes and then also switch back to the "main" frame.

Things to consider

  • How will we handle snapshotting? Currently we don't take snapshots for anything inside of an <iframe>.
  • How will we handle cross origin frames? It's possible to enable these with { chromeWebSecurity: false }.
  • How will we show context switching in the Command Log? It should probably look / be colored differently than the 'normal' main commands

Examples of how we could do this

// switch to an iframe subject
cy
  .get('#iframe-foo').switchToIframe()
  .get('#button').click() // executed in <iframe id='iframe-foo' />

// or pass in $iframe object in hand
cy
  .get('#iframe-foo').then(($iframe) => {
    cy.switchToIframe($iframe)
    cy.get('#button').click()
  })

// now switch back to the main frame
cy
  .switchToMain()
  .get(':checkbox').check() // issued on the main frame
@brian-mann brian-mann added the type: feature New feature that does not currently exist label Sep 23, 2017
@brian-mann brian-mann self-assigned this Sep 23, 2017
@brian-mann brian-mann changed the title Add Iframe Switching API's Proposal: Add Iframe Switching API's Sep 23, 2017
@brian-mann
Copy link
Member Author

Related to:

@jennifer-shehane jennifer-shehane changed the title Proposal: Add Iframe Switching API's Add Iframe Switching API's Sep 25, 2017
@jennifer-shehane jennifer-shehane added the stage: proposal 💡 No work has been done of this issue label Sep 25, 2017
@Robdel12
Copy link

This would be amazing! I like to try and keep all of the work in beforeEaches and have my assertions be pure (no side affects like clicking or visiting).

@jusefb
Copy link

jusefb commented Nov 14, 2017

Such a shame this is not in, I can not use the tool witouth this feautre :( makes it very hard to test legacy aplications

@aamorozov

This comment has been minimized.

2 similar comments
@jhartma

This comment has been minimized.

@ecostigan

This comment has been minimized.

@ianwalter
Copy link
Contributor

What about having Cypress automatically switch to the iframe if the element you .get() is an iframe?

@brian-mann
Copy link
Member Author

@ianwalter how would Cypress know to find the element in the iframe?

Iframes are completely separate windows and documents. It's not going to just "automatically" find them unless it queried across every single one. What if you did cy.get('button') and it was found in multiple frames?

The only way to do to this is with frame switching APIs.

@jusefb I'm confused... you can utilize iframes right now per this comment: #136 (comment)

Sure it's not as nice as iframe switching API's but it does work right now.

@ianwalter
Copy link
Contributor

ianwalter commented Dec 4, 2017

@brian-mann No I meant if you specifically get an iframe element it would automatically switch, so instead of cy.get('#someiframe').switchToIframe() you would just write cy.get('#someiframe'). Cypress would need some logic added to get() to detect if the element is an iframe, but it would just be a shorter syntax.

Another idea:
Just add a switchTo function to the API, if it's passed no selector switch to main, if it contains an iframe selector (e.g. #someiframe) it would switch to that iframe.

@brian-mann
Copy link
Member Author

Sure, the switchToIframe signature is not the problem here. That's the easy part. It could take an existing subject, or a DOM element as first argument, or a selector as first argument. All that is 👍

The harder part is doing all of the rest of the things that we do for the parent <window>. Things like automatically waiting for page loads, and XHR calls, and various page events.

Also when it comes to snapshotting, we currently don't snapshot inside of iframes. We'd have to do that (else this feature would be worthless) - but it may mean we'd have to snapshot both the parent document AND the iframe. Those API's don't currently take this into account. Same thing for element highlighting.

There are some other complexities that I can't remember at the moment but are in my notes somewhere. That's the stuff that's been blocking this from getting done. The half ass solution is mostly good enough which is why this hasn't been a super high priority.

@ianwalter
Copy link
Contributor

Oh for sure, I understand that this is a big feature and I'm only talking about the API layer. Just wanted to add some ideas to make the API nicer to use once all the hard parts are taken care of. IMHO, I would rather not have to chain commands like in the initial example, but using an alias or a promise is fine with me.

@vjragavan

This comment has been minimized.

2 similar comments
@vincebrick

This comment has been minimized.

@tomeraz

This comment has been minimized.

@arnifreyrs
Copy link

+1, this is blocking my company from using cypress. Otherwise, Cypress looks amazing.

@jennifer-shehane jennifer-shehane added the Epic Requires breaking up into smaller issues label Jan 31, 2018
@cypress-io cypress-io deleted a comment from knaumenko Feb 16, 2018
@cypress-io cypress-io deleted a comment from drawain Feb 16, 2018
@agnelo000
Copy link

any news on the completion of this new function

@joshsmith
Copy link

@brian-mann are there any updates on where this sits in the roadmap?

@jennifer-shehane
Copy link
Member

This feature is still in the 'proposal' stage. No work has been done on this feature as of yet. We're a small team and as much as we'd love to work on everything, we have to choose what to work on based on a multitude of things.

@joshsmith
Copy link

@jennifer-shehane I totally understand (particularly when things are open source), just wanted to see if there's anything that can be done from the outside to help make progress. It sounds like there are a number of people here who may be willing to contribute to it moving forward.

@Archanium
Copy link

I see that on the road-map this is listed as "partially complete", just wondering if there's any code anywhere for it, would love to help.

@eugenioghio
Copy link

eugenioghio commented Oct 17, 2018

However you still can't "easily" switch to iframe context which prevents you from using commands like cy.get()

So actually there IS a "not-so-easy" way to switch to iframes. Would you mind to point me to the docs that explain how to do it?

@jennifer-shehane
Copy link
Member

Many people have listed some workarounds to iframes in this issue: #136

@cbromberg
Copy link

for many SAAS / Cloud offerings the lack of this feature is showstopper, as integrations mostly happen within IFrames

@heitorlessa
Copy link

+1 - Just faced this when trying to test a Payment form that uses Stripe Elements which happens to use iFrame too

@aeendale

This comment has been minimized.

@jpvantuyl
Copy link

jpvantuyl commented Aug 2, 2019

Many people have listed some workarounds to iframes in this issue: #136

Something like:

.get('iframe.stripe_checkout_app')
.then(function ($iframe) {
    const $body = $iframe.contents().find('body')

    cy
      .wrap($body)
      .find('input:eq(0)')
      .type('4242424242424242')
    
    cy
      .wrap($body)
      .find('input:eq(1)')
      .type('1222')

    cy
      .wrap($body)
      .find('input:eq(2)')
      .type('123')
})

@st-schneider
Copy link

same was used here I guess https://medium.com/bratislava-angular/testing-an-app-inside-an-iframe-using-cypress-434a4d8b8bbe but with checking if the element is ready already

@jennifer-shehane
Copy link
Member

Duplicate of #136

I'm closing this to better consolidate our tracking of iframe support - these are essentially duplicates. If you have comments on what you'd like the API to be or what you need supported - please comment in #136

@jennifer-shehane jennifer-shehane added type: duplicate This issue or pull request already exists and removed Epic Requires breaking up into smaller issues difficulty: 5️⃣ stage: proposal 💡 No work has been done of this issue type: feature New feature that does not currently exist labels Feb 14, 2020
@cypress-io cypress-io locked as off-topic and limited conversation to collaborators Feb 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests