1
votes

I am sure it has to be an easy one to solve but nothing comes to my mind at this moment, here is the situation.

I have one Singleton class (DriverFactory.class) to set and retrieve a ThreadLocal Object. Two test classes running in parallel (FirstTestClass), (SecondTestClass) and the third TestListenerAdapter class with a method where I want to use the actual running WebDriver instance(it should be bound to the Thread) but here I am getting null pointer exception even if, here is the code

import config.DriverFactory;
import org.junit.Assert;
import org.testng.annotations.Test;
import org.openqa.selenium.WebDriver;

public class SecondTestClass {

    WebDriver driver;

    public SecondTestClass()throws Exception{
        DriverFactory.getInstance().setDriver();
        driver = DriverFactory.getInstance().getDriver();;
    }

    @Test
    public void testInSecondClass() {
        System.out.println("\n THREAD ID: " + Thread.currentThread().getId() + " " + "\n Name: " + Thread.currentThread().getName());
        driver.get("https://www.allsaints.com");
        System.out.println("CURRENT URL IS :" + driver.getCurrentUrl());

        Assert.assertTrue(false);

    }
}
package testParallel;

import config.DriverFactory;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
public class FirstTestClass {

    WebDriver driver;

    public FirstTestClass()throws Exception{
        DriverFactory.getInstance().setDriver();
        driver = DriverFactory.getInstance().getDriver();;
    }

    @Test
    public void testInFirstClass() throws Exception{
        System.out.println("\n THREAD ID: " + Thread.currentThread().getId() + " " + "\n Name: " + Thread.currentThread().getName());
        DriverFactory.getInstance().setDriver();
        driver = DriverFactory.getInstance().getDriver();;
        driver.get("https://pl.wikipedia.org");
        System.out.println("CURRENT URL IS :" + driver.getCurrentUrl());
    }
}
package config;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class DriverFactory {

    private static DriverFactory instance = null;

    public ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();

    private DriverFactory() {}

    @SuppressWarnings("varargs")
    public static DriverFactory getInstance() {
        if (instance == null) {
            instance = new DriverFactory();
        }
        return instance;
    }

    public final void setDriver() throws Exception {
        System.setProperty("webdriver.gecko.driver", "E:\\Projects\\allsaints\\tess\\drivers\\geckodriver.exe");
        webDriver.set(new FirefoxDriver());
    }

    public WebDriver getDriver() throws Exception {
        return webDriver.get();
    }
}
import config.DriverFactory;
import org.openqa.selenium.WebDriver;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

public class testSetup extends TestListenerAdapter {

    @Override
    public void onTestFailure(ITestResult tr) {
        System.out.println(
                "\n THREAD ID: " + Thread.currentThread().getId() + " " +
                        "\n Name: " + Thread.currentThread().getName()

        );
        WebDriver driver;
        try {
             driver = DriverFactory.getInstance().getDriver();
            System.out.println("CURRENT URL IS :" + driver.getCurrentUrl());

        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onTestFailure(tr);
    }
}
<?xml version="1.0"?>
<suite name="All Test Suite" parallel="tests" thread-count="5">
    <listeners>
        <listener class-name="testParallel.testSetup"/>
    </listeners>
    <test verbose="3" preserve-order="true" name="test1">
        <classes>
            <class name="testParallel.FirstTestClass"/>
        </classes>
    </test>
    <test name="test2">
        <classes>
            <class name="testParallel.SecondTestClass"/>
        </classes>
    </test>
</suite>

Console output

class testParallel.FirstTestClass THREAD ID: 22 Name: TestNG

class testParallel.SecondTestClass THREAD ID: 23 Name: TestNG

class testParallel.testSetup THREAD ID: 23 Name: TestNG java.lang.NullPointerException at testParallel.testSetup.onTestFailure(testSetup.java:21) at org.testng.internal.Invoker.runTestListeners(Invoker.java:1895) at org.testng.internal.Invoker.runTestListeners(Invoker.java:1879) at org.testng.internal.Invoker.invokeMethod(Invoker.java:778) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111) at org.testng.TestRunner.privateRun(TestRunner.java:767) at org.testng.TestRunner.run(TestRunner.java:617) at org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at org.testng.SuiteRunner.access$000(SuiteRunner.java:37) at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368) at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) CURRENT URL IS :https://pl.wikipedia.org/wiki/Wikipedia:Strona_g%C5%82%C3%B3wna

1

1 Answers

1
votes

In Listeners, we can't directly access other class instance.Since,It will start listen when the execution begins. If we need to get some particular class instance, then we can access through TestNG Listeners(ITestResult) as below and all your test class should be inherited the DriverFactory class .

Listener Class Code:

public class testSetup extends TestListenerAdapter {

    @Override
    public void onTestFailure(ITestResult tr) {
        System.out.println(
                "\n THREAD ID: " + Thread.currentThread().getId() + " " +
                        "\n Name: " + Thread.currentThread().getName()

        );

        Object currentClass=tr.getInstance();

        WebDriver driver;
        try {
             driver =((DriverFactory) currentClass).getDriver();
            System.out.println("CURRENT URL IS :" + driver.getCurrentUrl());

        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onTestFailure(tr);
    }

}

Test Class 1:

public class FirstTestClass extends DriverFactory {

    WebDriver driver;

Test Class 2:

public class SecondTestClass extends DriverFactory {

    WebDriver driver;