1

Parallel execution of test throws the following exception when parallel=true on DataProvider. Two browser instances will open running on separate threads but only one browser instance will execute successfully and the other one gets stuck on trying to find element and throwing an exception. Please, how do I get the test to execute successfully when parallel=true in dataprovider. I'm I missing something maybe the WebDriver instance in the BasePage. Please help. Thanks.

[PoolService-1] 15:44:06,447 INFO [Default test] Close driver PASSED: loginTest("[email protected]", "123456") FAILED: loginTest("[email protected]", "123456") WARNING: WebDriverException thrown by findElement(By.xpath: //button[contains(text(), 'NO THANKS')]) org.openqa.selenium.WebDriverException: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8478 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect 

When parallel=false on dataprovider, the test will open one browser instance at a time as the data is fed into the test and executes successfully.

PASSED: loginTest("[email protected]", "123456") PASSED: loginTest("[email protected]", "123456") 

Here's the code I wrote:

1) BrowserFactory

public class BrowserDriverFactory { private ThreadLocal<WebDriver> driver = new ThreadLocal<WebDriver>(); private String browser; private Logger log; public BrowserDriverFactory(String browser, Logger log) { this.browser = browser.toLowerCase(); this.log = log; } public WebDriver createDriver() { // Create driver log.info("Create driver: " + browser); if(browser.equals("chrome")) { System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe"); driver.set(new ChromeDriver()); } else if(browser.equals("firefox")) { System.setProperty("webdriver.gecko.driver", "src/main/resources/geckodriver.exe"); driver.set(new FirefoxDriver()); } else { System.out.println("Do not know how to start: " + browser + ", starting chrome."); System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe"); driver.set(new ChromeDriver()); } return driver.get(); } } 

2)BaseTest

public class BaseTest { protected WebDriver driver; public WebDriverWait wait; protected Logger log; protected FirefoxProfile profile; protected String url = "http://www.qaclickacademy.com/"; protected String testSuiteName; protected String testName; protected String testMethodName; @BeforeMethod(alwaysRun = false) public void setUp(Method method, ITestContext ctx) { String testName = ctx.getCurrentXmlTest().getName(); log = LogManager.getLogger(testName); BrowserDriverFactory factory = new BrowserDriverFactory(config.getBrowser(), log); driver = factory.createDriver(); driver.get(url); profile=new FirefoxProfile(); // Set preferences for file type profile.setPreference("browser.helperApps.neverAsk.openFile", "application/octet-stream"); driver.manage().window().maximize(); wait = new WebDriverWait(driver, 5); this.testSuiteName = ctx.getSuite().getName(); this.testName = testName; this.testMethodName = method.getName(); } @AfterMethod(alwaysRun = true) public void tearDown(ITestResult result) { if(result.getStatus()==ITestResult.FAILURE) { //capture screenshot } log.info("Close driver"); // Close browser driver.quit(); } } 

3)DataProvider

 @DataProvider(name="SearchProvider", parallel=true) public Object[][] getDataFromDataprovider(){ return new Object[][] { { "[email protected]", "123456" }, { "[email protected]", "123456" } }; } 

4)BasePage

 public class BasePage { protected WebDriver driver; public WebDriverWait wait; protected Logger log; public BasePage(WebDriver driver, Logger log) { this.driver = driver; this.log = log; wait = new WebDriverWait(driver, 5); } protected void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { e.printStackTrace(); } } protected void clickStallElement(By locator) { try { waitForVisibilityOf(locator, 30); findElement(locator).click(); } catch(org.openqa.selenium.StaleElementReferenceException ex) { waitForVisibilityOf(locator, 30); findElement(locator).click(); } } /** Open page with given URL */ protected void openUrl(String url) { driver.get(url); } /** Find element using given locator */ protected WebElement findElement(By locator) { return driver.findElement(locator); } /** Find all elements using given locator */ protected List<WebElement> findAllElements(By locator) { return driver.findElements(locator); } /** Click on element with given locator when its visible */ protected void click(By locator) { waitForVisibilityOf(locator, 30); findElement(locator).click(); log.info("Clicked WebElement"); } ... } 

