如何使用Java在Selenium WebDriver中切换框架

39

我正在使用Java和WebDriver。我必须在两个帧之间切换。我在Selenium IDE中记录了测试用例,在其中我得到的值为selectFrame relative=top select Frame=middle Frame。

但是有一个问题,它不能识别relative=top和middleFrame。我应该如何在Java的Selenium WebDriver中解决这个问题?

7个回答

58

WebDriver的driver.switchTo().frame()方法有三个可能的参数:

  • 一个数字。

    通过帧的索引(从零开始)选择一个帧。也就是说,如果一个页面有三个帧,第一个帧的索引为0,第二个帧为1,第三个帧为2。一旦选择了帧,所有后续对WebDriver接口的调用都将针对该帧进行。

  • 名称或ID。

    根据名称或ID选择一个帧。通过匹配名称属性定位的帧始终优先于通过匹配ID定位的帧。

  • 先前找到的WebElement

    使用先前定位的WebElement选择一个帧。

通过id/name获取框架,或使用driver.findElement()来定位它,这样你就可以了。

switchTo().frame(0)如何处理iframe和frameset中的frame-in-frameset?“frameset”标签是否被计算在内? - djangofan
@djangofan 很好的问题。我不知道,我从来没有使用过number参数。我猜它不会计算<frameset>元素。如果你测试过,请分享你的结果 :)。 - Petr Janeček
3
尽管这篇文章比较旧,但我会为其他人发布它。根据我的经验,它不会计算frameset元素。 - aurbano
3
@aurbano - 我只是想让你知道,三年后,你的评论解决了我遇到的问题!谢谢你!!! - FreeMan
我认为目前可能需要使用不同的方法 - SwitchToFrame()。更多信息可以在这里找到(https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/remote/server/handler/SwitchToFrame.html)。如果有人能够更新这个答案就好了。我自己是用JS的,但我不喜欢链接失效。 - Carolus

17

切换到一个框架:

driver.switchTo.frame("Frame_ID");

切换回默认选项。

driver.switchTo().defaultContent();

2
这很棘手。在Selenium API中,切换到默认内容是我所知道的最糟糕的方法之一。因为如果你选择driver.switchTo().defaultContent(),然后再次发出driver.switchTo().defaultContent(),那么你无法保证最终停留在哪里。Java Doc指出:选择页面上的第一个框架或包含iframes的主文档。因此,如果您已经在根框架中,您将进入第一个框架,并带来所有这种混乱。因此,请始终测试是否已经在根框架中(javascript->返回self.location === top.location;)。 - Martin Kersten

6

首先,您需要找到框架ID并在WebElement中定义它。

例如: WebElement fr = driver.findElementById("id");

然后使用以下代码切换到框架:driver.switchTo().frame("Frame_ID");

示例脚本:

WebElement fr = driver.findElementById("theIframe");

driver.switchTo().frame(fr);

Then to move out of frame use:- driver.switchTo().defaultContent();

3
您还可以使用以下方法:

driver.switch_to.frame(0)

第一个 iframe 的索引是 (0)

要切换回默认内容:

driver.switch_to.default_content()

2

需要确保一旦进入框架,就需要切换回默认内容以便在另一个框架中访问web元素。因为Webdriver倾向于在当前框架内查找新框架。

driver.switchTo().defaultContent()

2

还有一种可能性是使用带有ExpectedConditions的WebDriverWait(以确保Frame可用)。

  1. With string as parameter

    (new WebDriverWait(driver, 5)).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("frame-name"));
    
  2. With locator as a parameter

    (new WebDriverWait(driver, 5)).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("frame-id")));
    

更多信息可以在这里找到。


1

这段代码是用Groovy编写的,所以很可能需要进行一些重构。第一个参数是URL,第二个参数是限制尝试次数的计数器。

public boolean selectWindow(window, maxTries) {
    def handles
    int tries = 0
    while (true) {
        try {
            handles = driver.getWindowHandles().toArray()
            for (int a = handles.size() - 1; a >= 0 ; a--) { // Backwards is faster with FF since it requires two windows
                try {
                    Log.logger.info("Attempting to select window: " + window)
                    driver.switchTo().window(handles[a]);
                    if (driver.getCurrentUrl().equals(window))
                        return true;
                    else {
                        Thread.sleep(2000)
                        tries++
                    }
                    if (tries > maxTries) {
                        Log.logger.warn("Cannot select page")
                        return false
                    }
                } catch (Exception ex) {
                    Thread.sleep(2000)
                    tries++
                }
            }
        } catch (Exception ex2) {
            Thread.sleep(2000)
            tries++
        }
    }
    return false;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接