TestNG #Factory with #Dataprovider - selenium

So, I`m trying to make my testsuite run each test case for multiple credentials.
Hence, I defined a Data provider which would provide #Factory the credentials to run the test multiple times against each credential.
My code is the following:
package TestSuite.TP_LogOut;
import org.testng.Reporter;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.AfterTest;
import org.testng.annotations.Test;
import Repository.URLs;
import SeLib.CompareURL;
import SeLib.LogIn;
import SeLib.WaitAndClick;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class TC_LogOut{
#BeforeTest
public void beforeTest() throws InterruptedException{
Reporter.log("The test has just begun.");
}
private WebDriver driver;
private String username;
private String password;
#Factory (dataProvider="credentials")
public setter(String username, String password){
this.username=username;
this.password = password;
System.out.println("Credentials "+username+" "+password);
}
#DataProvider
public static Object[][] credentials() {
return new Object[][] { { "id1", "pass1" },
{ "id2", "pass2" } };
}
#Test
public void TC_LogIn() throws Exception{
// use username, password here:
LogIn.Execute(driver, username, password);
}
}
For some reason, #Factory does not admit a non-return type like in several examples that I saw, and points me out that it should be a void type function.
Is there any apparent solution which does not imply #Factory to create multiple test case instances?
If there isn`t, how should the return type be?
Thank you ...
EDIT: Since I am calling the log-in function inside the test case, by passing the driver to the LogIn.Execute method, I thought that it would be a great idea just for LogIn to handle running the multiple Test Cases and then it would just make it simpler, not having to maintain the #Factory and #DataProvider in each Test Case. But this would be like an incorrect programming setup, wouldn`t it be?

