Is the #After annotation always executed in Selenium when an exception occurs? - selenium

In the case of an exception occuring; is it necessary to close the driver in a catch block when writing a Selenium test case?
I closed the driver in the tearDown() method which has the #After annotation.

No, you don't need to close/quit the driver in catch block if you have done that in #After annotation.
Here.
All #After methods are guaranteed to run even if a Before or Test
method throws an exception.
taken from following website
http://junit.sourceforge.net/javadoc/org/junit/After.html
as it doesn't matter exception has occurred or not this annotation is going to be executed.
Following example is using TestNG but I think #After annotation of JUnit is same as #AfterMethod of TestNG
In below example, even though test will throw java.lang.ArithmeticException: / by zero the tearDown method will be executed and will close all the browsers.
public class GoogleTest {
WebDriver driver;
#BeforeMethod
public void setup() {
driver = new FirefoxDriver();
}
#AfterMethod
public void tearDown() {
driver.quit();
System.out.println("Closed all the browsers");
}
#Test
public void visitGoogle(){
driver.get("https://google.com");
int a=1/0;
}
}
In the Junit report you will see two thing.
Error: if any exception has occurred it will be reported as error
Failure: if any assertions has failed then it will be reported as Failure
I wouldn't handle the exception until you want to continue the flow. Exception like ElementNotFound or ElementNotVisible of webdriver is better unhandled. It will fail the test and you can see the whole stack trace, which will help you debug the root cause.

#After is nothing to do with selenium. It is an annotation of JUNIT if you are using java. There is no such rule to close driver in tearDown() or specify #After function. While it is good practice to quit driver instance once the testcase done. quit will close all your browser instances and clear memory and resources in machine if another script going to trigger.
Moreover, handling the error is also a good practice. You should handle the errors which can occur during script execution in runtime. example :- I/O operation, file upload etc
Example :-
WebDriver driver=null;
#BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver","D:\\Workspace\\JmeterWebdriverProject\\src\\lib\\chromedriver.exe");
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--start-maximized");
driver = new ChromeDriver(chromeOptions);
}
#AfterMethod
public void tearDown() {
//driver.quit();
System.out.println("Closed all the browsers");
}
#Test
public void visitGoogle(){
driver.get("https://google.com");
try {
int a=1/0;
}
catch(Exception ex){
ex.printStackTrace();
driver.quit();
}
}
Hope it will help you

Small update: there is an option in testNG for annonations i.e. beforetest, aftertest. And that option is #AfterTest(alwaysRun = true)...once this is set then the #AfterTest will always execute even if there was exception in the methods before.

Related

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

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.

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();
}

How to generate a configuration failure in TestNG?

I'm trying to reproduce a particular case from my production environment. In which tests will be skipped after getting a Configuration failure. Is there a simple way to generate a Configuration failure in TestNG run?
I'm just reiterating what was discussed in the above comments for the benefit of other people looking for an answer.
It is very easy to raise configuration failure issue in testng. All you have to do is throw an exception in any #Before method. Note that an exception will prevent the tests from execution. Unless you exclusively mention it.
public class someTest {
#BeforeClass
public beforeClassMethod() throws Exception {
throw new Exception();
// this will cause a configuration failure
}
#Test()
public void someTest() {
// will be skipped
}
}

How Caused by: java.lang.ClassNotFoundException:com.google.common.base.function will be handled in selenium?

Caused by: java.lang.ClassNotFoundException:com.google.common.base.function will be handled in selenium
got this error when running through Webdriver.
public class Logintoaccount {
#Before
public void setUp() throws Exception {
System.setProperty("webdriver.ie.driver", "d:\\IEDriverServer.exe");
WebDriver driver = new InternetExplorerDriver();
}
#Test
public void test() {
//System.setProperty("webdriver.chrome.driver", "d://chromedriver.exe");
}
}
I think you are missing the Selenium standalone server in your build path. Add the required version and you would be good to go...
selenium-server-standalone-version.jar
Add selenium-server-standalone-version.jar file in the project. the issue will be resolved
Use #BeforeTest instead of #Before, since this setup() is going to run at the beginning of the test.
Here is the solution for the problem you are facing:
You have used the Annotation as #Before. Going by the documentation of TestNG you can only use the following Annotations starting with #Before :
#BeforeSuite
#BeforeClass
#BeforeTest
#BeforeGroups
#BeforeMethod
Use the one which suits your test strategy. This will solve your issue. Do remember to import the classes​ from TestNG only.
Let me know if this helps you.

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.