I'm trying to get a Spring Boot Selenium app to work. I can get one test to run successfully, but when I run more than one test, the second test complains with:
Session ID is null. Using WebDriver after calling quit()?
After looking through the source code and putting in breakpoints, it looks like Spring is calling the quit() method for WebDriver after the first test.
How do I get it to not quit after each test? I've thought about just not using dependency injection for the page classes.
Here is my test class:
@SpringBootTest
public class LoginTest {
@Autowired LoginPage loginPage;
@Test
public void shouldLogin() {
loginPage.login();
}
@Test
public void shouldLoginToAdminPage() {
loginPage.adminLogin();
}
}
My LoginPage:
@Component
public class LoginPage extends BasePage {
@FindBy(how = How.XPATH, using = "//gat-input[@formcontrolname = 'userName']//input")
private WebElement txtUserName;
@FindBy(how = How.XPATH, using = "//gat-input[@formcontrolname='password']//input")
private WebElement txtPassword;
@FindBy(how = How.XPATH, using = "//gat-button[@label='Login']/button")
private WebElement btnLogin;
protected void login(String username, String password) {
loadPage();
sendKeysWhenReady(txtUserName, username);
sendKeysWhenReady(txtPassword, password);
clickWhenReady(btnLogin);
}
public void adminLogin() {
login(properties.getAdminUsername(), properties.getAdminPassword());
}
public void login() {
login(properties.getRegularUsername(), properties.getRegularPassword());
}
@Override
public void verifyPageLoaded() {
waitTillElementIsReady(btnLogin, 5);
}
@Override
protected String getPath() {
return "/login";
}
}
The BasePage:
public abstract class BasePage {
@Autowired private WebDriver driver;
@Autowired protected Properties properties;
@PostConstruct
public void initDriver() {
driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);
PageFactory.initElements(driver, this);
}
public void loadPage() {
getDriver().get(getUrl());
verifyPageLoaded();
}
public String getUrl() {
return properties.getBaseUrl().concat(getPath());
}
// example "/login"
protected abstract String getPath();
public abstract void verifyPageLoaded();
public WebDriver getDriver() {
return driver;
}
protected void waitTillElementIsReady(WebElement webElement, int seconds) {
WebDriverWait wait = new WebDriverWait(driver, seconds);
wait.until(ExpectedConditions.visibilityOf(webElement));
}
protected void sendKeysWhenReady(WebElement webElement, String keys) {
waitTillElementIsReady(webElement, 5);
webElement.sendKeys(keys);
}
protected void clickWhenReady(WebElement webElement) {
waitTillElementIsReady(webElement, 3);
webElement.click();
}
}
The Config class:
public class WebDriverLibrary {
@Bean
public WebDriver getChromeDriver() {
WebDriverManager.chromedriver().setup();
return new ChromeDriver();
}
}
And my dependencies:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.seleniumhq.selenium:selenium-java:4.2.1'
implementation 'io.github.bonigarcia:webdrivermanager:5.2.0'
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.testng:testng:7.6.0'
testImplementation 'org.testcontainers:junit-jupiter:1.17.2'
testImplementation 'org.testcontainers:selenium:1.17.2'
}