Issue encountered executing Selenium Java code - java

To get started, you need to import following two packages:
org.openqa.selenium.*- contains the WebDriver class needed to instantiate a new browser loaded with a specific driver
org.openqa.selenium.firefox.FirefoxDriver - contains the FirefoxDriver class needed to instantiate a Firefox-specific driver onto the browser instantiated by the WebDriver class
If your test needs more complicated actions such as accessing another class, taking browser screenshots, or manipulating external files, definitely you will need to import more packages.
Not able to understand the code?
package newproject;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
//comment the above line and uncomment below line to use Chrome
//import org.openqa.selenium.chrome.ChromeDriver;
public class PG1 {
public static void main(String[] args) {
// declaration and instantiation of objects/variables
System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
//comment the above 2 lines and uncomment below 2 lines to use Chrome
//System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe");
//WebDriver driver = new ChromeDriver();
String baseUrl = "http://demo.guru99.com/selenium/newtours/";
String expectedTitle = "Welcome: Mercury Tours";
String actualTitle = "";
// launch Fire fox and direct it to the Base URL
driver.get(baseUrl);
// get the actual value of the title
actualTitle = driver.getTitle();
/*
* compare the actual title of the page with the expected one and print
* the result as "Passed" or "Failed"
*/
if (actualTitle.contentEquals(expectedTitle)){
System.out.println("Test Passed!");
} else {
System.out.println("Test Failed");
}
//close Fire fox
driver.close();
}
}

Your code looks fine. You only need to change:
This line of your code:
System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe");
To this line:
System.setProperty("webdriver.gecko.driver","C:\\geckodriver.exe");

Related

Problem in doing action on new window using Selenium Webdriver with java

