Skip to content

[🐛 Bug]: Thread sharing with parallel testing #Urgent #Please help ASAP  #15518

@ramapriya1992

Description

@ramapriya1992

What happened?

Hi,

Our project structure is cloned from the following Git repository:
https://github.com/juniorerico/selenium-template-java/tree/master/src/test/java

When running tests individually or executing them together without parallel configuration, we only encounter only very few test cases failure due to some feature changes. However, when enabling parallel execution using the TestNG framework on our xml file, we face errors both locally and on Jenkins.

Fixes Attempted So Far which has worked a little
On the login page, we implemented a looping check to ensure the Login/Signup button is clicked only after the email and password fields are filled.
Applied similar logic on pages requiring phone number and OTP entry, as these steps are common across all test methods.
Despite these fixes, our pass percentage drops significantly when running tests in parallel.
Could you please review and suggest improvements to enhance stability in parallel execution?

How can we resolve this error
"Thread safety error; this instance of WebDriver was constructed on thread TestNG-tests-8 (id 25) and is being accessed by thread TestNG-tests-2 (id 19)This is not permitted and will cause undefined behaviour
Build info: version: '4.19.1', revision: 'abe0ee07dc'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.0-1079-azure', java.version: '17.0.8.1'
Driver info: driver.version: unknown"

Attaching the screenshot for the error we are facing in our report while running our tests parallel on both local and Jenkins

How can we reproduce the issue?

<suite name="Suite for All modules" parallel="tests" thread-count="12">

~~~
public class DriverManager {

    private static final ThreadLocal<WebDriver> driver = new ThreadLocal<>();

    private static DriverManager instance = null;
    private static volatile int driverCount = 0; // Track number of drivers created
    private static final int DELAY_BETWEEN_LAUNCH_MS = 5000;

    private DriverManager() {
    }

    public static WebDriver getDriver() {
//        return getInstance().getTheDriver();
        WebDriver webDriver = driver.get();
        if (webDriver == null) {
            throw new IllegalStateException("WebDriver instance is null for thread: " + Thread.currentThread().getName());
        }
        return webDriver;
    }

//    public static void setDriver(WebDriver driver) {
//        DriverManager.driver.set(driver);
//    }   // old code

    public static void setDriver(WebDriver driverInstance) {
        // Protect the WebDriver instance with ThreadGuard
//        driver.set(ThreadGuard.protect(driverInstance));
//        synchronized (DriverManager.class) {
//            driverCount++;
//            try {
//                // Delay only for subsequent drivers (not the first one)
//                if (driverCount > 1) {
//                    Thread.sleep(DELAY_BETWEEN_LAUNCH_MS);
//                }
//            } catch (InterruptedException e) {
//                Thread.currentThread().interrupt();
//                e.printStackTrace();
//            }
//        }
        // Protect the WebDriver instance with ThreadGuard
        driver.set(ThreadGuard.protect(driverInstance));

    }

//    public WebDriver getTheDriver() {
//        return driver.get();
//    }

    public static DriverManager getInstance() {
//        if (instance == null) {
//            instance = new DriverManager();
//        }
//        return instance;
        if (instance == null) {
            synchronized (DriverManager.class) {
                if (instance == null) {
                    instance = new DriverManager();
                }
            }
        }
        return instance;
    }

    public static void quit() {
//        DriverManager.driver.get().quit();
//        driver.remove();
        WebDriver webDriver = driver.get();
        if (webDriver != null) {
            try {
                webDriver.quit();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                driver.remove();
            }
        }
    }

    public static String getInfo() {
        var cap = ((RemoteWebDriver) DriverManager.getDriver()).getCapabilities();
        String browserName = cap.getBrowserName();
        String platform = cap.getPlatformName().toString();
        String version = cap.getBrowserVersion();

        return String.format("browser: %s v: %s platform: %s", browserName, version, platform);
    }

    public static void switchToiFrame(WebElement iFrameElement) {
        DriverManager.getDriver().switchTo().frame(iFrameElement);
    }


