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