[java] Switch tabs using Selenium WebDriver with Java

Using Selenium WebDriver with JAVA. I am trying to automate a functionality where I have to open a new tab do some operations there and come back to previous tab (Parent). I used switch handle but it's not working. And one strange thing the two tabs are having same window handle due to which I am not able to switch between tabs.

However when I am trying with different Firefox windows it works, but for tab it's not working.

Please help me. How can I switch tabs. OR how can I switch tabs without using window handle as window handle is same of both tabs in my case.

(I have observed that when you open different tabs in same window, window handle remains same)

This question is related to java testing selenium automation selenium-webdriver

The answer is


The first thing you need to do is opening a new tab and save it's handle name. It will be best to do it using javascript and not keys(ctrl+t) since keys aren't always available on automation servers. example:

public static String openNewTab(String url) {
    executeJavaScript("window.parent = window.open('parent');");
    ArrayList<String> tabs = new ArrayList<String>(bot.driver.getWindowHandles());
    String handleName = tabs.get(1);
    bot.driver.switchTo().window(handleName);
    System.setProperty("current.window.handle", handleName);
    bot.driver.get(url);
    return handleName;
}

The second thing you need to do is switching between the tabs. Doing it by switch window handles only, will not always work since the tab you'll work on, won't always be in focus and Selenium will fail from time to time. As I said, it's a bit problematic to use keys, and javascript doesn't really support switching tabs, so I used alerts to switch tabs and it worked like a charm:

public static void switchTab(int tabNumber, String handleName) {
        driver.switchTo().window(handleName);
        System.setProperty("current.window.handle", handleName);
        if (tabNumber==1)
            executeJavaScript("alert(\"alert\");");
        else
            executeJavaScript("parent.alert(\"alert\");");
        bot.wait(1000);
        driver.switchTo().alert().accept();
    }

This will work for the MacOS for Firefox and Chrome:

// opens the default browser tab with the first webpage
driver.get("the url 1");
thread.sleep(2000);

// opens the second tab
driver.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND + "t");
driver.get("the url 2");
Thread.sleep(2000);

// comes back to the first tab
driver.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND, Keys.SHIFT, "{");

protected void switchTabsUsingPartOfUrl(String platform) {
    String currentHandle = null;
    try {
        final Set<String> handles = driver.getWindowHandles();
        if (handles.size() > 1) {
            currentHandle = driver.getWindowHandle();
        }
        if (currentHandle != null) {
            for (final String handle : handles) {
                driver.switchTo().window(handle);
                if (currentUrl().contains(platform) && !currentHandle.equals(handle)) {
                    break;
                }
            }
        } else {
            for (final String handle : handles) {
                driver.switchTo().window(handle);
                if (currentUrl().contains(platform)) {
                    break;
                }
            }
        }
    } catch (Exception e) {
        System.out.println("Switching tabs failed");
    }
}

Call this method and pass parameter a substring of url of the tab you want to switch to


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

This method helps in switching between multiple windows. The restricting problem with this method is that it can only be used so many times until the required window is reached. Hope it helps.


I had a problem recently, the link was opened in a new tab, but selenium focused still on the initial tab.

I'm using Chromedriver and the only way to focus on a tab was for me to use switch_to_window().

Here's the Python code:

driver.switch_to_window(driver.window_handles[-1])

So the tip is to find out the name of the window handle you need, they are stored as list in

driver.window_handles

This is a simple solution for opening a new tab, changing focus to it, closing the tab and return focus to the old/original tab:

@Test
public void testTabs() {
    driver.get("https://business.twitter.com/start-advertising");
    assertStartAdvertising();

    // considering that there is only one tab opened in that point.
    String oldTab = driver.getWindowHandle();
    driver.findElement(By.linkText("Twitter Advertising Blog")).click();
    ArrayList<String> newTab = new ArrayList<String>(driver.getWindowHandles());
    newTab.remove(oldTab);
    // change focus to new tab
    driver.switchTo().window(newTab.get(0));
    assertAdvertisingBlog();

    // Do what you want here, you are in the new tab

    driver.close();
    // change focus back to old tab
    driver.switchTo().window(oldTab);
    assertStartAdvertising();

    // Do what you want here, you are in the old tab
}

private void assertStartAdvertising() {
    assertEquals("Start Advertising | Twitter for Business", driver.getTitle());
}

private void assertAdvertisingBlog() {
    assertEquals("Twitter Advertising", driver.getTitle());
}

Set<String> tabs = driver.getWindowHandles();
Iterator<String> it = tabs.iterator();
tab1 = it.next();
tab2 = it.next();
driver.switchTo().window(tab1);
driver.close();
driver.switchTo().window(tab2);

