Selenium JUnit tests not running org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()? - selenium

I have created a java/selenium/cucumber automation framework with 4 feature files each testing different functional area's.
I can run each of these within Eclipse as feature files and they all run fine.
However I am trying to figure out how I can run them all as a JUnit test so that I can generate the extent reports.
I run the mainRunner class as a Junit test like ..
The first feature runs fine but then the next three do not. A chrome browser is opened for each of these but
the site is not navigated to. The error
'org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?'
is shown in the console logs.
So is this issue to do with how I have set my feature files up to use the startBrowser, initBrowser and closeBrowser methods. Which are
defined in a seperate class 'BrowserInitTearDownStepDefinitions'?
All my feature files look like ..
Feature: Update a Computer in Database
-- left out details
#StartBrowser
Scenario: Start browser session
When I initialize driver
Then open browser
#MyTest4
Scenario Outline: Update a computer
-- left our details
Examples:
-- left out details
#CloseBrowser
Scenario: Close the browser
Then close browser
I have had a look at the other posts related to this message that reference the same error, but can't see a clear cut solution.
As the error would indicate I seem to be quitting the driver but then not reinitialising it for the next test. Although Im not sure why this
would be the case given that each feature file has the #StartBrowser and #CloseBrowser tags which should execute these methods. Below is my BrowserInitTearDownStepDefinitions class.
public class BrowserInitTearDownStepDefinitions {
//Initialises Chrome browser
#When("^I initialize driver$")
public void initializeDriver() {
System.out.println("initializeDriver runs");
System.setProperty("webdriver.chrome.driver","C:\\xxxx\\CucumberAutomationFramework\\src\\test\\java\\cucumberAutomationFramework\\resources\\chromedriver.exe");
WebDriverUtils.setDriver(new ChromeDriver());
}
//Opens Chrome browser and clicks in search input box
#Then("^open browser$")
public void openBrowser() {
System.out.println("Open Browser runs");
WebDriver driver = WebDriverUtils.getDriver();
driver.manage().window().maximize();
driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(60, TimeUnit.SECONDS);
driver.get("https://computer-database.gatling.io/computers");
}
//Closes browser after all scenarios run and deletes cookies
#Then("^close browser$")
public void closeBrowser() {
System.out.println("Close Browser runs");
WebDriver driver = WebDriverUtils.getDriver();
driver.manage().deleteAllCookies();
driver.quit();
driver =null;
}
}
I create a new instance of the webdriver within my stepDefs file with ..
WebDriver driver = WebDriverUtils.getDriver()
The webdriver utils class code is ..
package cucumberAutomationFramework.utilityClasses;
import org.openqa.selenium.WebDriver;
public class WebDriverUtils {
private static WebDriver driver;
public static void setDriver(WebDriver webDdriver) {
if (driver == null) {
driver = webDdriver;
}
}
public static WebDriver getDriver() {
if (driver == null) {
throw new AssertionError("Driver is null. Initialize driver before calling this method.");
}
return driver;
}
}
Any advice would be much appreciated. Thanks.

Related

Selenium Parallel execution

Hey guys i am running parallel operations in headless mode or without headless mode i get the same error, which are the following :
INFO: Using parallel execution mode 'CONCURRENT' set via the 'junit.jupiter.execution.parallel.mode.default' configuration parameter.
stale element reference: element is not attached to the page document
stale element reference error is a WebDriver error that occurs because the referenced web element is no longer attached to the DOM. ... When an element is no longer attached to the DOM, i.e. it has been removed from the document or the document has changed, it is said to be stale
How can i fix this problem?
My test configs
test {
systemProperty("junit.jupiter.execution.parallel.enabled", true)
systemProperty("junit.jupiter.execution.parallel.mode.default", "CONCURRENT")
useJUnitPlatform()
}
and my webdriver initialisation
protected WebDriver driver;
protected String TARGET_URL;
#BeforeEach
public void setUp() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver(new ChromeOptions());
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.manage().window().maximize();
loginToEnvironment();
}
#AfterEach
public void tearDown() {
driver.manage().deleteAllCookies();
driver.close();
}

