I have a design issue when I am trying to build a framework using cucumber, selenium and cucumber-spring. My expected behavior is to quit WebdDriver instance for every scenario. But
Here is my page objects in src\main\java
@Component
public class BasePage {
WebDriver driver;
public BasePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public WebDriver getDriver() {
return this.driver;
}
}
Here is another page object class which extends the Base class.
@Component
public class LoginPage extends BasePage
{
public LoginPage(WebDriver webDriver) {
super(webDriver);
}
@FindBy(xpath = "/html/body/app-root/s-login-pg/div/form/input[1]")
WebElement loginTextBox;
@FindBy(xpath = "/html/body/app-root/s-login-pg/div/form/input[2]")
WebElement passwordTextBox;
@FindBy(xpath="/html/body/app-root/s-login-pg/div/form/button")
WebElement loginButton;
public void openApplication(String url){
driver.get(url);
waitForPageToLoad();
}
public void inputUsername(String username){
loginTextBox.sendKeys(username);
}
public void inputPassword(String password){
loginTextBox.sendKeys(password);
}
public void clickLoginButton(){
loginButton.click();
}
}
The webdriver is created with Factory Design pattern. Based on the browser mentioned in the properties file it will create the desired webdriver instance. And these Driver classes are not created with @Component
And spring configuration class under src/test/java as shown below.
@Configuration
@ContextConfiguration(classes={PropertiesContext.class})
@ComponentScan(basePackages = "com.company.project")
public class CucumberContext {
@Autowired
private String browser;
@Bean(name = "webdriver", destroyMethod = "quit")
public WebDriver getWebDriver() {
WebDriver webdriver = null;
webdriver = DriverManagerFactory.getManager(browser).getDriver();
return webdriver;
}
}
This is the step definitions class under src\test\java
public class StepDefinitions extends ParentSteps {
@Autowired
private LoginPage loginPage;
@Autowired
private HomePage homePage;
@Before
public void init() {
if (System.getProperty("environment") == null) {
System.setProperty("environment", "DEV");
}
}
@After
public void tearDown(Scenario scenario) {
if(loginPage.getDriver() != null) {
loginPage.getDriver().quit;
}
}
}
Here is my actual problem in the Step Definitions. For every Test Scenario If I call driver.quit() the remaining test scenarios will be failed with the below exception because the bean WebDriver killed in @After
org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z'
Driver info: driver.version: RemoteWebDriver
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:125)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548)
The reason why I am getting this error is because the webdriver is closed which is an Injected bean. Is there any solution to create wedriver in @Before and kill webdriver in @After for each cucumber scenario? Is there any flaw in the design?
1.2.5- vkrams@DirtiesContextworks however the tests are very slow because its taking lot of time to load context for every test - vkrams