Try this. It should work


It is A very simple process: assume you have two tabs so you need to first close the current tab by using client.window(callback) because the switch command "switches to the first available one". Then you can easily switch tab using client.switchTab.


The flaw with the selected answer is that it unnecessarily assumes order in webDriver.getWindowHandles(). The getWindowHandles() method returns a Set, which does not guarantee order.

I used the following code to change tabs, which does not assume any ordering.

String currentTabHandle = driver.getWindowHandle();
String newTabHandle = driver.getWindowHandles()
       .stream()
       .filter(handle -> !handle.equals(currentTabHandle ))
       .findFirst()
       .get();
driver.switchTo().window(newTabHandle);

With Selenium 2.53.1 using firefox 47.0.1 as the WebDriver in Java: no matter how many tabs I opened, "driver.getWindowHandles()" would only return one handle so it was impossible to switch between tabs.

Once I started using Chrome 51.0, I could get all handles. The following code show how to access multiple drivers and multiple tabs within each driver.

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

Hopefully that gives you a good idea of how to manipulate multiple tabs in multiple browser windows.


String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL, Keys.RETURN);
    WebElement e = driver.findElement(By
            .xpath("html/body/header/div/div[1]/nav/a"));
e.sendKeys(selectLinkOpeninNewTab);//to open the link in a current page in to the browsers new tab

    e.sendKeys(Keys.CONTROL + "\t");//to move focus to next tab in same browser
    try {
        Thread.sleep(8000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    //to wait some time in that tab
    e.sendKeys(Keys.CONTROL + "\t");//to switch the focus to old tab again

Hope it helps to you..


A brief example of how to switch between tabs in a browser (in case with one window):

// open the first tab
driver.get("https://www.google.com");
Thread.sleep(2000);

// open the second tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
driver.get("https://www.google.com");
Thread.sleep(2000);

// switch to the previous tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "" + Keys.SHIFT + "" + Keys.TAB);
Thread.sleep(2000);

I write Thread.sleep(2000) just to have a timeout to see switching between the tabs.

You can use CTRL+TAB for switching to the next tab and CTRL+SHIFT+TAB for switching to the previous tab.


public class TabBrowserDemo {

public static void main(String[] args) throws InterruptedException {
    System.out.println("Main Started");
    System.setProperty("webdriver.gecko.driver", "driver//geckodriver.exe");
    WebDriver driver = new FirefoxDriver();
    driver.get("https://www.irctc.co.in/eticketing/userSignUp.jsf");
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

    driver.findElement(By.xpath("//a[text()='Flights']")).click();
    waitForLoad(driver);
    Set<String> ids = driver.getWindowHandles();
    Iterator<String> iterator = ids.iterator();
    String parentID = iterator.next();
    System.out.println("Parent WIn id " + parentID);
    String childID = iterator.next();
    System.out.println("child win id " + childID);

    driver.switchTo().window(childID);
    List<WebElement> hyperlinks = driver.findElements(By.xpath("//a"));

    System.out.println("Total links in tabbed browser " + hyperlinks.size());

    Thread.sleep(3000);
//  driver.close();
    driver.switchTo().window(parentID);
    List<WebElement> hyperlinksOfParent = driver.findElements(By.xpath("//a"));

    System.out.println("Total links " + hyperlinksOfParent.size());

}

public static void waitForLoad(WebDriver driver) {
    ExpectedCondition<Boolean> pageLoadCondition = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
                }
            };
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(pageLoadCondition);
}

Since the driver.window_handles is not in order , a better solution is this.

first switch to the first tab using the shortcut Control + X to switch to the 'x' th tab in the browser window .

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "1");
# goes to 1st tab

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "4");
# goes to 4th tab if its exists or goes to last tab.

There is a difference how web driver handles different windows and how it handles different tabs.

Case 1:
In case there are multiple windows, then the following code can help:

//Get the current window handle
String windowHandle = driver.getWindowHandle();

//Get the list of window handles
ArrayList tabs = new ArrayList (driver.getWindowHandles());
System.out.println(tabs.size());
//Use the list of window handles to switch between windows
driver.switchTo().window(tabs.get(0));

//Switch back to original window
driver.switchTo().window(mainWindowHandle);


Case 2:
In case there are multiple tabs in the same window, then there is only one window handle. Hence switching between window handles keeps the control in the same tab.
In this case using Ctrl + \t (Ctrl + Tab) to switch between tabs is more useful.

//Open a new tab using Ctrl + t
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
//Switch between tabs using Ctrl + \t
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");

