Use single driver instance in multiple methods & classes - java

I have created 2 packages each contains a java class file. The Utility class in 1st package initiates the driver & closes the driver with methods- launchDriver() & closeDriver(). In the 2nd package-Example java class file contains call to these methods. The driver is successfully launched using launchDriver() but when the driver is passed to closeDriver method, the value becomes null...
Please provide a solution.The code is as shown,..
public class Utility {
public static WebDriver driver;
public static String driverpath="E:\\Drivers";
#Test
public static WebDriver launchDriver(final String browser,final String url){
if(browser=="firefox"){
WebDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get(url);
}else if(browser=="chrome"){
System.setProperty("webdriver.chrome.driver", driverpath+"\\chromedriver.exe");
WebDriver driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get(url);
}else if(browser=="ie"){
System.setProperty("webdriver.ie.driver", driverpath+"\\IEDriverServer.exe");
WebDriver driver=new InternetExplorerDriver();
driver.manage().window().maximize();
driver.get(url);
}else{
WebDriver driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get(url);
}
return driver;
}
#Test
public static WebDriver closeDriver(WebDriver driver){
Utility.driver=driver;
driver.quit();
return driver;
}
}
class Example in tests package
public class Example{
#Test
public static void launchConfig(){
Utility.launchDriver("chrome", "https://www.google.com");
//Utility.launchDriver("firefox","www.google.com");
Utility.closeDriver(Utility.driver);
}
}

Create an abstract test class and have your test classes extend that. your abstract test class might look like this:
public abstract class Abstract test {
//delcare driver
public static WebDriver driver;
//Assign the correct driver
#BeforeSuite
public void webdriverSetUp() {
if(browser=="firefox"){
WebDriver driver=new FirefoxDriver();
} else if(browser=="chrome"){
WebDriver driver=new ChromeDriver();
} else if(browser=="ie"){
WebDriver driver=new InternetExplorerDriver();
} else{
WebDriver driver=new FirefoxDriver();
}
}
//call getDriver() in your tests
public static WebDriver getDriver() {
return driver;
}
}
Just dont forget your probably going to want to clear all cookies between test methods.

Related

java.lang.NullPointerException at creating new object line

I'm trying to use TestNG and Page Object for my Selenium test. But it fails with java.lang.NullPointerException error at a line where I'm creating new object of my Page Object Class.
public class TestTitle {
#Test
public void scenario1() {
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
WebDriver driver=new ChromeDriver();
FirstPage fp = new FirstPage(driver);
driver.get("https://www.google.com/");
fp.element.click();
}
}
public class FirstPage {
WebDriver driver;
public FirstPage (WebDriver driver) {
this.driver = driver;
}
public WebElement element = driver.findElement(By.id("hptl"));
}
FAILED: scenario1
java.lang.NullPointerException
at Pages.FirstPage.<init>(FirstPage.java:14)
at Test.TestTitle.scenario1(TestTitle.java:15)
FirstPage.java:14 is public WebElement element = driver.findElement(By.id("hptl"));
TestTitle.java:15 is FirstPage fp = new FirstPage(driver);
try this
public class FirstPage {
public WebDriver driver;
public WebElement element;
public FirstPage (WebDriver driver) {
this.driver = driver;
this.element = driver.findElement(By.id("hptl"));
}
}

How to use the same Webdriver from different class

I have 2 Java classes; Main.java and Methods.java. At Main.java, I initialize the chrome webdriver and I want to use the same webdriver for a method at Methods.java. Below are the codes.
Under Main.java
Methods getMethods = new Methods();
#BeforeTest
public void Setup()
{
System.setProperty("webdriver.chrome.driver", "C:\\...\\chromedriver.exe");
driver = new ChromeDriver();
driver.get(PropertiesConfig.getObject("websiteUrl"));
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#Test
public void TestCase1()
{
getMethods.method1();
}
#AfterTest
public void QuitTC() {
getMethods.QuitTC(); }
Under Methods.java
public void method1 (){
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
….. }
public void QuitTC() {
driver.quit();
}
My question is how do I called the initialize Webdriver from Main.java and used it at Methods.java?
Any help with be appreciated! Thanks!
You can do something like this in a utility class (say TestUtil.java)
private static WebDriver wd;
public static WebDriver getDriver() {
return wd;
}
and then you can use following line to get the webdriver in any of the classes mentioned and work on it
WebDriver driver = TestUtil.getDriver();
Declare a global variable for driver like this :
WebDriver driver = null;
#BeforeTest
public void Setup()
{
System.setProperty("webdriver.chrome.driver", "C:\\...\\chromedriver.exe");
driver = new ChromeDriver();
driver.get(PropertiesConfig.getObject("websiteUrl"));
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
Now, you can call method1 from method class like this :
public class Methods{
public Methods(WebDriver driver){
this.driver = driver;
}
public void method1 (){
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
….. }
}
Now once you create the instance of Methods class, constructor would be called and driver reference could be passed.
Try this
Class1 {
public WebDriver driver = null;
public String baseURL="...";
public void openURL() {
System.setProperty("webdriver.chrome.driver", "D:...\\chromedriver.exe");
driver = new ChromeDriver();
driver.get(baseURL);
}
Class2 extends Class1 {
driver.findElement(....);
}

Not able to call the properties of two separate classes from TestNG Class ->java.lang.NullPointerException

I have 2 classes
1.BROWSER--- This class has methods for loading browser so that i can call in my every test case
2.LOCATORS --This class contains methods for storing all webelements
3.NEW TEST-This is my test case, in which i have called "browser" and "locators" class...
Below is my Browser class
BROWSER CLASS
package TestProject.TestProject;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Browser {
WebDriver driver;
public Browser (WebDriver driver) {
this.driver = driver;
}
public WebDriver GetBrowser()
{
System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");
driver = new ChromeDriver();
String baseurl = "https:\\live.guru99.com\\index.php\\";
driver.get(baseurl);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return driver;
}
}
Below is my Locator class
package TestProject.TestProject;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class Locators {
WebDriver driver;
//Locators
By mobile = By.xpath("//a[contains(.,'Mobile')]");
public Locators (WebDriver driver){
this.driver = driver;
}
public void mobile()
{
driver.findElement(mobile).click();
}
}
MY TEST CASE
package TestProject.TestProject;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeTest;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
public class NewTest {
WebDriver driver;
#BeforeTest
public void beforeTest() {
Browser load = new Browser(driver);
driver =load.GetBrowser();
}
#Test
public void VerifyMobile() {
Locators mobilemenu = new Locators(driver);
mobilemenu.mobile();
}
#AfterTest
public void afterTest() {
}
}
You get NullPointerException because you are using non-initialized WebDriver
Below code gives you trouble. You are passing null driver to Browser class and... Then you probably do something with it but you did not return any initialized WebDriver
public class NewTest {
WebDriver driver;
#BeforeTest
public void beforeTest() {
Browser load = new Browser(driver);
load.GetBrowser();
}
Try this:
public WebDriver GetBrowser() {
System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");
driver = new ChromeDriver();
String baseurl = "https:\\live.guru99.com\\index.php\\";
driver.get(baseurl);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
return driver;
}
You will return initialized WebDriver to your test like this:
driver = load.GetBrowser();
This is bound to give a NullPointerException as the WebDriver object in #BeforeTest method is not yet initialized and is thus Null.
Browser load = new Browser(driver);
Here, the driver object is not yet initialized.
Advice:
Instead of calling the GetBrowser() method, initialize the WebDriver object in the Browser class constructor, and inherit the Browser class, and use the WebDriver object as and when required.

Best practice to list my Driver instance as static, especially for dual test execution?

Best practice to list my Driver instance as static, especially for dual test execution?
Driver factory (Used to setup the driver instance):
public class DriverFactory {
public static WebDriver driver;
protected BasePage basePage;
protected LoginPage loginPage;
public WebDriver getDriver() throws Exception {
try {
ReadConfigFile file = new ReadConfigFile();
String browserName = file.getBrowser();
switch (browserName) {
//firefox setup
case "firefox":
if (null == driver) {
System.setProperty("webdriver.gecko.driver", Constant.GECKO_DRIVER_DIRECTORY);
DesiredCapabilities capabilities=DesiredCapabilities.firefox();
capabilities.setCapability("marionette", true);
driver = new FirefoxDriver();
}
break;
}
}
}
}
Steps class: (Cucumber step class):
public class LoginSteps extends DriverFactory {
#Given("^User navigates to the \"([^\"]*)\" website$")
public void user_navigates_to_the_website(String url) throws Throwable {
BasePage basePage = new BasePage();
basePage.loadUrl(url);
}
}
Base Page(Base page for page objects):
public class BasePage extends DriverFactory {
protected WebDriverWait wait;
protected JavascriptExecutor jsExecutor;
public BasePage() throws IOException {
this.wait = new WebDriverWait(driver, 15);
jsExecutor = ((JavascriptExecutor) driver);
}
}

Using Common Selenium WebDriver instance

I want use a common WebDriver instance across all my TestNG tests by extending my test class to use a base class as shown below but it doesn't seem to work :
public class Browser {
private static WebDriver driver = new FirefoxDriver();
public static WebDriver getDriver()
{
return driver;
}
public static void open(String url)
{
driver.get(url);
}
public static void close()
{
driver.close();
}
}
I want to use the WebDriver in my test class as shown below, but I get the error message :
The method getDriver() is undefined for the type GoogleTest:
public class GoogleTest extends Browser
{
#Test
public void GoogleSearch() {
WebElement query = getDriver().findElement(By.name("q"));
// Enter something to search for
query.sendKeys("Selenium");
// Now submit the form
query.submit();
// Google's search is rendered dynamically with JavaScript.
// Wait for the page to load, timeout after 5 seconds
WebDriverWait wait = new WebDriverWait(getDriver(), 30);
// wait.Until((d) => { return d.Title.StartsWith("selenium"); });
//Check that the Title is what we are expecting
assertEquals("selenium - Google Search", getDriver().getTitle().toString());
}
}
The problem is that your getDriver method is static.
Solution #1: Make method non-static (this will either need to make the driver variable non-static as well, or use return Browser.getDriver(); )
public WebDriver getDriver() {
return driver;
}
Or, call the getDriver method by using Browser.getDriver
WebElement query = Browser.getDriver().findElement(By.name("q"));
You need to start your driver, one of many solution is to try #Before to add, Junit will autorun it for you.
public class Browser {
private WebDriver driver;
#Before
public void runDriver()
{
driver = new FirefoxDriver();
}
public WebDriver getDriver()
{
return driver;
}
public void open(String url)
{
driver.get(url);
}
public void close()
{
driver.close();
}
}

Categories