如何使用Selenium WebDriver和Java切换到另一个选项卡

时间:2015-04-05 08:08:28

标签: java selenium-webdriver

我正在打开google.com,然后点击“GMail”超链接,在同一浏览器上打开一个新标签页。

现在我想切换到使用Selenium WebDriver打开GMail的新选项卡。

代码段是:

  WebDriver wd = new ChromeDriver();
  wd.get("https://www.google.co.in/?gws_rd=ssl");       
  wd.findElement(By.linkText("Gmail")).sendKeys(Keys.CONTROL,Keys.RETURN);

现在我想转到我打开GMail链接的标签页。我已经搜索了N个解决方案,但没有一个解决方案。

例如

解决方案1:

String Tab1 = wd.getWindowHandle(); 
ArrayList<String> availableWindows = new ArrayList<String>(wd.getWindowHandles()); 
if (!availableWindows.isEmpty()) { 
wd.switchTo().window(availableWindows.get(1)); 
}

解决方案2:

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");

请建议。我坚持这个。

8 个答案:

答案 0 :(得分:8)

在我看来,driver.getWindowHandles()不适用于标签...你总是会使用CURRENT标签的句柄返回一个项目数组... [删除旧答案,因为这个似乎现在已经修好了]

UPDATE(2016年6月16日):当前版本的Selenium(服务器独立版2.53.0)似乎采取了不同的行动。现在我使用这样的东西打开/切换驱动程序到新选项卡:

UPDATE(2016年11月16日):Selenium 3.0.1似乎又改变了一些东西?我现在必须使用javascript打开一个新标签。这似乎只适用于Chrome ... Firefox打开一个新窗口。我是否可以使用geckodriver的设置(功能/配置文件?)来查看是否可以更改此行为。

// Actions actions = new Actions(driver); 
// actions.keyDown(Keys.CONTROL).sendKeys("t").keyUp(Keys.CONTROL).build().perform();

((JavascriptExecutor)driver).executeScript("window.open('about:blank', '_blank');");

Set<String> tab_handles = driver.getWindowHandles();
    int number_of_tabs = tab_handles.size();
    int new_tab_index = number_of_tabs-1;
    driver.switchTo().window(tab_handles.toArray()[new_tab_index].toString()); 

getWindowHandles()方法现在返回一个Set。到目前为止,这只在Chrome中进行了测试,因为Firefox 47目前在使用firefoxdriver时遇到了一些严重的问题......并且使用geckodriver,Actions根本就不起作用。 [update 6/11/2016]:Firefox通过geckodriver现在返回一个Set]

您也可以执行以下操作..将其强制转换为ArrayList:

  //  set tab_index to the number of window/tab you want.  0 is the first tab 

       ArrayList<String> tabs_windows = new ArrayList<String> (driver.getWindowHandles());
    driver.switchTo().window(tabs_windows.get(tab_index));
更新:为了解决这个geckodriver错误,我已经切换到使用element.sendkeys ...这样的东西似乎可以在Marionette和Chrome中使用..(Update2):由于Selenium的变化而更新为javascript 3.0.1:

// driver.findElement(By.cssSelector("body")).sendKeys(Keys.chord(Keys.CONTROL, "t"));

((JavascriptExecutor)driver).executeScript("window.open('about:blank', '_blank');");

    Set<String> tab_handles = driver.getWindowHandles();
    int number_of_tabs = tab_handles.size();
    int new_tab_index = number_of_tabs-1;
    driver.switchTo().window(tab_handles.toArray()[new_tab_index].toString()); 

UPDATE(2016年11月16日):使用Ctrl-W关闭的旧方法似乎也被破坏了...使用此:

((JavascriptExecutor)driver).executeScript("close();");

答案 1 :(得分:5)

我们手动切换到下一个标签的方法是按 - CTRL + Page Down我们可以像使用Selenium一样 -

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL, Keys.PAGE_DOWN);

答案 2 :(得分:3)

窗口句柄对索引号不是很安全,因为它们可能非常无序。我建议你找一个清单并做一个循环,然后寻找预期的清单。

public void TabHandles() {
    driver.get("https://www.google.co.in/?gws_rd=ssl");

    String currentWindowHandle = driver.getWindowHandle();

    driver.findElement(By.linkText("Gmail")).sendKeys(Keys.CONTROL, Keys.RETURN);

    //Get the list of all window handles
    ArrayList<String> windowHandles = new ArrayList<String>(driver.getWindowHandles());

    for (String window:windowHandles){

        //if it contains the current window we want to eliminate that from switchTo();
        if (window != currentWindowHandle){
            //Now switchTo new Tab.
            driver.switchTo().window(window);
            //Do whatever you want to do here.

            //Close the newly opened tab
            driver.close();
        }
    }
}

答案 3 :(得分:1)

