简体   繁体   中英

How to switch to another Tab using Selenium WebDriver with Java

I am opening google.com and then clicking on "GMail" hyperlink a new tab is opened on the same browser.

Now I want to switch to this new tab where GMail is opened using Selenium WebDriver.

Code snippet is :

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

Now I want to go to the tab where I have opened GMail link. I have googled through N number of solutions but none of them worked.

For eg

Solution 1 :

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

Solution 2 :

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

Kindly suggest. I am stuck on this.

Seems to me that driver.getWindowHandles() does not work for tabs... you'll always get back a one item array with the CURRENT tab's handle... [deleted old answer as this seems to be fixed now]

UPDATE (6/16/2016): the current version of Selenium (server standalone 2.53.0) seems to act differently. Now I'm using something like this to open/switch the driver to the new tab:

UPDATE (11/16/2016): Selenium 3.0.1 seems to have changed things again? I have to use javascript to open a new tab now. This seems to work in Chrome only... Firefox opens a new window. I'm going to see if that behavior can be changed using geckodriver's settings (capabilities/profile?).

// 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()); 

the getWindowHandles() method is now returning a Set. This has only been tested in Chrome so far, since Firefox version 47 currently has some serious problems using the firefoxdriver... and using geckodriver the Actions aren't working at all. [update 6/11/2016]: Firefox through geckodriver now returns a Set]

You can also do something like this.. cast it to 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));

Update: To get around the geckodriver bug, I've switched to using element.sendkeys... something like this seems to work in Marionette and Chrome.. (Update2): Updated to javascript because of changes in Selenium 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 (11/16/2016): the old method to close using Ctrl-W seems to be broken, too... use this:

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

我们手动切换到下一个选项卡的方式是按 - CTRL + Page Down我们可以使用 Selenium 做同样的事情 -

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

The window handles is not very safe with the index number since they could be very unordered. I would suggest you to find a list and do a loop and look for the intended one.

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.equals(currentWindowHandle){
            //Now switchTo new Tab.
            driver.switchTo().window(window);
            //Do whatever you want to do here.
            
            //Close the newly opened tab
            driver.close();
        }
    }
}

You have a possible right solution (Sol2), but the problem is you can't switch to a new tab untill it will not be loaded fully.

So, solutions: 1) BAD ONE: put in a waiting timer, just sleep(2000) some time, and then

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

2) Good one!

Use native selenium things. First get all the available tabs opened with:

driver.getWindowHandle();

Then swith to another tab:

driver.switchTo().window(myWindowHandle );

You can provide tab name parameter and try this:

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;
}

There is an easy and short way:

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));

That's it, hope it help.

I'd suggest initializing a second driver to do the work for that tab, or open a second tab in the first driver and have that tab have it's own set of logic accomplishing what you need.

The code below should give you a good idea of how you can manipulate different drivers/browsers/windows and multiple tabs within each driver using Selenium 2.53.1 and 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
 }

I hope that helps

Below is the Java Implementation using Robot Class, I have switched tabs multiple(7) times.

I Hope it will Help.

Imports:

import java.awt.Robot;

import java.awt.event.KeyEvent;

import java.util.ArrayList;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

Main Method

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) {
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM