Search code examples
javaspringseleniumtestngspring-ioc

Unable to maintain two parallel sessions while running tests using testNG(Selenium) using Spring?


I am facing problem while running simple tests using TestNG with Selenium using Spring framework, the issue is that it unable to start two parallel session (without parallel its working fine without any issue). The overall objective is to launch two parallel browsers and each session managed by springIOC. Without Spring its easy to do using static threadLocal, but with spring i want to maintain two separate IOC containers managed by spring itself.

Please help me to resolve this issue. Code is available on below link, https://github.com/priyankshah217/AutomationFrameworkUsingSpringDI.git

testNg.xml

<test name="search-engine-test">
    <classes>
        <class name="com.test.framework.tests.TestAmazonWeb"/>
    </classes>
</test>

TestConfig.java

@Configuration
@ComponentScan("com.test.framework")
public class TestConfig {

  WebDriver webDriver;

  @Bean
  public WebDriver getDriver() {
    if (webDriver == null || ((ChromeDriver) webDriver).getSessionId() == null) {
      webDriver = new ChromeDriver();
    }
    return webDriver;
  }
}

BaseTest.java

@ContextConfiguration(classes = {TestConfig.class})
public class BaseTest extends AbstractTestNGSpringContextTests {

    @Autowired
    private WebDriver webDriver;

    @AfterMethod
    public void tearDown() {
        webDriver.quit();
    }
}

GoogleHomePage.java

@PageObject
public class GoogleHomePage extends BasePage {
    @FindBy(name = "q")
    private WebElement searchTextbox;

    public void enterGoogleSearch() {
        hardWait();
        searchTextbox.sendKeys("Selenium");
        searchTextbox.sendKeys(Keys.RETURN);
    }

}

All Page objects are spring component with WebDriver (autowired).


Solution

  • There were a few issues in your codebase which is preventing concurrency support.

    1. The autowired WebDriver instance should have been defined with scope as prototype instead of singleton (which is the default scope). That way each of the page objects would basically get their own WebDriver instance. This is in a way a bit of a convoluted approach though when your @Test method spans across multiple pages.
    2. The way in which you have handled post processing (wherein you are initialising the page factory) also has to be changed if you are going to be working with a prototype scoped webdriver, because you now cannot afford to autowire the webdriver in there, but it now has to be extracted from the page object class.

    To explain the changes in a much more easy to understand way, I have raised a pull request against your repository.

    Refer to https://github.com/priyankshah217/AutomationFrameworkUsingSpringDI/pull/2

    for the full set of changes.