I am using TestNG framework for writing test cases for my Android application. For which I am using Appium testing tool.
For this I have defined following files :
pom.xml file - required for dependencies
One BaseTest.java class
Two child classes which is extended from BaseTest.java
testng.xml file - defines running test classes in it.
For better understanding of my question posting classes & xml files.
This is pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.testing</groupId>
<artifactId>android-appium</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
This is BaseTest.java class
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
public class BaseTest {
#BeforeSuite
public void setUp()
{
}
#AfterSuite
public void tearDown()
{
}
}
This is FirstTest.java class
import io.appium.java_client.MobileBy;
import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import scenarios.BaseTest;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class FirstTest extends BaseTest {
private AndroidDriver<MobileElement> mAndroidDriver;
#BeforeTest
protected void setUpDriver() throws MalformedURLException {
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability("device", "Android");
desiredCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "abfg34e");
desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
desiredCapabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "7.0");
desiredCapabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator1");
desiredCapabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.example.test");
desiredCapabilities.setCapability(MobileCapabilityType.APP,"/home/desktop/app-developer-debug.apk");
desiredCapabilities.setCapability(MobileCapabilityType.NO_RESET, "true");
mAndroidDriver = new AndroidDriver(new URL(Constants.BASE_URL), desiredCapabilities);
System.out.println("setUpDriver() :: time : "+ DateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
}
#Test(groups = "app_screen_group_1", priority = 1)
public void splashScreen_1() throws InterruptedException {
System.out.println("splashScreen_1() :: startTime : "+ DateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
Thread.sleep(7000);
}
#Test(groups = "app_screen_group_1", priority = 2)
public void splashScreen_2() throws InterruptedException {
System.out.println("splashScreen_2() :: startTime : "+ DateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
MobileElement menuElement = mAndroidDriver.findElementByAccessibilityId("More options");
menuElement.click();
Thread.sleep(10);
MobileElement splashElement = mAndroidDriver.findElementByAndroidUIAutomator("new UiSelector().text(\"Splash\")");
splashElement.click();
}
}
This is SecondTest.java class
import io.appium.java_client.MobileBy;
import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import scenarios.BaseTest;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class SecondTest extends BaseTest {
private AndroidDriver<MobileElement> mAndroidDriver;
#Test(groups = "app_screen_group_2", priority = 1)
public void logInScreen_1() throws InterruptedException {
System.out.println("logInScreen_1() :: startTime : "+ DateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
Thread.sleep(7000);
}
#Test(groups = "app_screen_group_2", priority = 2)
public void logInScreen_2() throws InterruptedException {
System.out.println("logInScreen_2() :: startTime : "+ DateFormat.getDateTimeInstance().format(System.currentTimeMillis()));
MobileElement menuElement = mAndroidDriver.findElementByAccessibilityId("More options");
menuElement.click();
Thread.sleep(10);
MobileElement logInElement = mAndroidDriver.findElementByAndroidUIAutomator("new UiSelector().text(\"Log in\")");
logInElement.click();
}
}
This is testng.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="androidapp" group-by-instances="true">
<test name="FirstScenario_1" >
<classes>
<class name="scenarios.FirstTest" ></class>
<class name="scenarios.SecondTest"></class>
</classes>
</test>
<!-- Following scenario runs perfectly if I have each separate class in separate test name. But in above case scenario it is not working properly, it gives Test ignored error for second method of FirstTest.java
<test name="secondScenario_1" >
<classes>
<class name="scenarios.FirstTest" ></class>
</classes>
</test>
<test name="secondScenario_2" >
<classes>
<class name="scenarios.SecondTest" ></class>
</classes>
</test>-->
</suite>
When I run this code using appium tool then on second function splashScreen_2() of FirstTest.java class got error Test ignored & it is not running properly. But when I do uncomment secondScnario_2 in testng.xml file & comment FirstScenario_1 then my test cases run properly (as I mention in comment also) & android app executes each function properly one by one.
But I want to do execute all classes in <test> </test> functions in testng.xml.
If I use secondScnario_2 in testng.xml file then I need to give separate test name for each scenario. And I want to use only one test name. So here when I use FirstScenario_1 in testng.xml file, Why is their an error of test ignored ocurring here?
Based on what you have described in comments , I think you want to run everything in order by defining all classes in one test. Then you should remove priorities and groups and run it with this xml with preserve-order="true" . This should run test in the order they are defined in xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="androidapp" >
<test name="FirstScenario_1" preserve-order="true">
<classes>
<class name="scenarios.FirstTest" >
<methods>
<include name="setUpDriver" />
<include name="splashScreen_1" />
<include name="splashScreen_2" />
</methods>
</class>
<class name="scenarios.SecondTest">
<methods>
<include name="logInScreen_1" />
<include name="logInScreen_2" />
</methods>
</class>
</classes>
</test>
</suite>
You can also use #dependsOnMethods to run methods in the order you want . Have a look at this . The ordering described there should also help you to resolve this
Related
I have a problem with my code. I want to test some elements on a website but after run the tests, TestNG throws the error: "No tests were found".
I have already tried to create a new testng.xml but it doesn't work.
package tests;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.testng.Assert;
import org.testng.annotations.*;
import pages.LoginToAutomationAccount;
public class TestsOnLogin {
WebDriver driver;
// #FindBy(css = "a[class='login'][rel='nofollow']")
// WebElement signInButton;
//
public TestsOnLogin(WebDriver driver){
this.driver=driver;
//PageFactory.initElements(driver, this);
}
LoginToAutomationAccount account;
#BeforeSuite
public void setUp() {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Gabriel\\Downloads\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://automationpractice.com/index.php");
}
#Test
public void test_HomePageLogin() {
//Locate Sign-In button and press it to start the adventure
driver.findElement(By.cssSelector("a[class='login'][rel='nofollow']")).click();
//completion for object -account-
account = new LoginToAutomationAccount(driver);
//login to website account
account.loginAutomationPage("gabriel.noki9#gmail.com", "capptain3");
//verify if it is logged in
String textConfirmation = account.getConfirmationLogin();
Assert.assertTrue(textConfirmation.contains("My account"));
}
#AfterSuite
public void downPage(){
driver.quit();
}
}
TestNG file - I tried to modify the link but it doesn't work
<?xml version="1.0" encoding ="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="LoginToAutomationAccount">
<test name="testngTest">
<packages>
<package name="tests" />
</packages>
</test>
</suite>
Trying to get a driver factory set up for a framework I am building as a learning tool. However I am struggling to get parallel execution of the test classes in testng.
I am using the surefire plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<properties>
<suiteXmlFiles>
<suiteXmlFile>src/main/resources/master.xml</suiteXmlFile>
</suiteXmlFiles>
</properties>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
The version of testng I am using is:
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
<scope>test</scope>
</dependency>
and the master.xml is as follows:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test suite" parallel="classes" thread-count="2">
<test name="Test 1">
<classes>
<class name="testsuite.TestCase1"/>
<class name="testsuite.TestCase2"/>
</classes>
</test>
</suite>
I have simplified the driver factory for the purposes of posting here:
public class DriverFactory
{
//protected WebDriver driver;
private DriverFactory()
{
//Do-nothing..Do not allow to initializethis class from outside
}
private static DriverFactory instance = new DriverFactory();
public static DriverFactory getInstance()
{
return instance;
}
ThreadLocal<WebDriver> driver = new ThreadLocal<WebDriver>() // thread local driver object for webdriver
{
#Override
protected WebDriver initialValue()
{
System.setProperty("webdriver.chrome.driver",
"src/main/resources/chromedriver.exe");
return new ChromeDriver(); // can be replaced with other browser drivers
}
};
public WebDriver getDriver() // call this method to get the driver object and launch the browser
{
return driver.get();
}
public void removeDriver() // Quits the driver and closes the browser
{
driver.get().quit();
driver.remove();
}
}
Using the following mvn command to run:
mvn clean test
I know this is going to be something stupid on my part having read almost every tutorial, blog post and document relating to this I cad find.
Any assistance even just pointing me off in the right direction is greatly appreciated.
TestNG allows you to run your tests in parallel, including JUnit tests. To do this, you must set the parallel parameter, and may change the threadCount parameter if the default of 5 is not sufficient. You have to set configuration parameters:
<configuration>
<parallel>methods</parallel>
<threadCount>10</threadCount>
</configuration>
For you:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<parallel>methods</parallel>
<threadCount>10</threadCount>
<properties>
<suiteXmlFiles>
<suiteXmlFile>src/main/resources/master.xml</suiteXmlFile>
</suiteXmlFiles>
</properties>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
UPDATE
try the following
<suite name="Parallel test suite" parallel="classes" thread-count="2">
<test name="Test 1">
<classes>
<class name="testsuite.TestCase1"/>
</classes>
</test>
<test name="Test 2">
<classes>
<class name="testsuite.TestCase2"/>
</classes>
</test>
I resolved it myself all the suggestions made were correct and the logic I posted was originally correct as well.
However, the test cases themselves were not.
public class TestCase1 {
LandingPage page = new LandingPage();
#BeforeMethod
public void beforeMethod() throws Exception {
page.navigate();
}
#Test (priority = 1, description="SS1 Verify the login section")
#Description ("Verify that user mngr116116 can logon to the system")
public void login()
{
System.out.println("Test Case One in " + getClass().getSimpleName()
+ " with Thread Id:- " + Thread.currentThread().getId());
page.enterUser("mngr116116");
page.enterPass("ytUhUdA");
page.submitBtn();
}
#AfterMethod
public void validate(){
Assert.assertEquals(LandingPage.getExpectedPageTitle(),
page.getObservedPageTitle());
}
}
This was causing the issue replace it with:
public class TestCase1 {
LandingPage page;
#BeforeMethod
public void beforeMethod() throws Exception {
page = new LandingPage();
page.navigate();
}
#Test (priority = 1, description="SS1 Verify the login section")
#Description ("Verify that user mngr116116 can logon to the system")
public void login()
{
page = new LandingPage();
System.out.println("Test Case One in " + getClass().getSimpleName()
+ " with Thread Id:- " + Thread.currentThread().getId());
page.enterUser("mngr116116");
page.enterPass("ytUhUdA");
page.submitBtn();
}
#AfterMethod
public void validate(){
page = new LandingPage();
Assert.assertEquals(LandingPage.getExpectedPageTitle(),
page.getObservedPageTitle());
}
}
And I am in business.
Thanks for the help
Prerequisites
The flow of most sites looks something like this:
where "dashboard" is where all the fun site-specific business logic takes place.
What's the problem?
I'm trying to use Selenium WebDriver and TestNG to test such a site. My code base thus far is something like:
TestNG.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<!-- Root tag for TestNG.xml will always be suite. The name can be whatever you want -->
<suite name="MyCustomSuite">
<test name="MyFirstTest">
<classes>
<class name="com.mikewarren.testsuites.MercuryToursTest"></class>
<class name="com.mikewarren.testsuites.MercuryLogin"></class>
<!-- You can have the class tag for multiple classes of unique name -->
</classes>
</test>
</suite>
TestNGGroups.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<!-- Root tag for TestNG.xml will always be suite. The name can be whatever you want -->
<suite name="MySmokeTestSuite">
<test name="MyFirstTest">
<groups>
<run>
<exclude name="regression"></exclude>
<include name="smoke"></include>
</run>
</groups>
<classes>
<class name="com.mikewarren.testsuites.MercuryLogin">
<methods>
<include name="methodName"></include>
<!-- you can also include or exclude methods -->
</methods>
</class>
<!-- You can have the class tag for multiple classes of unique name -->
</classes>
</test>
</suite>
MercuryToursTest.java
package com.mikewarren.testsuites;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
public class MercuryToursTest {
protected static WebDriver driver;
protected String url = "http://newtours.demoaut.com";
#BeforeTest
public void beforeTest()
{
System.setProperty("webdriver.chrome.driver", "Drivers/chromedriver.exe" );
driver = new ChromeDriver();
driver.get(url);
// wait a second
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
}
#AfterTest
public void afterTest()
{
if (driver != null)
driver.quit();
}
}
MercuryLogin.java
package com.mikewarren.testsuites;
import java.io.File;
import java.io.FileInputStream;
import java.util.concurrent.TimeUnit;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.mikewarren.pages.MercuryLoginFactory;
public class MercuryLogin extends MercuryToursTest {
#Test(priority=0, groups={"smoke"})
public void validateLandingPage() {
Assert.assertEquals(driver.getTitle(), "Welcome: Mercury Tours");
}
#Test(dependsOnMethods="validateLandingPage",
priority=2,
groups={"regression", "somethingElse"},
dataProvider="provideAccountDetailsDynamic")
// #BeforeTest(groups = {"loginFirst"})
public void loginToMercury(String username, String password)
{
MercuryLoginFactory mlf = new MercuryLoginFactory(driver);
mlf.driverLogIntoMercury(username, password);
driver.findElement(By.xpath("//a[contains(text(), 'Home')]")).click();
}
#DataProvider
public Object[][] provideAccountDetailsDynamic() throws Exception {
File file = new File("src/test/resources/mercuryData.xlsx");
FileInputStream fis = new FileInputStream(file);
Workbook workbook = new XSSFWorkbook(fis);
Sheet sheet = workbook.getSheet("sheet1");
int rowCount = sheet.getLastRowNum() - sheet.getFirstRowNum();
Object[][] data = new Object[rowCount][2];
/*
* Data driven framework example.
* • This is a design patern for test automation where you develop the tests in a manner where they will run
* based on provided data. In this case, a tester could have 3 rows data, warranting the test to run 3
* separate times with the given values.
* This allows for configurable automation tests at the hands of a non-developer.
*/
for (int i = 1; i <= rowCount; i++)
{
Row row = sheet.getRow(i);
data[i-1] = new Object[] {
row.getCell(0).getStringCellValue(),
row.getCell(1).getStringCellValue()
};
}
return data;
}
}
What I tried thus far
Whenever I hit "Run" on MercuryLogin.java, it's all good, but as soon as I try to un-comment the #BeforeTest(groups = {"loginFirst"}) annotation on MercuryLogin.loginToMercury() my tests fail horribly. Namely, it tells me that method is expecting two parameters but only gets 0 in the #Configuration annotation.
Failing this, I did the following:
I added MercuryLogin.loginToMercury() to loginFirst group. Then, keeping consistent with the style of the rest of my code base, created MercuryToursTestLoginFirst.java :
package com.mikewarren.testsuites;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class MercuryToursTestLoginFirst extends MercuryToursTest {
#BeforeClass(dependsOnGroups = "loginFirst")
public void init()
{
}
#Test
public void test()
{
System.out.println("mock test");
}
}
test() works, but it's the only test that actually runs. No login is happening, even though the class invokes it! How to make sure MercuryToursTestLoginFirst actually logs in, and using the data provider?
I guess you are using code from tutorial site?
I think you misunderstood the concept of #beforeTest.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
You don't combine both tags in 1 (#Test + #BeforeTest). It will not make any sense doing so. You are telling Testng to run this method before others test. #BeforeTest is usually use for config like you did with driver.exe. Leave your #Test for testing purpose only.
So now what were trying to accomplish with #BeforeTest? Perhaps I am misunderstanding.
I have created 2 separate classes to test a webpage. But, unfortunately when I add them both to the testing.xml, only one of them execute and the other doesn't. The browsers open in parallel even after setting them to preserve-order="true" parallel="false" in the XML. I'm confused as to where I'm doing it wrong.
This is my XML file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" preserve-order="true" parallel="false">
<test name="Test">
<classes>
<class name="TestServiceNow.loginOne"/>
<class name="TestServiceNow.loginTwo"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
loginOne is as follows:
package TestServiceNow;
import org.testng.annotations.Test;
import ServiceNow.login;
public class loginOne extends loginTest{
#Test
public void test_Login(){
//Create Login Page object
objLogin = new login(driver);
//login to application
objLogin.loginGurukula("admin", "admin");
}
}
loginTwo is as follows:
import org.testng.annotations.Test;
import ServiceNow.login;
public class loginTwo extends loginTest{
#Test
public void test_Login_Fail(){
//Create Login Page object
objLogin = new login(driver);
//login to application
objLogin.loginGurukula("admin", "admin1");
}
}
The base class is as follows:
public class loginTest {
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
File file = new File("C:/Users/gattu_000/Documents/selenium-java-3.0.0-beta2/chromedriver_win32/chromedriver.exe");
WebDriver driver;
login objLogin;
#BeforeClass
public void a() {
driver = new ChromeDriver(capabilities);
capabilities.setCapability("marionette", true);
System.setProperty("webdriver.chrome.driver", file.getAbsolutePath());
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
System.out.println("Before class called");
}
#BeforeTest
public void setup(){
System.out.println("Before test called");
driver.get("http://localhost:8080/#/login");
}
#AfterTest
public void close() {
System.out.println("After test called");
}
#AfterClass
public void b() {
System.out.println("After class called");
driver.close();
}
}
The results look like
After the Edit
You are extending loginTest by both loginOne and loginTwo. But in loginTest you initialized your driver. That's why two browser are opening. To get around this issue, you can initialize your driver inside a setup method like #BeforeTest or #BeforeSuite. As an example here's a code snippet -
#BeforeSuite
public void a() {
driver = new ChromeDriver(capabilities);
System.out.println("Before suite called");
}
Do other things as usual like before except the initialization part.
Edit
I missed something. You are closing your driver at the after test method. To run your tests properly remove the driver.close() from your after test method and place it to aftereSuite section.
The XML is supposed to be like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" preserve-order="true">
<test name="Test">
<classes>
<class name="TestServiceNow.loginOne"/>
</classes>
</test> <!-- Test -->
<test name="Test1">
<classes>
<class name="TestServiceNow.loginTwo"/>
</classes>
</test>
</suite> <!-- Suite -->
To launch the browser twice, we need to have 2 separate tests. (Possibly, this may be one of the solutions out of many)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Selenium Test Suite">
<test name="Selenium Test Suite">
<classes>
<class name="packagename.classname1"/>
<class name="packagename.classname1"/>
</classes>
</test>
</suite>
Which is proper. If you are getting null point don't use driver in all the class. because of that only you are getting null pointer i guess.
The code I am using is shown below.
MultiBrowser
package com;
import java.io.File;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class MultiBrowser {
public WebDriver driver;
// Passing Browser parameter from TestNG xml
#Parameters("browser")
#BeforeClass
public void beforeTest(String browser) {
// If the browser is Firefox, then do this
if(browser.equalsIgnoreCase("firefox")) {
driver = new FirefoxDriver();
}else if (browser.equalsIgnoreCase("ie")) {
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
File fil = new File("C:\\IEDriver\\IEDriverServer.exe");
System.setProperty("webdriver.ie.driver", fil.getAbsolutePath());
driver = new InternetExplorerDriver(capabilities);
}
driver.get("http://www.store.demoqa.com");
}
#Test
public void login() throws InterruptedException{
driver.findElement(By.xpath(".//*[#id='account']/a")).click();
driver.findElement(By.id("log")).sendKeys("testuser_1");
driver.findElement(By.id("pwd")).sendKeys("Test#123");
driver.findElement(By.id("login")).click();
}
#AfterClass
public void afterTest(){
driver.quit();
}
}
TestNG.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="none">
<test name="FirefoxTest">
<parameter name="browser" value="firefox" />
<classes>
<class name="com.MultiBrowser" />
</classes>
</test>
<test name="IETest">
<parameter name="browser" value="ie" />
<classes>
<class name="com.MultiBrowser" />
</classes>
</test>
</suite>
It works fine when I use Firefox but I get the below issue when I run the same code on IE
Exception :
Unable to find element with xpath == .//*[#id='account']/a (WARNING: The server did not provide any stacktrace information)
It needs to set Security level in all zones. To do that follow the steps below:
1.Open IE
2.Go to Tools -> Internet Options -> Security
3.All check boxes in Security should be enabled.