5) BaseTest

public class SignInPageTest extends BaseTest { @Test(dataProvider = "SearchProvider", dataProviderClass = DBDataProvider.class) public void loginTest(String username, String password) { System.err.println("Running Test=> " + this + " -> on thread [" + Thread.currentThread().getId() + "]"); log.info("Starting LogInTest # for " + username); ClickAcadamyLandingPage home = new ClickAcadamyLandingPage(driver, log); home.openPage(); home.closeNewsLetterPopup(); // click login ClickAcadamyLoginPage loginPage = new ClickAcadamyLoginPage(driver, log); loginPage = home.clickLoginBtn(); loginPage.enterEmailAddress(username); loginPage.enterPassword(password); ClickAcadamyDashboard dashboard = loginPage.clickLogin(); dashboard.clickLogout(); } } 

6)testng.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="Suite" data-provider-thread-count = "2" thread-count="2" verbose="1" parallel="tests"> <listeners> <listener class-name="com.paralleltest.basetest.TestListener"/> </listeners> <test name="loginTest"> <classes> <class name="com.paralleltest.SignInPageTest"/> </classes> </test> </suite> 

1 Answer 1

3

The problem lies in your test code. Your webdriver instances are getting shared across test methods when you run tests in parallel and powered by a data provider.

Here's a fixed version of your BaseTest and BrowserDriverFactory to include thread safety.

import java.lang.reflect.Method; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxProfile; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.ITestContext; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; public class BaseTest { private static final ThreadLocal<WebDriver> drivers = new ThreadLocal<>(); public WebDriverWait wait; protected FirefoxProfile profile; protected String url = "http://www.qaclickacademy.com/"; protected String testSuiteName; protected String testName; protected String testMethodName; public WebDriver getDriver() { return drivers.get(); } @BeforeMethod() public void setUp(Method method, ITestContext ctx) { String testName = ctx.getCurrentXmlTest().getName(); WebDriver driver = BrowserDriverFactory.createDriver("firefox"); drivers.set(driver); driver.get(url); driver.manage().window().maximize(); wait = new WebDriverWait(driver, 5); this.testSuiteName = ctx.getSuite().getName(); this.testName = testName; this.testMethodName = method.getName(); } @AfterMethod(alwaysRun = true) public void tearDown(ITestResult result) { getDriver().quit(); drivers.remove(); } } 

BrowserDriverFactory.java

import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.firefox.FirefoxOptions; import org.openqa.selenium.firefox.FirefoxProfile; public class BrowserDriverFactory { public static WebDriver createDriver(String browser) { System.err.println("Create driver: " + browser); if (browser.equals("chrome")) { System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe"); return new ChromeDriver(); } else if (browser.equals("firefox")) { System.setProperty("webdriver.gecko.driver", "src/main/resources/geckodriver.exe"); FirefoxOptions options = new FirefoxOptions(); FirefoxProfile profile = new FirefoxProfile(); profile.setPreference("browser.helperApps.neverAsk.openFile", "application/octet-stream"); options.setProfile(profile); return new FirefoxDriver(options); } System.out.println("Do not know how to start: " + browser + ", starting chrome."); System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe"); return new ChromeDriver(); } } 

Now in all the test methods of test classes that extend BaseTest whenever you need access to the driver object, you would get it by invoking getDriver() method.

You can find a full fledge explanation and some more explanation around this in this blog of mine: https://rationaleemotions.com/parallel_webdriver_executions_using_testng/

I also created a library that abstracts out the webdriver lifecycle management and makes it even more simpler for you via a custom annotation.

Take a look at https://github.com/rationaleEmotions/autospawn

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

2 Comments

Thanks very very much. You saved my soul. Everything now works perferctly. Thanks a million. :)
Can you please accept the answer so that the question gets closed ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.