34

Can anyone tell me how I can identify and switch to the iframe which has only a title?

<iframe frameborder="0" style="border: 0px none; width: 100%; height: 356px; min-width: 0px; min-height: 0px; overflow: auto;" dojoattachpoint="frame" title="Fill Quote" src="https://tssstrpms501.corp.trelleborg.com:12001/teamworks/process.lsw?zWorkflowState=1&zTaskId=4581&zResetContext=true&coachDebugTrace=none">

I have tried by below code but it is not working

driver.switchTo().frame(driver.findElement(By.tagName("iframe")));
Matt
  • 74,352
  • 26
  • 153
  • 180
Sunil wali
  • 495
  • 3
  • 7
  • 11

11 Answers11

46

driver.switchTo().frame() has multiple overloads.

  1. driver.switchTo().frame(name_or_id)
    Here your iframe doesn't have id or name, so not for you.

  2. driver.switchTo().frame(index)
    This is the last option to choose, because using index is not stable enough as you could imagine. If this is your only iframe in the page, try driver.switchTo().frame(0)

  3. driver.switchTo().frame(iframe_element)
    The most common one. You locate your iframe like other elements, then pass it into the method.

Here locating it by title attributes seems to be the best.

driver.switchTo().frame(driver.findElement(By.cssSelector("iframe[title='Fill Quote']")));
// driver.switchTo().frame(driver.findElement(By.xpath(".//iframe[@title='Fill Quote']")));
Yi Zeng
  • 32,020
  • 13
  • 97
  • 125
  • Hi, I am using driver.switchTo().frame(driver.findElement(By.cssSelector("iframe[id='mobileNumber']"))); and getting the below error: Unable to locate element: {"method":"css selector","selector":"iframe[id='mobileNumber']"} – ChanGan Mar 31 '14 at 13:18
  • @ChanGan: The logic looks correct. However, I can't possibly know if locator is right or not without seeing HTML. Also have you used WebDriverWait for this iframe? – Yi Zeng Mar 31 '14 at 20:11
  • NO i did not use WebDriverWait.. when i use driver.switchTo().frame(0) it is working but through this element in iframe logic is not working. – ChanGan Apr 01 '14 at 05:33
  • @ChanGan: I see. In this case, it's most likely because of the locator. I cannot comment further without seeing your HTML. But if index works and your application doesn't change often (because 0 means the first), you can stick with it. – Yi Zeng Apr 01 '14 at 06:51
  • Thanks. Can you please confirm that generally this will work??? driver.switchTo().frame(driver.findElement(By.xpath(".//iframe[@title='Fill Quote']"))) – ChanGan Apr 01 '14 at 06:54
  • @ChanGan: Yes, the logic is correct. It finds the first element by XPath `.//iframe[@title='Fill Quote']`, then switch to it. However, various issues may cause strange behaviours, for example, timing issue, IE render issue, driver/browser version dismatch, etc. – Yi Zeng Apr 01 '14 at 07:17
  • @ChanGan: Yes, you can. Try something like [this](http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe) – Yi Zeng Apr 01 '14 at 20:04
32

you can use cssSelector,

driver.switchTo().frame(driver.findElement(By.cssSelector("iframe[title='Fill Quote']")));
Amith
  • 6,818
  • 6
  • 34
  • 45
4

You also can use src to switch to frame, here is what you can use:

driver.switchTo().frame(driver.findElement(By.xpath(".//iframe[@src='https://tssstrpms501.corp.trelleborg.com:12001/teamworks/process.lsw?zWorkflowState=1&zTaskId=4581&zResetContext=true&coachDebugTrace=none']")));
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
3

Make sure you switch to default content before switching to frame:

driver.switchTo().defaultContent();
driver.switchTo().frame(x);

x can be the frame number or you can do a driver.findlement and use any of the options you have available eg: driver.findElementByName("Name").

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
2

1) goto html view

2) type iframe and find your required frame and count the value and switch to it using

oASelFW.driver.switchTo().frame(2); 

if it is first frame then use oASelFW.driver.switchTo().frame(0);

if it is second frame then use oASelFW.driver.switchTo().frame(1); respectively

