最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Ways to deal with #document under iframe - Stack Overflow

programmeradmin3浏览0评论

For the portal I am testing now, I came with the problem that I could not create any xpath locators, after some time I figured out that it was because of an '#document', this cuts the path and makes the simple "copy xpath" to direct the path to a completely different element.

<iframe id="FRAMENAME" src="/webclient/workspace/launch-task/REMbl?ds=BP" width="100%" height="100%" frameborder="0" data-navitemname="navitemname" style="" xpath="1">
#document
    <html>
        CODE....
    </html>

I found the solution for this is it is simply add a switchTo like this:

driver.switchTo().frame("FRAMENAME");

This works and makes the rest of the code to work properly but, takes some extra time processing this command till the code moves to the next line.

So I would like to ask, is there is a better solution for this? something smarter/faster?

I am concerned that when the point where I have lots of scripts comes, the execution time will take too long.

I don't use id locators for example because they are all dynamic so sometimes a xpath is required.

Thank you!

For the portal I am testing now, I came with the problem that I could not create any xpath locators, after some time I figured out that it was because of an '#document', this cuts the path and makes the simple "copy xpath" to direct the path to a completely different element.

<iframe id="FRAMENAME" src="/webclient/workspace/launch-task/REMbl?ds=BP" width="100%" height="100%" frameborder="0" data-navitemname="navitemname" style="" xpath="1">
#document
    <html>
        CODE....
    </html>

I found the solution for this is it is simply add a switchTo like this:

driver.switchTo().frame("FRAMENAME");

This works and makes the rest of the code to work properly but, takes some extra time processing this command till the code moves to the next line.

So I would like to ask, is there is a better solution for this? something smarter/faster?

I am concerned that when the point where I have lots of scripts comes, the execution time will take too long.

I don't use id locators for example because they are all dynamic so sometimes a xpath is required.

Thank you!

Share Improve this question edited Nov 13, 2018 at 8:57 undetected Selenium 193k44 gold badges303 silver badges378 bronze badges asked Nov 8, 2018 at 7:54 AlexandreAlexandre 4621 gold badge3 silver badges14 bronze badges 4
  • This is the only way to access elements inside <iframe>. You could post your code at code review, maybe someone will see things you can improve. – Guy Commented Nov 8, 2018 at 7:58
  • Hi, thanks for the answer, the portal is not developed by us which makes difficult to change the code, we are developing a tool to work with this and the purpose of this test is to check that the info was imported correctly. the rest of the test code goes fast, the only point is that slowdown, but anyway I will post there just in case. thanks! – Alexandre Commented Nov 8, 2018 at 8:34
  • I suggested you post your code there, not the website :). How much time does the switch take, I never incarcerated any problem with it. – Guy Commented Nov 8, 2018 at 8:38
  • ah ok hehehe, well it depends the screen it is but I would say from 4 to 6 seconds per switch, so in a test case where I need to interact with different frames this would increase the execution time, for now it is no big issue but in the future might take too long. thanks for the help! – Alexandre Commented Nov 8, 2018 at 9:36
Add a comment  | 

2 Answers 2

Reset to default 8

To work with elements inside iframe you must switch to this specific iframe.

Your solution .switchTo().frame("FRAMENAME"); is correct. Selenium does not have any other ways to work with iframe wrappers.

inline frames

As per the documentation in Using inline frames, an inline frame is a construct which embeds a document into an HTML document so that embedded data is displayed inside a subwindow of the browser's window. This does not mean full inclusion and the two documents are independent, and both them are treated as complete documents, instead of treating one as part of the other.


iframe structure and details

  • Generally, an iframe element is in the form of:

    <iframe src="URL" more attributes>
    alternative content for browsers which do not
    support iframe
    </iframe>
    
  • Browsers which support iframe display the document referred to by the URL in a subwindow, typically with vertical and/or horizontal scroll bars. Such browsers ignore the content of the iframe element (i.e. everything between the start tag <iframe...> and the end tag </iframe>). Browsers which do not support iframe (or have such support disabled) does the opposite, i.e. process the content as if the <iframe...> and </iframe> tags were not there. Thus, the content matters, despite being ignored by some browsers.

  • So to summarize, inline frames do not mean an include feature, although it might sometimes serve similar purposes.

  • Note that, when inline frames are used, the browser (if it supports them) sends a request to the server referred to by the URL in the iframe element, and after getting the requested document displays it inside an inline frame. In this sense inline frames are a joint browser-server issue, but only the browser needs to be specifically iframe-aware; from the server's point of view, there's just a normal HTTP request for a document, and it sends the document without having (or needing) any idea on what the browser is going to do with it.


Something Smarter

As per the best practices while switching to an iframe you need to induce WebDriverWait as follows:

  • Switch through Frame Name (Java Sample Code):

    new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.name("frame_name")));
    
  • Switch through iframe XPath (Python Sample Code):

    WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id='ptifrmtgtframe' and @name='TargetContent']")))
    
  • Switch through iframe CssSelector (C# Sample Code):

    new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(By.CssSelector("iframe#twitter-widget-0")));
    

Reference

You can find a couple of relevant discussions in:

  • Python: How can I select a html element no matter what frame it is in in selenium?
  • Java: Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?
  • C#: How to wait for a frame to load before locating an element?

tl; dr

Inline frames vs. normal frames

发布评论

评论列表(0)

  1. 暂无评论