I have to execute test scripts using dynamic testng.xml file which means I have to create testng.xml file thru code and pass the parameters to the #Test methods pro grammatically.
For that I have created two Java files DynamicTestNG.java which should generate testng.xml file and run SampleClass.java where the #Test method has been written along with the parameters.
DynamicTestNG.java
public class DynamicTestNG {
public void runTestNGTest(Map<String,String> testngParams) {
//Create an instance on TestNG
TestNG myTestNG = new TestNG();
//Create an instance of XML Suite and assign a name for it.
XmlSuite mySuite = new XmlSuite();
mySuite.setName("MySuite");
//Create an instance of XmlTest and assign a name for it.
XmlTest myTest = new XmlTest(mySuite);
myTest.setName("MyTest");
//Add any parameters that you want to set to the Test.
myTest.setParameters(testngParams);
//Create a list which can contain the classes that you want to run.
List<XmlClass> myClasses = new ArrayList<XmlClass> ();
myClasses.add(new XmlClass("SampleClass"));
//Assign that to the XmlTest Object created earlier.
myTest.setXmlClasses(myClasses);
//Create a list of XmlTests and add the Xmltest you created earlier to it.
List<XmlTest> myTests = new ArrayList<XmlTest>();
myTests.add(myTest);
//add the list of tests to your Suite.
mySuite.setTests(myTests);
//Add the suite to the list of suites.
List<XmlSuite> mySuites = new ArrayList<XmlSuite>();
mySuites.add(mySuite);
//Set the list of Suites to the testNG object you created earlier.
myTestNG.setXmlSuites(mySuites);
TestListenerAdapter tla = new TestListenerAdapter();
myTestNG.addListener(tla);
//invoke run() - this will run your class.
myTestNG.run();
}
public static void main (String args[])
{
DynamicTestNG dt = new DynamicTestNG();
//This Map can hold your testng Parameters.
Map<String,String> testngParams = new HashMap<String,String> ();
testngParams.put("searchtext1", "testdata1");
testngParams.put("searchtext2", "testdata2");
dt.runTestNGTest(testngParams);
}
}
And SampleClass.java
public class SampleClass {
private WebDriver driver;
#BeforeTest
public void setUp()
{
System.setProperty("webdriver.chrome.driver","C:\\Users\\AK5040691\\Desktop\\IE driver\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.navigate().to("http://executeautomation.com/blog/custom-testng-library-for-appium/#more-1562");
}
//#Parameters({"searchText1","searchText2"})
//#Test
public void searchText(String text1, String text2)
{
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.findElement(By.className("search-field")).sendKeys(text1);
driver.findElement(By.className("search-field")).clear();
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.findElement(By.className("search-field")).sendKeys(text2);
}
}
Its not running. Please let me know the mistake here.
You have to uncomment the #Test annotation in your SampleClass file. And if your SampleClass is in a package , then absolute package name + class name is to be specified in this statement.
myClasses.add(new XmlClass("com.some.package.SampleClass"));
Generally TestNG classes have a suffix or prefix labelled "Test" so that surefire plugin can include them in the execution flow, in case if you are using maven.
You can instead use the constructor with parameter of class object .
myClasses.add(new XmlClass(SampleClass.class));
Related
Normally I would write a cucumber option as below:
#CucumberOptions(
features = "src\\main\\java\\feature"
, glue= "stepdefination",
plugin= {"com.cucumber.listener.ExtentCucumberFormatter:Report/Report.html"}
tags="#tag, #tag1, #sort"
)
public class TestRunner extends TestFunction {
#Test
public void runcukes( ) {
new TestNGCucumberRunner(getClass()).runCukes();
}
#BeforeClass
public void tags() {
}
#AfterClass
public void writeExtentReport() {
Reporter.loadXMLConfig("extent-config.xml");
}
}
My question is: How can I fetch #tag, #tag1, #sort from an excel file to #cucmberoptions and run the program in Selenium Java?
I am not sure about using cucumber options but by using cucumber RuntimeOptions class you can achieve it. The below method needs to be called in a loop that means you have 10 tags to execute then call this method in for loop.
public static boolean cucumberRun(String tag) {
try {
ClassLoader classLoader = CustomClass.class.getClassLoader();
ResourceLoader resourceLoader = new MultiLoader(classLoader);
ClassFinder classFinder = new ResourceLoaderClassFinder(resourceLoader, classLoader);
/* Adding cucumber plugins */
List<String> pluginList = new ArrayList<String>();
pluginList.add("--plugin");
pluginList.add("html:target/cucumber-html-report");
pluginList.add("--plugin");
pluginList.add("json:target/cucumber.json");
pluginList.add("--plugin");
pluginList.add("com.cucumber.listener.ExtentCucumberFormatter:");
pluginList.add("--plugin");
pluginList.add("rerun:target/failedScenarios.txt");
/* Location for BDD extent report. */
ExtentProperties extentProperties = ExtentProperties.INSTANCE;
extentProperties.setReportPath("location/Extent_report.html");
/*
* Adding cucumberOptions.
*
* You can get the tag value from excel and pass it here. We need to add # before tag value.
*/
RuntimeOptions ro = new RuntimeOptions(pluginList);
ro.getFilters().add("#"+tag);
ro.getFeaturePaths().add("location of feature files");
ro.getGlue().add("location of glue code");
/* Loads all the resources into Cucumber RunTime class and execute. */
cucumber.runtime.Runtime runtime = new cucumber.runtime.Runtime(resourceLoader, classFinder, classLoader,
ro);
runtime.run();
}catch(Exception e){
// Handle exception
}
I wanted to trigger the execution from a java main method instead of testng.xml file.
My doubt is how to add the parameters to Java main method for the execution. I have found .addListener and .setGroups to add listener and groups respectively, but couldn't able to find a way to add parameters.
Please help me out to start the exection through java main method.
Sample:
public class Execution {
public static void main(String[] args) throws IOException {
TestNG test = new TestNG();
test.setTestClasses(new Class[] {AETVTests.class});
test.addListener(new MyTestListenerAdapter());
test.setGroups("");
test.run();
}
}
If you would reconsider using xml - you can also trigger execution through the main method with the xml file. Add the testng.xml file to your project path (in eclipse you can right click project - new - file - testng.xml), and this will work:
public static void main(String[] args) throws IOException
{
TestNG testng = new TestNG();
List<String> suites = Lists.newArrayList();
suites.add("C:\\eclipse-2018\\Tests\\testng.xml"); //path to xml
testng.setTestSuites(suites);
testng.run(); //run TestNG
}
You can access args by arg[0],arg[1] likewise. in cmd run your jar file>
java -jar classname.jar param1 param2
I need to run my project in other system(computer2) also through cmd what requirement need in (Computer2).
System.setProperty("webdriver.chrome.driver","Project1\\Driver\\chromedriver.exe);
driver=new ChromeDriver();
driver.get("http://www.gmail.net/");
driver.close();
These are the code and contain main method also
public class Mainpage
{
#SuppressWarnings("deprecation")
public static void main(String[] args) {
TestListenerAdapter t2=new TestListenerAdapter();
TestNG testng = new TestNG();
testng.setTestClasses(new Class[]{login.class});
testng.addListener(t2);
testng.run();
}
}
It's unclear what error you're getting (or if you're even getting an error), but changing "http://www.gmail.net/" to "http://www.gmail.com/" might solve your issue.
i am new to selenium and i have created a java project with different classes (each class for every page of my application). The project has only 1 main method and the class having main method is inherited by all other classes.
So, is it correct to code in this way that the class having main is inherited by all other classes?
Or is there some other better way to code?
Another question is,
The main method has the chrome driver initiation in it as well in addition to objects of all classes used to call the methods of different classes.
Should main contain only objects for all classes? or is there a way to initiate chrome in some other way.
Sample of my code below (main class and login class):
public class Main {
static WebDriver driver;
static Logger logger;
public static void main(String[] args) throws IOException {
logger=Logger.getLogger("Log4jdemo");
PropertyConfigurator.configure("Log4j.property.txt");
String exePath = "F:\\selenium\\Chrome Driver\\New Folder\\chromedriver.exe";
System.setProperty("webdriver.chrome.driver", exePath);
driver = new ChromeDriver();
driver.get("https://www.gmail.com");
driver.manage().window().maximize();
logger.info("Browser launched");
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
wait.withTimeout(15, TimeUnit.SECONDS);
wait.pollingEvery(1, TimeUnit.SECONDS);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("ei-login-Username")));
Login l1 = new Login();
l1.login();
A name= new A();
name.InitiateJourney();
B IO = new B();
IO.Help();
Agreeterms a = new Agreeterms();
a.Agreeterm();
AmendDetails ad = new AmendDetails();
ad.Amend();
AmendBank ab = new AmendBank();
ab.amendbankdetails();
}
}
public class Login extends Main{
public void login() throws IOException{
File src = new File("F:\\selenium\\AutomationData.xlsx");
FileInputStream fin = new FileInputStream(src);
XSSFWorkbook wbook = new XSSFWorkbook(fin);
XSSFSheet sheet = wbook.getSheetAt(0);
WebElement username =driver.findElement(By.id("ei-login-Username"));
username.sendKeys("12365478");
WebElement next =driver.findElement(By.id("btnSubmit"));
next.click();
driver.manage().timeouts().implicitlyWait(6, TimeUnit.SECONDS);
WebElement pin =driver.findElement(By.id("ei-login-Pin"));
pin.sendKeys("971997");
WebElement login =driver.findElement(By.id("btnPinSubmit"));
login.click();
}
}
Try TestNG or JUnit frameworks, Main method is not Mandatory for selenium. You can write your own classes and methods. Can call them by Annotations.
I'm trying with the following code to change the default test name, but still the value has remains as: default test name and not the test i set it to be:
TestNG testng = new TestNG();
XmlSuite suite = new XmlSuite();
suite.setName("Programmatic suite");
XmlTest xmlTest = new XmlTest(suite);
xmlTest.setName(testcase);
List<XmlClass> classes = new ArrayList<XmlClass>();
classes.add(new XmlClass(testsuite));
xmlTest.setXmlClasses(classes) ;
xmlTest.setName(testcase);
List<XmlTest> xmlTestsList = new ArrayList<XmlTest>();
xmlTestsList.add(xmlTest);
suite.setTests(xmlTestsList);
List<XmlSuite> suites = new ArrayList<XmlSuite>();
suites.add(suite);
testng.setXmlSuites(suites);
testng.setTestNames(Arrays.asList(testcase));
testng.setTestClasses(new Class[] { autotestClass });
testng.addListener(tla);
testng.run();
Ok, basically added the call to the method:
testng.setDefaultTestName("your default testname");
Also i needed to implement the interface:
IMethodInterceptor