Saturday 17 November 2012

Working with frames/iframes in Selenium/WebDriver

Hey Guys,

It has been long time, anything posted in the blog from my side. Busy in trying a new tool WatiN. But this post is related to Selenium and WebDriver. How Selenium2 or Selenium -WebDriver handles frames/iframes. In a very simple word, Frames or IFrames can be treated as web page inside a web page. And no wonder, Selenium also treats them in same line. That means, you have to switch to a frame, to find elements present inside that frame. And you need to come out of the frame when you want to find elements outside of the frame.

1st thing to remember is frame/Iframes are nothing  but Web Elements in side a web page. So you can use findElement() method to find out the frame/Iframe. But there is another simple way, where you only provide the name of the frame and Selenium and Web Driver automatically switch the control to that frame.

Consider the below HTML portion, where two frames are present. To find out an element inside those frames, you need to switch the control to that frame.
######################################################
<frame name="Frame1" id="Frame1">
        -----------
        -----------
        -----------
 </frame>

 <frame name="Frame2" id="Fram2">
        ----------
        -----------
        -----------
  </frame>
######################################################


Lets find out frame1 using find element technique:
WebElement frame = driver.findElement(By.Name("Frame1"));
   or 
WebElement frame = driver.findElement(By.Id("Frame1"));

Now you can use frame object to switch the control.
driver.switchto.frame(frame);

In the method above, you need get the object web element and then use it in switchto method.

But you can directly call the switchto  method on frame name like:
driver.switchto.frame("Frame1");

You can also switch to frame by using index of the frame.
In the above example, to switch to "Frame1" using index, the code will be like :
driver.switchto.frame(0);

And the last thing is once you switch to a frame, then you must go out of the frame to find elements outside of the frame boundry.
driver.switchto.defaultcontent();

Please feel free to leave a comment about this post. I would like to hear from you guys if you have any specific issue/doubts related to handling frames in selenium then I would try to clear.

Thanks!!

14 comments:

  1. How to handle variable xpths in selenium?
    How to handle if one object is not identifying in webpage?
    How to handle popup it is not identifying by any locators in selenium?
    How to handle more than one objects having same properties?

    ReplyDelete
    Replies
    1. Krishna,

      How to handle variable xpths in selenium?
      Ans: What do you mean by variable xpath? is the location of the element changing in every page load? You should be able to use other locators like id, class or title etc to find the element.
      How to handle if one object is not identifying in webpage?
      Ans: Can you elaborate your question here?
      How to handle popup it is not identifying by any locators in selenium?
      Ans:http://krezydibs.blogspot.in/2012/08/switching-to-popup-in-webdriver.html?showComment=1363535258463#c1079169290620334711
      How to handle more than one objects having same properties?
      Ans: Again this come back to same question as the first one, You need to find out unique property to find the web element. Or else you may need to use index which I personally do not like to use.

      Thanks
      Dibya

      Delete
    2. 2)if object is visible means use javascript executor.
      3)you can use driver.swithTo().window() for handling popup


      Thanks
      Karthik.R
      Test Automation

      Delete
  2. HEy if u guys can help me to resolve this :
    In application--> to upload a photo i see a light box which is in a iframe .As per my script i performed some action in that iframe(where my iframe is dynamic) by switching into it,then when i tried to switch back to default content and perform action like type/click.the iframe is not getting switched to default content . i used below code to switch to default-->driver.switchTo().defaultContent();

    Note:As i close the Light box in which their is Iframe--->the application reloads the page

    ReplyDelete
    Replies
    1. Hello Rasna,

      Thanks for visiting the blog. Can you try to get the main window handle as string and switch back to that handle after performing your action. Do not use "driver.switchTo().defaultContent()". Let me know if it worked.

      The code for the above approach will be :
      String sHndl=driver.getWindowHandle();
      // your script
      // script contd.
      //to switch back to default content
      driver.switchTo.Window(sHndl);

      Thanks
      Dibyaranjan

      Delete
  3. how to get the id or xpath of text area in composing message in gmail application .

    ReplyDelete
  4. WebElement msgBox = driver.findElement(By.xpath("//div[@class='Am Al editable']/iframe"));
    msgBox.sendKeys("This is a test email sent via Selenium Web Driver");

    This worked fine for me, however i was not able to clear the signature in the iframe as the function was not supported for this particular web element. Please let me know f there is a way

    ReplyDelete
  5. Hi Dibyaranjan,

    I am working in phpunit-selenium2 environment.
    My problem is to locate to the element present in lightbox in iframe.
    when i click on the preview widget button, new widow opens up which have widget in iframe.
    I am using following code to go iframe.
    $window_handles = $test->windowHandles();
    $test->window($window_handles[1]);
    $test->frame(0);

    But problem arises, when lightbox comes up in iframe. I am unable to locate to the any element present in lightbox.

    Hope you understand my problem.

    Thanks
    Dalip

    ReplyDelete
  6. how can i handle iframe whose id is changing dynamically "id=pngNewCase1143241142570_IFrame" those numbers change dynamically and i also tried using xpath but failed., can anyone please help me to find a solution for this

    ReplyDelete
    Replies
    1. You can try with index or name if it exists. Frames are like web elements inside the page.

      Delete
    2. Hi,
      For the dynamically changing xpath you can use 'contains()'
      Ex: contains(@id,'pngNewCase') or contains(@id,'_IFrame')
      In this case you should use only the part of the value which dosn't change(Avoid numeric values).


      Thanks
      Karthik.R
      Test Automation

      Delete
  7. Hi,

    Thanks for informative article. Am able to handle two windows at a time using getWindowHandle(). But facing problem in handling more than 2 windows . It would be helpful if u provide me with the solution.

    Thanks in Advance

    ReplyDelete
  8. How to switch to the frame having the same name
    Please help

    ReplyDelete
  9. html>
    head>
    frameset id="gc3frameset" cols="165,79%,0" framespacing="0" border="0" frameborder="NO" name="gc3frameset">
    frame id="sidebar" scrolling="auto" src="/url" name="sidebar" noresize="true">
    frameset id="footframeset" rows="*,10%" border="0" framespacing="0" frameborder="no" name="footframeset">
    frameset rows="45,*" border="0" framespacing="0" frameborder="no">
    frame scrolling="NO" src="/urlgoes here" name="topbar" noresize="true">
    frameset id="workframeset" cols="*,0,0" framespacing="0" border="0" frameborder="NO" name="workframeset">
    frame scrolling="yes" src="/urlgoes here" name="body" noresize="true">
    html
    head
    frameset rows="*,55" framespacing="0" border="0" frameborder="0">
    frame scrolling="yes" src="/urlgoes here" name="body" noresize="true">
    frame scrolling="auto" src="/urlgoes here" name="buttons" noresize="true" frameborder="3">
    /frameset
    /html
    /frame
    frame scrolling="auto" src="/html/web/black.html" noresize="true" name="border">
    frame scrolling="auto" src="/urlgoes here" noresize="true" name="workspace">
    /frameset
    /frameset
    frame scrolling="no" src="/urlgoes here" name="footer" noresize="true">
    /frameset
    /frameset
    noframes body /body /noframes
    /html

    From the above snippet ,

    How to switch to the inner frame @name=body

    Thanks in advance

    ReplyDelete

Related Posts

Related Posts...