Switch tabs using Selenium WebDriver with Java - 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.
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)

psdbComponent.clickDocumentLink();
ArrayList<String> tabs2 = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(tabs2.get(1));
driver.close();
driver.switchTo().window(tabs2.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.

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

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

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

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.

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

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

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.

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.

Simple Answer which worked for me:
for (String handle1 : driver1.getWindowHandles()) {
System.out.println(handle1);
driver1.switchTo().window(handle1);
}

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

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

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

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!

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.

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.

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

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

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

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

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

WebDriver driver = new FirefoxDriver();
driver.switchTo().window(driver.getWindowHandles().toArray()[numPage].toString());
numPage - int (0,1..)

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

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.

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

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

Related

Error trying to close a tab and switching to the other tab using selenium / java

I have a window with two tabs. I am trying to close the tab with a specific title and switch the control to the other tab.
Here is my code:
public static void closeTheWindowWithTitle(String title) {
ArrayList<String> tabs = new ArrayList<String> (driver.getWindowHandles());
String mainWindow = driver.getWindowHandle();
for(int i = 0; i < tabs.size(); i++) {
log.debug("switched to " + driver.getTitle() + " Window");
if(driver.getTitle().contains(title))
{
driver.switchTo().window(tabs.get(i));
driver.close();
log.debug("Closed the " + driver.getTitle() + " Window");
}
}
driver.switchTo().window(mainWindow);
}
When I run my code, I am getting the following exception:
org.openqa.selenium.NoSuchWindowException: no such window: target window already closed
from unknown error: web view not found
I am unable to figure out what is the problem. Please help.
I'm guessing, that the WindowHandle of your Main-Window got changed, somewhere along the way. You should be able to get your problem solved by doing something similar to the suggested solution here, i.e. getting all WindowHandles, and iterating over them and in the end switching to [0], which should be the only one left, after closing the second one.
I hope this will help you to fix your issue, i dont want to provide code fix and i want to explain you the details process step by step.
Open firefox/IE/Chrome browser and Navigate to https://www.bbc.co.uk
WebDriver driver = new AnyDriveryourusing();
// set implicit time to 30 seconds
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
// navigate to the url
driver.get("https://www.bbc.co.uk");
Get the GU ID of the current (parent) window using getWindowHandle() method present in the webdriver and store the value in a String
// get the Session id of the Parent
String parentGUID = driver.getWindowHandle();
Click on the Open New Window button, application open new window with google page.
// click the button to open new window
driver.findElement(By.id("two-window")).click();
Thread.sleep(5000);
Get the GU IDs of the two windows (parent + google), using getWindowHandles() method present in the webdriver. Store the GU IDs in a Set Collection, this Set will have GU IDs of both parent and Child Browsers
// get the All the session id of the browsers
Set allGUID = driver.getWindowHandles();
iterate the Set of GUID values, and if the value is parent value skip it if not switch to the new window
// iterate the values in the set
for(String guid : allGUID){
// one enter into if block if the GUID is not equal to parent window's GUID
if(! guid.equals(parentGUID)){
//todo
}
}
Switch to window using switchTo().window() method, pass the GU ID of the child browser to this method.
// switch to the guid
driver.switchTo().window(guid);
Find the search bar in Google.com and search for "success"
driver.findElement(By.name("q")).sendKeys("success");
Close the Google tab/Window and return to parent tab/browser window
// close the browser
driver.close();
// switch back to the parent window
driver.switchTo().window(parentGUID);
You were close but you weren't switching windows before checking the title. I've updated the code to something that should work.
public static void closeTheWindowWithTitle(String title)
{
Set<String> tabs = driver.getWindowHandles();
String mainWindow = driver.getWindowHandle();
for(int i = 0; i < tabs.size(); i++)
{
// you need to switch to the window before checking title
driver.switchTo().window(tabs.get(i));
log.debug("switched to " + driver.getTitle() + " Window");
if(driver.getTitle().contains(title))
{
driver.close();
log.debug("Closed the " + driver.getTitle() + " Window");
break; // this breaks out of the loop, which I'm assuming is what you want when a match is found
}
}
driver.switchTo().window(mainWindow);
}

Selenium - TimeOutException when attempting to interact with elements on a new tab [duplicate]

For automation purposes, I am working on creating a script that finds a row in a table. This row is clickable and opens a new tab/adress.
With selenium, I am now able to find the table row, click on the link, and the new tab opens. The problem is that I can't find any way to switch the focus to the newly opened tab. I tried to get all windowHandles and see if I could switch, but even after the new tab has opened, there is only 1 windowHandle.
Below is my code:
WebElement tableRow=driver.findElement(By.xpath("/html/body/div[1]/table/tbody/tr[2]"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", tableRow);
ArrayList<String> tabs = new ArrayList<String> (driver.getWindowHandles());
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
The Arraylist always contains 1 single windowHandle, not 2. So I am not able to switch focus to the new tab. Is there any way to solve this?
To properly switch to the newly opened Tab you need to induce WebDriverWait for the New Tab to render and then through a for() loop you need to iterate through the available WindowHandles and invoke switchTo().window() with the WindowHandle which is not the previous TAB through the following code block :
String first_handle = driver.getWindowHandle();
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", tableRow);
new WebDriverWait(driver,5).until(ExpectedConditions.numberOfWindowsToBe(2));
Set<String> allHandles = driver.getWindowHandles();
for(String winHandle:allHandles)
{
if (!first_handle.equalsIgnoreCase(winHandle)
{
driver.switchTo().window(winHandle);
}
}
Maybe you just have to wait until a second window is created? Maybe selenium checks window handles too fast?
Try with WebDriverWait
Example:
String currentHandle = driver.getWindowHandle();
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
Set<String> allHandles = driver.getWindowHandles();
for (String handle : allHandles) {
if (!handle.equals(currentHandle)) driver.switchTo().window(handle);
}
If a number of windows will be less or more than 2, TimeoutException will occur.
**Try this code:**
public static void switchToNewWindow(WebDriver driver, WebElement
causeOfNewWindow) {
// Get Handles before opening new window
Set<String> oldHandles = driver.getWindowHandles();
// Click element to open new Window
causeOfNewWindow.click();
// Get Handles after opening new window
Set<String> newHandles = driver.getWindowHandles();
for (String handle : newHandles) {
if (!oldHandles.contains(handle)) {
driver.switchTo().window(handle);
}
}
}

How to switch tab using for loop in Selenium Webdriver

I struggle with the problem of not being able to switch between tabs using the loop in Selenium WebDriver. I can do this at once, but I need to use the code repeatedly, in a loop.
Here comes the error:
"Exception in thread" main "org.openqa.selenium.NoSuchWindowException: Unable to locate window"
My code can find all the elements, open a link in a new tab, close it. However, it can not perform this operation again with the next element.
Here is my code( I'm using Firefox):
List<WebElement> allElements = driver.findElements(By.className("_4zhc5"));
int s = allElements.size();
System.out.println("total users to check: " + allElements.size());
for (int i = 0; i < s; i++) {
allElements = driver.findElements(By.className("_4zhc5"));
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL, Keys.RETURN);
allElements.get(i).sendKeys(selectLinkOpeninNewTab);
for (String winHandle : driver.getWindowHandles()) {
driver.switchTo().window(winHandle);
Thread.sleep(3000);
}
driver.close();
Thread.sleep(2000);
}
I also created a prototype page using jsfiddle. The error appears on the second attempt to execute the code. Just the script does not click on another element called "lovely"
You need to switch back to the original window where the links are.
Click on one if the links
Switch to that tab
Close tab
Switch back to default window where you are getting the links
Easiest way is to store the "original" window and switch back to that one all the time.
winHandleBefore = driver.getWindowHandle();
when closing the tab
driver.close();
driver.switchTo().window(winHandleBefore)
/*the second "for loop" will not help you so u should use another logic with another condition it will switch using while loop and hasNext method
try it: */
List allElements = driver.findElements(By.className("_4zhc5"));
int s = allElements.size();
System.out.println("total users to check: " + allElements.size());
for (int i = 0; i < s; i++) {
allElements = driver.findElements(By.className("_4zhc5"));
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL, Keys.RETURN);
allElements.get(i).sendKeys(selectLinkOpeninNewTab);
Set<String>windowat=driver.getWindowHandles();
Iterator<String>itro=windowat.iterator();
while(itro.hasNext()) {
String currntpage=itro.next();
driver.switchTo().window(currntpage);
String thetitle=driver.getTitle();
System.out.println(thetitle); }

How to switch between multiple tabs(more than 2) open in same window using Selenium Webdriver

I am learning Selenium-Webdriver and so for practice working on one scenario, but I'm stuck in step#3. Scenario is as follows:
Open google homepage and perform some search, say for the word "WebDriver".
Open the first two links in new tabs of the same window.
Navigate to the second and third tab and get their titles
Close the tabs and switch back to the google result tab.
So far, I'm able to open google home page, perform a search on the word "WebDriver" and open the first two links, but now I'm unable to switch to the second and third tab and close them. My code so far is:
String originalHandle = driver.getWindowHandle();
System.out.println("Before switching title is:" +driver.getTitle());
String selectLinkOpeninNewTab = Keys.chord(Keys.COMMAND,Keys.ENTER);
WebElement link1 = driver.findElement(By.xpath(".//*[#id='rso']/div[2]/div[1]/div/h3/a"));
link1.sendKeys(selectLinkOpeninNewTab);
WebElement link2 = driver.findElement(By.xpath(".//*[#id='rso']/div[2]/div[2]/div/h3/a"));
link2.sendKeys(selectLinkOpeninNewTab);
Set<String> s1 = driver.getWindowHandles();
Iterator<String> i1 = s1.iterator();
int i = 0;
while(i1.hasNext())
{
i++;
String childwindow = i1.next();
if(!originalHandle.equalsIgnoreCase(childwindow))
{
driver.switchTo().window(childwindow);
Thread.sleep(10000);
System.out.println("After switching title of new Tab "+i+ " title is " +driver.getTitle());
driver.close();
}
}
driver.switchTo().window(originalHandle);
System.out.println("Original window tab title is" +driver.getTitle() );
I'm not sure where it's going wrong and how to fix it. :(
Could be too late, but hope this helps :
for (String winHandle : driver.getWindowHandles()) { //Gets the new window handle
System.out.println(winHandle);
driver.switchTo().window(winHandle); // switch focus of WebDriver to the next found window handle (that's your newly opened window)
}
Please try with the below code:
Set<String> s1 = driver.getWindowHandles();
for(String childwindow : s1) {
if(!originalHandle.equals(childwindow)) {
driver.switchTo().window(childwindow);
System.out.println("Tab title is " + driver.getTitle();
}
driver.close();
}
driver.switchTo().window(originalHandle);
Hope this helps.
I searched for such functionality as tab switching but found nothing.
Closest to this is switch of windows. (there are lot of comments that WindowHandles can be used for tab switching, but this is not true -- I had tried a lot. Its can be used only for windows switch, but not tabs switch)
if you need to open in new window -- you need to click on link with pressed shift btn
code is something like
Actions.KeyDown(Keys.Shift).Click(ElementToClick).KeyUp(Keys.Shift).Build().Perform();
and if you need to switch the window
var _windowsList = new List<String>(Instance.WindowHandles);
Instance.SwitchTo().Window(_windowsList[0]);
Get all window handler by below code.
Set windowHandleSet = driver.getWindowHandles();
Loop in the window handler set, switchTo each of them.
driver.switchTo().window(windowHandleStr);
Run command Ctrl+number to switch between different tab in same Firefox window.
WebElement bodyEle = driver.findElement(By.tagName("body"));
bodyEle.sendKeys(Keys.CONTROL + "1");
http://www.dev2qa.com/open-multiple-windows-tabs-in-selenium-webdriver/

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 e.g.
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();");
The way we manually switch to next tab is by pressing - CTRL + Page Down The same we can do using Selenium like -
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) {
}
}

Categories