您有一个可能正确的解决方案(Sol2),但问题是您无法切换到新选项卡,直到它无法完全加载。

所以,解决方案: 1)BAD ONE:放入等待计时器,只是睡觉(2000)一段时间,然后

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");

2)好的!

使用本地硒的东西。首先获取打开的所有可用选项卡:

driver.getWindowHandle();

然后转到另一个标签:

driver.switchTo().window(myWindowHandle );

答案 4 :(得分:1)

您可以提供标签名称参数并尝试此操作:

public boolean switchToTab(String tabName){
    log.debug("Switch to {} tab",tabName);
    ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
    ArrayList<String> tabList = new ArrayList<>();
    for (int i =0;i<tab.size();i++){
        tabList.add(i,driver.switchTo().window(tab.get(i)).getTitle());
        driver.switchTo().window(tab.get(0));
        if(tabList.get(i).equals(tabName)){
            driver.switchTo().window(tab.get(i));
                return true;
        }
    }
    return false;
}

答案 5 :(得分:0)

我建议初始化第二个驱动程序来为该选项卡执行工作,或者在第一个驱动程序中打开第二个选项卡,并让该选项卡拥有自己的逻辑集,以完成您的需要。

下面的代码可以让您了解如何使用Selenium 2.53.1和Chrome 51.0操作不同的驱动程序/浏览器/窗口以及每个驱动程序中的多个选项卡。

// INITIALIZE TWO DRIVERS (THESE REPRESENT SEPARATE CHROME WINDOWS)
driver1 = new ChromeDriver();
driver2 = new ChromeDriver();

// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
   driver1.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
   // SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
   Thread.sleep(100);

// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs1 = new ArrayList<String> (driver1.getWindowHandles());

// REPEAT FOR THE SECOND DRIVER (SECOND CHROME BROWSER WINDOW)

// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
   driver2.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
   // SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
   Thread.sleep(100);

// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs2 = new ArrayList<String> (driver1.getWindowHandles());

// NOW PERFORM DESIRED TASKS WITH FIRST BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
   driver1.switchTo().window(tabs1.get(ii));
   // LOGIC FOR THAT DRIVER'S CURRENT TAB
}

 // PERFORM DESIRED TASKS WITH SECOND BROWSER IN ANY TAB
 for(int ii = 0; ii <= TAB_NUMBER; ii++) {
    drvier2.switchTo().window(tabs2.get(ii));
    // LOGIC FOR THAT DRIVER'S CURRENT TAB
 }

我希望有帮助

答案 6 :(得分:0)

有一种简便的方法:

import java.util.ArrayList;

ArrayList<String> tabs2 = new ArrayList<String>(driver.getWindowHandles());
driver.switchTo().window(tabs2.get(1)); //Tab number

//Can change it for next tab like that or previous:

driver.switchTo().window(tabs2.get(1));
driver.close();
driver.switchTo().window(tabs2.get(0));

就是这样,希望对您有所帮助。

答案 7 :(得分:-1)

下面是使用机器人类的Java实现,我已经多次(7)次切换标签。

我希望它会有所帮助。

<强>进口:

import java.awt.Robot;

import java.awt.event.KeyEvent;

import java.util.ArrayList;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

主要方法

public static void main(String[] args) {

    System.setProperty("webdriver.chrome.driver", "/Path/To/chromedriver/" + "chromedriver.exe");
    WebDriver driver = new ChromeDriver();

    // go to URL1
    driver.navigate().to("http://www.facebook.com");
    try {
        // Open New Tab by simulating Ctrl+t
        Robot r = new Robot();
        r.keyPress(KeyEvent.VK_CONTROL);
        r.keyPress(KeyEvent.VK_T);
        r.keyRelease(KeyEvent.VK_CONTROL);
        r.keyRelease(KeyEvent.VK_T);
        Thread.sleep(1000);

        // Create Array List to keep Tab information
        ArrayList<String> tabs2 = new ArrayList<String>(driver.getWindowHandles());

        // Navigate to New Tab
        driver.switchTo().window(tabs2.get(1));

        // go to URL2
        driver.navigate().to("http://www.google.com");

        // Navigate to Tab 0
        driver.switchTo().window(tabs2.get(0));

        Thread.sleep(2000);
        // Navigate to Tab 1
        driver.switchTo().window(tabs2.get(1));

        Thread.sleep(2000);
        // Navigate to Tab 0
        driver.switchTo().window(tabs2.get(0));

        Thread.sleep(2000);
        // Navigate to Tab 1
        driver.switchTo().window(tabs2.get(1));

        Thread.sleep(2000);
        // Navigate to Tab 1
        driver.switchTo().window(tabs2.get(0));
        driver.close();

        Thread.sleep(2000);

        // Navigate to Tab 1
        driver.switchTo().window(tabs2.get(1));
        driver.close();

    } catch (Exception e) {
    }

}