NullPointerException in Selenium WebDriver Instance When Using in TestNG - java

I have created a Selenium test suite using TestNG for my website.
The name of my project is Test My Website. In order to execute my Selenium test script and create a test report, I execute the TestNG.xml file directly from the command prompt. For different modules of my website, I have created different Java classes for different modules and have kept them in one package. The source code of my files is given as follows:
TestNG.xml
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Test My Website">
<test name="My Website Test">
<packages>
<package name="testmywebsite" />
</packages>
</test>
</suite>
TestLogin.java
public class TestLogin {
public static WebDriver driver;
#BeforeTest
public void setup() {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
}
#Test
void loginTest() {
//Code to perform the login test
}
#AfterClass
public void setupWorkHistory() {
TestModule1.driver = driver;
}
}
TestModule1.java
public class TestModule1 {
public static WebDriver driver;
#Test
void module1Test() {
//Code to perform the module 1 test
driver.getTitle();
}
#AfterClass
public void setupModule2() {
TestModule2.driver = driver;
}
}
TestModule2.java
public class TestModule2 {
public static WebDriver driver;
#Test
void module2Test() {
//Code to perform the module 2 test
driver.getTitle();
}
#AfterTest
public void tearDown() {
driver.close();
driver.quit();
}
}
Note that in the first two Java classes I have added the setup<Next Class's name>() method to pass my driver instance.
The problem here is that the driver instance gets successfully passed from TestLogin.java to TestModule1.java. However it throws a NullPointerException in the module2Test() method and hence it shows a failed TestNG report for module2Test() despite creating the setupModule2() method in TestModule1.java and adding the #AfterClass annotation to it.
Can anyone tell me why exactly is this happening here? Replies at the earliest will be highly appreciated. Thank you.

Okay I found a solution to the problem myself.
For that I edited the source code of my TestNG.xml file and my Java class files. They are given as follows:
TestNG.xml
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Test RockON">
<test name="Rockon Test" allow-return-values="true">
<classes>
<class name="testmywebsite.TestLogin" />
<class name="testmywebsite.TestModule1" />
<class name="testmywebsite.TestModule2" />
</classes>
</test>
</suite>
TestLogin.java
public class TestLogin {
public static WebDriver driver;
#BeforeTest
public void setup() {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
}
#Test
void loginTest() {
//Code to perform the login test
}
public static WebDriver getDriver() {
return driver;
}
}
TestModule1.java
public class TestModule1 {
public static WebDriver driver;
#BeforeClass
public void setup() {
driver = TestLogin.getDriver();
}
#Test
void module1Test() {
//Code to perform the module 1 test
}
public static WebDriver getDriver() {
return driver;
}
}
Module2.java
public class TestModule2 {
public static WebDriver driver;
#BeforeClass
public void setup() {
driver = TestModule1.getDriver();
}
#Test
void module2Test() {
//Code to perform the module 2 test
}
public static WebDriver getDriver() {
return driver;
}
}
What I did is called the classes individually from my XML file and added the allow-return-values="true" attribute to my tests, which allows the classes to allow return types. In my Java classes I instantiated my WebDriver instance in every class in a #BeforeClass method. Hence I was able to prevent my WebDriver instance from throwing a NullPointerException.

Related

Can a TestNG cross-browser test be executed with Cucumber runner?

