Selenium TestNG tests depending on other methods - java

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.

Related

In Inheritance method the Child class not receiving the URL from the Parent class

This is Parent Class to run the ChromeDriver.
package logInCredit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class LogInPage {
public WebDriver driver ;
public void LogInCredit() {
//Open ChromeDriver
WebDriver driver= new ChromeDriver();
driver.get("https://opensource-demo.orangehrmlive.com/");
driver.manage().window().maximize();
System.out.println(driver);
}
}
This Is Child Class which takes the url from Parent Class
package afterLogIn;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
import logInCredit.LogInPage;
public class NextLogIn extends LogInPage {
#Test
public void DashboardPage() {
System.out.println("driver is " +driver);
//Admin UserName Enter
WebElement AdminUserName =
driver.findElement(By.xpath("//input[#name='txtUsername']"));
AdminUserName.sendKeys("Admin");
//Admin Password Enter
WebElement AdminPassword =
driver.findElement(By.xpath("//input[#name='txtPassword']"));
AdminPassword.sendKeys("admin123");
//click Login
WebElement LogInButton = driver.findElement(By.xpath("//input[#id='btnLogin']"));
LogInButton.click();
WebElement ClickAdmin = driver.findElement(By.xpath("//*[text()='Admin']"));
ClickAdmin.click();
WebElement ClickPIM = driver.findElement(By.xpath("//*[text()='PIM']"));
ClickPIM.click();
}
}
This is my testng.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="After Login Test">
<classes>
<class name="afterLogIn.NextLogIn"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
While running the program I get the Exception
[RemoteTestNG] detected TestNG version 7.4.0
driver is null
FAILED: DashboardPage
java.lang.NullPointerException
at afterLogIn.NextLogIn.DashboardPage(NextLogIn.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
The Webdriver url from the parent class is not passing to the child class. Is their any Issues with my code. When I run the parent class with main method it navigate the browser to the url but when I call from the child class it not giving the same url.
the class member driver is not instantiated, in the method logInCreated() in the parent class you are using another object reference ( not the class member ).
in the LoginPage add a no arg constructor in wich you instntialize driver
public LoginPage(){ driver = new ChromeDriver(); }
and in the method LogInCredit() delete the line WebDriver driver= new ChromeDriver();

TestNG : Test case is ignored

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

TestNG - no tests were found

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>

Can a Parameterized method be called in a TestNG XML Suite?

I have a parameterized method(readConfig_1(String path)) in a class which I need to run before the tests in a TestNG Suite. Is there a way that I can call this method and define the parameter for the same in the TestNG.xml file?
Here's the Parameterized Method, I have written which actually needs a path to where the XML file is stored.
public static void readConfig_1(String configXmlPath)
{
browser = CoreLib.fGetNodeText(configXmlPath, "config",
"browser");
env = CoreLib.fGetNodeText(configXmlPath, "config", "env");
release = CoreLib.fGetNodeText(configXmlPath, "config", "release");
serverName = CoreLib.fGetNodeText(configXmlPath, env,
"serverName");
host = CoreLib.fGetNodeText(configXmlPath, env, "host");
userName = CoreLib.fGetNodeText(configXmlPath, env, "userName");
passWord = CoreLib.fGetNodeText(configXmlPath, env, "passWord");
portNumber = CoreLib.fGetNodeText(configXmlPath, env,
"portNumber");
schema = CoreLib.fGetNodeText(configXmlPath, env, "schema");
url = CoreLib.fGetNodeText(configXmlPath, env, "url");
screenShotForPass=CoreLib.fGetNodeText(configXmlPath, env, "SCreenShotForPass");
screenShotForFail=CoreLib.fGetNodeText(configXmlPath, env, "SCreenShotForFail");
CoreLib.LOGGER.info("****************************************************");
CoreLib.LOGGER.info(" Configuration Details ");
CoreLib.LOGGER.info("****************************************************");
CoreLib.LOGGER.info("Browser ::" + browser);
CoreLib.LOGGER.info("env ::" + env);
CoreLib.LOGGER.info("serverName ::" + serverName);
CoreLib.LOGGER.info("host ::" + host);
CoreLib.LOGGER.info("userName ::" + userName);
CoreLib.LOGGER.info("passWord ::" + passWord);
CoreLib.LOGGER.info("portNumber ::" + portNumber);
CoreLib.LOGGER.info("schema ::" + schema);
CoreLib.LOGGER.info("url::" + url);
CoreLib.LOGGER.info("ScreenSnapShotForPass::"+screenShotForPass );
CoreLib.LOGGER.info("ScreenSnapShotForFail::"+screenShotForFail );
}
In this TestNG Suite seen below, I need to call the above method passing a parameter to it before it can go ahead and run the tests written in the other classes.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Smoke Suite" parallel="false" preserve-order="true">
<listeners>
<listener class-name="com.healthcare.reports.MyListener"></listener>
</listeners>
<test name="XYZ Tests">
<classes>
<class name="com.healthcare.utility.Config">
<methods>
<include name="readConfig_1"></include>
</methods>
</class>
<class name="com.healthcare.businessLib.xyz.AddUserTests" />
</classes>
</test>
</suite>
By this I intend to restrict a TestNG Suite to read a particular Config.XML file which will have it's own values such as Env, URL, browser etc., set before the tests can be executed. Is there a way I can achieve this?
----Added 11/24/2017-----
---- I thought adding the readConfig_1 to a #BeforeClass annotation would resolve the problem. But there's more to it-----
My Listener Class has **#onStart** annotation which needs the config file to be run on the start of the Suite. As you see below my Listener Class has the variables release_1 coming from Config file.
public class MyListener implements ITestListener, ISuiteListener {
// This belongs to ISuiteListener and will execute before the Suite start
ReportLib report=new ReportLib();
#Override
public void onStart(ISuite arg0) {
Config.readConfig_1(configXlsPath);
ExportTestResults export = new ExportTestResults();
export.exportExcelHeader(Config.release_1);
CoreLib.fCreateLogger(Config.release_1);
}
But if I put it in #BeforeClass in a TestClass these variables(Config.release_1) are returning null as they would be running before the test class. So I need the readconfig_1 to run before or with the Listener class and unable to add a parameter to the onStart(ISuite arg0).
Tried a few things by :
Running the readConfig_1() in the TestNG.XML as the first method even before the listener class could be called.
putting a #BeforeClass annotation in the Listener class with readConfig_1() method parameterized in it- hoping that the readConfig would be called before the onStart() is executed.
public class MyListener2 implements ITestListener, ISuiteListener {
ReportLib report=new ReportLib();
#BeforeClass
#Parameters("configXlsPath")
public void beforeSuite(String configXlsPath)
{
Config.readConfig_1(configXlsPath);
System.out.println("In Before Class(Listener_2)"+ Config.release_1);
}
#Override
public void onStart(ISuite arg0) {
ExportTestResults export = new ExportTestResults();
System.out.println("In onStart(Listener_2)"+ Config.release_1);
export.exportExcelHeader(Config.release_1);
CoreLib.fCreateLogger(Config.release_1);
}
}
But none worked.
Is there a way around this now?
Thanks in advance.
Yes, you can do this. Firstly, add #Parameters("configXmlPath") annotation to your test class. configXmlPath parameter must also be defined in testng.xml file like <parameter name = "configXmlPath" value="Whateverthevalueis"/> this. Here is an example.
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class YourTest {
#Test
#Parameters("configXmlPath")
public void test1(String configXmlPath) {
System.out.println("Parameterized value is : " + configXmlPath);
}
}
Then, in your testng.xml define parameter like this:
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name = "Suite1">
<test name = "test1">
<parameter name = "configXmlPath" value="Whateverthevalueis"/>
<classes>
<class name = "YourTest" />
</classes>
</test>
</suite>
In your java method , use #BeforeClass and #Parameters annotation ,
#BeforeClass
#Parameters({"configXlsPath"})
public static void readConfig_1(#Optional("addaDefaultPathValue") String configXlsPath)
In your xml , add a parameter tag after tests tag.
<test name="Purchaser Tests">
<parameter name="configXlsPath" value="target/path/to/xmlFile">
You need to define your Parameterized Method under #BeforeClass annotations and should be inside the test class or inherited from other class. I was also dealing with the same issue and resolved this in the below ways:
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class AddUserTests {
#BeforeClass(alwaysRun = true)
#Parameters("configXmlPath")
public void readConfig_1(String configXmlPath){
System.out.println("File path : "+ configXmlPath);
/*
You can use the configXmlPath value to
your code that goes here
*/
}
#Test
public void test_1(){
//Test Code
}
#Test
public void test_2(){
//Test Code
}
}
You need to define and set your parameter value in the xml file like
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Smoke Suite" parallel="false" preserve-order="true">
<listeners>
<listener class-name="com.healthcare.reports.MyListener"></listener>
</listeners>
<test name="XYZ Tests">
<parameter name="configXmlPath" value="USE_ABSOLUTE_PATH_HERE"/>
<classes>
<class name="com.healthcare.businessLib.xyz.AddUserTests" />
</classes>
</test>
</suite>
Please use the absolute path [i.e,C://Config.XML] of the config file instead of USE_ABSOLUTE_PATH_HERE

Unable to click the link on IE using IEDriver

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.

Categories