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