Design issue in Cucumber spring WebDriver quit in @After method

让人想犯罪 __ 提交于 2021-02-08 11:05:30

问题


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:


Apart from the @DirtiesContext used by OP as solution . Tried using @Scope(SCOPE_CUCUMBER_GLUE)/@Scope("cucumber-glue") . Unique instance of Webdriver is created and destroyed in each scenario.

Reference

Changing a Spring bean's scope to SCOPE_CUCUMBER_GLUE will bound its lifecycle to the standard glue lifecycle.

import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Scope;
import static io.cucumber.spring.CucumberTestContext.SCOPE_CUCUMBER_GLUE;

@Component
@Scope(SCOPE_CUCUMBER_GLUE)
public class MyComponent {
}

Base Page:

@Component
@Scope("cucumber-glue")
public class BasePage {
WebDriver driver;
 public BasePage(WebDriver driver) {
    this.driver = driver;
    PageFactory.initElements(driver, this);

 }
 public WebDriver getDriver() {
    return this.driver;
  }

}

Base Page :

@Component
@Scope("cucumber-glue")
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();
 }
}

Configuration:

@Configuration
// Not define in example so commented @ContextConfiguration(classes= 
//{PropertiesContext.class})
@ComponentScan(basePackages = "com.company.project")
public class CucumberContext {

@Autowired
private String browser;

  @Bean(name = "webdriver", destroyMethod = "quit")
  @Scope("cucumber-glue")
  public WebDriver getWebDriver() {
      WebDriver webdriver = null;
      // Removed the factory initialization code. Used simple ChromeDriver
      webdriver = new ChromeDriver();
      return webdriver;
  }
}

Steps:

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) {
   // Removed quit
   // if(loginPage.getDriver() != null) {
   //     loginPage.getDriver().quit;
  //   }
}
}

Note: All chromeriver background processes are killed.



来源:https://stackoverflow.com/questions/57478175/design-issue-in-cucumber-spring-webdriver-quit-in-after-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!