【问题标题】:How to switch between frames in Selenium WebDriver using Java如何使用 Java 在 Selenium WebDriver 中的帧之间切换
【发布时间】:2012-06-08 09:39:18
【问题描述】:

我正在使用带有 WebDriver 的 java。我必须在两个帧之间切换。我已经在 selenium IDE 中记录了测试用例,其中我得到的值是 selectFrame relative=top select Frame=middle Frame

但是有一个问题是它无法识别 relative=top 和 middleFrame。如何使用 Java 在 Selenium WebDriver 中解决这个问题?

【问题讨论】:

    标签: java selenium-webdriver


    【解决方案1】:

    WebDriver 的driver.switchTo().frame() 方法采用三个可能的参数之一:

    • A number.

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

    • A name or ID.

      按名称或 ID 选择框架。按匹配名称定位的框架 属性总是优先于那些通过 ID 匹配的。

    • A previously found WebElement.

      使用之前定位的 WebElement 选择一个框架。

    通过它的 id/name 获取框架或通过 driver.findElement() 定位它,你会很好的。

    【讨论】:

    • switchTo().frame(0) 如何处理 iframe VS。框架中的框架? “frameset”标签算不算?
    • @djangofan 好问题。我不知道,我从来没有使用过 number 参数。我猜它不算<frameset> 元素。我你曾经测试过它,请分享你的结果:)。
    • 尽管这是旧的,但我会为其他人发布,但根据我的经验,它确实计入 frameset 元素。
    • @aurbano - 只是想让您知道,3 年后,您的评论解决了我遇到的问题!谢谢!!!
    • @FreeMan 哈哈哈很高兴它有帮助:)
    【解决方案2】:

    切换到一个框架:

    driver.switchTo.frame("Frame_ID");
    

    再次切换到默认值。

    driver.switchTo().defaultContent();
    

    【讨论】:

    • 这很棘手。切换到默认内容是我在 Seleniums API 中知道的最糟糕的方法之一。因为如果您使用 driver.switchTo().defaultContent() 并再次发出 driver.switchTo().defaultContent() 则无法保证您最终会在哪里。 Java Doc 状态:选择页面上的第一个框架,或者当页面包含 iframe 时选择主文档。因此,如果您已经在根框架中,那么您最终会在第一框架中带来所有混乱。所以总是测试你是否已经在根框架中(javascript -> return self.location === top.location;)
    【解决方案3】:

    首先,您必须找到框架 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();
    

    【讨论】:

      【解决方案4】:

      需要确保一旦切换到一个框架,需要切换回默认内容才能访问另一个框架中的 web 元素。由于 Webdriver 倾向于在当前框架内找到新框架。

      driver.switchTo().defaultContent()
      

      【讨论】:

        【解决方案5】:

        你也可以使用:

        driver.switch_to.frame(0)
        

        (0) 是 html 上的第一个 iframe。

        切换回默认内容:

        driver.switch_to.default_content()
        

        【讨论】:

        • 你拯救了我的一天。谢谢
        • 很高兴能帮上忙!
        【解决方案6】:

        还可以将 WebDriverWait 与 ExpectedConditions 一起使用(以确保 Frame 可用)。

        1. 以字符串为参数

          (new WebDriverWait(driver, 5)).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("frame-name"));
          
        2. 以定位器为参数

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

        更多信息可以找到here

        【讨论】:

          【解决方案7】:

          此代码非常规范,因此您很可能需要进行一些返工。第一个参数是一个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;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-05-13
            • 1970-01-01
            • 1970-01-01
            • 2014-10-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多