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()");
}
}
Related
I'm a beginner Selenium practitioner. I have 2 classes, one for the WebDriver another is for Log In. I followed some youtube tutorials but can't pinpoint what I'm doing wrong. I tried the concept of 'Baseclass' where I extend the other class.
LogIn Class
WebDriver Class
If I add the WebDriver in the other class, it will run successfully. But I want to make it more 'organized'
this is the error
Error message
public Webdriver driver;
Please add static in this line
public static Webdriver driver;
because you need use same driver instance for all classes
create above line in top of both classes
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
public class TestApp {
private WebDriver driver;
private static TestApp myObj;
// public static WebDriver driver;
utils.PropertyFileReader property = new PropertyFileReader();
public static TestApp getInstance() {
if (myObj == null) {
myObj = new TestApp();
return myObj;
} else {
return myObj;
}
}
//get the selenium driver
public WebDriver getDriver()
{
return driver;
}
//when selenium opens the browsers it will automatically set the web driver
private void setDriver(WebDriver driver) {
this.driver = driver;
}
public static void setMyObj(TestApp myObj) {
TestApp.myObj = myObj;
}
public void openBrowser() {
//String chromeDriverPath = property.getProperty("config", "chrome.driver.path");
//String chromeDriverPath = property.getProperty("config", getChromeDriverFilePath());
System.setProperty("webdriver.chrome.driver", getChromeDriverFilePath());
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
options.addArguments("disable-infobars");
driver = new ChromeDriver(options);
driver.manage().window().maximize();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void navigateToURL() {
String url =property.getProperty("config","url");
;
driver.get(url);
}
public void closeBrowser()
{
driver.quit();
}
public WebElement waitForElement(By locator, int timeout)
{
WebElement element = new WebDriverWait(TestApp.getInstance().getDriver(), timeout).until
(ExpectedConditions.presenceOfElementLocated(locator));
return element;
}
private String getChromeDriverFilePath()
{
// checking resources file for chrome driver in side main resources
URL res = getClass().getClassLoader().getResource("chromedriver.exe");
File file = null;
try {
file = Paths.get(res.toURI()).toFile();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return file.getAbsolutePath();
}
}
//create package name called utils and under that package create class name with TestApp and paste above code
if you want use driver anywhere in your project
TestApp.getInstance().getdriver();
You didn't initialize your driver anywhere.
You need to use a before
#BeforeClass
public void setupClass(){
driver = new Chromedriver();
}
and in opensite
public static WebDriver driver;
You want your OpenSite class to act as the base class which you can extend it to your test class to intialize your driver. Remove your "#test" annotaion from the OpenSite class.
Add static with "public WebDriver driver";
Create a method openBrowser(already there) or driverInitialization in this class.
Return the driver instance.
Updated code will look like
public class OpenSite{
public static WebDriver driver;
public static void openBrowser(){
System.setProperty("webdriver","path");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("your URL");
return driver;
}
}
And in test class LogIn extend this class and call this method:
public class LogIn extends OpenSite{
#BeforeTest
public void driver initialization(){
openBrowser();
}
#Test
public void logInVendor(){
//Write your code here
}
}
I am using Dependency injection technique to invoke the driver in my step definition class,
In the first class, I have initialized the chrome driver and set it to the DI class.
But while running the code, it's not sharing to my next step Definition Class.
Created a driver in the DIClass and then initiated the chrome driver in the login class.
and then set the chrome driver object to the DIClass driver but while reaching second step definition class, I am getting null pointer error on hamburger method.
DIClass:
public class DIClass {
public WebDriver driver;
public WebDriver getDriver() {
return driver;
}
public void setDriver(WebDriver driver) {
this.driver = driver;
}
StepDefinition class:
public class LoginPage extends DIClass{
DIClass base;
public LoginPage(DIClass testContextUI) {
this.base = testContextUI;
}
#Given("I open a {string} browser")
public void i_open_a_browser(String browser) {
// System.setProperty("webdriver.chrome.driver", "/Users/vinoth/eclipse-workspace/yocoBoardI/chromedriver");
// WebDriver driver = new ChromeDriver();
// base.signIn = PageFactory.initElements(base.driver, SignIn.class);
}
#Given("I navigate to url {string}")
public void i_navigate_to_url(String url) {
System.setProperty("webdriver.chrome.driver", "/Users/vinoth/eclipse-workspace/yocoBoardI/chromedriver");
WebDriver driver = new ChromeDriver();
base.setDriver(driver);
base.signIn = PageFactory.initElements(base.driver, SignIn.class);
base.driver.get(url);
}
#When("user login into application with {string} and {string}")
public void user_login_into_application_with_and(String string, String string2) {
base.signIn.normalSignIn(string, string2);
}
#Then("I navigated to Hours page")
public void i_navigated_to_Hours_page() throws InterruptedException {
base.hoursPage = PageFactory.initElements(base.driver, HoursPage.class);
base.hoursPage.validateHOursPage();
// base.pages = PageFactory.initElements(base.driver, LeftSideBar.class);
// base.pages.clockInOut();
// base.driver.quit();
}
}
2nd Class:
public class ProfileSettings {
// WebDriver driver;
DIClass base;
LoginPage loginPage;
public ProfileSettings(DIClass testContextUI) {
this.base = testContextUI;
}
#Given("User should see the hamburger icon")
public void user_should_see_the_hamburger_icon() {
// base.setDriver(driver);
base.profileSettings = PageFactory.initElements(base.driver, ProfileSettingsPage.class);
base.profileSettings.hamburgerIcon(); - here i am getting the error .
}
#When("I clicks the profile settings label")
public void i_clicks_the_profile_settings_label() {
base.profileSettings.openFooterPopup();
}
#Then("landed to the respective page.")
public void landed_to_the_respective_page() {
base.profileSettings.validateProfileSettingsPage();
}
#When("I upload Invalid {string} formats")
public void i_upload_Invalid_formats(String string) {
//StringSelection is a class that can be used for copy and paste operations.
StringSelection stringSelection = new StringSelection(string);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
base.profileSettings.fileUpload("Mac");
}
#Then("Should see the respective voice message")
public void should_see_the_respective_voice_message() {
base.profileSettings.fileUploadValidation();
}
import depenencyInjection.DIClass;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import org.junit.BeforeClass;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class DriverClass extends DIClass {
DIClass base;
public DriverClass(DIClass testContextUI) {
this.base = testContextUI;
}
#Before
public void testStep()
{
if(base.getDriver() ==null) {
System.out.println("Test Environment Setup");
System.setProperty("webdriver.chrome.driver", "Filepath");
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
base.driver = new ChromeDriver(options);
base.driver.navigate().to("https:********");
}
}
}
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.
" 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.
Can anyone help me with AssertEquals?
I have the below code for my test case class, but after AssertEquals fails, the test continues to proceed to the next method i.e. createClientTodelete. Why?
public class Client
{
public String baseUrl = "http://test.abc.com";
public WebDriver driver;
#BeforeTest
public void setBaseURL()
{
driver = new FirefoxDriver();
driver.get(baseUrl);
driver.manage().window().maximize();
}
#Test(priority = 0, description = "verify successful login")
public void verifyLogin()
{
String expectedDashTitle = "oms";
String actualDashTitle = driver.getTitle();
Assert.assertTrue(driver.findElements(By.name("username")).size()>0);
Assert.assertTrue(driver.findElements(By.name("password")).size()>0);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.findElement(By.name("username")).sendKeys("admin");
driver.findElement(By.name("password")).sendKeys("123#123");
driver.findElement(By.name("login")).submit();
Assert.assertEquals(actualDashTitle, expectedDashTitle,"Title Not Found!");
}
#Test(priority = 1, description = "verify client is created successfully")
public void createClientTodelete()
{
driver.findElement(By.xpath(".//*[#id='mainMenu']/ul/li[2]/a/span")).click();
Assert.assertTrue(driver.findElements(By.linkText("Create")).size()>0);
driver.findElement(By.linkText("Create")).click();
driver.findElement(By.id("company_name")).sendKeys("TestCompany");
driver.findElement(By.id("contact_person_firstname")).sendKeys("FirstName");
driver.findElement(By.id("contact_person_lastname")).sendKeys("LastName");
driver.findElement(By.id("contact_person_email")).sendKeys("abc#test.com");
driver.findElement(By.id("save")).click();
}
By looking at your code, its clear that you are using TestNG for these test.
In TestNG, you can use "dependsOnMethods" property as below.
package sample.testng;
import org.testng.annotations.Test;
import org.testng.Assert;
public class SampleTest {
#Test
public void test(){
System.out.println("Executing test 1");
Assert.assertEquals("ABCD", "abc");
}
#Test(dependsOnMethods={"test"})
public void test1(){
System.out.println("Second test runs only if the first one is successful, otherwise its ignored");
//Asserts or whatever
}
}