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")));
This question is related to
testing
selenium
selenium-webdriver
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")
.
I think I can add something here.
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.
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.
unless we use some fazzy search method.
use
find_elements()
withcontains(@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()
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");
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
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']")));
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) 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
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']")));
driver.switchTo().frame()
has multiple overloads.
driver.switchTo().frame(name_or_id)
Here your iframe
doesn't have id or name, so not for you.
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)
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']")));
Source: Stackoverflow.com