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

Make it easier to switch between frames #366

jan-molak opened this issue Nov 9, 2019 · 0 comments

Make it easier to switch between frames #366

jan-molak opened this issue Nov 9, 2019 · 0 comments
enhancement A good idea that should be implemented


Copy link

jan-molak commented Nov 9, 2019

Extracted from #365 - @nbarrett, @rajeshwarp


It would be great if Serenity/JS made the task of switching between frames easier.


I was thinking of separating the logic of switching the frames from the one responsible for targetting the elements, if possible.

So something like

const someIFrame = Target.the('iframe').located(by.tagName('iframe'));
const someButtonWithinTheIFrame = Target.the('button').located('some-button'));


I agree it's an additional line or two of code, but those could be nicely wrapped into a self-contained task:

const DoStuffWithIframe = () =>
    Task.where(`#actor does stuff with the iFrame`,,               // get in
        Click.on(someButtonWithinTheIFrame),      // do stuff
        SwitchFrame.toDefaultContent(),           // get out


Hmm, in my experience, the problem with switching iframes is that it can get quite complex when your page has multiple nested frames. You are only able to switch to an iframe that is a child of the currently selected iframe (or the default content if the element is not in an iframe). If you don’t get the switching sequence exactly right you’ll get NoSuchFrameException. Conversely, if you try to refer to an element and you haven’t switched to the right iframe beforehand, you’ll get NoSuchElementException. All of this puts a lot of burden on the writer of the test, who in the latter case might think that they need to wait longer for the element to appear when in fact they are just in the wrong iframe! It’s quite possible that in a test you might want to refer to a web element that is buried deep in a nested iframe, followed by a reference to one that’s not in an inframe at all. If you leave responsibility for this to the writer of the test, they would need to keep track of which iframe they were last on, in order to know whether a switch to default content is first required before they then switch to the child iframe. All this can get extremely messy, fast and clutters our beautiful test!. Another problem is that a Task might work fine at one point in a test but might fail later on because another Task switched to a different Iframe beforehand.

Given that the relationship between a web element and its iframe(s) never changes, to me it makes sense to define this relationship up-front within the Target, just like you would do with the locator.

In the java Serenity core library, an IFrame is an Optional type on the Target, so by default, a Target will exist in default content. An IFrame is constructed with a vararg of By locators which allows any nesting depth to be modelled. Switching of the IFrame is done transparently by means of the iFrameswitcher which is invoked within the TargetResolver. I relied heavily on the transparent Iframe switching capability when I worked with one particular client for a couple of years and I was very glad this feature was in serenity-core!

Given this background of how the problem was tackled in the java product, do you think this is something that could be of value in serenity-js?

@jan-molak jan-molak added the enhancement A good idea that should be implemented label Jan 24, 2020
@jan-molak jan-molak added this to Ideas in Serenity/JS Board Mar 10, 2020
@jan-molak jan-molak moved this from Ideas to To do in Serenity/JS Board Mar 10, 2020
@jan-molak jan-molak moved this from To do to In progress in Serenity/JS Board Oct 4, 2020
Serenity/JS Board automation moved this from In progress to Done Oct 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
enhancement A good idea that should be implemented

No branches or pull requests

1 participant