【问题标题】:WebDriver open new tabWebDriver 打开新标签
【发布时间】:2011-09-19 07:15:47
【问题描述】:

我已经搜索了网络和 WebDriver API。我看不到使用 WebDriver/Selenium2.0 打开新标签的方法。

有人可以确认我是否正确吗?

谢谢, 克里斯。 P.S:我看到的当前替代方法是在同一窗口中加载不同的 url 或打开新窗口。

【问题讨论】:

  • 我已经为您的具体问题添加了正确答案,但鉴于您关于“替代品”的陈述,我怀疑您的问题还有更多。如果您想提供更多上下文,可以给出更完整的答案。

标签: java automated-tests webdriver selenium-webdriver


【解决方案1】:

我希望打开一个新窗口。从自动化解决方案的角度来看,打开新窗口与打开新标签真的有区别吗?

您可以修改锚点目标属性,一旦单击目标页面将在新窗口中打开。

然后使用driver.switchTo() 切换到新窗口。用它来解决你的问题

【讨论】:

    【解决方案2】:
    @Test
     public void openTab() {
      //Open tab 2 using CTRL + t keys.
      driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
    
    
     //Open URL In 2nd tab.
      driver.get("http://www.qaautomated.com/p/contact.html");
    
      //Call switchToTab() method to switch to 1st tab
      switchToTab(); 
    }
    
    public void switchToTab() {
      //Switching between tabs using CTRL + tab keys.
      driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");
      //Switch to current selected tab's content.
      driver.switchTo().defaultContent();  
     } 
    

    我们可以使用键盘事件并非常轻松地自动打开和切换多个选项卡。这个例子引用自HERE

    【讨论】:

      【解决方案3】:

      Java Robot 可用于发送 Ctrl+t(如果 MAC OS X 则为 Cmd+t),如下所示:

      int vkControl = IS_OS_MAC ? KeyEvent.VK_META : KeyEvent.VK_CONTROL;
      Robot robot = new Robot();
      robot.keyPress(vkControl);
      robot.keyPress(KeyEvent.VK_T);
      robot.keyRelease(vkControl);
      robot.keyRelease(KeyEvent.VK_T);
      

      使用 Chrome 作为浏览器的完整运行示例可以 fork here

      【讨论】:

        【解决方案4】:

        这样做

        _webDriver.SwitchTo().Window(_webDriver.WindowHandles.Where(x => x != _webDriver.CurrentWindowHandle).First());
        

        或 Last() 等

        PS 不能保证 WindowHandles 的顺序在您的浏览器上显示,因此,我建议您在执行导致新选项卡打开的命令之前保留当前窗口的一些历史记录。然后,您可以将存储的窗口句柄与当前集合进行比较,并切换到列表中的新窗口句柄,其中应该只有一个。

        【讨论】:

          【解决方案5】:

          对于 MAC 操作系统

          from selenium import webdriver
          from selenium.webdriver.common.keys import Keys
          
          driver = webdriver.Firefox()
          driver.get("http://google.com")
          body = driver.find_element_by_tag_name("body")
          body.send_keys(Keys.COMMAND + 't')
          

          【讨论】:

            【解决方案6】:

            您可以使用以下代码打开新窗口,而不是打开新标签。

            for(String childTab : driver.getWindowHandles())
                {
                    driver.switchTo().window(childTab);
                }
            

            【讨论】:

              【解决方案7】:

              您可以尝试这种方式,因为新的 webdriver 中有action_chain。 我用的是Python,语法请忽略:

              act = ActionChains(driver)
              act.key_down(Keys.CONTROL)
              act.click(link).perform()
              act.key_up(Keys.CONTROL)
              

              【讨论】:

                【解决方案8】:

                嘿@Paul,谁曾在 python 中打开第二个标签时遇到问题。这是解决方案

                我不确定这是 webdriver 中的错误,还是因为它与 mutlitab 不兼容,但它肯定有问题,我将展示如何修复它。

                问题: 好吧,我看到不止一个问题。

                第一个问题必须这样做,当您打开第二个标签时,您只能看到一个句柄而不是两个。

                第二期这就是我的解决方案的用武之地。似乎虽然句柄值仍存储在驱动程序中,但由于某种原因,窗口与它失去了同步。

                这是解决第二个问题的解决方案:

                elem = browser.find_element_by_xpath("/html/body/div[2]/div[4]/div/a") #href link
                time.sleep(2) 
                elem.send_keys(Keys.CONTROL + Keys.RETURN + "2") #Will open a second tab
                
                #solution for the 2nd issue is here    
                for handle in browser.window_handles:
                        print "Handle is:" + str(handle) #only one handle number
                        browser.switch_to_window(handle)
                
                time.sleep(3)
                
                #Switch the frame over. Even if you have switched it before you need to do it again
                browser.switch_to_frame("Frame") 
                
                
                """now this is how you handle closing the tab and working again with the original tab"""
                
                #again switch window over
                elem.send_keys(Keys.CONTROL + "w")
                for handle in browser.window_handles:
                    print "HandleAgain is:" + str(handle) #same handle number as before
                    browser.switch_to_window(handle)
                
                #again switch frame over if you are working with one
                browser.switch_to_frame("Frame") 
                
                time.sleep(3)
                #doing a second round/tab
                elem = browser.find_element_by_xpath("/html/body/div[2]/div[4]/div/a") #href link
                time.sleep(2) 
                elem.send_keys(Keys.CONTROL + Keys.RETURN + "2") #open a 2nd tab again
                
                """Got it? find the handle, switch over the window then switch the frame"""
                

                它对我来说非常有效。我愿意提问...

                【讨论】:

                  【解决方案9】:
                          var windowHandles = webDriver.WindowHandles;
                          var script = string.Format("window.open('{0}', '_blank');", url);
                          scriptExecutor.ExecuteScript(script);
                          var newWindowHandles = webDriver.WindowHandles;
                          var openedWindowHandle = newWindowHandles.Except(windowHandles).Single();
                          webDriver.SwitchTo().Window(openedWindowHandle);
                  

                  【讨论】:

                  • 这解决了我在 chromedriver 上打开标签的问题。
                  【解决方案10】:

                  我遇到了同样的问题并找到了答案。试一试。

                  Robot r = new Robot(); 
                  r.keyPress(KeyEvent.VK_CONTROL); 
                  r.keyPress(KeyEvent.VK_T); 
                  r.keyRelease(KeyEvent.VK_CONTROL); 
                  r.keyRelease(KeyEvent.VK_T);
                  

                  它将打开一个新标签,您可以在新标签中执行您的操作。

                  【讨论】:

                  • 有趣的想法。这会通过 Selenium Grid 管道工作吗?
                  【解决方案11】:

                  IJavaScriptExecutor 是一个非常有用的类,它可以在运行时通过 JavaScript 操作 HTML DOM,下面是关于如何通过 IJavaScriptExecutor 在 Selenium 中打开新浏览器选项卡的示例代码:

                  IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
                                  object linkObj = js.ExecuteScript("var link = document.createElement('a');link.target='_blank';link.href='http://www.gmail.com';link.innerHTML='Click Me';document.getElementById('social').appendChild(link);return link");
                                  /*IWebElement link = (IWebElement)linkObj;
                                  link.Click();*/
                                  browser.Click("//*[@id='social']/a[3]");
                  

                  为了说明一下,Selenium 中没有允许您打开新标签页的方法,上面的代码将动态创建一个锚元素并引导它打开一个新标签页。

                  【讨论】:

                    【解决方案12】:

                    我们无法使用 Web 驱动程序/selenium 2.0 创建新的 TAB 或处理选项卡

                    您可以改为打开一个新窗口。

                    【讨论】:

                      【解决方案13】:

                      感谢@Jonathan Azoff 的好主意!

                      这是我在 Ruby 中的做法:

                      def open_new_window(url)
                        a = @driver.execute_script("var d=document,a=d.createElement('a');a.target='_blank';a.href=arguments[0];a.innerHTML='.';d.body.appendChild(a);return a", url)
                        a.click
                        @driver.switch_to.window(@driver.window_handles.last)
                      end
                      

                      【讨论】:

                        【解决方案14】:

                        我必须说我也试过这个,虽然它似乎适用于某些绑定(Java,据 Jonathan 所说,当然也适用于 ruby​​),但对于其他绑定则不行:selenium python bindings 报告每个窗口只有一个句柄, 即使包含多个标签

                        【讨论】:

                          【解决方案15】:

                          使用 webdriver 完全有一种跨浏览器的方法可以做到这一点,那些说你不能的人只是太懒了。首先,您需要使用 WebDriver 将标签注入并锚定到打开您想要的选项卡的页面中。我是这样做的(注意:驱动程序是一个 WebDriver 实例):

                          /**
                           * Executes a script on an element
                           * @note Really should only be used when the web driver is sucking at exposing
                           * functionality natively
                           * @param script The script to execute
                           * @param element The target of the script, referenced as arguments[0]
                           */
                          public void trigger(String script, WebElement element) {
                              ((JavascriptExecutor)driver).executeScript(script, element);
                          }
                          
                          /** Executes a script
                           * @note Really should only be used when the web driver is sucking at exposing
                           * functionality natively
                           * @param script The script to execute
                           */
                          public Object trigger(String script) {
                              return ((JavascriptExecutor)driver).executeScript(script);
                          }
                          
                          /**
                           * Opens a new tab for the given URL
                           * @param url The URL to 
                           * @throws JavaScriptException If unable to open tab
                           */
                          public void openTab(String url) {
                              String script = "var d=document,a=d.createElement('a');a.target='_blank';a.href='%s';a.innerHTML='.';d.body.appendChild(a);return a";
                              Object element = trigger(String.format(script, url));
                              if (element instanceof WebElement) {
                                  WebElement anchor = (WebElement) element; anchor.click();
                                  trigger("var a=arguments[0];a.parentNode.removeChild(a);", anchor);
                              } else {
                                  throw new JavaScriptException(element, "Unable to open tab", 1);
                              }       
                          }
                          

                          接下来,您需要告诉 webdriver 将其当前窗口句柄切换到新选项卡。我是这样做的:

                          /**
                           * Switches to the non-current window
                           */
                          public void switchWindow() throws NoSuchWindowException, NoSuchWindowException {
                              Set<String> handles = driver.getWindowHandles();
                              String current = driver.getWindowHandle();
                              handles.remove(current);
                              String newTab = handles.iterator().next();
                              locator.window(newTab);
                          }
                          

                          完成后,您可以使用相同的 WebDriver 实例与新页面上下文中的元素进行交互。完成该选项卡后,您始终可以使用与上述 switchWindow 函数类似的机制返回到默认窗口上下文。我将把它作为练习留给你来解决。

                          【讨论】:

                          • switchWindow()最后一行的locator是什么?
                          • 在 Webdriver 的常规非远程版本中,我相信定位器可能只是 driver.switchTo() 对吧?
                          • 我同意此处提供的代码将通过 WebDriver 在任何给定浏览器窗口中打开一个新选项卡。但是,不能保证特定驱动程序能够控制生成的新标签页。
                          • 不错的解决方法...只是我无法捕捉到创建的新标签。我正在使用 C#.net 任何帮助表示赞赏
                          • @Jonathan Azoff 你如何控制打开的标签页?打开标签是可行的,但如果驱动程序无法处理标签,您会感到无尽的悲痛
                          【解决方案16】:

                          虽然没有用于打开新选项卡的 API,但您可以创建一个 WebDriver 的新实例,调用它稍有不同,并在新选项卡中传递您想要的 URL。完成所有需要做的事情后,关闭该选项卡并将新驱动程序设为 NULL,这样它就不会干扰 Webdriver 的原始实例。如果您需要打开两个选项卡,请确保您引用了相应的 WebDriver 实例。将其用于 Sitecore CMS 自动化,并且有效。

                          【讨论】:

                            【解决方案17】:

                            Selenium WebDriver API 目前不支持管理浏览器中的标签页。

                            【讨论】:

                            • 谢谢吉姆,我想确定没有办法处理标签。我所说的“替代方案”只是指我还能如何处理选项卡式浏览,不涉及特殊情况,所以打开多个窗口对我来说似乎很好。
                            • Downvoters:这是您将从项目本身得到的答案。仅仅因为它不是您喜欢的答案,并不意味着它是错误的或质量差。
                            • @Kyralessa 尊敬的,我不同意。有时,正确的答案,“你不能那样做。”在这种情况下确实如此。 API 不支持,也不会支持。其他答案中的任何所谓的解决方法都可能会为您打开一个新选项卡,但不能保证 WebDriver 将能够打开新选项卡。事实上,我很确定至少有一个浏览器不会。与其对任何解决方案都可以跨浏览器工作(WebDriver 的主要承诺之一)抱有错误的希望,不如明确其局限性。
                            • @Kyralessa 你可以让它在 Chrome 中工作。伟大的。告诉我,它也适用于 IE 或 Safari 吗?哦,请记住,仅仅因为它在今天的 Chrome 中工作,因为它明确不受 API 支持,所以绝对不能保证它会在未来的版本中继续工作。不过,很高兴你能够让它在某些情况下工作。
                            • 您已经说过的话,无需重复。我完全明白。我根本不同意你的看法。由于您似乎决心试图说服人们项目本身提供的答案是错误的或不如项目作者不能保证有效的答案有用,并且还决心对这个问题有最后的发言权,我将把这作为我对此事的最后评论。
                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2022-11-18
                            • 1970-01-01
                            • 2014-03-13
                            • 1970-01-01
                            • 2014-11-05
                            • 2015-10-18
                            相关资源
                            最近更新 更多