Selenium Webdriver Function Continuity - java

So i have the following java code with a selenium webdrive code. The code works as intended untill the AddItems function. It does not work, I can't make it continue the work from the Login function. I've tried calling both function in the main, i've tried calling one AddItems into Login. I don't understand how i should link the two process so one continuies the other. I've tried what i've seen here: https://www.youtube.com/watch?v=ph3NJm4Z7m4&t=4472s , at 1:02:44 ish .
Please help me understand how can the function use the same "test" and continue the function.
package TestEmagShoppingCart;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class ShoppingCart {
WebDriver test;
public void Login() throws InterruptedException
{
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
WebDriver test = new ChromeDriver();
test.get("http://www.emag.ro");
test.manage().window().maximize();
//test.manage().deleteAllCookies();
//test.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
//test.manage().timeouts().pageLoadTimeout(40, TimeUnit.SECONDS);
String title = test.getTitle();
System.out.println("Titlul paginii este: "+ title);
test.findElement(By.xpath("/html/body/div[3]/nav[1]/div/div/div[3]/div/div[2]/a/span")).click();
test.findElement(By.id("email")).sendKeys("anghelalex1994#gmail.com");
Thread.sleep(1000);
test.findElement(By.xpath("/html/body/form/div[4]/div/button")).click();
Thread.sleep(1000);
test.findElement(By.id("password")).sendKeys("alex21");
test.findElement(By.xpath("/html/body/form/div[4]/div/button")).click();
//test.findElement(By.xpath("/html[1]/body[1]/div[3]/div[1]/div[1]/div[1]/ul[1]/li[5]/a[1]")).click();
//AddItems();
}
public void AddItems()
{
test.findElement(By.xpath("/html[1]/body[1]/div[3]/div[1]/div[1]/div[1]/ul[1]/li[5]/a[1]")).click();
}
public static void main(String[] args) throws InterruptedException {
ShoppingCart cart = new ShoppingCart();
cart.Login();
cart.AddItems();
}
}

Please use PageObject and add all action listener from there:
public class EmagPageObject {
private WebDriver driver;
public EmagPageObject(WebDriver driver) {
this.driver = driver;
}
public EmagPageObject loginToApp(String user, String password) {
// Your code
return this;
}
public EmagPageObject AddItems() {
// Your code
return this;
}
}
And do not user thread.sleep use only Implicit Wait or Explicit Waits

I've fixed it myself.
I've deleted " WebDriver test = new ChromeDriver();" from the Login function and put it as a global variabile exactly as written above.

Related

tearDown is not being initialised

I have a Java Automation script. I have a set up method that works but my tearDown isn't being read for some reason.
When I run my Automation test I seem to have two problems
If it fails the test run multiple times and the browser window stays open.
even if a test passed the browser window never closes, which makes things really messy.
I haven't added any feature files of code for the actual test as I think the issue is in the set up but more than happy to.
I suspect both issues are linked but I can't fathom where or how.
Here is my SeleniumSetUp Class
public class SeleniumSetup {
protected WebDriver driver;
public SeleniumSetup(WebDriver driver)
{
}
public SeleniumSetup() {
}
public void prepareBrowserForSelenium() {
// setup();
if(DriverSingleton.getDriver() == null)
{
setup();
}
else
{
driver = DriverSingleton.getDriver();
}
}
public void setup() {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Selenium and drivers\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://the-internet.herokuapp.com/");
driver.manage().window().maximize();
System.out.println("Set up running");
}
public void tearDown() {
driver.quit();
System.out.println("Tear down running");
}
}
I have added a Println and can see that this is never returned when I run my script.
Here's my Base Page;
package pages;
import org.openqa.selenium.WebDriver;
public class BasePage {
protected WebDriver driver;
public BasePage(WebDriver driver) {
this.driver = driver;
}
}
And my Driver
package support;
import org.openqa.selenium.WebDriver;
public class DriverSingleton {
private static WebDriver driver;
public DriverSingleton () {
}
public static WebDriver getDriver() {
return driver;
}
public static void setDriver (WebDriver driver) {
DriverSingleton.driver = driver;
}
}
Any help would be most appreciated.
It seems your DriverSingleton's driver never been initialized, and in setup() method of SeleniumSetup class, driver of SeleniumSetup is initialized and used every time you run the code , put the tearDown() at the end of setup() and your browser window will close.
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Selenium and drivers\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://the-internet.herokuapp.com/");
driver.manage().window().maximize();
System.out.println("Set up running");
// <<------your test scenario should be placed here
tearDown();
Try extending your driver class with junit(j5 jupiter) interfaces and override the before/after methods, here is a simple example, using some of your code:
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
public class Driver implements AfterTestExecutionCallback, BeforeTestExecutionCallback, BeforeAllCallback, AfterAllCallback {
protected WebDriver driver;
#Override
public void beforeAll(ExtensionContext context) throws Exception {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Selenium and drivers\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://the-internet.herokuapp.com/");
driver.manage().window().maximize();
System.out.println("Set up running");
}
#Override
public void afterAll(ExtensionContext context) throws Exception {
driver().quit();
}
#Override
public void beforeTestExecution(ExtensionContext context) throws Exception {
//whatever steps you need before EACH test, like navigate to homepage etc...
}
#Override
public void afterTestExecution(ExtensionContext context) throws Exception {
// steps do to after each test, best practice is to clear everything:
driver.manage().deleteAllCookies();
driver.executeScript("window.sessionStorage.clear()");
driver.executeScript("window.localStorage.clear()");
}
}

