77

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.

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)

2

27 Answers 27

131
 psdbComponent.clickDocumentLink(); ArrayList<String> tabs = new ArrayList<String> (driver.getWindowHandles()); driver.switchTo().window(tabs.get(1)); driver.close(); driver.switchTo().window(tabs.get(0)); 

This code perfectly worked for me. Try it out. You always need to switch your driver to new tab, before you want to do something on new tab.

4
  • 2
    Tabs aren't windows. I guess it's not working in Firefox.
    – Alex78191
    CommentedJul 10, 2017 at 0:43
  • 5
    This answer assumes order in driver.getWindowHandles(). That method returns a Set and therefore guarantees no order at the contract level. Perhaps your WebDriver implementatation is returning a Set implementation that does guarantee order, but why take the risk?CommentedFeb 28, 2018 at 11:25
  • Using ChromeDriver 2.33, getWindowHandles() does return a LinkedHashSet, so accessing by index works well. Note that you need to use getAt() instead of get()
    – SourMonk
    CommentedMar 15, 2018 at 13:32
  • I don't know why but the above does not work for firefox versions below 80.Any suggestion for switching tabs in versions below 80CommentedAug 19, 2022 at 5:47
29

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()); } 
2
  • I'm using chrome driver and in that when I use the line "driver.switchTo().window(newTab.get(0));" a new window is opened along with a new tab...Any idea why this is happening?
    – Lucy
    CommentedAug 1, 2016 at 8:31
  • I haven't checked it, but I guess it is browser configuration.CommentedApr 12, 2017 at 15:35
15

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

1
  • YES. This is the first response the indicates there is only a single window handle and that is not the same as a tab. I don't know how the other solutions even work. How does getWindowHandles get the list of tabs for them? It only gets window handles for me in IE (I know, IE, blech)
    – BClaydon
    CommentedJun 13, 2016 at 18:30
7

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(); 
1
  • Works only on Chrome
    – Jury
    CommentedFeb 14, 2016 at 11:17
7

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. 
0
    4
    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..

      3

      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(); } 
        3
         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(); } 
          2
          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.

          1
          • Maybe between multiple tabs?
            – Alex78191
            CommentedJul 10, 2017 at 0:41
          2

          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.

            2

            Simple Answer which worked for me:

            for (String handle1 : driver1.getWindowHandles()) { System.out.println(handle1); driver1.switchTo().window(handle1); } 
              2
              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

              0
                1

                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 
                1
                • 4
                  Be very, very careful when indexing into the collection of window handles. There is no guarantee that these handles are presented in any order, and the first window opened may have the last window handle in the list returned by the getWindowhandles method (or its equivalent in your language).
                  – JimEvans
                  CommentedApr 29, 2013 at 16:09
                1

                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!

                  1

                  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.

                    1

                    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.

                      1

                      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, "{"); 
                        1

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

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

                              1

                              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); } 
                              1
                              • 4
                                Welcome to Stack Overflow! Please don't just throw your source code here. Be nice and try to give a nice description to your answer, so that others will like it and upvote it. See: How do I write a good answer?CommentedJun 25, 2018 at 7:46
                              1
                              WebDriver driver = new FirefoxDriver(); driver.switchTo().window(driver.getWindowHandles().toArray()[numPage].toString()); numPage - int (0,1..) 
                              1
                              • 2
                                Could you please add some explanations to your answer, some reference to a documentation, etc, etc?
                                – Dada
                                CommentedNov 25, 2021 at 9:06
                              0

                              String mainWindow = driver.getWindowHandle(); seleniumHelper.switchToChildWindow(); .. ..//your assertion steps

                              seleniumHelper.switchToWindow(mainWindow);

                              1
                              • 1
                                As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
                                – CommunityBot
                                CommentedFeb 10, 2022 at 20:06
                              0

                              with Java I used this for switching the selenium focus to the new tab.

                              //Before the action that redirect to the new tab: String windHandleCurrent = driver.getWindowHandle(); // code that click in a btn/link in order to open a new tab goes here // now to make selenium move to the new tab ArrayList<String> windows = new ArrayList<String>(driver.getWindowHandles()); for(int i =0;i<windows.size();i++ ) { String aWindow = windows.get(i); if(aWindow != windHandleCurrent) { driver.switchTo().window(aWindow); } } // now you can code your AssertJUnit for the new tab. 
                                0

                                Selenium 4 has new features:

                                // Opens a new tab and switches to new tab driver.switchTo().newWindow(WindowType.TAB);

                                // Opens a new window and switches to new window driver.switchTo().newWindow(WindowType.WINDOW);

                                  0

                                  driver.getWindowHandles() is a Set.I converted it to array of objects by

                                  Object[] a=driver.getWindowHandles().toArray; 

                                  Say you want to switch to 2nd tab then (after conversion) use

                                  driver.switchTo().windows(a[1].toString()); 
                                    0

                                    Solution with Java

                                    Set<String> handles = driver.getWindowHandles(); Iterator<String> it = handles.iterator(); String parentTab = it.next(); String childTab = it.next(); // switch to the second tab driver.switchTo().window(childTab); // switch to the first tab driver.switchTo().window(parentTab); 

                                      Start asking to get answers

                                      Find the answer to your question by asking.

                                      Ask question

                                      Explore related questions

                                      See similar questions with these tags.