I am working with Selenium Webdriver with Cucumber. My tests work as expected with that combination. In order to achieve cross-browser testing, I added TestNG framework. To verify that my cross-browser test was working good, I ran it with TestNG alone, without Cucumber. It ran perfectly in both Chrome and Firefox browsers.
public class WebTest {
WebDriver driver = null;
BasePageWeb basePage;
public String browser;
#Parameters({ "Browser" })
public WebTest(String browser) {
this.browser = browser;
}
#BeforeClass
public void navigateToUrl() {
switch (browser) {
case "CHROME":
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
break;
case "FF":
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
break;
default:
driver = null;
break;
}
driver.get("https://demosite.executeautomation.com/Login.html");
}
#Test
public void loginToWebApp() {
basePage = new BasePageWeb(driver);
basePage.enterUsername("admin")
.enterPassword("admin")
.clickLoginButton();
driver.quit();
}
}
The testng.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests" thread-count="5">
<test name="Chrome Test">
<parameter name="Browser" value="CHROME"/>
<classes>
<class name="tests.web.WebTest"/>
</classes>
</test>
<test name="Firefox Test">
<parameter name="Browser" value="FF"/>
<classes>
<class name="tests.web.WebTest"/>
</classes>
</test>
</suite>
I needed to integrate the TestNG test with my Cucumber set-up so that I can run the whole test with Cucumber. To do this, I added cucumber-testng dependency to POM and created a Cucumber runner extending the AbstractCucumberTestNG class. I specified the location of my feature file and step definition. The step definition is mapped to the TestNG test.
Cucumber runner:
#CucumberOptions(
plugin = {"pretty", "html:target/surefire-reports/cucumber",
"json:target/surefire-reports/cucumberOriginal.json"},
glue = {"stepdefinitions"},
tags = "#web-1",
features = {"src/test/resources/features/web.feature"})
public class RunCucumberNGTest extends AbstractTestNGCucumberTests {
}
Step definition:
public class WebAppStepDefinitions {
private final WebTest webTest = new WebTest("CHROME"); //create an object of the class holding the testng test. If I change the argument to FF, the test will run only on Firefox
static boolean prevScenarioFailed = false;
#Before
public void setUp() {
if (prevScenarioFailed) {
throw new IllegalStateException("Previous scenario failed!");
}
}
#After()
public void stopExecutionAfterFailure(Scenario scenario) throws Exception {
prevScenarioFailed = scenario.isFailed();
}
#Given("^I have navigated to the web url \"([^\"]*)\"$")
public void navigateToUrl(String url) { test
webTest.navigateToUrl(url); //calling the first method holding the testng
}
#When("^I log into my web account with valid credentials as specicified in (.*) and (.*)$")
public void logintoWebApp(String username, String password) {
webTest.loginToWebApp(username, password); //calling the second method holding the testng
}
}
On running the class, the test got executed only in one browser (Chrome). Somehow, Firefox got lost in the build-up. I suspect that I am calling the parameterised TestNG method wrongly from another class. How do I do the call successfully?
For running TestNG tests with Cucumber you have to define Test Runner classes in testng.xml.
your Test Runner class is RunCucumberNGTest.
So the xml should look like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests" thread-count="5">
<test name="Chrome Test">
<parameter name="Browser" value="CHROME"/>
<classes>
<class name="some.package.name.RunCucumberNGTest"/>
</classes>
</test>
<test name="Firefox Test">
<parameter name="Browser" value="FF"/>
<classes>
<class name="some.package.name.RunCucumberNGTest"/>
</classes>
</test>
</suite>
From this xml I see the next requirements:
Run the same set of tests but with different parameter value.
This should work in parallel, so this should be thread-safe.
1 Introduce TestNG Parameter for Test Runner class
#CucumberOptions(
plugin = {"pretty", "html:target/surefire-reports/cucumber",
"json:target/surefire-reports/cucumberOriginal.json"},
glue = {"stepdefinitions"},
tags = "#web-1",
features = {"src/test/resources/features/web.feature"})
public class RunCucumberNGTest extends AbstractTestNGCucumberTests {
// static thread-safe container to keep the browser value
public final static ThreadLocal<String> BROWSER = new ThreadLocal<>();
#BeforeTest
#Parameters({"Browser"})
public void defineBrowser(String browser) {
//put browser value to thread-safe container
RunCucumberNGTest.BROWSER.set(browser);
System.out.println(browser);
}
}
2 Use the value in Step Definition class
public class WebAppStepDefinitions {
private WebTest webTest;
static boolean prevScenarioFailed = false;
#Before
public void setUp() {
if (prevScenarioFailed) {
throw new IllegalStateException("Previous scenario failed!");
}
//get the browser value for current thread
String browser = RunCucumberNGTest.BROWSER.get();
System.out.println("WebAppStepDefinitions: " + browser);
//create an object of the class holding the testng test. If I change the argument to FF, the test will run only on Firefox
webTest = new WebTest(browser);
}
#After
public void stopExecutionAfterFailure(Scenario scenario) throws Exception {
prevScenarioFailed = scenario.isFailed();
}
#Given("^I have navigated to the web url \"([^\"]*)\"$")
public void navigateToUrl(String url) {
webTest.navigateToUrl(url); //calling the first method holding the testng
}
#When("^I log into my web account with valid credentials as specicified in (.*) and (.*)$")
public void logintoWebApp(String username, String password) {
webTest.loginToWebApp(username, password); //calling the second method holding the testng
}
}
NOTE: All TestNG annotations should be removed from WebTest class, they won't work and not required. WebTest used explicitly by WebAppStepDefinitions class, all the methods invoked explicitly and not by TestNG.
So, based on your initial requirements:
public class WebTest {
WebDriver driver = null;
BasePageWeb basePage;
public String browser;
public WebTest(String browser) {
this.browser = browser;
}
public void navigateToUrl(String url) {
switch (browser) {
case "CHROME":
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
break;
case "FF":
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
break;
default:
driver = null;
break;
}
driver.get(url);
}
public void loginToWebApp(String username, String password) {
basePage = new BasePageWeb(driver);
basePage.enterUsername(username)
.enterPassword(password)
.clickLoginButton();
driver.quit();
}

Selenium with TestNG Script is not working?

Selenium with TestNG Script is not working? Script is not working in testng framework but in a modular framework, it is working fine ?? Here is the code snapshot.
//Script To Register Inside The Application
public class AppTest{
WebDriver driver;
#BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver","F:\\ResourceFiles\\chromedriver_win32\\chromedriver_win32\\chromedriver.exe");
WebDriver driver =new ChromeDriver();
driver.get("http://newtours.demoaut.com/mercurywelcome.php");
driver.manage().window().maximize();
// driver.manage().timeouts().implicitlyWait(8000, TimeUnit.SECONDS);
}
#Test
public void registerApp(){
//driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[2]/td/table/tbody/tr/td[2]/a")).click();
driver.findElement(By.linkText("REGISTER")).click();
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[2]/td[2]/input")).sendKeys("kartikey");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[3]/td[2]/input")).sendKeys("gautam");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[4]/td[2]/input")).sendKeys("7248006980");
driver.findElement(By.xpath("//*[#id=\"userName\"]")).sendKeys("kartikeygautam#gmail.com");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[7]/td[2]/input")).sendKeys("22 Dayal Bagh Colony");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[9]/td[2]/input")).sendKeys("Agra");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[10]/td[2]/input")).sendKeys("UttarPradesh");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[11]/td[2]/input")).sendKeys("282005");
Select fruits = new Select(driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[12]/td[2]/select")));
fruits.selectByVisibleText("INDIA ");
driver.findElement(By.xpath("//*[#id=\"email\"]")).sendKeys("kartikeygautam#gmail.com");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[15]/td[2]/input")).sendKeys("Mummyp#p#123");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[16]/td[2]/input")).sendKeys("Mummyp#p#123");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[16]/td[2]/input")).click();
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[5]/td/form/table/tbody/tr[18]/td/input")).click();
}
#Test
public void loginApp() {
driver.get("http://newtours.demoaut.com/mercurywelcome.php");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[2]/td[3]/form/table/tbody/tr[4]/td/table/tbody/tr[2]/td[2]/input")).sendKeys("kartikeygautam");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[2]/td[3]/form/table/tbody/tr[4]/td/table/tbody/tr[3]/td[2]/input")).sendKeys("Mummyp#p#123");
driver.findElement(By.xpath("/html/body/div/table/tbody/tr/td[2]/table/tbody/tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[2]/td[3]/form/table/tbody/tr[4]/td/table/tbody/tr[4]/td[2]/div/input")).click();
}
#AfterMethod
public void tearDown() {
driver.quit();
}
}
Your #BeforeMethod is not setting a value to the class instance of driver, it's generating a new driver object that only exists in the context of the #BeforeMethod. You need to tweak your #BeforeMethod to be:
#BeforeMethod
public void setup() {
System.setProperty("webdriver.chrome.driver","F:\\ResourceFiles\\chromedriver_win32\\chromedriver_win32\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://newtours.demoaut.com/mercurywelcome.php");
driver.manage().window().maximize();
}