i got an error - java.lang.NullPointerException while running the selenium web driver code block

" Here is the code of selenium web driver in which i use POM design to define all the locators of the web page. So after running the code i got an error regarding the null pointer exception.
"
{
package Pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class LoginPage {
WebDriver driver;
By username = By.id("user_login");
By password = By.id("user_pass");
By login = By.id("wp-submit");
By rememberme = By.id("rememberme");
public LoginPage(WebDriver driver){
this.driver = driver;
}
public void typeusername(){
driver.findElement(username).sendKeys("admin");
}
public void typepassword(){
driver.findElement(password).sendKeys("demo123");
}
public void clickrememberme(){
driver.findElement(rememberme).click();
}
public void clicklogin(){
driver.findElement(login).click();
}
}
"Here in this code i created an object of a login page and call all the locators using TestNG annotations."
{
package Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import Pages.LoginPage;
public class verifylogin {
#BeforeTest
public void beforetest(){
System.setProperty("webdriver.chrome.driver","C:\\Users\\saniket.soni\\Desktop\\chrome\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://demosite.center/wordpress/wp-login.php");
}
#Test
public void verifyvalidlogin(){
WebDriver driver = null;
LoginPage login_test = new LoginPage(driver);
login_test.typeusername();
login_test.typepassword();
login_test.clickrememberme();
login_test.clicklogin();
}
}
You might want to consider studying scope in java to understand what is happening in this issue. Here is an explanation for what is happening in your case.
In your public void beforetest() method, you're creating a driver, and using it, but when that method is done the driver variable goes out of scope, and you no longer have access to it.
Later, in your verifyValidLogin method, you're creating a new driver variable, and setting it to null:
WebDriver driver = null;
Then you pass this null driver to your LoginPage here:
LoginPage login_test = new LoginPage(driver);//driver is null here
So when you use it here:
public LoginPage(WebDriver driver){
this.driver = driver;
}
public void typeusername(){
driver.findElement(username).sendKeys("admin");
}
It's null
Try making these changes:
First, save your driver somewhere when you initialize it like this:
public class verifylogin {
//STORE YOUR DRIVER SOMEWHERE!!! Like here
private WebDriver driver;
#BeforeTest
public void beforetest(){
System.setProperty("webdriver.chrome.driver","C:\\Users\\saniket.soni\\Desktop\\chrome\\chromedriver.exe");
//Store the driver in the class variable
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://demosite.center/wordpress/wp-login.php");
}
#Test
public void verifyvalidlogin(){
//Now you can use the driver you stored
LoginPage login_test = new LoginPage(driver);
login_test.typeusername();
login_test.typepassword();
login_test.clickrememberme();
login_test.clicklogin();
}
You are removing object reference by using "WebDriver driver = null" in verifyvalidlogin() method. Remove this line and try, it will work.
You instance variable 'driver' as private ('private WebDriver driver').
With 'private' access modifier you can access driver within the class but not from outside, change it to public it will work.
In beforetest() method you are instantiating the browser object and navigating to demo Url.
After that in verifyvalidlogin() method you are making driver object to null and passing this null object to Login page, here you are passing null instead of driver object.
We can solve this issue by declaring driver instance variable inside the class and outside of all methods like below.
WebDriver driver;
Instantiate this driver object in beforetest() method and pass the same driver object to LoginPage without declaring it again as mentioned below.(I executed this script in my local machine its working fine)
package Tests;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import Pages.LoginPage;
public class verifylogin {
WebDriver driver;
#BeforeTest
public void beforetest(){
System.setProperty("webdriver.chrome.driver","C:\\Users\\saniket.soni\\Desktop\\ chrome\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://demosite.center/wordpress/wp-login.php");
}
#Test
public void verifyvalidlogin(){
LoginPage login_test = new LoginPage(driver);
login_test.typeusername();
login_test.typepassword();
login_test.clickrememberme();
login_test.clicklogin();
}
}
package Pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class LoginPage {
WebDriver driver;
By username = By.id("user_login");
By password = By.id("user_pass");
By login = By.id("wp-submit");
By rememberme = By.id("rememberme");
public LoginPage(WebDriver driver){
this.driver = driver;
}
public void typeusername(){
driver.findElement(username).sendKeys("admin");
}
public void typepassword(){
driver.findElement(password).sendKeys("demo123");
}
public void clickrememberme(){
driver.findElement(rememberme).click();
}
public void clicklogin(){
driver.findElement(login).click();
}
}
Try this solution and let me know if it works for you.

(Should be easy) Selenium chromedriver (java) no element found error

I tried this exact code on other websites and it seems to work fine. It's just on pizza hut that it can't even locate an element let alone click on it. Thread.sleep() doesn't make a difference. The problem is between the commented *, according to the compiler. Here's the code.
package training;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class PizzaHut {
WebDriver driver;
#Test
public void open() throws Exception {
//SET UP WEBDRIVER AND OPEN WEBSITE
System.setProperty("webdriver.chrome.driver","/Users/1mr4n/Downloads/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("https://www.pizzahut.com/#/home");
Thread.sleep(1000);
//CLICK PIZZA
Thread.sleep(5000);
test("before");
//**************PROBLEM*CODE**********************
driver.findElement(By.xpath("//a[#id='lg-nav-pizza']")).click();
//************************************************
test("clicked pizza");
//CLOSE BROWSER
Thread.sleep(15000);
driver.close();
}
public static void test(String x) {
System.out.println(x);
}
}
I just ran the code below and it worked just fine. No need for sleep or waits and I'm using Chrome also.
driver.get("https://www.pizzahut.com");
driver.findElement(By.id("lg-nav-pizza")).click();
Try this one ,definitely it help you.
package training;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class PizzaHut {
WebDriver driver;
#Test
public void open() throws Exception {
//SET UP WEBDRIVER AND OPEN WEBSITE
// System.setProperty("webdriver.chrome.driver","/Users/1mr4n/Downloads/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("https://www.pizzahut.com/#/home");
Thread.sleep(1000);
//CLICK PIZZA
Thread.sleep(5000);
test("before");
List<WebElement> webElements=driver.findElement(By.cssSelector("div.btn-group.btn-group-lg.btn-group-justified.ph-header-navigation"))
.findElements(By.cssSelector("div.btn.btn-link.ph-ghost-padding.ng-scope"));
for (WebElement element : webElements) {
if (element.getAttribute("title").equals("PIZZA")) {
element.click();
}
}
Thread.sleep(5000);
test("clicked pizza");
//CLOSE BROWSER
Thread.sleep(15000);
driver.close();
}
public static void test(String x) {
System.out.println(x);
}
}
You are not able to click it because it is an AngularJS tag, hence it takes some time to load: add some wait like below and it works (Here i'm just adding thread.sleep for the sake of simplicity,I've increased it to 15000ms):
//CLICK PIZZA
Thread.sleep(15000);
test("before");
//**************PROBLEM*CODE**********************
driver.findElement(By.xpath("//a[#id='lg-nav-pizza']")).click();

How to create two object drivers of type WebDriver and use the same Classes and Methods

I have a question related to improving my Selenium Java code. I am really beginner in Java and Selenium either.
I have written a code which I got an example from the internet and adapted to my reality. The coding works fine as described below:
package test;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import page.Login;
public class LoginTest extends BaseTest {
Login login = new Login(driver);
#Test
public void loginWithSuccess() {
sendLoginData("my_user#something.com", "my_password");
login.clickLogin();
assertEquals("View Posted Jobs", login.checkLoginSuccess());
}
private void sendLoginData(String user, String password) {
login.sendUser(user);
login.sendPassword(password);
}
}
The above program is testing and performing a loginWithSucess in the WebSite
package config;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class WebDriverFactory {
public static WebDriver createFirefoxDriver() {
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
return driver;
}
}
In this above example I am instancing a new object WebDriver called driver.
package test;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.openqa.selenium.WebDriver;
import config.WebDriverFactory;
public class BaseTest {
protected static WebDriver driver;
private static boolean setUpIsDone = false;
#BeforeClass
public static void setUp() {
if (setUpIsDone) {
return;
}
// Creating first browser for student login
driver = WebDriverFactory.createFirefoxDriver();
driver.get("http://test-tuitiondesk.rhcloud.com/auth");
driver.manage().window().maximize();
setUpIsDone = true;
}
The above example is where I open my WebSite to authenticate
package page;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class Login {
private WebDriver driver;
public Login(WebDriver driver) {
this.driver = driver;
}
public void sendUser(String user) {
driver.findElement(By.xpath("//*[#id='email']")).sendKeys(user);
}
public void sendPassword(String password) {
driver.findElement(By.id("password")).sendKeys(password);
}
public void clickLogin() {
driver.findElement(By.xpath("//*[#id='login-box']/div/div[1]/form/fieldset/div[2]/button")).click();
}
public String checkLoginSuccess() {
return driver.findElement(By.xpath("//a[contains(text(),'View Posted Jobs')]")).getText();
}
}
The above example I have methods which will send a user id and password to the webpage.
So far is everything working fine. The program is performing the following steps:
1 - Open the firefox
2 - Open the webpage
3 - Send the correct user_id, password and click in login button
4 - Check if login was performed with success.
My question now is that I need open a new firefox driver and login with different user_id and this new user_id will interact some actions with the first user_id, so I will need two browsers opened to perform actions with both users in the same time.
I would like to write this implementation the best way than simply write every method again with the second driver. What I thought for the first time was create a new WebDriver called driver2 and create again all methods referring to driver2, but I think I should reuse my methods and classes in a clever way.
Does Anybody have any idea how to implement this second browser in my code?
Thank you
André
You can do this simply by entering this code:
driver2 = WebDriverFactory.createFirefoxDriver();
driver2.get("http://test-tuitiondesk.rhcloud.com/auth");
//call log in function for driver2
//code to interact driver2 with driver1

Selenium click action directs to page other than by Selenium IDE

I am trying to click on a web element using Selenium WebDriver(2.21.0).
When I try driving through the Selenium IDE it works properly but when I try the same set of actions using the Java implementation of Firefox driver- it leads to the wrong page.
While the code is running and I manually scroll to the desired element, it works.
I am making sure that the web element is visible and enabled using
By by = By.xpath("(//a[contains(#href, 'javascript:void(0);')])[26]"); //**Edit:** this is how i
//am getting the locator
WebElement element = driver.findElement(by);
return (element.isEnabled() || element.isDisplayed()) ? element : null;
which returns some element but not the one I am expecting.
This looks strange to me as Selenium webdriver mostly scrolls to an element(if not visible on the screen) by itself and does the required interaction.
I have tried some answers like one, two with no success.
Thanks in advance!
EDIT: here is the IDE's exported code(java/JUnit4/webdriver)
package com.example.tests;
import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;
import org.junit.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
public class Bandar {
private WebDriver driver;
private String baseUrl;
private StringBuffer verificationErrors = new StringBuffer();
#Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "http://e.weibo.com/";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Test
public void testBandar() throws Exception {
driver.get(baseUrl + "/nescafechina");
driver.findElement(By.xpath("(//a[contains(#href, 'javascript:void(0);')])[26]")).click();
driver.findElement(By.xpath("(//a[contains(#href, 'javascript:void(0);')])[12]")).click();
}
#After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
}
Ishank,
What I have done is gone through and created a test that shows the different kind of asserts that you can use in your testing. They do look a little different from what you are looking at, I feel your main problem is WebElement element = driver.findElement(by); because you are not giving it an actual element. The (by); section is looking for a string that can be found on the page. Acceptable strings would be; id("gbfqb"); or xpath("(//a[contains(#href, 'javascript:void(0);')])[26]"); or even name("find-button");.
/**
* Test the main Google page.
* #throws InterruptedException
*
*/
#Test
public void signUp() throws InterruptedException {
String testId = "TestStack01";
entered(testId);
webDriver.get("www.google.com");
webDriver.findElement(By.id("gbqfq")).clear();
webDriver.findElement(By.id("gbqfq")).sendKeys("Test");
assertEquals("", webDriver.findElement(By.id("gbqfb")).getText());
WebElement whatyourlookingfor = webDriver.findElement(By.id("gbqfb"));
assertTrue(selenium.isElementPresent("gbqfb"));
assertTrue(whatyourlookingfor.isEnabled());
assertTrue(whatyourlookingfor.isDisplayed());
assertFalse(whatyourlookingfor.isSelected());
webDriver.findElement(By.id("gbqfb")).click();
leaving(testId);
}
I hope that this has helped in getting which element is being returned.
Curtis Miller

Categories

Resources