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

Comments

@brian-mann
Copy link
Member

@brian-mann 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 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

@brian-mann brian-mann commented Sep 24, 2017

Related to:

@jennifer-shehane jennifer-shehane changed the title Proposal: Add Iframe Switching API's Add Iframe Switching API's Sep 25, 2017
@Robdel12
Copy link

@Robdel12 Robdel12 commented Oct 23, 2017

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 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 was marked as off-topic.

2 similar comments
@jhartma

This comment was marked as off-topic.

@ecostigan

This comment was marked as off-topic.

@ianwalter
Copy link
Contributor

@ianwalter ianwalter commented Dec 4, 2017

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

@brian-mann
Copy link
Member Author

@brian-mann brian-mann commented Dec 4, 2017

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

@brian-mann brian-mann commented Dec 4, 2017

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

@ianwalter ianwalter commented Dec 4, 2017

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 was marked as off-topic.

2 similar comments
@vincebrick

This comment was marked as off-topic.

@tomeraz

This comment was marked as off-topic.

@arnifreyrs
Copy link

@arnifreyrs arnifreyrs commented Jan 30, 2018

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

@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

@agnelo000 agnelo000 commented Jun 25, 2018

any news on the completion of this new function

@joshsmith
Copy link

@joshsmith joshsmith commented Jul 12, 2018

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

@jennifer-shehane
Copy link
Member

@jennifer-shehane jennifer-shehane commented Jul 12, 2018

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

@joshsmith joshsmith commented Jul 13, 2018

@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

@Archanium Archanium commented Aug 31, 2018

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

@jennifer-shehane jennifer-shehane commented Oct 25, 2018

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

@cbromberg
Copy link

@cbromberg cbromberg commented Dec 6, 2018

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

@heitorlessa
Copy link

@heitorlessa heitorlessa commented Jun 26, 2019

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

@aeendale

This comment was marked as off-topic.

@jpvantuyl
Copy link

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

@st-schneider st-schneider commented Sep 13, 2019

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

@jennifer-shehane jennifer-shehane commented Feb 14, 2020

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet