-1

I am trying to create a framework where I can run my test cases(test tags in xml file) in parallel in different browsers. I have tried using all combinations of testNG annotations but after reading a blog came to know that this can only be achieved by using testNg listners. I am using ThreadLocal to keep my driver thread-safe. I am getting null pointer exception when trying to access Webdriver in my test cases class in line LocalDriverManager.getDriver().get(url);

This is LocalBrowserFactory.Class

package BrowserFactory;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;

import DataProvider.ConfigDataProvider;

public class LocalDriverFactory {

        public static WebDriver createInstance(String browserName) {
            WebDriver driver = null;
            ConfigDataProvider config=new ConfigDataProvider();

            if (browserName.toLowerCase().contains("firefox")) {
                System.setProperty("webdriver.gecko.driver", config.getgeckoPath());
                driver = new FirefoxDriver();

            }
            if (browserName.toLowerCase().contains("internet")) {
                driver = new InternetExplorerDriver();

            }
            if (browserName.toLowerCase().contains("chrome")) {
                System.setProperty("webdriver.chrome.driver", config.getchromePath());
                driver = new ChromeDriver();

            }
            driver.manage().window().maximize();
            return driver;
        }

}

This is my LocalDriverManager.class

package BrowserFactory;

import org.openqa.selenium.WebDriver;

public class LocalDriverManager {
    private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();

    public static WebDriver getDriver() {
        return webDriver.get();
    }

    public static void setWebDriver(WebDriver driver) {
        webDriver.set(driver);
    }
}

This is my ConfigPropertyReader.class

package DataProvider;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

public class ConfigDataProvider {

    static Properties p;
    public ConfigDataProvider()
    {   

        File f =new File("C:/Eclipse/parallelframework/configuration/config.properties");

        try {
            FileInputStream fis = new FileInputStream(f);
            p=new Properties();
            p.load(fis);

        } 
        catch (Exception e)
        {
        System.out.println("Custom Exception- cannot load properties file"+e.getMessage());
        }       
    }

    public String getvalue(String key)  
    {
        return p.getProperty(key);
    }

    public  String getUrl()
    {
        return p.getProperty("url");    
    }   

    public String getchromePath()
    {
        return p.getProperty("chromepath");
    }

    public String getgeckoPath()
    {
        return p.getProperty("firefoxpath");
    }

    public String getIEPath()
    {
        return System.getProperty("User.dir")+p.getProperty("IEPath");
    }

}

This is WebDriverListner.class

package Listners;

import org.openqa.selenium.WebDriver;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

import BrowserFactory.LocalDriverFactory;
import BrowserFactory.LocalDriverManager;

public class WebDriverListner implements IInvokedMethodListener {

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        if (method.isTestMethod()) {
            String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
            System.out.println(browserName);
            WebDriver driver = LocalDriverFactory.createInstance(browserName);
            LocalDriverManager.setWebDriver(driver);
            System.out.println("Driver Set");
        }

    }

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        if (method.isTestMethod()) {
            WebDriver driver = LocalDriverManager.getDriver();
            if (driver != null) {
                driver.quit();
            }
        }
    }

}

This is my sample testcase.class

package tests;

import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;

import BrowserFactory.LocalDriverManager;

public class sampleTest {


    @Test
    public void testMethod1() {
        invokeBrowser("http://www.ndtv.com");
    }

    @Test
    public void testMethod2() {
        invokeBrowser("http://www.facebook.com");

    }

    private void invokeBrowser(String url) {

    LocalDriverManager.getDriver().get(url);

    }

}
2
  • 1
    Seems that the afterInvocation and beforeInvocation methods need to have their names switched... Commented Oct 30, 2017 at 7:22
  • In this line LocalDriverManager.getDriver().get(url); there is getDriver which returns webDriver.get() as per your code, so it becomes LocalDriverManager.webDriver.get().get(url) which is confusing to me. I think issue is here. Or you need to put this part of code WebDriver driver = null; outside of class LocalDriverFactory Commented Oct 30, 2017 at 7:53

1 Answer 1

1

Your Listener code is messed up. You basically have the beforeInvocation and afterInvocation in the wrong order.

Here's how it should have looked like

import org.openqa.selenium.WebDriver;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class WebDriverListener implements IInvokedMethodListener {

    @Override
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        if (method.isTestMethod()) {
            String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
            WebDriver driver = LocalDriverFactory.createInstance(browserName);
            LocalDriverManager.setWebDriver(driver);
        }
    }

    @Override
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        if (method.isTestMethod()) {
            WebDriver driver = LocalDriverManager.getDriver();
            if (driver != null) {
                driver.quit();
            }
        }
    }
}

You basically would setup the webdriver into the thread local variable (push the webdriver instance into the thread local variable's context) from within the beforeInvocation and then within your afterInvocation method, you would pop it out and clean up the webdriver instance (by calling quit() ). In your case, your code is doing the opposite.

For more details you can refer to my blog post here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.