    public static void switchDriverToFrame(WebElement element) {
        try {
            DriverManager.getDriver().switchTo().frame(element);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void switchDriverToDefaultContent() {
        try {
            DriverManager.getDriver().switchTo().defaultContent();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

~~~

~~~
@Listeners({TestListener.class})
public abstract class BaseWeb {

    public static Faker faker = new Faker();

    @BeforeSuite(alwaysRun = true)
    public void beforeSuite() {
        System.out.println("Before Suite check first");
        System.setProperty("webdriver.http.factory", "jdk-http-client");
        AllureManager.setAllureEnvironmentInformation();
        System.out.println("Before Suite check last");
    }

    @BeforeMethod(alwaysRun = true)
//    @Parameters("browser")
    public void preCondition() { //@Optional("chrome") String browser
        System.out.println("Before Method check first");
        System.out.println(System.getProperty("browser"));
        String browser = System.getProperty("browser");
        try{
            System.out.println("Before Method check inside try block");
            WebDriver driver = new TargetFactory().createInstance(browser);
            DriverManager.setDriver(driver);

        }catch(Exception e){
            System.out.println("Before Method check inside catch block");
            WebDriver driver = new ChromeDriver();
            DriverManager.setDriver(driver);
        }
        DriverManager.getDriver().get(configuration().url());
        System.out.println("Before Method check last");
    }

    @AfterMethod(alwaysRun = true)
    public void postCondition(ITestResult result) {
        if (result.getStatus() == ITestResult.FAILURE) {
            System.out.println("Taking screenshot before quitting WebDriver...");
            AllureManager.takeScreenshotToAttachOnAllureReport();
        }
        DriverManager.quit();
    }
}

~~~

Relevant log output

org.openqa.selenium.WebDriverException: Thread safety error; this instance of WebDriver was constructed on thread TestNG-tests-8 (id 25) and is being accessed by thread TestNG-tests-2 (id 19)This is not permitted and *will* cause undefined behaviour
Build info: version: '4.19.1', revision: 'abe0ee07dc'
System info: os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.0-1079-azure', java.version: '17.0.8.1'
Driver info: driver.version: unknown
	at org.openqa.selenium.support.ThreadGuard$WebDriverInvocationHandler.invoke(ThreadGuard.java:85)
	at jdk.proxy2/jdk.proxy2.$Proxy33.findElement(Unknown Source)
	at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:68)
	at org.openqa.selenium.support.pagefactory.AjaxElementLocator.access$001(AjaxElementLocator.java:38)
	at org.openqa.selenium.support.pagefactory.AjaxElementLocator$SlowLoadingElement.isLoaded(AjaxElementLocator.java:156)
	at org.openqa.selenium.support.ui.SlowLoadableComponent.get(SlowLoadableComponent.java:58)
	at org.openqa.selenium.support.pagefactory.AjaxElementLocator.findElement(AjaxElementLocator.java:86)
	at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38)
	at jdk.proxy2/jdk.proxy2.$Proxy37.getAttribute(Unknown Source)
	at com.remitbee.pages.auth.SignupPage.fillcredentials(SignupPage.java:211)
	at com.remitbee.functions.auth.SignUpFunction.signUpForBusiness(SignUpFunction.java:47)
	at com.remitbee.tests.auth.SignupTest.signUpAndLogOut(SignupTest.java:84)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
	at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:664)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:228)
	at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:63)
	at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:961)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:201)
	at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:148)
	at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.base/java.util.ArrayList.forEach(Unknown Source)
	at org.testng.TestRunner.privateRun(TestRunner.java:819)
	at org.testng.TestRunner.run(TestRunner.java:619)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:443)
	at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:481)
	at org.testng.internal.thread.ThreadUtil.lambda$execute$0(ThreadUtil.java:58)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)

Operating System

mac / Linux

Selenium version

4.19.1 (Selenium Version). 17.0.8.1(JAVA version)

What are the browser(s) and version(s) where you see this issue?

Chrome : 120.0.6099.62

What are the browser driver(s) and version(s) where you see this issue?

chromedriverVersion: 120.0.6099.109

Are you using Selenium Grid?

Version 3

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-defectSomething is not working as intendedI-questionApplied to questions. Issues should be closed and send the user to community resources.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions