Reputation: 159
I have raised that question previously, but nobody seemed to be able to answer it. Therefore I will go ahead and post a question one more time with the current code structure:
I have a parent with a @BeforeEach
method that sets up everything:
public class WebDriverSettings {
public static WebDriver driver;
@BeforeEach
public void setUp() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS);
loginToEnvironment();
}
@AfterEach
public void tearDown(){
driver.manage().deleteAllCookies();
driver.close();
}
private void loginToEnvironment() {
String TARGET_URL = System.getProperty("TARGET_URL", "");
String URL = " + "@" + TARGET_URL;
driver.get(URL);
}
Than it's a parent's child, one of the tests classes:
public class LoginServiceTest extends WebDriverSettings {
private LoginModal loginModal;
@BeforeEach
public void setUp() {
super.setUp();
loginModal = HomePage.homepageInstance(driver)
.acceptCookies()
.closeCovidMessage()
.clickOnMyAccountTab()
.switchToLoginTab();
}
@Test
public void shouldSuccessfullyLogin() {
assertEquals(userName, loginModal.login(loginCorrectData()).myAccountName.getText());
}
@Test
public void shouldDisplayIncorrectCredentialsMessage() {
loginModal.login(loginIncorrectData());
assertEquals(incorrectCredentialsMessage,loginModal.wrongCredentials.getText());
}
Example of pom object, in which way all my pom objects are build :
ublic class LoginModal extends BasePage {
private static LoginModal loginModal;
@FindBy(xpath = "//input[@name='email']")
public WebElement emailInputField;
@FindBy(xpath = "//input[@name='password']")
public WebElement passwordInputField;
@FindBy(css = ".button-hover-wrapper > div.button-inner")
public WebElement loginButton;
@FindBy(xpath = "//a[text()='Log In']")
public WebElement loginTab;
@FindBy(css = ".error-info")
public WebElement wrongCredentials;
private LoginModal(WebDriver driver) {
super(driver);
}
public static LoginModal loginModalInstance(WebDriver driver) {
return loginModal == null ? loginModal = new LoginModal(driver) : loginModal;
}
public HomePage login(Login login) {
loginModal.clickOnLoginTab()
.fillInEmail(login.getEmail())
.fillInPassword(login.getPassword())
.clickOnLoginButton();
return HomePage.homepageInstance(driver);
}
public LoginModal clickOnLoginTab() {
loginModal.loginTab.click();
return loginModal;
}
public LoginModal fillInEmail(String email) {
loginModal.emailInputField.clear();
loginModal.emailInputField.sendKeys(email);
return loginModal;
}
public LoginModal fillInPassword(String password) {
loginModal.passwordInputField.clear();
loginModal.passwordInputField.sendKeys(password);
return loginModal;
}
public void clickOnLoginButton() {
loginModal.loginButton.click();
}
}
From my understanding, my code does the following:
setUp
method in parent runs each time before the test, than setUp
method in the child starts to run, which successfully opens a browser and completes the test. However, when it goes to another test, I get the following:
invalid session id
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'Artjoms-MacBook-Air.local', ip: 'fe80:0:0:0:10eb:9260:8538:39df%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.15.6', java.version: '15'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 86.0.4240.183, chrome: {chromedriverVersion: 86.0.4240.22 (398b0743353ff..., userDataDir: /var/folders/z6/46cwjtvx2fj...}, goog:chromeOptions: {debuggerAddress: localhost:56802}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: MAC, platformName: MAC, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true}
Session ID: 9837fd96a4efca85f4bcdbf90fea8a77
*** Element info: {Using=css selector, value=.cookie-accept-all}
org.openqa.selenium.NoSuchSessionException: invalid session id
Current dependencies stack:
dependencies {
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
compile group: 'org.seleniumhq.selenium', name: 'selenium-chrome-driver', version: '3.141.5'
compile group: 'io.github.bonigarcia', name: 'webdrivermanager', version: '4.2.2'
compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'
testCompileOnly 'org.projectlombok:lombok:1.18.16'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
}
Upvotes: 2
Views: 1245
Reputation: 8676
So the issue is that the page objects are designed in Singleton way:
public static LoginModal loginModalInstance(WebDriver driver) {
return loginModal == null ? loginModal = new LoginModal(driver) : loginModal;
}
So that once initialized with a driver in first test they remain refering to old driver instance (which has been already closed) in new test.
The solution would be to rework loginModalInstance
and other similar methods so that they re-initialize the fields of existing objects with new driver instance.
Upvotes: 2