The best solution was just to use #DataProvider without #Factory, for the method, such as:
#DataProvider
public static Object[][] credentials() {
return new Object[][] { { "id1", "pass1" },
{ "id2", "pass2" } };
}
#Test
public void TC_LogIn(String username, String password) throws Exception{

Related

Getting NullPointerException when trying to access Selenium Webdriver instance in below scenario.

I am trying to create a framework where I can run my test cases(test tags in xml file) in parallel in different browsers. I have tried using all combinations of testNG annotations but after reading a blog came to know that this can only be achieved by using testNg listners. I am using ThreadLocal to keep my driver thread-safe. I am getting null pointer exception when trying to access Webdriver in my test cases class in line LocalDriverManager.getDriver().get(url);
This is LocalBrowserFactory.Class
package BrowserFactory;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import DataProvider.ConfigDataProvider;
public class LocalDriverFactory {
public static WebDriver createInstance(String browserName) {
WebDriver driver = null;
ConfigDataProvider config=new ConfigDataProvider();
if (browserName.toLowerCase().contains("firefox")) {
System.setProperty("webdriver.gecko.driver", config.getgeckoPath());
driver = new FirefoxDriver();
}
if (browserName.toLowerCase().contains("internet")) {
driver = new InternetExplorerDriver();
}
if (browserName.toLowerCase().contains("chrome")) {
System.setProperty("webdriver.chrome.driver", config.getchromePath());
driver = new ChromeDriver();
}
driver.manage().window().maximize();
return driver;
}
}
This is my LocalDriverManager.class
package BrowserFactory;
import org.openqa.selenium.WebDriver;
public class LocalDriverManager {
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
public static WebDriver getDriver() {
return webDriver.get();
}
public static void setWebDriver(WebDriver driver) {
webDriver.set(driver);
}
}
This is my ConfigPropertyReader.class
package DataProvider;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
public class ConfigDataProvider {
static Properties p;
public ConfigDataProvider()
{
File f =new File("C:/Eclipse/parallelframework/configuration/config.properties");
try {
FileInputStream fis = new FileInputStream(f);
p=new Properties();
p.load(fis);
}
catch (Exception e)
{
System.out.println("Custom Exception- cannot load properties file"+e.getMessage());
}
}
public String getvalue(String key)
{
return p.getProperty(key);
}
public String getUrl()
{
return p.getProperty("url");
}
public String getchromePath()
{
return p.getProperty("chromepath");
}
public String getgeckoPath()
{
return p.getProperty("firefoxpath");
}
public String getIEPath()
{
return System.getProperty("User.dir")+p.getProperty("IEPath");
}
}
This is WebDriverListner.class
package Listners;
import org.openqa.selenium.WebDriver;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
import BrowserFactory.LocalDriverFactory;
import BrowserFactory.LocalDriverManager;
public class WebDriverListner implements IInvokedMethodListener {
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
System.out.println(browserName);
WebDriver driver = LocalDriverFactory.createInstance(browserName);
LocalDriverManager.setWebDriver(driver);
System.out.println("Driver Set");
}
}
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
WebDriver driver = LocalDriverManager.getDriver();
if (driver != null) {
driver.quit();
}
}
}
}
This is my sample testcase.class
package tests;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
import BrowserFactory.LocalDriverManager;
public class sampleTest {
#Test
public void testMethod1() {
invokeBrowser("http://www.ndtv.com");
}
#Test
public void testMethod2() {
invokeBrowser("http://www.facebook.com");
}
private void invokeBrowser(String url) {
LocalDriverManager.getDriver().get(url);
}
}
Your Listener code is messed up. You basically have the beforeInvocation and afterInvocation in the wrong order.
Here's how it should have looked like
import org.openqa.selenium.WebDriver;
import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;
public class WebDriverListener implements IInvokedMethodListener {
#Override
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
String browserName = method.getTestMethod().getXmlTest().getLocalParameters().get("browserName");
WebDriver driver = LocalDriverFactory.createInstance(browserName);
LocalDriverManager.setWebDriver(driver);
}
}
#Override
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
if (method.isTestMethod()) {
WebDriver driver = LocalDriverManager.getDriver();
if (driver != null) {
driver.quit();
}
}
}
}
You basically would setup the webdriver into the thread local variable (push the webdriver instance into the thread local variable's context) from within the beforeInvocation and then within your afterInvocation method, you would pop it out and clean up the webdriver instance (by calling quit() ). In your case, your code is doing the opposite.
For more details you can refer to my blog post here.

Null pointer exception in Java while calling the library

Now i modified the code but still i am getting Null Pointer Exception
Below is my modified code
enter code here
package lib;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.BeforeMethod;
//#SuppressWarnings("unused")
public class Login {
WebDriver driver;
#BeforeMethod
void Initalisation()
{
System.setProperty("webdriver.ie.driver", "C:\\Eclipse\\IEDriverServer.exe");
DesiredCapabilities capability=new DesiredCapabilities();
capability.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
InternetExplorerDriver driver=new InternetExplorerDriver(capability);
driver.get("http://segotn11540.rds.volvo.com/vss_connect_testr1/Login/Login.aspx");
}
public Login(String UserName,String BrandName)
{
driver.findElement(By.xpath("//input[#name='UserNameInputText']")).sendKeys(UserName);
driver.findElement(By.xpath("//input[#name='Brand']")).sendKeys(BrandName);
driver.findElement(By.xpath("//input[#name='CmdLogin']")).click();
String Title=driver.getTitle();
if(!Title.contains("VSS 4.0"))
{
System.out.println(UserName+""+"does not exists");
driver.quit();
}
CheckForCancel();
}
private void CheckForCancel() {
if(!driver.findElements(By.id("Cancel")).isEmpty())
{
driver.findElement(By.id("Cancel")).click();
}
}
}
Now I will create the main Java file
Blockquote
This will initalise the login with the parameters supplied
Import Login library
public class MessageBoard {
public static void main(String[] args)
{
Login login=new Login("TYP40FI","Volvo");
}
}
What is wrong in above code
Try to initialize the driver variable as
WebDriver driver = new WebDriver();
public Login(String UserName,String BrandName)
{
//Add this line in your code as you are trying in IE
driver = new InternetExplorerDriver();
driver.findElement(By.xpath("//input[#name='UserNameInputText']")).sendKeys(UserName);
driver.findElement(By.xpath("//input[#name='Brand']")).sendKeys(BrandName);
driver.findElement(By.xpath("//input[#name='CmdLogin']")).click();
String Title=driver.getTitle();
if(!Title.contains("VSS 4.0"))
{
System.out.println(UserName+""+"does not exists");
driver.quit();
}
CheckForCancel();
}
Debug and check: Is Initalisation() being called in the beginning?
Usually #BeforeMethod is called before test starts, so where is your #Test function. (syntax could be wrong)
If you don't really care about #Test property, that means your Main function needs to call Initalisation() before calling Login(...), otherwise the driver is not set yet (aka Null)

can someone teach me how to use property file for a simple login application

can someone help me with using property file for a sample login application? this helps in achieving me for another big automation.
I have given objects in objects.propreties
in main java class how shall i proceed with?
package valuescompare;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class practice {
public static FileInputStream fis;
public static String propertyfilepath="E:\\Ashik\\wkspSelenium\\valuescompare\\src\\valuescompare\\object.properties";
public static String getProperty(String key) throws IOException, FileNotFoundException{
fis=new FileInputStream(propertyfilepath);
Properties prop=new Properties();
prop.load(fis);
return prop.getProperty(key);
}
static WebDriver driver=new FirefoxDriver();
public static void openBrowser() throws FileNotFoundException, IOException {
//public WebDriver driver;
driver.get(getProperty("url"));
//maximizes the window
driver.manage().window().maximize();
Wait(1000);
}
public static void login() throws FileNotFoundException, IOException{
driver.findElement(By.xpath(getProperty("uidxpath"))).sendKeys(getProperty("uid"));
driver.findElement(By.xpath(getProperty("pwdxpath"))).sendKeys(getProperty("pwd"));
driver.findElement(By.xpath(getProperty("submit"))).click();
Wait(5000);
}
public static void main(String[] args) throws FileNotFoundException, IOException {
// TODO Auto-generated method stub
/*practice prac=new practice();
prac.openBrowser();
prac.login(); */
openBrowser();
login();
}
public static void Wait(int time){
try {
Thread.sleep(time);
} catch (Exception e) {
// TODO: handle exception
}
}
}
Say you create a 'config.properties' named file somewhat like this :
userName=admin
password=admin
and say you are using Java as your programming language, then you have to use it in this manner:
Properties properties = new Properties();
properties.load(new FileInputStream("Config.properties"));
String uName = properties.getProperty("userName");
String pwd = properties.getProperty("password");
Now you have got the values fetched from properties file, use it wherever required.
For more info you may refer this link: http://www.mkyong.com/java/java-properties-file-examples/

Wrong test executed first in Selenium TestNG

In the below script I want to run the Test 'Login' first and then the 'CreateCompany'. But whenever I try to run the script always the control goes to the 'CreateCompany' test at first. And since the user is not already logged in the script execution fails. Please someone tell me what is wrong with the script below.
package MyPackage;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import MyPackage.PageObjects.CompanyListing;
import MyPackage.PageObjects.LoginPage;
public class SetUpCompany {
public static WebDriver driver;
public String BaseURL=LoginPage.BaseURL();
#BeforeClass
public static void setup() {
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
//public static WebDriver driver = new FirefoxDriver();
#Test(dataProvider="UserData")
void Login(String username, String password, String usertype){
//dr.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
if(usertype.equals("SuperAdmin")){
String LoginURL=BaseURL+"/Manage";
driver.get(LoginURL);
LoginPage.UsernameBox(driver).sendKeys(username);
LoginPage.PasswordBox(driver).sendKeys(password);
LoginPage.LoginButton(driver).click();
//System.out.println("Hello Super admin!");
}
}
#Test(dataProvider="CompanyData")
void CreateCompany(String FrstNm, String LastNm, String CmpnyNm, String Email, String Phone, String Cell, String Web){
System.out.println("I'm here");
String ManageCompanyURL=BaseURL+"/Manage/Company";
driver.get(ManageCompanyURL);
CompanyListing.AddCmpnyBtn(driver).click();
}
#DataProvider(name="UserData")
public Object[][] loginData() {
Object[][] LoginArray = DataReader.getExcelData("E:/DataBase.xls","LoginData");
return LoginArray;
}
#DataProvider(name="CompanyData")
public Object[][] CompanyInfo() {
Object[][] CompanyArray = DataReader.getExcelData("E:/DataBase.xls","CompanyInfo");
return CompanyArray;
}
#AfterClass
public static void teardown() {
driver.close();
driver.quit();
}
}
What you have is dependent tests where CreateCompany is dependent upon login test.
You should be using dependsOnMethods. Read more here
Try writing priorities in your #Test annotations in TestNG to set the execution sequence. Here's how to do it -
#Test(priority=1, dataProvider="UserData")
void Login(String username, String password, String usertype){
//Your login code
}
#Test(priority=2, dataProvider="CompanyData")
void CreateCompany(String FrstNm, String LastNm, String CmpnyNm, String Email, String Phone, String Cell, String Web){
//Your CreateCompany code
}
More info on priorities in TestNG. Hope this helps.

TestNG + Selenium woes. noClassDef error, TestNG based selenium test

I've followed a lot of the guides and forum posts online but haven't had any luck getting this to work inside TestNG. It's a selenium grid based test, programmed in eclipse.
Had trouble, so used the libraries listed in the suggestion of this forum post: http://clearspace.openqa.org/message/66867
I am trying to run the suite in the testNG test plugin for eclipse (org.testng.eclipse). Also tried running the jar from command line through selenium grid to no avail.
Since I'm not a java developer, to be honest I'm not entirely sure what to look for. I've some familiarity with Java thanks to the Processing environment, but I've kind of been thrown into java/eclipse for this task and am at a bit of a loss. Anyway, any help is appreciated and thank you in advance.
Here's my code:
suite.java:
package seleniumRC;
//import com.thoughtworks.selenium.*;
//import junit.framework.*;
//import java.util.regex.Pattern;
//import static org.testng.AssertJUnit.assertTrue;
//import org.testng.annotations.AfterMethod;
//import org.testng.annotations.BeforeMethod;
//import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class suite extends Testcase1 {
#Test(groups = {"example", "firefox", "default"}, description = "test1")
public void user1() throws Throwable {
testCase1();
}
#Test(groups = {"example", "firefox", "default"}, description = "test2")
public void user2() throws Throwable {
testCase1();
}
}
The actual test case
package seleniumRC;
//import com.thoughtworks.selenium.*;
//import org.testng.annotations.*;
//import static org.testng.Assert.*;
//import com.thoughtworks.selenium.grid.demo.*;
//import junit.framework.*;
//import com.ibm.icu.*;
//import java.util.regex.Pattern;
//import static org.testng.AssertJUnit.assertTrue;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
public class Testcase1 extends SeleneseTestNgHelper {
private static int $itter = 10;
public static void main(String args[]) {
//junit.textui.TestRunner.run(Suite());
}
//public static Test Suite() {
// return new TestSuite(Testcase1.class);
//}
// public void setUp() throws Exception {
// setUp("http://localhost:8080/test", "*firefox");
//}
#BeforeMethod(groups = {"default", "example"}, alwaysRun = true)
#Parameters({"seleniumHost", "seleniumPort", "browser", "webSite"})
protected void startSession(String seleniumHost, int seleniumPort, String browser, String webSite) throws Exception {
startSession(seleniumHost, seleniumPort, browser, webSite);
selenium.setTimeout("120000");
}
#AfterMethod(groups = {"default", "example"}, alwaysRun = true)
protected void closeSession() throws Exception {
closeSession();
}
public void testCase1() throws Exception {
selenium.open("/login.action#login");
selenium.type("userName", "foo");
selenium.type("password", "bar");
selenium.click("login");
selenium.waitForPageToLoad("30000");
selenium.click("link=test");
Thread.sleep(4000);
selenium.click("//tr[4]/td[1]/a");
if(selenium.isElementPresent("//input[#id='nextButton']") != false){
selenium.click("//div[2]/input");
}
Thread.sleep(2000);
for(int i=0; i < $itter; i++) {
if(selenium.isElementPresent("//label") != false){
selenium.click("//label");
selenium.click("submitButton");
Thread.sleep(1500);
}
else{ Thread.sleep(1500);}
}
selenium.click("//body/div[2]/div[1]/div/a");
Thread.sleep(1500);
selenium.click("//a[contains(text(),'Finish Now')]");
Thread.sleep(2000);
selenium.click("link=View Results");
Thread.sleep(30000);
selenium.click("showAllImgCaption");
Thread.sleep(12000);
selenium.click("generateTimeButton");
Thread.sleep(2000);
selenium.click("link=Logout");
selenium.waitForPageToLoad("15000");
}
}
and the SeleneseTestNGHelper class
package seleniumRC;
import java.lang.reflect.Method;
//import java.net.BindException;
import com.thoughtworks.selenium.*;
//import org.openqa.selenium.SeleniumTestEnvironment;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverBackedSelenium;
//import org.openqa.selenium.environment.GlobalTestEnvironment;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
public class SeleneseTestNgHelper extends SeleneseTestCase
{
private static Selenium staticSelenium;
#BeforeTest
#Override
#Parameters({"selenium.url", "selenium.browser"})
public void setUp(#Optional String url, #Optional String browserString) throws Exception {
if (browserString == null) browserString = runtimeBrowserString();
WebDriver driver = null;
if (browserString.contains("firefox") || browserString.contains("chrome")) {
System.setProperty("webdriver.firefox.development", "true");
driver = new FirefoxDriver();
} else if (browserString.contains("ie") || browserString.contains("hta")) {
driver = new InternetExplorerDriver();
} else {
fail("Cannot determine which browser to load: " + browserString);
}
if (url == null)
url = "http://localhost:4444/selenium-server";
selenium = new WebDriverBackedSelenium(driver, url);
staticSelenium = selenium;
}
#BeforeClass
#Parameters({"selenium.restartSession"})
public void getSelenium(#Optional("false") boolean restartSession) {
selenium = staticSelenium;
if (restartSession) {
selenium.stop();
selenium.start();
}
}
#BeforeMethod
public void setTestContext(Method method) {
selenium.setContext(method.getDeclaringClass().getSimpleName() + "." + method.getName());
}
#AfterMethod
#Override
public void checkForVerificationErrors() {
super.checkForVerificationErrors();
}
#AfterMethod(alwaysRun=true)
public void selectDefaultWindow() {
if (selenium != null) selenium.selectWindow("null");
}
#AfterTest(alwaysRun=true)
#Override
public void tearDown() throws Exception {
// super.tearDown();
}
//#Override static method of super class (which assumes JUnit conventions)
public static void assertEquals(Object actual, Object expected) {
SeleneseTestBase.assertEquals(expected, actual);
}
//#Override static method of super class (which assumes JUnit conventions)
public static void assertEquals(String actual, String expected) {
SeleneseTestBase.assertEquals(expected, actual);
}
//#Override static method of super class (which assumes JUnit conventions)
public static void assertEquals(String actual, String[] expected) {
SeleneseTestBase.assertEquals(expected, actual);
}
//#Override static method of super class (which assumes JUnit conventions)
public static void assertEquals(String[] actual, String[] expected) {
SeleneseTestBase.assertEquals(expected, actual);
}
//#Override static method of super class (which assumes JUnit conventions)
public static boolean seleniumEquals(Object actual, Object expected) {
return SeleneseTestBase.seleniumEquals(expected, actual);
}
//#Override static method of super class (which assumes JUnit conventions)
public static boolean seleniumEquals(String actual, String expected) {
return SeleneseTestBase.seleniumEquals(expected, actual);
}
#Override
public void verifyEquals(Object actual, Object expected) {
super.verifyEquals(expected, actual);
}
#Override
public void verifyEquals(String[] actual, String[] expected) {
super.verifyEquals(expected, actual);
}
}
So I solved this by dropping the seleniumTestNGHelper class and reworking the classpaths by way of the ant file. It required completely working my suite/original testcases, but worked well within Grid.