I am working on Selenium with java, I open a driver change its proxy and do some actions, when I tried to switch to another window and change its proxy the actions don't happened, it showed this error
java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.SearchContext.findElement(org.openqa.selenium.By)" because "this.searchContext" is null
if their is someone who has already worked with switching to windows and change proxy please help
I tried to use the method swith().to but I couldn't change the proxy so I tried to use another driver.
The code, First driver:
Proxy proxy = new Proxy();
proxy.setHttpProxy("http://" + proxyy);
proxy.setSslProxy("http://" + proxyy);
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.setCapability("proxy", proxy);
driver = new ChromeDriver(options);
randomSleep();
driver.get(JDD.url);
driver.manage().window().maximize();
Second driver:
Proxy proxy = new Proxy();
proxy.setHttpProxy("http://" + "104.227.100.66:8147");
proxy.setSslProxy("http://" + "104.227.100.66:8147");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.setCapability("proxy", proxy);
driver2 = new ChromeDriver(options);
randomSleep();
driver2.get(JDD.url);
driver2.manage().window().maximize();
profil("djfbadhz", "s9djq1ri28fz");
driver2.getWindowHandle();
Since you haven't provided reproducible code, I am just going to provide a simple example on how to switch tabs using Selenium 4 (and JUnit 5). If you are using Selenium 3, the way to do it is almost the same. I can provide an appropriate example if you require it.
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class ChromeTest {
#Test
void helloWorldTest () {
System.setProperty("webdriver.chrome.driver",
"F:/drivers/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.google.com");
driver.manage().window().maximize();
String firstTabHandle = driver.getWindowHandle(); // save the first tab handle
// Open a new tab in the same browser session
WebDriver newTab = driver.switchTo().newWindow(WindowType.TAB);
newTab.get("https://www.msn.com/");
String secondTabHandle = driver.getWindowHandle(); // save the new tab handle
assertNotEquals(firstTabHandle, secondTabHandle); // not needed.. test the handles are different if you would like
sleep(driver);
driver.switchTo().window(firstTabHandle); // switch back to first tab
sleep(driver);
driver.switchTo().window(secondTabHandle); // switch back to new tab
sleep(driver);
driver.quit(); // end your browser session
}
private void sleep (WebDriver driver) {
new WebDriverWait(driver, Duration.ofSeconds(3))
.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//body")));
}
}
Can a web driver gain access to a window controlled by another web driver?
To my knowledge, the only way to do this is by using a driver created from the same session. You cannot start two independent sessions and hand off control to the other driver (to the best of my knowledge).
When invoking driver.switchTo().window(String windowHandle), a web driver is returned that has focus on the newly created window. HOWEVER, this is the same instance as the "driver" used to call switchTo().window(). Therefore, whether you used the returned driver or the original driver is immaterial, since they the same. Honestly, I don't know why this method returns an object at all. That said, when I ran this test using the returned driver, the test was more stable. When I used the same original instance, it tended to fail more for NoSuchElement during the second iteration. I know this could be fixed with the appropriate WebDriverWait, but I found this interesting.
To simulate the fact that this driver can interact with either window, I created the test below. The test passes three inputs to iterate over, and uses these strings to search on both Yahoo (original window) and Google (new window); all of which is done with the second (new) driver. This course of action is not necessary. Of course, each driver can interact with whichever window they created. However, in order to interact with a page, it needs to contain focus.
What does this mean related to using proxies? I do not know. All I know is that
A browser session can be interacted with by one and only one driver
Proxies (along with other options) are set before the session starts and cannot be changed after the session has begun.
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.time.Duration;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class ChromeTest {
private static WebDriver driver;
#BeforeAll
static void setup () {
System.setProperty("webdriver.chrome.driver",
"F:/drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
#AfterAll
static void teardown () {
if (driver != null) {
driver.quit();
}
}
#ParameterizedTest
#ValueSource(strings = {"dog", "cat", "birds"})
void simulateCodeTest (String input) {
driver.get("https://www.yahoo.com");
driver.manage().window().maximize();
String originalWindow = driver.getWindowHandle();
WebDriver newWindowDriver = driver.switchTo().newWindow(WindowType.WINDOW);
newWindowDriver.get("https://www.google.com");
String newWindowHandle = newWindowDriver.getWindowHandle();
newWindowDriver.switchTo().window(originalWindow);
assertTrue(originalWindow.equals(newWindowDriver.getWindowHandle()));
newWindowDriver.switchTo().window(newWindowHandle);
WebElement searchField = new WebDriverWait(newWindowDriver,
Duration.ofSeconds(5), Duration.ofMillis(10))
.until(ExpectedConditions
.elementToBeClickable(By.xpath("//input[#title='Search']")));
new Actions(newWindowDriver).sendKeys(searchField, input)
.sendKeys(Keys.ENTER).perform();
newWindowDriver.switchTo().window(originalWindow);
searchField = new WebDriverWait(newWindowDriver, Duration.ofSeconds(5),
Duration.ofMillis(10))
.until(ExpectedConditions
.elementToBeClickable(By.xpath("//input[#name='p']")));
new Actions(newWindowDriver).sendKeys(searchField, input)
.sendKeys(Keys.ENTER).perform();
WebElement searchButton =
newWindowDriver.findElement(By.xpath("//button[#type='submit']"));
searchButton.click();
}
}

Can I make the WebDrivers as global variables in Java

I want to create a class where I set all the common actions of the WebDrivers such as: waitExplicit, findElement, click. But if I create a method then I have to create the WebDriver and WebDriverWait over and over on each method of the class, I already tried having a class for the Drivers, but when I call the methods, they just create instances over and over, so multiple windows open, I tried this way, but still cannot get to it:
public class AutomationActions{
static LoadProperties prop = new LoadProperties(); //This class has the System.setProperty for the driver
prop.getSysProp(); //***This is the issue, how can I solve this?****
WebDriver driver = new ChromeDriver(); //this will not work without the one above working
WebDriverWait wait = new WebDriverWait(driver, 30);//this will not work without the one above working
public void waitForPageToLoad() throws Exception {
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); // I want to avoid having to set this in every method
wait.until(pageLoadCondition); //this is supposed to replace the line of code above
}
I don't really work on Java much any more, I've written our framework in C# but I put together some quick classes in Java to show you how I set things up. I use page object model and I recommend you do too so I've written this example using page object model. I've written a simple test that uses Dave Haeffner's (one of the Selenium contributors) demo site, http://the-internet.herokuapp.com.
The basic concepts are:
There is a class BaseTest that holds things that correspond to tests, e.g. setting up the driver at the start of the test, quitting the driver at the end of the test, etc. All of your tests will inherit from BaseTest
There is a class BasePage that holds things that correspond to generic methods for finding elements, clicking on elements, etc. Each of your tests inherit from BasePage. (This is what I think the main part of your question is asking about).
To follow the page object model, each page (or part of a page) is its own class and holds all locators and actions done on that page. For example, a simple login page would have the locators for username, password, and the login button. It would also hold a method Login() that takes a String username and a String password, enters those in the appropriate fields and clicks the Login button.
The final class of this example is a sample test aptly named SampleTest.
You shouldn't have any FindElements() or related calls in your tests, all those should be in the appropriate page object.
This is using TestNG as the unit test library. Use it or JUnit, your preference but if you use JUnit, you will need to change the asserts and the annotations.
Under 'src', I create a folder for page objects, 'PageObjects', and a folder for tests, 'Tests'. Here's what the files look like on disk.
\src
\PageObjects
BasePage.java
DropdownListPage.java
\Tests
BaseTest.java
SampleTest.java
BasePage.java
package PageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class BasePage
{
private WebDriver driver;
private final int shortWait = 10;
public BasePage(WebDriver _driver)
{
driver = _driver;
}
public void ClickElement(By locator)
{
new WebDriverWait(driver, shortWait).until(ExpectedConditions.elementToBeClickable(locator)).click();
}
public WebElement FindElement(By locator)
{
return new WebDriverWait(driver, shortWait).until(ExpectedConditions.presenceOfElementLocated(locator));
}
// add more methods
}
DropdownListPage.java
package PageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.Select;
public class DropdownListPage extends BasePage
{
private final By dropdownListLocator = By.id("dropdown");
public DropdownListPage(WebDriver _driver)
{
super(_driver);
}
public String GetSelectedOption()
{
return new Select(FindElement(dropdownListLocator)).getFirstSelectedOption().getText();
}
public void SelectOptionByIndex(int index)
{
new Select(FindElement(dropdownListLocator)).selectByIndex(index);
}
}
BaseTest.java
package Tests;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
public class BaseTest
{
public WebDriver driver;
public WebDriver GetChromeDriver()
{
System.setProperty("webdriver.chrome.driver", "C:\\Path\\To\\Chrome\\Driver\\chromedriver.exe");
return new ChromeDriver();
}
#BeforeTest
public void Setup()
{
driver = GetChromeDriver();
driver.manage().window().maximize();
driver.get("http://the-internet.herokuapp.com/dropdown");
}
#AfterTest
public void Teardown()
{
driver.close();
}
}
SampleTest.java
package Tests;
import org.testng.Assert;
import org.testng.annotations.Test;
import PageObjects.DropdownListPage;
public class SampleTest extends BaseTest
{
#Test
public void SampleTestCase()
{
DropdownListPage dropdownListPage = new DropdownListPage(driver);
dropdownListPage.SelectOptionByIndex(1);
Assert.assertEquals(dropdownListPage.GetSelectedOption(), "Option 1", "Verify first option was selected");
}
}
You will need to create a project that contains Selenium for Java and TestNG. Download them and put them on your build path. Create the folder structure as described above and create each of these classes and copy/paste the contents into them. Now all you need to do is run SampleTest as a TestNG Test and it should go.
The test creates a new Chromedriver instance, navigates to the sample page, selects the first option in the dropdown, asserts that the dropdown text is correct, and then quits the driver.
That should get you started. There's a lot of info crammed into the above wall of text, let me know if you have some questions.

Why does Selenium testing website not work on more than one page?

The first part of the code work will work. But the second part doesn't work, and no error appears, and I don't know where the problem is. So please help.
First part is the login page, and the second part is home page.
package Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
//import org.openqa.selenium.chrome.ChromeDriver;
public class test {
public static void main(String[] args) throws InterruptedException {
WebDriver driver;
System.setProperty("webdriver.gecko.driver",
"E:\\Quality\\drivers\\geckodriver.exe");
driver =new FirefoxDriver();
driver.get("https://www.linkedin.com/uas/login");
// first part//
driver.findElement(By.xpath("//*[#id=\"session_key-login\"]")).click();
driver.findElement(By.xpath("//[#id=\"session_keylogin\"]")).sendKeys("Email");
driver.findElement(By.xpath("//*[#id=\"session_password-login\"]")).click();
driver.findElement(By.xpath("//*[#id=\"session_password-login\"]")).sendKeys("*******");
driver.findElement(By.xpath("//*[#id=\"btn-primary\"]")).click();
// second part//
WebElement test = null ;
test.findElement(By.xpath("/html/body/div[5]/div[5]/aside/div/header")).click();
}
}
You have putted a wrong id for xpath of email textbox.
You should use session_key-login instead of session_keylogin.
Just use the below revised code where you're using sendKeys() method:
driver.findElement(By.xpath("//*[#id=\"session_key-login\"]")).sendKeys("Email");
2nd part Solution
Skip WebElement declaration, thus comment the line //WebElement test = null;
Use the line using driver object
driver.findElement(By.xpath("/html/body/div[5]/div[5]/aside/div/header")).click();
You can also use xpath //*[#id=\"msg-overlay\"]/div/header
thus for the revised code is:
driver.findElement(By.xpath("//*[#id=\"msg-overlay\"]/div/header")).click();

Not able to close instances of different browser using driver.quit

I have opened different browser instances and at the end i would like to close all the instances but when i use driver.close() or driver.quit() it is only closing the last instance of the browser. Please help.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
public class showClose {
static WebDriver driver;
public showClose(WebDriver driver){
this.driver=driver;
}
public static void main(String[] args) {
showClose sc = new showClose(driver);
sc.IE("http://www.msn.com");
sc.Firefox("http://seleniumhq.org");
sc.Chrome("http://google.com");
driver.quit();
}
//Internet Explorer driver
public void IE(String URL){
//Set the driver property for IE
System.setProperty("webdriver.ie.driver", System.getProperty("user.dir")+"\\IEDriverServer.exe");
DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();
ieCapabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
//Create object of Internet explorer driver
driver = new InternetExplorerDriver(ieCapabilities);
driver.get(URL);
}
//Firefox driver
public void Firefox(String URL){
driver = new FirefoxDriver();
driver.get(URL);
}
//Chrome driver
public void Chrome(String URL){
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\\chromedriver.exe");
driver = new ChromeDriver();
driver.get(URL);
}
}
In every call of „sc.IE“, „sc.Firefox“ or „sc.Chrome“ you are overwriting the instance variable “driver”.
So the only driver that is closed by your call “driver.quit” is the last one.
If you want to close the browser after visiting the URL you would either have to do a “driver.quit” in before each call to „sc.IE“, „sc.Firefox“ or „sc.Chrome“ or manage a list of WebDrivers and close all of them.
For example you could do something like this:
import java.util.ArrayList;
import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
public class ShowClose {
private List<WebDriver> drivers;
public ShowClose(){
this.drivers = new ArrayList<WebDriver>();
}
public static void main(String[] args) {
ShowClose sc = new ShowClose();
sc.IE("http://www.msn.com");
sc.Firefox("http://seleniumhq.org");
sc.Chrome("http://google.com");
sc.CloseAll();
}
public void CloseAll() {
for(WebDriver d : drivers) {
d.quit();
}
}
//Internet Explorer driver
public void IE(String URL){
//Set the driver property for IE
System.setProperty("webdriver.ie.driver", System.getProperty("user.dir")+"\\IEDriverServer.exe");
DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();
ieCapabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
//Create object of Internet explorer driver
WebDriver driver = new InternetExplorerDriver(ieCapabilities);
driver.get(URL);
this.drivers.add(driver);
}
//Firefox driver
public void Firefox(String URL){
WebDriver driver = new FirefoxDriver();
driver.get(URL);
this.drivers.add(driver);
}
//Chrome driver
public void Chrome(String URL){
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get(URL);
this.drivers.add(driver);
}
}
Step1:
In Main Class declare 'List list' Interface and declare it as 'Static'
public static List<WebDriver> drivers;
Reason for Using List: It represents an ordered list of objects, meaning you can access the elements of a List in a specific order, and by an index too. You can also add the same element more than once to a List.
Step2:
Now Create a Constructor in which we will point to out current driver from the Stored List of Drivers. (I assume my class name as Test)
public Test()
{
this.drivers = new ArrayList<WebDriver>();
}
Step3:
Add a WebDriver Instance to out ArrayList for drivers in all methods of IE, Firefox and Chrome.
this.drivers.add(driver);
Step4: In main class copy all the instances of stored drivers to an object and use that object to close all opened instances.
for(WebDriver d : drivers)
{
d.quit();
}
For one thing: driver.quit() should be used if you want to close all windows. driver.close() is for a single window.
Perhaps it has something to do with the browser windows throwing an alert when they attempt to close?
See this other topic on StackOverflow for a solution to that problem

creating user defined function for selenium webdriver

I want to create some user defined functions for my webdriver automation code. I tried it, but resulted in failure.
the following is my code
public class snapdeal {
WebDriver driver= new FirefoxDriver();
#Test
public void test() {
// I want open browser in function 1
driver.get("http://amazon.in");
driver.manage().window().maximize();
// Function 2 for searching
driver.findElement(By.xpath("//li[#id='nav_cat_2'")).click();
driver.findElement(By.id("twotabsearchtextbox")).sendKeys("Shoes");
driver.findElement(By.xpath("//input[#class='nav-submit-input']")).click();
driver.findElement(By.xpath("//h2[#class='a-size-medium s-inline s-access-title a-text-normal' and contains(text(), \"Fbt Men's 8876 Casual Shoes\")]")).click();
}
}
How ca i write two functions inside the class?
You were probably trying to nest methods inside test() . It is not possible.
You can use this code below which calls the respective methods in the test(). It works as expected:
public class snapdeal {
static WebDriver driver= new FirefoxDriver();
#Test
public void test() {
//Method1 for Opening Browser.
openBrowser();
// Method2 for searching
searchElement();
}
public static void openBrowser(){
driver.get("http://amazon.in");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
}
public static void searchElement(){
driver.findElement(By.xpath("//li[#id='nav_cat_2']")).click();
driver.findElement(By.id("twotabsearchtextbox")).sendKeys("Shoes");
driver.findElement(By.xpath("//input[#class='nav-submit-input']")).click();
driver.findElement(By.xpath("//h2[#class='a-size-medium s-inline s-access-title a-text-normal' and contains(text(), \"Fbt Men's 8876 Casual Shoes\")]")).click();
}
}
I think this is like a Hello World for Selenium for you, you could make use defined methods in Java using Junit with the following annotations which can be found here
But as per norms we usually have a #Before method in Junit or #BeforeTest method in testng for setting up the webdriver and the url of AUT, also in your code a couple of xpaths were wrong which were causing the error, Please find below the correct working code with comments:
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.safari.SafariDriver;
public class snapdeal {
public WebDriver driver;
#Before
public void setUP()
{
// I want open browser in function 1
driver= new SafariDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.get("http://amazon.in");
driver.manage().window().maximize();
}
#Test
public void test() {
// Function 2 for searching
//driver.findElement(By.xpath("//li[#id='nav_cat_2")).click(); //element not needed
driver.findElement(By.id("twotabsearchtextbox")).sendKeys("Shoes");
driver.findElement(By.xpath("//input[#class='nav-submit-input']")).click();
driver.findElement(By.xpath("//*[#title=\"Fbt Men's 8876 Casual Shoes\"]//h2")).click();
}
}
The above code works as desired.
Creating user defined function have two different scope
1) Create function with piece of code and call that function whenever u needed it (Which is done above)
2) Second one creating a custom function wrt each controls like edit boxes , radiobutton , check boxes - etc , so by creating this functions u can make better feasible of your automation framework

Categories