Selenium Webdriver: Element Not Visible Exception - java

Here is my code to click a simple login button on this Website
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Reports {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("https://platform.drawbrid.ge");
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
driver.findElement(By.xpath(".//*[#id='_loginButton']")).click();
}
}
I am getting following error:
Exception in thread "main" org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with
Command duration or timeout: 2.05 seconds

You have two buttons with given xpath on this page, first is not visible, thats why you are getting ElementNotVisibleException
One is under <div class="loginPopup">
Second (the one you need) is under <div class="page">
So change your xpath to look like this, and it will fix your problem:
By.xpath("//div[#class='page']//div[#id='_loginButton']")

There are even 3 elements with id="_loginButton" on the page, and only one is visible - the one located inside the login form, you can get it by a CSS selector:
By.cssSelector("form#_loginForm div#_loginButton")

There are 3 occurrences of id="_loginButton".
Used the id="_loginButton" under class="signIn" by cssSelector to get the exact button in the page.
By.cssSelector("div.signIn div#_loginButton")

Webdriver may throw an ElementNotVisible exception in-case there are multiple elements with the same locator and if Webdriver has already operated upon one of the element matching the locator.
In such scenarios you can first get the size of the element using
int var_ele_size= driver.findElements(By.xpath("locator")).size();
and then take the first element from the list and click on the element.
driver.findElements(By.xpath("locator")).get(var_ele_size-1).click();

public static void Listget (WebDriver driver) throws Exception
{
Thread.sleep(5000);
UtilityMethod.getAppLocaters(driver, "closeicon").click();
Actions action = new Actions(driver);
WebElement we = driver.findElement(By.xpath("//li[#class='parent dropdown aligned-left']"));
Thread.sleep(5000);
action.moveToElement(we).build().perform();
List<WebElement>links = driver.findElements(By.xpath("//span[#class='menu-title']"));
int total_count = links.size();
System.out.println("Total size :=" +total_count);
for(int i=0;i<total_count;i++)
{
WebElement element = links.get(i);
String text = element.getAttribute("innerHTML");
System.out.println("linksnameis:=" +text);
try{
File src = new File("D:ReadFile.xlsx");
FileInputStream fis = new FileInputStream(src);
XSSFWorkbook wb=new XSSFWorkbook(fis);
XSSFSheet sh = wb.getSheetAt(0);
sh.createRow(i).createCell(1).setCellValue(text);
FileOutputStream fos = new FileOutputStream(new File("D:/ReadFile.xlsx"));
wb.write(fos);
fos.close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
}

Make sure your window on the remote server is big enough so the elements are not hidden because of space constraints ..
This worked for me: (I use c#)
driver.Manage().Window.Size = new System.Drawing.Size(1928, 1060);

You could try:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("your locator value")));
Or
wait.until(ExpectedConditions.ElementIsVisible(By.xpath("your locator value")));

Related

Capture upload file size in Selenium WebDriver

Is it possible if I want to capture the file size after I uploaded the files using Selenium WebDriver? Btw I'm using Java. Currently I'm following this one tutorial & here's the code:
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
public class upload {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver","webdriver location");
String baseUrl = "http://demo.guru99.com/test/upload/";
WebDriver driver = new ChromeDriver();
driver.get(baseUrl);
WebElement uploadElement = driver.findElement(By.id("uploadfile_0"));
// enter the file path onto the file-selection input field
uploadElement.sendKeys("file location");
// check the "I accept the terms of service" check box
driver.findElement(By.id("terms")).click();
// click the "UploadFile" button
driver.findElement(By.name("send")).click();
}
}
I want to print the file size output in console. May I know is this action is possible or not? Thanks.
Do you mean something like this? It prints the size of the file uploaded prior to uploading.
import java.io.File;
String fileName = "C:/users/something.txt";
File f = new File(fileName);
long fileSize = f.length();
System.out.format("The size of the file: %d bytes", fileSize);

