9
votes

Need to access elements inside a modal iframe.

Below code works perfectly fine for FireFox driver while fails for Chrome -

String frameId = null;
List<WebElement> frameSet = driver.findElements(By.tagName("iframe"));  
for (WebElement frameName : frameSet){  
    if(!(frameName.getAttribute("id").isEmpty()) && (frameName.getAttribute("id").contains("DlgFrame"))){
            frameId = frameName.getAttribute("id");
        }
}

try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
    e.printStackTrace();
    }

Logger.info("Switch to Frame - "+frameId);
driver.switchTo().frame(driver.findElement(By.id(frameId)));

Does Chrome driver support switchTo.frame(<'frameId'>)?

Error while using Chrome Driver -

org.openqa.selenium.WebDriverException: Unknown command. Options: ActivateTab, CaptureEntirePage, CloseTab, DeleteCookie, ...

Command duration or timeout: 220 milliseconds Build info: version: '2.25.0', revision: '17482', time: '2012-07-18 22:18:01' System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_05' Driver info: driver.version: RemoteWebDriver Session ID: cbde65cb0394ee0434b3bb528918ce40 at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:188) at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:145) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:498) at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:244) at org.openqa.selenium.remote.RemoteWebElement.sendKeys(RemoteWebElement.java:87) at com.shn.services.Office365.sharePointUploadFile(Office365.java:173) at com.shn.test.RunOffice365Test.testSharePointUploadAndDeleteFile(RunOffice365Test.java:55) at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:74) at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:92) at org.apache.maven.surefire.Surefire.run(Surefire.java:180) at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350) at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)

5
In 2021 chromedriver seems to still have issues with the switchTo command - user1593165

5 Answers

8
votes

ChromeDriver supports switchTo since it implements the WebDriver Interface. It works fine for me.

You have to do it like this:

driver.switchTo().frame(driver.findElement(By.id("frameId")));
//do your stuff
driver.switchTo().defaultContent();
5
votes

The issue was neither with chromeDriver nor selenium. Both were running on latest versions.

chromeDriver - 23.0.1240.0

Selenium - 2.25.0

The issue was with Chrome Browser.

My browser was running on ver. 12.0.742.112. Automatic updates were failing due to -

update Server not available (error:7)

I had to uninstall & install back the browser to get it to the latest ver. 21.0.1180.89 m.

The issue is now fixed & I am able to switch between frames.

2
votes

I don't know if this will help anyone, but I was having a similar issue polling frames and this is what the solution was for me.

Switch to DefaultContent():

_driver.SwitchTo().DefaultContent();

Get the frames:

IWebElement iFrames = _driver.FindElements(By.XPath("//iframe"));

Poll through the frames, but only switch to it if "Displayed" is true:

foreach (var frame in iFrames)
{
    if (!frame.Displayed)
        continue;

    _driver.SwitchTo().Frame(frame);
}
1
votes

It looks like the problem not in the iframe. Error listing includes org.openqa.selenium.remote.RemoteWebElement.sendKeys(RemoteWebElement.java:87) at. So I assuming another part of your code leads to app. fail.

1
votes

This is my implementation of switching to frame for all browsers, because switching to frame by Id or Name doesn't work for Chrome (with latest versions)

  • using Xpath (more elegant/readable code):
/**
 * This switch to frame method improves standard way to switching to frame
 * ( driver.switchTo().{@linkplain org.openqa.selenium.WebDriver.TargetLocator#frame(String) frame(String nameOrId)} )
 * because Chrome browser has problem with this method.   <br/>
 *
 * Bug: http://code.google.com/p/chromedriver/issues/detail?id=107
 * @param frameIdOrName the id or name of the &lt;frame&gt; or &lt;iframe&gt; element
 * @return This driver focused on the given frame.
 */
public WebDriver switchToFrameByIdOrName(String frameNameOrId) {
    if (driver instanceof ChromeDriver) {
        String frameElementXpath = String.format("//frame[@name='%1$s' or @id='%1$s']", frameNameOrId);
        WebElement f = driver.findElement(By.xpath(frameElementXpath));
        return driver.switchTo().frame(f);
    }
    return driver.switchTo().frame(frameNameOrId);
}

or

public WebDriver switchToFrameByIdOrName(String frameIdOrName) {
    if (!(driver instanceof ChromeDriver)) {
        return driver.switchTo().frame(frameIdOrName);
    }
    WebElement frame = null;
    try {
        frame = driver.findElement(By.cssSelector("frame[id='" + frameIdOrName + "']"));
    } catch (NoSuchElementException e) { /* It's ok for the moment */  }

    if (frame == null) {
        try {
            frame = driver.findElement(By.cssSelector("frame[name='" + frameIdOrName + "']"));
        } catch (NoSuchElementException e) {
            log.severe(String.format("CORE > switchToFrameByIdOrName() error: Frame with name or id '%s' not found.", frameIdOrName));
        }
    }
    return driver.switchTo().frame(element);
}

I'm using:

Selenium 2.37.1
Session info: chrome=31.0.1650.57)
Driver info: chromedriver=2.7.236900,platform=Windows NT 6.1 SP1 x86_64