ThreadSafety Issues - #Urgent help needed

28 views
Skip to first unread message

Ramapriya Prasathe

unread,
Mar 27, 2025, 11:43:51 PM3/27/25
to Selenium Users

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)



Krishnan Mahadevan

unread,
Mar 27, 2025, 11:55:46 PM3/27/25
to seleniu...@googlegroups.com
Can you please share your code by uploading it to 

* GitHub.com as a sample project (or)

So that it’s easier to see what is going on? The snippet you have shared is all garbled and it’s hardly readable.


Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

--
You received this message because you are subscribed to the Google Groups "Selenium Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to selenium-user...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/selenium-users/11399e1b-9326-468e-ac78-ff9f290dc876n%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages