Iframe selectors, notation

Hello all,

I am writing test cases for a web app and most of action is happening inside an iframe.
Fortunately, it is just one iframe and interacting with elements works simply by prefixing selectors with: //iframe >>> [selector]

I would like to ask whether you have any experience or suggestions on how to define the selectors within iframe without having to repeat //iframe >>> every time?
It doesn’t appear too nice having a lot of them and I’m thinking it will get harder to maintain and more error prone.

Thank you and best regards,
JC

Check the Set Selector Prefix Keyword.

2 Likes

Thank you @Many, I somehow missed this keyword.
In the documentation, I see that the scope for prefix usage can be one of

Allowed Values

  • Global
  • Suite
  • Test
  • Task

This wouldn’t work for me, since there are still selectors that wouldn’t be prefixed, perhaps in a separate resource file.
Nonetheless though, it is good to know about this keyword and I might use it in some way in future.

Hi Josh,

Could you do something like set a variable in the variables section for each of the various frames you need (how many frames do you need to deal with?)

Then in each keyword you simply call Set Selector Prefix with None to go back to the top level window and the call it again with the frame variable that keyword needs if it need another frame, then all the subsequent keywords in that keyword can call the elements directly knowing you’ve selected the right frame.

Another approach you could try is to create some select frame keywords, imagine an app with a top level window that has a menu bar and two frames an action frame on the left and an edit frame on the right, you would create 3 keywords like this:

*** Keywords ***
Return To Top
   Set Selector Prefix   None

Select Action Frame
    Return To Top
   Set Selector Prefix   ${actionframeselector}

Select Edit Frame
    Return To Top
   Set Selector Prefix   ${editframeselector}

Then you just call these keywords as needed, or like I mentioned before in every keyword you call the keyword that ensures you have the right frame selected.

Dave.

1 Like

Hi @damies13

There is only one iframe. The thing is that 80% (or more) of selectors I would be using are inside iframe, but others are not.
So It seems like best option for me is to define a variable with iframe selector and manually use it for prefixing selectors within iframe.
For a very simplified example:
${iframe} = //iframe
${login_button} = ${iframe}//button[id=“login”]

It would require using ${iframe} variable as prefix many times and setting it manually. I don’t however see any alternative at the moment.

Thank you for your input as well!

Best, JC

Hi Josh,

Setting and using an ${iframe} variable is a good approach then, luckily you are using Browser Library and not SeleniumLibrary, as this is one of the things Browser Library does better.

What you need is the >>> frame selector syntax as mentioned here Frames in the documentation.

You should just need to change ${login_button} to something like this:

${login_button}=    ${iframe} >>> //button[id=“login”]

Dave.

1 Like

Hi Josh,

I just realised you had the >>> frame selector in your original post.

So yeah there’s only 2 ways to deal with it, use the frame selector with a variable for the frame or use the Set Selector Prefix I mentioned.

At least Browser Library gives you 2 options, SeleniumLibrary only has Select Frame

Dave.

1 Like

You are right, I did forget >>> frame selector in my last post. So

${iframe} = //iframe

should be

${iframe} = //iframe >>>

Indeed it is quite fortunate to have this simple and handy solution in Browser. Although I wondered whether a more elegant solution exists, I can’t complain at all.

Best

1 Like