-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
Description
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