Selenium Java while reading from Excel getting-No such window exception

I am trying to understand and practice reading from and Excel file and send login credential to a webpage. In the test excel file I have 2 usernames and 2 password. The 1st set works properly(meaning being sent to webpage fields), however during the 2nd set I get the following problem :
Exception in thread "main" org.openqa.selenium.NoSuchWindowException: Window not found. The browser window may have been closed.
Command duration or timeout: 221 milliseconds
Here is the code:
public class EX1 {
public static WebDriver driver;
public int cellNo;
public WebDriver utility(String browser, String url){
if(browser.equals("ff")){
driver= new FirefoxDriver();
}
driver.get(url);
return driver;
}
public ArrayList<String> readExcel(int cellNo) throws IOException{
FileInputStream fis = new FileInputStream("C:\\dev\\Petco.xls");
HSSFWorkbook workbook = new HSSFWorkbook(fis);
HSSFSheet sheet = workbook.getSheetAt(0);
Iterator<Row> rowIterator= sheet.iterator();
rowIterator.next();// Escapes the Header
ArrayList<String> list= new ArrayList<String>(); //After reading the data I will add them to String list
while(rowIterator.hasNext()){
//list.add(rowIterator.next().getCell(0).getStringCellValue());//will just print 1st username
//list.add(rowIterator.next().getCell(1).getStringCellValue()); // will just print 1st password
//The above code with hardcoded 0,1- I can't call them in below getPage function. I will
//make a parameter for this method which I will pass, cellNo is a parameter instead of 0,1
list.add(rowIterator.next().getCell(cellNo).getStringCellValue());//will just print 1st username
}
return list;
}
public void loginPage(String uname,String psd){
WebElement username=driver.findElement(By.xpath("//input[#id='WC_AccountDisplay_FormInput_logonId_In_Logon_1']"));
WebElement password=driver.findElement(By.xpath("//input[#id='WC_AccountDisplay_FormInput_logonPassword_In_Logon_1']"));
WebElement login_btn=driver.findElement(By.xpath("//button[contains(#id,'WC_AccountDisplay_links_2')]"));
username.sendKeys(uname);
password.sendKeys(psd);
login_btn.click();
}
public void getPage() throws InterruptedException, IOException{
EX1 e= new EX1();
e.utility("ff", "https://www.petco.com/shop/AjaxLogonForm?catalogId=10051&myAccountActivePage=myAccount&myAcctMain=1&langId=-1&storeId=10151");
EX1 e1=PageFactory.initElements(driver, EX1.class);
//Will use the list from above that contains the login information here
ArrayList<String> username=e.readExcel(0); //-- reading the 1st column which has user name
ArrayList<String> password=e.readExcel(1); //-- reading the 1st column which has user name
for(int i=0; i<username.size(); i++){ //-- I want to read excel multiple times which is why the for loop
e1.loginPage(username.get(i), password.get(i));
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.close();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
EX1 e= new EX1();
e.getPage();
//e.readExcel();
}
}
I have tried Thread.sleep, driver.quit() those modifications did not have any impact.
Let me know what else I can try, thanks n advance for your time.
Error seems browser window closed after first iteration...Observe your test case while running...see it's closing browser window after first iteration i.e. driver.close();..removing this line and putting somewhere after for loop completion, may help you. e.g.
for(int i=0; i<username.size(); i++){ //-- I want to read excel multiple times which is why the for loop
e1.loginPage(username.get(i), password.get(i));
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
driver.close();

How can I close my close my browser or switch to pop up when automating Google sign in?

I am trying to refresh my Selenium knowledge. So, I am writing a script to navigate through my Google account. After I successfully sign in to Google, a pop up appears under my profile icon on the upper right side in Firefox. I no longer get these pop ups when I sign manually. This is probably because of cookies or some other browser setting. I do not care about the reason why this occurs.
However, since it occurs, I believe it may be preventing my script from closing the browser with driver.close(); I also tried driver.quit(); Neither of these are causing the browser to close.
So, I thought I would try switching windows by doing an iteration through the windows. This is not allowing me to select the pop up that appears to close it.
I also tried to create an Alert alert and switch to it:
driver.switchto.alert();
driver.dismiss();
This is not dismissing this pop up in Google either.
In the end, I do not care about this pop up. I know I listed 2 separate issues here. But, in the end, I just want to close the browser. If I can also learn how to switch to this pop up and click the x to close it, that is a bonus.
//Code added here -------------------------
public void sign_out( WebDriver driver )
{
//At this point,I am already signed in. But, that Google pop up appears
//The pop up says "Get to Google faster. Switch your default search engine to Google."
//Wait for "x" to appear
myDynamicElement = (new WebDriverWait(driver, wait_for_element_time)).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(x_path_x_pop_up)));
//This is set above as a class member
//final String x_path_x_pop_up = "/html/body/div/div[3]/div[1]/div/div/div/div[2]/div[4]/div/a";
WebElement x_icon = driver.findElement(By.xpath(x_path_x_pop_up));
//Click x to close it
x_icon.click();
String myWindowHandle = driver.getWindowHandle();
String subWindowHandle = null;
Set<String> handles = driver.getWindowHandles(); // get all window handles
Iterator<String> iterator = handles.iterator();
while (iterator.hasNext()){
subWindowHandle = iterator.next();
}
driver.switchTo().window(subWindowHandle); // switch to popup window
// driver.switchTo().window(myWindowHandle);
// This never happens now on this click of the profile icon in Google to sign out.
//Click on profile icon
m_profile_icon.click();
//Wait for "Sign Out" button to appear
myDynamicElement = (new WebDriverWait(driver, wait_for_element_time)).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(x_path_sign_out_button)));
//Get sign out button
WebElement sign_out_button = driver.findElement(By.xpath(x_path_sign_out_button) );
sign_out_button.click();
}
}
Well as long as you are working in Java you can try the Robot framework and sendKeys as a workaround (ALT+F4):
import java.lang.reflect.*;
import java.awt.Robot;
import java.awt.event.KeyEvent;
public class RobotUtilities {
public static void sendKeyCombo(String keys[]) {
try {
Robot robot = new Robot();
Class<?> cl = KeyEvent.class;
int [] intKeys = new int [keys.length];
for (int i = 0; i < keys.length; i++) {
Field field = cl.getDeclaredField(keys[i]);
intKeys[i] = field.getInt(field);
robot.keyPress(intKeys[i]);
}
for (int i = keys.length - 1; i >= 0; i--)
robot.keyRelease(intKeys[i]);
}
catch (Throwable e) {
System.err.println(e);
}
}
// main for testing purposes
public static void main(String args[]) {
String [] keys = {"VK_ALT", "VK_F4"};
sendKeyCombo(keys);
}
}
Alternative more robust solution using windowHandles:
I took this from here
You can switch between windows as below:
// Store the current window handle
String winHandleBefore = driver.getWindowHandle();
// Perform the click operation that opens new window
// Switch to new window opened
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
// Perform the actions on new window
// Close the new window, if that window no more required
driver.close();
// Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);
// Continue with original browser (first window)
So, my problem had to do with errors in the JUnit part of my code. I commented out these sections. Once everything was error free, the driver.quit() closed the browser.
I also did some research and found that JUnit does not allow passing class values between different #Test tests. So, I also moved all of my open browser and close browser into the same #Test. This cleaned everything up as well.

capture a downloaded pdf file name with selenium webdriver

Need to capture the the file name of a PDFs which we get by clicking a download link in a URL. I've tried with this code.but, I cannot get the title or url from the second window
kindly help me out with this or suggest me any other methods to handle this...
**code I tried**
#Test
public void pdfname() throws Exception {
driver.get(baseUrl + "/english/investments/iv_funds.htm");
Set<String> winids = driver.getWindowHandles();
Iterator<String> iterate = winids.iterator();
Thread.sleep(3000);
driver.findElement(By.linkText("FUND MATERIALS")).click();
Thread.sleep(3000);
driver.findElement(By.className("sbToggle")).click();
Thread.sleep(3000);
driver.findElement(By.linkText("Fund Details and Performance Update")).click();
driver.findElement(By.id("fundPerformance")).click();
driver.findElement(By.id("fundPerformance")).clear();
driver.findElement(By.id("fundPerformance")).sendKeys("AEGAU");
Thread.sleep(3000);
driver.findElement(By.xpath("//*[#id='perform']")).click();
Thread.sleep(18000);
winids = driver.getWindowHandles();
iterate = winids.iterator();
String firstwindow=iterate.next();
String secondwindow = iterate.next();
System.out.println(firstwindow);
System.out.println(secondwindow);
driver.switchTo().window(secondwindow); //switch to pdf window
Thread.sleep(3000);
System.out.println("url is"+driver.getCurrentUrl());
driver.close();
}
I think you are trying to get the name from a OS system window. Selenium does not interact with the OS. For windows you can use autoit (http://www.autoitscript.com/site/autoit/) to interact with the OS.

How to open a new tab using Selenium WebDriver in Java?

How can I open a new tab in the existing Firefox browser using Selenium WebDriver (a.k.a. Selenium 2) in Java?
Just for anyone else who's looking for an answer in Ruby, Python, and C# bindings (Selenium 2.33.0).
Note that the actual keys to send depend on your OS. For example, Mac uses CMD + T, instead of Ctrl + T.
Ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
driver.get('http://stackoverflow.com/')
body = driver.find_element(:tag_name => 'body')
body.send_keys(:control, 't')
driver.quit
Python
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://stackoverflow.com/")
body = driver.find_element_by_tag_name("body")
body.send_keys(Keys.CONTROL + 't')
driver.close()
C#
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
namespace StackOverflowTests {
class OpenNewTab {
static void Main(string[] args) {
IWebDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://stackoverflow.com/");
IWebElement body = driver.FindElement(By.TagName("body"));
body.SendKeys(Keys.Control + 't');
driver.Quit();
}
}
}
The code below will open the link in a new tab.
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,Keys.RETURN);
driver.findElement(By.linkText("urlLink")).sendKeys(selectLinkOpeninNewTab);
The code below will open an empty new tab.
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,"t");
driver.findElement(By.linkText("urlLink")).sendKeys(selectLinkOpeninNewTab);
Why not do this
driver.ExecuteScript("window.open('your url','_blank');");
To open new tab using JavascriptExecutor,
((JavascriptExecutor) driver).executeScript("window.open()");
ArrayList<String> tabs = new ArrayList<String>(driver.getWindowHandles());
driver.switchTo().window(tabs.get(1));
Will control on tab as according to index:
driver.switchTo().window(tabs.get(1));
Driver control on main tab:
driver.switchTo().window(tabs.get(0));
As of selenium >= 4.0, there is no need for javascript or send_keys workarounds. Selenium 4 provides a new API called newWindow that lets you create a new window (or tab) and automatically switches to it. Since the new window or tab is created in the same session, it avoids creating a new WebDriver object.
Python
Open new tab
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.window import WindowTypes
driver.switch_to.new_window(WindowTypes.TAB)
Open new window
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.window import WindowTypes
driver.switch_to.new_window(WindowTypes.WINDOW)
Java
Open new window
driver.get("https://www.google.com/");
// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW);
// Opens LambdaTest homepage in the newly opened window
driver.navigate().to("https://www.lambdatest.com/");
Open new tab
driver.get("https://www.google.com/");
// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.TAB);
// Opens LambdaTest homepage in the newly opened tab
driver.navigate().to("https://www.lambdatest.com/")
You can use the following code using Java with Selenium WebDriver:
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
By using JavaScript:
WebDriver driver = new FirefoxDriver(); // Firefox or any other Driver
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.open()");
After opening a new tab it needs to switch to that tab:
ArrayList<String> tabs = new ArrayList<String>(driver.getWindowHandles());
driver.switchTo().window(tabs.get(1));
To open a new window in Chrome Driver.
// The script that will will open a new blank window
// If you want to open a link new tab, replace 'about:blank' with a link
String a = "window.open('about:blank','_blank');";
((JavascriptExecutor)driver).executeScript(a);
For switching between tabs, read here.
Almost all answers here are out of date.
(Ruby examples)
WebDriver now has support for opening tabs:
browser = Selenium::WebDriver.for :chrome
new_tab = browser.manage.new_window
Will open a new tab. Opening a window has actually become the non-standard case:
browser.manage.new_window(:window)
The tab or window will not automatically be focussed. To switch to it:
browser.switch_to.window new_tab
Try this for the Firefox browser.
/* Open new tab in browser */
public void openNewTab()
{
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
ArrayList<String> tabs = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(tabs.get(0));
}
To open a new tab in the existing Chrome browser using Selenium WebDriver you can use this code:
driver.FindElement(By.CssSelector("body")).SendKeys(Keys.Control + "t");
string newTabInstance = driver.WindowHandles[driver.WindowHandles.Count-1].ToString();
driver.SwitchTo().Window(newTabInstance);
driver.Navigate().GoToUrl(url);
The below code will open the link in a new window:
String selectAll = Keys.chord(Keys.SHIFT, Keys.RETURN);
driver.findElement(By.linkText("linkname")).sendKeys(selectAll);
I had trouble opening a new tab in Google Chrome for a while.
Even driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t"); didn't work for me.
I found out that it's not enough that Selenium has focus on driver. Windows also has to have the window in the front.
My solution was to invoke an alert in Chrome that would bring the window to front and then execute the command. Sample code:
((JavascriptExecutor)driver).executeScript("alert('Test')");
driver.switchTo().alert().accept();
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
ArrayList<String> tabs = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(tabs.get(0));
// To open a new tab in an existing window
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
How can we open a new, but more importantly, how do we do stuff in that new tab?
Webdriver doesn't add a new WindowHandle for each tab, and only has control of the first tab. So, after selecting a new tab (Control + Tab Number) set .DefaultContent() on the driver to define the visible tab as the one you're going to do work on.
Visual Basic
Dim driver = New WebDriver("Firefox", BaseUrl)
' Open new tab - send Control T
Dim body As IWebElement = driver.FindElement(By.TagName("body"))
body.SendKeys(Keys.Control + "t")
' Go to a URL in that tab
driver.GoToUrl("YourURL")
' Assuming you have m tabs open, go to tab n by sending Control + n
body.SendKeys(Keys.Control + n.ToString())
' Now set the visible tab as the drivers default content.
driver.SwitchTo().DefaultContent()
I am using Selenium 2.52.0 in Java and Firefox 44.0.2. Unfortunately none of the previous solutions worked for me.
The problem is if I a call driver.getWindowHandles() I always get one single handle. Somehow this makes sense to me as Firefox is a single process and each tab is not a separate process. But maybe I am wrong. Anyhow, I try to write my own solution:
// Open a new tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// URL to open in a new tab
String urlToOpen = "https://url_to_open_in_a_new_tab";
Iterator<String> windowIterator = driver.getWindowHandles()
.iterator();
// I always get handlesSize == 1, regardless how many tabs I have
int handlesSize = driver.getWindowHandles().size();
// I had to grab the original handle
String originalHandle = driver.getWindowHandle();
driver.navigate().to(urlToOpen);
Actions action = new Actions(driver);
// Close the newly opened tab
action.keyDown(Keys.CONTROL).sendKeys("w").perform();
// Switch back to original
action.keyDown(Keys.CONTROL).sendKeys("1").perform();
// And switch back to the original handle. I am not sure why, but
// it just did not work without this, like it has lost the focus
driver.switchTo().window(originalHandle);
I used the Ctrl + T combination to open a new tab, Ctrl + W to close it, and to switch back to original tab I used Ctrl + 1 (the first tab).
I am aware that mine solution is not perfect or even good and I would also like to switch with driver's switchTo call, but as I wrote it was not possible as I had only one handle. Maybe this will be helpful to someone with the same situation.
How to open a new tab using Selenium WebDriver with Java for Chrome:
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-extensions");
driver = new ChromeDriver(options);
driver.manage().window().maximize();
driver.navigate().to("https://google.com");
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_T);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_T);
The above code will disable first extensions and using the robot class, a new tab will open.
This line of code will open a new browser tab using Selenium WebDriver:
((JavascriptExecutor)getDriver()).executeScript("window.open()");
Java
I recommend using JavascriptExecutor:
Open new blank window:
((JavascriptExecutor) driver).executeScript("window.open()");
Open new window with specific URL:
((JavascriptExecutor) driver).executeScript("window.open('https://google.com')");
Following import:
import org.openqa.selenium.JavascriptExecutor;
Check this complete example to understand how to open multiple tabs and switch between the tabs and at the end close all tabs.
public class Tabs {
WebDriver driver;
Robot rb;
#BeforeTest
public void setup() throws Exception {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Anuja.AnujaPC\\Downloads\\chromedriver_win32\\chromedriver.exe");
WebDriver driver=new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get("http://qaautomated.com");
}
#Test
public void openTab() {
// Open tab 2 using CTRL + T keys.
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
// Open URL In 2nd tab.
driver.get("http://www.qaautomated.com/p/contact.html");
// Call switchToTab() method to switch to the first tab
switchToTab();
// Call switchToTab() method to switch to the second tab.
switchToTab();
}
public void switchToTab() {
// Switching between tabs using CTRL + tab keys.
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");
// Switch to current selected tab's content.
driver.switchTo().defaultContent();
}
#AfterTest
public void closeTabs() throws AWTException {
// Used Robot class to perform ALT + SPACE + 'c' keypress event.
rb = new Robot();
rb.keyPress(KeyEvent.VK_ALT);
rb.keyPress(KeyEvent.VK_SPACE);
rb.keyPress(KeyEvent.VK_C);
}
}
This example is given by this web page.
There are 3 ways to do this. In below example I am doing following steps to open the facebook in new tab,
Launching https://google.com
Searching for facebook text and getting the facebook URL
Opening facebook in different tab.
Solution#1: Using window handles.
driver = new ChromeDriver(options);
driver.get("https://www.google.com/search?q=facebook");
String facebookUrl = driver.findElement(By.xpath("(//a[contains(#href,'facebook.com')])[1]")).getAttribute("href");
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.open()");
ArrayList<String> tabs = new ArrayList<String>(driver.getWindowHandles());
driver.switchTo().window(tabs.get(1));
driver.get(facebookUrl);
Solution#2: By creating new driver instance. It's not recommended but it is also a possible way to do this.
driver = new ChromeDriver(options);
driver.get("https://www.google.com/search?q=facebook");
String facebookUrl = driver.findElement(By.xpath("(//a[contains(#href,'facebook.com')])[1]")).getAttribute("href");
/*Create an another instance of driver.*/
driver = new ChromeDriver(options);
driver.get(facebookUrl);
Solution#3: Using Selenium 4
driver.get("https://www.google.com/search?q=facebook");
String facebookUrl = driver.findElement(By.xpath("(//a[contains(#href,'facebook.com')])[1]")).getAttribute("href");
driver.switchTo().newWindow(WindowType.TAB);
driver.navigate().to(facebookUrl);
If you need to open a specific link in a new tab, you can send the shortcut directly to the link like so:
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL, Keys.RETURN);
driver.findElement(By.xpath("//a[strong[.='English']]")).sendKeys(selectLinkOpeninNewTab);
Here is an runnable example
If you need to open a new tab and want to choose which link is opened immediately in said tab, you can use JavaScriptExecutor like so:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.open('https://www.wikipedia.org/', '_blank');");
Here is a runnable case that uses JSE
In new versions of selenium for java, they added a method to create a new tab:
driver.switchTo().newWindow(WindowType.TAB);
or a new window:
driver.switchTo().newWindow(WindowType.WINDOW);
here is the link to an example on the official repo
To open a new tab in the existing Firefox browser using Selenium WebDriver
FirefoxDriver driver = new FirefoxDriver();
driver.findElement(By.tagName("body")).sendKeys(Keys.CONTROL,"t");
Actions at=new Actions(wd);
at.moveToElement(we);
at.contextClick(we).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ENTER).build().perform();
The same example for Node.js:
var webdriver = require('selenium-webdriver');
...
driver = new webdriver.Builder().
withCapabilities(capabilities).
build();
...
driver.findElement(webdriver.By.tagName("body")).sendKeys(webdriver.Key.COMMAND + "t");
This code is working for me (Selenium 3.8.1, chromedriver 2.34.522940, and Chrome 63.0):
public void openNewTabInChrome() {
driver.get("http://www.google.com");
WebElement element = driver.findElement(By.linkText("Gmail"));
Actions actionOpenLinkInNewTab = new Actions(driver);
actionOpenLinkInNewTab.moveToElement(element)
.keyDown(Keys.CONTROL) // MacOS: Keys.COMMAND
.keyDown(Keys.SHIFT).click(element)
.keyUp(Keys.CONTROL).keyUp(Keys.SHIFT).perform();
ArrayList<String> tabs = new ArrayList(driver.getWindowHandles());
driver.switchTo().window(tabs.get(1));
driver.get("http://www.yahoo.com");
//driver.close();
}
Question: How can I open a new tab using Selenium WebDriver with Java?
Answer: After a click on any link, open a new tab.
If we want to handle a newly open tab then we have need to handle tab using the .switchTo().window()
command.
Switch to a particular tab, and then perform an operation and switch back to into the parent tab.
package test;
import java.util.ArrayList;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Tab_Handle {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver", "geckodriver_path");
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com");
// Store all currently open tabs in Available_tabs
ArrayList<String> Available_tabs = new ArrayList<String>(driver.getWindowHandles());
// Click on link to open in new tab
driver.findElement(By.id("Url_Link")).click();
// Switch newly open Tab
driver.switchTo().window(Available_tabs.get(1));
// Perform some operation on Newly open tab
// Close newly open tab after performing some operations.
driver.close();
// Switch to old(Parent) tab.
driver.switchTo().window(Available_tabs.get(0));
}
}
Selenium doesn't support opening new tabs. It only supports opening new windows. For all intents and purposes a new window is functionally equivalent to a new tab anyway.
There are various hacks to work around the issue, but they are going to cause you other problems in the long run.
If you want to open the new tab you can use this
((JavascriptExecutor) getDriver()).executeScript("window.open()");
If you want to open the link from the new tab you can use this
With JavascriptExecutor:
public void openFromNewTab(WebElement element){
((JavascriptExecutor)getDriver()).executeScript("window.open('"+element.getAttribute("href")+"','_blank');");
}
With Actions:
WebElement element = driver.findElement(By.xpath("your_xpath"));
Actions actions = new Actions(driver);
actions.keyDown(Keys.LEFT_CONTROL)
.click(element)
.keyUp(Keys.LEFT_CONTROL)
.build()
.perform();

Categories