I need to inject different PageObject implementations depending on some property, but faced a problem with managing WebDriver sessions.
@Configuration
public class WebDriverConfig {
@Bean
@Scope("browserscope")
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ConditionalOnProperty(name = "browser", havingValue = "chrome")
public WebDriver chromeDriver(){
ChromeOptions chromeOptions = new ChromeOptions();
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver(chromeOptions);
driver.manage().window().maximize();
return driver;
}
}
I am using Cucumber to launch my tests and it’s working as expected when I run a single cucumber scenario, but when I run them in parallel, the values from one Thread are being used in another Thread
This is how my step definition class looks like
@SpringBootTest
@CucumberContextConfiguration
@Scope("cucumber-glue")
public class CPLSteps {
}
I am using testng to lauch my cucumber Features in parallel
import io.cucumber.testng.CucumberOptions;
import io.cucumber.testng.FeatureWrapper;
import io.cucumber.testng.PickleWrapper;
import io.cucumber.testng.TestNGCucumberRunner;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@CucumberOptions(
features = "src/test/resources/features",
glue = "com.intact.contactpl.web.ui.bdd",
tags = "@smoke",
plugin = {"pretty", "html:target/cucumber-reports/index.html",
"json:target/cucumber-reports/CucumberTestReport.json"
},
monochrome = true
)
public class FeatureParallelTest {
private TestNGCucumberRunner testNGCucumberRunner;
@BeforeClass(alwaysRun = true)
public void setUpClass() {
testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
}
@Test(groups = "cucumber", description = "Runs Cucumber Feature", dataProvider = "features")
public void feature(PickleWrapper pickleWrapper, FeatureWrapper featureWrapper) throws Throwable{
testNGCucumberRunner.runScenario(pickleWrapper.getPickle());
}
@DataProvider(parallel = true)
public Object[][] features() {
return testNGCucumberRunner.provideScenarios();
}
@AfterClass(alwaysRun = true)
public void tearDownClass() {
if (testNGCucumberRunner == null) {
return;
}
testNGCucumberRunner.finish();
}
}
Not sure what I am doing wrong, how can I manage the sessions properly ??
Example of my page object class:
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public class Login extends BasePageObject {
@FindBy(id = "username")
private WebElement txt_username;
@FindBy(id = "password")
private WebElement txt_password;
@FindBy(id = "login-btn-label")
private WebElement btn_login;
@Value("${internalURL}")
private String URL;
public Login openLoginPage(String url) {
this.driver.get(url);
return this;
}
I tried adding @Scope("cucumber-glue")
to the Step definition class but it didn’t helped me to fix my issue.