Detailed sample code can be found here:
http://design-interviews.blogspot.com/2014/11/switching-between-tabs-in-same-browser-window.html


    public void switchToNextTab() {
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(1));
    }
    
    public void closeAndSwitchToNextTab() {
        driver.close();
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(1));
    }

    public void switchToPreviousTab() {
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(0));
    }

    public void closeTabAndReturn() {
        driver.close();
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(0));
    }

    public void switchToPreviousTabAndClose() {
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(1));
        driver.close();
    }

Work around

Assumption : By Clicking something on your web page leads to open a new tab.

Use below logic to switch to second tab.

new Actions(driver).sendKeys(driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(driver.findElement(By.tagName("html")),Keys.NUMPAD2).build().perform();

In the same manner you can switch back to first tab again.

new Actions(driver).sendKeys(driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(driver.findElement(By.tagName("html")),Keys.NUMPAD1).build().perform();

Simple Answer which worked for me:

for (String handle1 : driver1.getWindowHandles()) {
        System.out.println(handle1); 
        driver1.switchTo().window(handle1);     
}

Please see below:

WebDriver driver = new FirefoxDriver();

driver.manage().window().maximize();
driver.get("https://www.irctc.co.in/");
String oldTab = driver.getWindowHandle();

//For opening window in New Tab
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,Keys.RETURN); 
driver.findElement(By.linkText("Hotels & Lounge")).sendKeys(selectLinkOpeninNewTab);

// Perform Ctrl + Tab to focus on new Tab window
new Actions(driver).sendKeys(Keys.chord(Keys.CONTROL, Keys.TAB)).perform();

// Switch driver control to focused tab window
driver.switchTo().window(oldTab);

driver.findElement(By.id("textfield")).sendKeys("bangalore");

Hope this is helpful!


To get parent window handles.

String parentHandle = driverObj.getWindowHandle();
public String switchTab(String parentHandle){
    String currentHandle ="";
    Set<String> win  = ts.getDriver().getWindowHandles();   

    Iterator<String> it =  win.iterator();
    if(win.size() > 1){
        while(it.hasNext()){
            String handle = it.next();
            if (!handle.equalsIgnoreCase(parentHandle)){
                ts.getDriver().switchTo().window(handle);
                currentHandle = handle;
            }
        }
    }
    else{
        System.out.println("Unable to switch");
    }
    return currentHandle;
}

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to testing

Test process.env with Jest How to configure "Shorten command line" method for whole project in IntelliJ Jest spyOn function called Simulate a button click in Jest Mockito - NullpointerException when stubbing Method toBe(true) vs toBeTruthy() vs toBeTrue() How-to turn off all SSL checks for postman for a specific site What is the difference between smoke testing and sanity testing? ReferenceError: describe is not defined NodeJs How to properly assert that an exception gets raised in pytest?

Examples related to selenium

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81 session not created: This version of ChromeDriver only supports Chrome version 74 error with ChromeDriver Chrome using Selenium Selenium: WebDriverException:Chrome failed to start: crashed as google-chrome is no longer running so ChromeDriver is assuming that Chrome has crashed WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser Class has been compiled by a more recent version of the Java Environment How to configure ChromeDriver to initiate Chrome browser in Headless mode through Selenium? How to make Firefox headless programmatically in Selenium with Python? element not interactable exception in selenium web automation Selenium Web Driver & Java. Element is not clickable at point (x, y). Other element would receive the click How do you fix the "element not interactable" exception?

Examples related to automation

element not interactable exception in selenium web automation Upload file to SFTP using PowerShell Check if element is clickable in Selenium Java Schedule automatic daily upload with FileZilla How can I start InternetExplorerDriver using Selenium WebDriver How to use Selenium with Python? Excel VBA Automation Error: The object invoked has disconnected from its clients How to type in textbox using Selenium WebDriver (Selenium 2) with Java? Sending email from Command-line via outlook without having to click send R command for setting working directory to source file location in Rstudio

Examples related to selenium-webdriver

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81 Selenium: WebDriverException:Chrome failed to start: crashed as google-chrome is no longer running so ChromeDriver is assuming that Chrome has crashed WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser How to configure ChromeDriver to initiate Chrome browser in Headless mode through Selenium? How to make Firefox headless programmatically in Selenium with Python? Selenium Web Driver & Java. Element is not clickable at point (x, y). Other element would receive the click How do you fix the "element not interactable" exception? Scrolling to element using webdriver? Only local connections are allowed Chrome and Selenium webdriver Check if element is clickable in Selenium Java