How to run multiple test classes in testng suite with only one web driver instance? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I'm trying to use #beforeSuite and #AfterSuite to run my test in one browser instance. however it run the first the first test class but fail with null pointer exception when it the second class.
Here is my code below:
LaunchBrowser.java class
public class LaunchBrower {
protected WebDriver driver;
public WebDriver getDriver() {
return driver;
}
#Parameters({ "browserType", "appURL" })
#BeforeSuite
public void setUp(#Optional String browsertype, #Optional String appURL) {
System.out.println("Launching google chrome with new profile..");
driver = getBrowserType(browsertype);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.navigate().to(appURL);
}
private WebDriver getBrowserType(String browserType) {
if (driver == null ) {
if (browserType.equalsIgnoreCase("chrome")) {
return new ChromeDriver();
}
else if (browserType.equalsIgnoreCase("InternetExplorer")) {
return new InternetExplorerDriver();
}
}
return driver;
}
#AfterSuite
public void tearDown() {
if (driver != null)
driver.quit();
}
}
LoginPageTest class
public class LoginPageTest extends LaunchBrower {
protected WebDriver driver;
private LoginPage loginpage;
private MyProfile profilepage;
Logger log = Logger.getLogger("Results:");
#BeforeClass(alwaysRun = true)
public void setUp() {
loginpage = PageFactory.initElements(getDriver(), LoginPage.class);
//loginpage = new LoginPage(driver);
//driver=getDriver();
}
#Test(groups = "LoginPage")
public void verifyLogin() throws InterruptedException {
//LoginPage login = new LoginPage(driver);
System.out.println("Sign In functionality details...");
//System.out.println("Sign In functionality details seee...");
Thread.sleep(10000);
//login.enterUserName("11111111");
Assert.assertEquals("11111111",loginpage.enterUserName("11111111"));
log.debug("Correct Username Pass");
//System.out.println("Correct username...");
Assert.assertEquals("fe9245db",loginpage.enterPassword("fe9245db"));
log.debug("Correct Password Pass");
loginpage.clickOnLogin();
log.debug("Login Pass");
}
}
MyProfileTest java class
public class MyProfileTest extends LaunchBrower {
protected WebDriver driver;
private MyProfile profilepage;
#BeforeClass(alwaysRun = true)
public void setUp() {
profilepage = PageFactory.initElements(getDriver(), MyProfile.class);
//driver=getDriver();
}
#Test(groups = "Myprofile")
public void verifyMyprofile() throws InterruptedException {
System.out.println("My profile test...");
//MyProfile profile = new MyProfile(driver);
profilepage.ClickToggleLink();
profilepage.ClickMyProfile();
}
}
The problem lies in your test code. #BeforeSuite is designed in TestNG to be invoked only once per <suite>. You are combining that logic along with inheritance and then relying on the #BeforeSuite method to initialize your WebDriver. So it will do it for the first class in your <suite> by from the second class onwards TestNG is not going to be invoking the #BeforeSuite and thus your second class onwards you start seeing the NullPointerException.
You should instead consider relying on a ISuiteListener implementation as a listener and then wire it into your test execution.
Your tests would now start relying on a webdriver that is created in this manner and then work with it.
Please ensure that you are using TestNG 6.12 or higher (which at this point doesn't exist).
Here's a full fledged example that shows all of this in action.
The base class of my test classes look like below
package com.rationaleemotions.stackoverflow.qn46323434;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.Listeners;
#Listeners(BrowserSpawner.class)
public class MyBaseClass {
protected void launchPage(String url) {
RemoteWebDriver driver = BrowserSpawner.getDriver();
driver.get(url);
System.err.println("Page Title :" + driver.getTitle());
}
}
The test classes that I am using in this example look like below
package com.rationaleemotions.stackoverflow.qn46323434;
import org.testng.annotations.Test;
public class MyFirstTestCase extends MyBaseClass {
#Test
public void testGooglePage() {
launchPage("http://www.google.com");
}
#Test
public void testFaceBookPage() {
launchPage("http://www.facebook.com");
}
}
package com.rationaleemotions.stackoverflow.qn46323434;
import org.testng.annotations.Test;
public class MySecondTestCase extends MyBaseClass {
#Test
public void testHerokkuPage() {
launchPage("https://the-internet.herokuapp.com/");
}
#Test
public void testStackOverFlowPage() {
launchPage("http://stackoverflow.com/");
}
}
The ISuiteListener implementation looks like below
package com.rationaleemotions.stackoverflow.qn46323434;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ISuite;
import org.testng.ISuiteListener;
import org.testng.ITestResult;
import org.testng.Reporter;
public class BrowserSpawner implements ISuiteListener {
private static final String DRIVER = "driver";
#Override
public void onStart(ISuite suite) {
RemoteWebDriver driver;
String browserType = suite.getParameter("browserType");
switch (browserType) {
case "chrome":
driver = new ChromeDriver();
break;
default:
driver = new FirefoxDriver();
}
suite.setAttribute(DRIVER, driver);
}
#Override
public void onFinish(ISuite suite) {
Object driver = suite.getAttribute(DRIVER);
if (driver == null) {
return;
}
if (!(driver instanceof RemoteWebDriver)) {
throw new IllegalStateException("Corrupted WebDriver.");
}
((RemoteWebDriver) driver).quit();
suite.setAttribute(DRIVER, null);
}
public static RemoteWebDriver getDriver() {
ITestResult result = Reporter.getCurrentTestResult();
if (result == null) {
throw new UnsupportedOperationException("Please invoke only from within an #Test method");
}
Object driver = result.getTestContext().getSuite().getAttribute(DRIVER);
if (driver == null) {
throw new IllegalStateException("Unable to find a valid webdriver instance");
}
if (! (driver instanceof RemoteWebDriver)) {
throw new IllegalStateException("Corrupted WebDriver.");
}
return (RemoteWebDriver) driver;
}
}
The suite xml file that I am using looks like below
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="46323434_Suite" parallel="false" verbose="2">
<parameter name="browserType" value="chrome"/>
<test name="46323434_test1">
<classes>
<class name="com.rationaleemotions.stackoverflow.qn46323434.MyFirstTestCase"/>
</classes>
</test>
<test name="46323434_test2">
<classes>
<class name="com.rationaleemotions.stackoverflow.qn46323434.MySecondTestCase"/>
</classes>
</test>
</suite>
When you run this the output would look like below
...
... TestNG 6.12 by Cédric Beust (cedric#beust.com)
...
Starting ChromeDriver 2.32.498537 (cb2f855cbc7b82e20387eaf9a43f6b99b6105061) on port 45973
Only local connections are allowed.
log4j:WARN No appenders could be found for logger (org.apache.http.client.protocol.RequestAddCookies).
log4j:WARN Please initialize the log4j system properly.
Sep 20, 2017 10:36:41 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
Page Title :Facebook – log in or sign up
Page Title :Google
PASSED: testFaceBookPage
PASSED: testGooglePage
===============================================
46323434_test1
Tests run: 2, Failures: 0, Skips: 0
===============================================
Page Title :The Internet
Page Title :Stack Overflow - Where Developers Learn, Share, & Build Careers
PASSED: testHerokkuPage
PASSED: testStackOverFlowPage
===============================================
46323434_test2
Tests run: 2, Failures: 0, Skips: 0
===============================================
===============================================
46323434_Suite
Total tests run: 4, Failures: 0, Skips: 0
===============================================
The most important things to remember here are :
Your tests are no longer going to be starting and cleaning up the browser. This is now going to be done by your ISuiteListener implementation.
Due to the model that is being used (i.e., relying on one browser instance per <suite>) you will never be able to run your tests in parallel. All of your tests should strictly run in sequential manner.
You need to ensure that none of your #Test methods either crash the browser (or) cause the browser instance to be cleaned up (this is applicable when you are dealing with a Grid setup wherein you probably endup leaving the browser idle for sometime causing the node to cleanup the browser from the server side). If you cause any of this, then your tests are going to fail with unexpected results.

Testng in selenium ------suggest which annotations are suits

I have created Project(Page Object Model) in Eclipse like this
Project name
Package 1
src
bin
package 2
src
bin
In package 1 contains, element description and method
In package 2 contains,
BaseScript.java ---------
preconditon
webdriver driver=new FirefoxDriver();
driver.get("url");
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.manage().window().maximize();
LoginPage l=new LoginPage(driver);
l.setusername("");
l.setpassword("");
l.LoginBut();
Postconditons
driver.quit();
I have T1.java,T2.java and converted into.xml(testng.xml) and Run using Testng that file(testng.xml)
I want to execute all testcases at a time with one browser but i've got when i execute testcases it's calls BaseScript.java
Selenium is a tool which controls the browser/website like a user. It simulates a user clicking through the pages. Knowing the functionality of your web application, you can setup your tests. Now run set of test cases together i.e. Test Suite. TestNG gives this capability to manage test execution.
I suggest you to read this simple tutorial to setup TestNG suite of tests.
I want to execute all testcases at a time
Selenium Grid is a part of the Selenium Suite to run tests in parallel. You setup the driver in base classs
public class TestBase {
protected ThreadLocal<RemoteWebDriver> threadDriver = null;
#BeforeMethod
public void setUp() throws MalformedURLException {
threadDriver = new ThreadLocal<RemoteWebDriver>();
DesiredCapabilities dc = new DesiredCapabilities();
FirefoxProfile fp = new FirefoxProfile();
dc.setCapability(FirefoxDriver.PROFILE, fp);
dc.setBrowserName(DesiredCapabilities.firefox().getBrowserName());
threadDriver.set(new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), dc));
}
public WebDriver getDriver() {
return threadDriver.get();
}
#AfterMethod
public void closeBrowser() {
getDriver().quit();
}
}
An example of sample test would be:
public class Test01 extends TestBase {
#Test
public void testLink()throws Exception {
getDriver().get("http://facebook.com");
WebElement textBox = getDriver().findElement(By.xpath("//input[#value='Name']"));
// test goes here
}
}
You can add more tests in similar way as above
public class Test02 extends TestBase {
#Test
public void testLink()throws Exception {
// test goes here
}
}
TestNG Configurations:
testng.xml
<suite name="My Test Suite">
<suite-files>
<suite-file path="./testFiles.xml" />
</suite-files>
testFiles.xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test runs" parallel="tests" thread-count="2">
<test name="T_01">
<classes>
<class name="com.package.name.Test01" ></class>
</classes>
</test>
<test name="T_02">
<classes>
<class name="com.package.name.Test02" ></class>
</classes>
</test>
<!-- more tests -->
</suite>