giri-sh
  • 6,934
  • 2
  • 25
  • 50
Ajay
  • 395
  • 1
  • 4
  • 11
2

You can use Css Selector or Xpath:

Approach 1 : CSS Selector

driver.switchTo().frame(driver.findElement(By.cssSelector("iframe[title='Fill Quote']")));

Approach 2 : Xpath

driver.switchTo().frame(driver.findElement(By.xpath("//iframe[@title='Fill Quote']")));

https://seleniumatfingertips.wordpress.com/2016/07/05/handling-frames-in-selenium-webdriver-with-java/

mathielo
  • 6,725
  • 7
  • 50
  • 63
2

Easiest way of doing this is like this. If its a frame you can right click on the field and if you see the choice of "open frame in a tab" do it.

Then take the URL of the frame and that is what you put in your Python script using "driver.get (http://blah blah..)

Then Selenium can find your named element. This saved me hours of trying all the suggestions here which was learning about but didn't work. Problem with mine was it was in a frame.

I'm using Linux which gives me the right-click option of opening the frame, on its own, in another tab. I don't use Windows so don't know if you would get that option in you right-click menu.

Ganzarola

Ganz
  • 21
  • 1
2

I struggled with this for a while; a particularly frustrating website had several nested frames throughout the site. I couldn't find any way to identify the frames- no name, id, xpath, css selector- nothing.

Eventually I realised that frames are numbered with the top level being frame(0) the second frame(1) etc.

As I still didn't know which frame the element I needed was sitting in, I wrote a for loop to start from 0 and cycle to 50 continually moving to the next frame and attempting to access my required element; if it failed I got it to print a message and continue.

Spent too much time on this problem for such a simple solution -_-

driver.switch_to.default_content()
for x in range(50):
    try:
        driver.switch_to.frame(x)
        driver.find_element_by_xpath("//*[@id='23']").click()
        driver.find_element_by_xpath("/html/body/form/table/tbody/tr[1]/td/ul/li[49]/a").click()
    except:
        print("It's not: ", x)
        continue
1

There are three ways to switch to the frame

1)Can use id
2)Can use name of the frame
3)Can use WebElement of the frame

2->driver.switchTo().frame("name of the frame");

Derrick
  • 3,669
  • 5
  • 35
  • 50
0

I think I can add something here.

Situation I faced

  1. I cannot or not easily use the debug tools or inspection tools like firebug to see which frame I am currently at and want to go to.

  2. The XPATH/CSS selector etc. that the inspection tool told me doesn't work since the current frame is not the target one. e.g. I need to first switch to a sub-frame to be able to access/locate the element from XPATH or any other reference.

In short, the find_element() or find_elements() method doesn't apply in my case.

Wait Wait! not exactly

unless we use some fazzy search method.

use find_elements() with contains(@id,"frame") to filter out the potential frames.

e.g.

driver.find_elements(By.XPATH,'//*[contains(@id,"frame")]')

Then use switchTo() to switch to that frame and hopefully the underlying XPATH for your target element can be accessed this time.

If you're similar unlucky like me, iteration might need to be done for the found frames and even iterate deeper in more layers.

e.g. This is the piece I use.

try:
    elf1 = mydriver.find_elements(By.XPATH,'//*[contains(@id,"rame")]')
    mydriver.switch_to_frame(elf1[1])
    elf2 = mydriver.find_elements(By.XPATH,'//*[contains(@id,"rame")]')
    mydriver.switch_to_frame(elf2[2])
    len(mydriver.page_source) ## size of source tell whether I am in the right frame 

I try out different switch_to_frame(elf1[x])/switch_to_frame(elf2[x]) combinations and finally found the wanted element by the XPATH I found from the inspection tool in browser.

try:
    element = WebDriverWait(mydriver, 10).until(
        EC.presence_of_element_located((By.XPATH, '//*[@id="C4_W16_V17_ZSRV-HOME"]'))
        )
    #Click the link
    element.click()
Kangqiao Zhao
  • 111
  • 1
  • 8
0

I could solve that with the following code

browser.switch_to.frame(browser.find_element_by_tag_name('iframe'))
TBR920
  • 77
  • 7