Kill GeckoDriver by PID Process [Java]

My question is very similar to this question. I launch many instances of WebDriver and some of them don't respond to driver.quit(). As described in this response I am able to kill browser instance by retrieving PID directly from capabilities object via the following code:
Code Block:
import java.io.IOException;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
public class Kill_Firefox_PID {
public static void main(String[] args) throws IOException {
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
Capabilities cap = ((RemoteWebDriver) driver).getCapabilities();
System.out.println("moz:processID value is : "+cap.getCapability("moz:processID"));
Runtime.getRuntime().exec("taskkill /PID "+cap.getCapability("moz:processID"));
}
}
Console Output:
moz:processID value is : 8492
While this works excellently to kill browser itself I still see instances of Geckodriver when I open task manager. As stated in the other thread I am unable to indiscriminately kill all Geckdriver instances via taskkill /f /im geckodriver.exe as there are some instances that are needed.
In short, I want to be able to retrieve PID of Geckodriver via capabilities and destroy those instances of Geckodriver (via PID) in a similar way that we are able to retrieve PID of Firefox WebDriver as outlined in response to this question.
Is this possible?
Thanks!
A new set of GeckoDriver and Firefox Browser are initiated when you invoke:
WebDriver driver = new FirefoxDriver();
You can find a detailed discussion in Is this correct - FirefoxDriver driver = new FirefoxDriver();?
The life span of GeckoDriver / Firefox Browser ceases to exist when you invoke:
driver.quit()
You can find a detailed discussion in PhantomJS web driver stays in memory
Solution
So a generic solution would be, instead of keeping the keeping/preserving the stale instances of geckodriver invoke close() or quit() as per the flow of your test execution which will relieve you from indiscriminately killing all the GeckoDriver instances.
However at the end of your Test Execution if you want to kill all the GeckoDriver instances, you can use the following solution:
public class Killing_GeckoDriver_PID {
public static void main(String[] args) throws IOException {
String line;
String pidInfo ="";
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
Process p =Runtime.getRuntime().exec(System.getenv("windir") +"\\system32\\"+"tasklist.exe");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
pidInfo+=line;
}
input.close();
if(pidInfo.contains("geckodriver.exe"))
{
Runtime.getRuntime().exec("taskkill /F /IM geckodriver.exe");
}
System.out.println("Killed all the instances of GeckoDriver");
}
}
You can find a alternative approach within the discussion Selenium : How to stop geckodriver process impacting PC memory, without calling driver.quit()?

Can selenium test run without using System.setProperty in the code?

I am able to run the selenium test in our project without using System.setProperty. Not sure how it works, we have set the environment Path variable with value "C:\Akash\Drivers" where all the drivers are stored. Can anyone explain how/ this works without setting up chrome path?
public class SeleniumTest {
public static void main(String[] args) throws MalformedURLException {
// TODO Auto-generated method stub
localSettings();
}
public static void localSettings() {
// System.setProperty("webdriver.chrome.driver", "C:\\Akash\\Drivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.google.com");
}
}
Please Refer official explanation given Seleniumhq & Chrome,
How it retrieves and Work with Environment Variables :
WebDriver works with Chrome through the chromedriver binary. You need to have both chromedriver and a version of chrome browser installed. chromedriver needs to be placed somewhere on your system’s path in order for WebDriver to automatically discover it. The Chrome browser itself is discovered by chromedriver in the default installation path. These both can be overridden by environment variables.
Provided by Seleniumhq, Blog Link : Click Here
Chrome Driver Setup Provisions:
Provided by Chrome, Blog Link : Click Here

Execute time every steps in JUnit