How to run multiple testcase with One login testcase in selenium WD with TestNG

Hi I have three class files. In first class, only one test case is used for login Gmail account. rest of the classes having only one test case and both are used for navigating Inbox and sent items. I have created testng.xml to run these multiple classes. Now the problem is when first class is being executed, I could be log in Gmail account. But when it comes to second class, I am unable to navigate to Inbox as I did not perform login operation in class 2 and class 3.
So it thrown me an error Null Pointer Exception. I know the reason why I am getting this exception. But I want to perform login action only one time but it should be available to all classes which means When I am going to execute class 2 and class 3, it should not throw error. It should continue from the class 1. How I can achieve this task.
I googled a lot. None of them helped me. Please suggest me any idea if you have. I have tried to extend my class also. I got no result. Please guide me where am I struggling?
Following is my testng.xml
<suite name="MynaTestCase">
<test name="order">
<classes>
<class name="myPackage.Login" />
<class name="myPackage.Inbox" />
<class name="myPackage.SentItems" />
</classes>
</test>
</suite>
Here is the Login Code
#BeforeSuite(alwaysRun = true)
public void setup(){
System.setProperty("webdriver.chrome.driver", "/home/vadmin/workspace/samplepjt/lib/chromedriver");
driver = new ChromeDriver();
baseUrl = "http://www.google.com";
driver.get(baseUrl+"/");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
System.out.println("Before suite executed");
}
#Test
public void LoginTest(){
driver.findElement(By.cssSelector("i.fa.fa-user-secret")).click();
driver.findElement(By.id("user_username")).clear();
driver.findElement(By.id("user_username")).sendKeys(username);
driver.findElement(By.id("user_password")).clear();
driver.findElement(By.id("user_password")).sendKeys(password);
driver.findElement(By.id("signInButton")).click();
}
Here is the Inbox.Java
#Test
public void testcase1()
{
driver.findElement(By.xpath("html/body/div[1]/div[2]/div/div/div/div[1]/div[4]/ul/li[8]/a/div/p")).click();
Assert.assertEquals(driver.findElement(By.xpath("html/body/div[1]/div[2]/div/div/div/div[2]/div/h4")).getText(), "Sections");
driver.findElement(By.name("commit")).click();
driver.findElement(By.xpath(".//*[#id='new_section']/div[3]/input")).submit();
}
The problem is that you defined your WebDriver in the Login class, so the Inbox class won't see it.
To solve it, create an abstract class, which include the BeforeSuite and AfterSuite classes and extend every test class with it.
Abstract class
public class MyAbstractClass
{
public WebDriver driver;
#BeforeSuite
public void beforeSuite() {
//...
this.driver = new ChromeDriver();
//...
}
#AfterSuite
public void afterSuite() {
//...
this.driver.quit();
//...
}
}
A Test Class
public class MyTestClass extends MyAbstractClass
{
#Test
public void myTest() {
this.driver.get("http://google.com");
}
}
You'll want to set #Test(priority = 1) for every test.

Categories