I'm stuck on some task over 2 days. I have JUnit test, which will be executed on JMeter, here's the code:
public class LoadTest5 extends TestCase {
private WebDriver driver;
public LoadTest5(){}
public LoadTest5(String testName){
super(testName);
}
#BeforeClass
public void setUp() throws Exception {
super.setUp();
driver = new FirefoxDriver();
driver.get("link"); //just hide the link
}
#Test
public void testTestLoad() throws InterruptedException {
driver.findElement(By.id("loginForm:authLogin")).sendKeys("LoadTest5");
driver.findElement(By.id("loginForm:authPassword")).sendKeys("Abc123");
driver.manage().timeouts().implicitlyWait(60, TimeUnit.MILLISECONDS);
driver.findElement(By.id("loginForm:btnLogin")).click();
driver.manage().timeouts().implicitlyWait(2000, TimeUnit.MILLISECONDS);
driver.findElement(By.xpath(".//*[#id='settingsLink']/a")).click();
driver.manage().timeouts().implicitlyWait(5000, TimeUnit.MILLISECONDS);
driver.findElement(By.xpath("//a[#class='logout']")).click();
System.out.println();
}
#AfterClass
public void tearDown() throws Exception {
super.tearDown();
driver.quit();
}
}
I will run this test in 5 thread in JMeter, and I need to write execute time for all steps. For example Step - Login:
driver.findElement(By.id("loginForm:authLogin")).sendKeys("LoadTest5");
driver.findElement(By.id("loginForm:authPassword")).sendKeys("Abc123");
driver.manage().timeouts().implicitlyWait(60, TimeUnit.MILLISECONDS);
driver.findElement(By.id("loginForm:btnLogin")).click();
Count for how long it will execute and write to .csv, and do it with other steps. I can do it with one test, but if it will be 2 and more I can't work with one .csv file.
How can I do it?
May be the are some way to do it in JMeter, and make a Graph result?
I would suggest to split your steps into separate JUnit Requests like
setUp Thread Group
JUnit Request - Initialize FirefoxDriver(s)
Main Thread Group
JUnit Request - Open Login Page
JUnit Request - Perform Login
JUnit Request - Perform Logout
tearDown Thread Group
Junit Request - Quit Firefox Driver
You can also use WebDriver Sampler plugin which provides seamless integration of JMeter and Selenium, in that case you will be able to modify your code right in JMeter without having to recompile it in case of changes or updates and split your tests in separate samplers in easier way. See The WebDriver Sampler: Your Top 10 Questions Answered for migration and usage tips and tricks.

WebDriver not opening URL

I'm very new to selenium so I'm having trouble spotting the problem with my code. I'm using a webDriver backed selenium object, it starts the driver but never opens the URL and the driver just closes after a few moments. The last time this happened to me it was just because I had left "http" out of the URL. So what's causing it this time?
public void testImages() throws Exception {
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.testsite.com/login");
System.out.println(selenium.getXpathCount("//img"));
}
The setup looks like:
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\User1\\Desktop\\chromedriver_win_16.0.902.0\\chromedriver.exe");
driver = new ChromeDriver();
Thread.sleep(2000);
}
The teardown method just consists of driver.close().
I'm using selenium 2.14 and the testNG Eclipse plug-in.
You might need to do the following
selenium.open("www.testsite.com/login");
Check out this example from the selenium site:
// You may use any WebDriver implementation. Firefox is used here as an example
WebDriver driver = new FirefoxDriver();
// A "base url", used by selenium to resolve relative URLs
String baseUrl = "http://www.google.com";
// Create the Selenium implementation
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
// Perform actions with selenium
selenium.open("http://www.google.com");
selenium.type("name=q", "cheese");
selenium.click("name=btnG");
// Get the underlying WebDriver implementation back. This will refer to the
// same WebDriver instance as the "driver" variable above.
WebDriver driverInstance = ((WebDriverBackedSelenium) selenium).getUnderlyingWebDriver();
//Finally, close the browser. Call stop on the WebDriverBackedSelenium instance
//instead of calling driver.quit(). Otherwise, the JVM will continue running after
//the browser has been closed.
selenium.stop();
link to selenium
You would need to add driver.get(url) like below.
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\User1\\Desktop\\chromedriver_win_16.0.902.0\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://www.testsite.com/login");
}