I am working on a test automation framework using testNG, Selenium and Jenkins. The code is working fine, it reads one or more csv files and uses that as test data. I run the test from Jenkins.
package test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
public class runTest {
private WebDriver myDriver = null;
#BeforeTest
public void openBrowser(){
System.out.println("This test automation framework is created by --- for ---");
//Set browser
//System.setProperty("webdriver.chrome.driver", "C://Temp//chromedriver.exe");
//System.setProperty("webdriver.ie.driver", "C://Temp//IEDriverServer.exe");
//Instantiate new WebDriver object with browser of choice
myDriver = new FirefoxDriver();
//myDriver = new InternetExplorerDriver();
//myDriver = new ChromeDriver();
myDriver.get("http://localhost/tests/");
}
#Test (dataProvider="provideData")
public void csvTest(String stepNr, String timeWaitMil, String waitForElement, String clickOnCssNameXpathLink,
String valueInTextBox, String backspaceText, String assertReturnTrueFalse,
String assertBy, String getUrl,
String deleteCookie, String snapshot, String specialSnapshot){
// Click on a something based on css, name xpath or link
if (!"-".equals(clickOnCssNameXpathLink)){
myDriver.findElement(By.name(clickOnCssNameXpathLink)).click();
}
// Enter value in textbox
if (!"-".equals(valueInTextBox)){
myDriver.findElement(By.name(clickOnCssNameXpathLink)).sendKeys(valueInTextBox);
}
// Delete cookies
if (!"-".equals(deleteCookie)){
myDriver.manage().deleteAllCookies();
}
// Make snapshot of whole page
if (snapshot.equalsIgnoreCase("true")){
// take the screenshot of full page
File scrFile = ((TakesScreenshot)myDriver).getScreenshotAs(OutputType.FILE);
// prepare date to use in filename
Date d = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH-mm-ss");
// Save screenshot
try {
FileUtils.copyFile(scrFile, new File("c:\\Temp\\screenshots\\full_page_" +dateFormat.format(d)+ ".png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Could not make screenshot");
}
}
}
#DataProvider
public Iterator<Object []> provideData() throws InterruptedException, IOException
{
//Array with multiple csv's
String csvFiles[] = {"C:/Users/---/Desktop/JES2.0/testingSelenium/testNG/data.csv", "C:/Users/---/Desktop/JES2.0/testingSelenium/testNG/data2.csv"};
List<Object []> testCases = new ArrayList<>();
//loop through csv files
for(String csvFile:csvFiles){
String[] data= null;
//read csv file
BufferedReader br = new BufferedReader(new FileReader(csvFile));
//Skip first line in the csv file, because that only contains the column names
String line = br.readLine();
//loop through csv and split parameters by comma sign ,
while ((line = br.readLine()) != null) {
// use comma as separator
data= line.split(",");
testCases.add(data);
}//end of while loop
}// end of for loop
return testCases.iterator();
}
#AfterTest
public void closeBrowser(){
//close browser
myDriver.quit();
}
}
As you can see, the browser, the url and the CSV files are hardcoded. I want to be able to pass these as parameters. What is the best way to do this? Is it possible to pass them through Jenkins?
I am thinking of building a dashboard where I can specify what tests (csv files) to run using which browser.
This is the Jenkins batch command I am running
java -cp C:\Users\---\Desktop\JES2.0\testingSelenium\testNG\libs\selenium-server-standalone-2.43.1.jar;C:\Users\---\Desktop\JES2.0\testingSelenium\testNG\bin org.testng.TestNG testng.xml
Jenkins have a built-in parameters handling, which is quite flexible in it's own way. But in this case, since you want to pass a filename as parameter, you can easily combine that functionality with a Filesystem List Parameter, which can build the list based on a regexp that will parse list of files.
If you use Maven or Ant, you can embed that parameter within your build process, in a form similar to this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<environment>${env.PARAM}</environment>
</systemPropertyVariables>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
With this you can read the parameter that was passed on to Maven - in Jenkins using it's internal caller, and on command line with:
mvn install -Denv.PARAM=VALUE
So it should work either way...
Related
enter image description here
1: https://i.stack.imgur.com/sRx3n.jpg**strong text**##
I am trying to write the Java program to get the input something like this for multiple rows and process it by creating concurrency thread group which can generate number of threads from tstfeedback function and complete the execution.enter image description here
Here is an example of creating an empty Test Plan with the Throughput Shaping Timer configured like at your first image via JMeter API:
import kg.apc.jmeter.JMeterPluginsUtils;
import kg.apc.jmeter.timers.VariableThroughputTimer;
import kg.apc.jmeter.timers.VariableThroughputTimerGui;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.config.gui.ArgumentsPanel;
import org.apache.jmeter.control.gui.TestPlanGui;
import org.apache.jmeter.gui.util.PowerTableModel;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestPlan;
import org.apache.jmeter.testelement.property.CollectionProperty;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.collections.HashTree;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ThroughputShapingTImer {
public static void main(String[] args) throws IOException {
File jmeterHome = new File("c:/apps/jmeter");
String slash = System.getProperty("file.separator");
File jmeterProperties = new File(jmeterHome.getPath() + slash + "bin" + slash + "jmeter.properties");
//JMeter initialization (properties, log levels, locale, etc)
JMeterUtils.setJMeterHome(jmeterHome.getPath());
JMeterUtils.loadJMeterProperties(jmeterProperties.getPath());
JMeterUtils.initLocale();
// JMeter Test Plan, basically JOrphan HashTree
HashTree testPlanTree = new HashTree();
//Throughput Shaping Timer
VariableThroughputTimer throughputShapingTimer = new VariableThroughputTimer();
throughputShapingTimer.setName("Timer");
PowerTableModel load_profile = new PowerTableModel(new String[]{"Start RPS", "End RPS", "Duration, sec"}, new Class[]{String.class, String.class, String.class});
load_profile.addRow(new Integer[]{0, 10, 20});
load_profile.addRow(new Integer[]{10, 10, 20});
CollectionProperty data = JMeterPluginsUtils.tableModelRowsToCollectionProperty(load_profile, VariableThroughputTimer.DATA_PROPERTY);
throughputShapingTimer.setData(data);
throughputShapingTimer.setProperty(TestElement.TEST_CLASS, VariableThroughputTimer.class.getName());
throughputShapingTimer.setProperty(TestElement.GUI_CLASS, VariableThroughputTimerGui.class.getName());
// Test Plan
TestPlan testPlan = new TestPlan("Create JMeter Script From Java Code");
testPlan.setProperty(TestElement.TEST_CLASS, TestPlan.class.getName());
testPlan.setProperty(TestElement.GUI_CLASS, TestPlanGui.class.getName());
testPlan.setUserDefinedVariables((Arguments) new ArgumentsPanel().createTestElement());
// Construct Test Plan from previously initialized elements
testPlanTree.add(testPlan);
HashTree threadGroupHashTree = testPlanTree.add(testPlan);
threadGroupHashTree.add(throughputShapingTimer);
// save generated test plan to JMeter's .jmx file format
SaveService.saveTree(testPlanTree, Files.newOutputStream(Paths.get("example.jmx")));
}
}
The resulting .jmx test plan will be stored in the current folder.
More information: Five Ways To Launch a JMeter Test without Using the JMeter GUI
Hey all I have a question.
My assignment is that my program takes a command-line argument and then prints out the data.
I managed to navigate to the desired page and also print out the data I need but I did it with .sendKeys("name i need here"). Is it possible that at the start there would be like a question "what name do you want to type in" and you would then type the name in the command-line and everything else would play out the same?
Here's my code:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By.ByXPath;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.IOException;
import java.util.List;
public class Scraper {
public static void main( String[] args ) throws IOException
{
System.setProperty("webdriver.chrome.driver", "D:/Chrome/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.basketball-reference.com/");
driver.findElement(By.xpath("//*[#id='header']/div[3]/form/div/div/input[2]")).sendKeys("Luka Dončić");
driver.findElement(ByXPath.xpath("//*[#id='qc-cmp2-ui']/div[2]/div/button[3]")).click();
driver.findElement(ByXPath.xpath("//*[#id='header']/div[3]/form/input[1]")).click();
driver.findElement(ByXPath.xpath("//*[#id='players']/div[1]/div[1]/strong/a")).click();
WebElement element = driver.findElement(By.id("div_per_game"));
List<WebElement> trojke = element.findElements(By.cssSelector("td[data-stat='fg3a_per_g']"));
List<WebElement> sezona = element.findElements(By.xpath("//*[#id='per_game']/tbody/tr/th/a"));
for (WebElement s: sezona)
{
System.out.println(s.getText());
}
for (WebElement t : trojke)
{
System.out.println(t.getText());
}
}
}
So instead of sendKeys("Luka Dončić") that automatically puts the name in the search box of a page I want to write the name myself in command line and when I press enter or something the rest would execute the same. Is it possible?
Here's the page I want to send the name to in the search box: https://www.basketball-reference.com/
Oh yes and I'm using Java with Selenium and Maven.
Before sending the text to the web element you can read the user input from console
import java.util.Scanner;
Scanner my_scan = new Scanner(System.in);
String my_text = my_scan.nextLine();
so now you can send the my_text
driver.findElement(By.xpath("//*[#id='header']/div[3]/form/div/div/input[2]")).sendKeys(my_text);
the entire code will look like this:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By.ByXPath;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;
public class Scraper {
public static void main( String[] args ) throws IOException
{
System.setProperty("webdriver.chrome.driver", "D:/Chrome/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.basketball-reference.com/");
Scanner my_scan = new Scanner(System.in);
String my_text = my_scan.nextLine();
driver.findElement(By.xpath("//*[#id='header']/div[3]/form/div/div/input[2]")).sendKeys(my_text);
driver.findElement(ByXPath.xpath("//*[#id='qc-cmp2-ui']/div[2]/div/button[3]")).click();
driver.findElement(ByXPath.xpath("//*[#id='header']/div[3]/form/input[1]")).click();
driver.findElement(ByXPath.xpath("//*[#id='players']/div[1]/div[1]/strong/a")).click();
WebElement element = driver.findElement(By.id("div_per_game"));
List<WebElement> trojke = element.findElements(By.cssSelector("td[data-stat='fg3a_per_g']"));
List<WebElement> sezona = element.findElements(By.xpath("//*[#id='per_game']/tbody/tr/th/a"));
for (WebElement s: sezona)
{
System.out.println(s.getText());
}
for (WebElement t : trojke)
{
System.out.println(t.getText());
}
}
}
I am trying to use phantomjs for testing, I have one login page with obvious two parameters username and password. If i try same code with google url where i have to pass only one element with and say element.submit(); but in my login page i want to pass two elements how to achieve the same ?
here is my code -
import java.io.File;
import java.io.IOException;
import org.apache.maven.shared.utils.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.Test;
public class PhantomExample {
public PhantomExample() {
System.out.println("this is constructor");
}
#Test
public void verify() {
File src = new File("C:\\Users\\Admin\\Downloads\\Compressed\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe");
DesiredCapabilities phantomjsCap = new DesiredCapabilities();
phantomjsCap.setJavascriptEnabled(true);
phantomjsCap.setCapability("phantomjs.binary.path", src.getAbsolutePath());
System.out.println("inside the verify method");
System.setProperty("phantomjs.binary.path", src.getAbsolutePath());
WebDriver driver = new PhantomJSDriver(phantomjsCap);
driver.get("http://localhost:8080/MyApp/Login");
System.out.println(driver.getPageSource());
WebElement el =driver.findElement(By.name("username"));
WebElement elp =driver.findElement(By.name("password"));
el.sendKeys("username");
elp.sendKeys("0");
el.submit();
elp.submit();
System.out.println(driver.getTitle());
System.out.println(driver.getCurrentUrl());
System.out.println(driver.getPageSource());
File Ss=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(Ss, new File("d:/sample.jpg"));
}
catch (IOException e) {
System.out.println(e.getMessage());
}
driver.quit();
}
}
Here i created two separate elements and expecting to get the response, but when i run it in debugger mode it is not executing after line el.submit();
I am quite sure that i am doing this wrong way, but can someone tell me what is the right approach to this and explain how to get response object which server would send after log in ?
Calling the submit() method on an input field submits the whole form (with all input values), so the following line can be deleted:
elp.submit();
If the form has a submit button, then after executing el.submit() login will be done.
I need to ceate file and set permissions(-rwxrw-r) to it, the permission of parent dir is (drwxrwxr--). The problem is that the write permission is
not set in created files. The user that ran this application is the owner of the parent dir.
Below is my test class that present the same problem. When I run this program, the permissions of generated file is (-rwxr--r--) though the class set permissions (-rwxrw-rw-). Why the write permission is not set
and I don't see any exception?
Any idea?
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
public class TestPermission{
static String parentDir = "/tmp/test/";
static Set<PosixFilePermission> defaultPosixPermissions = null;
static {
defaultPosixPermissions = new HashSet<>();
defaultPosixPermissions.add(PosixFilePermission.OWNER_READ);
defaultPosixPermissions.add(PosixFilePermission.OWNER_WRITE);
defaultPosixPermissions.add(PosixFilePermission.OWNER_EXECUTE);
defaultPosixPermissions.add(PosixFilePermission.GROUP_READ);
defaultPosixPermissions.add(PosixFilePermission.GROUP_WRITE);
//Others have read permission so that ftp user who doesn't belong to the group can fetch the file
defaultPosixPermissions.add(PosixFilePermission.OTHERS_READ);
defaultPosixPermissions.add(PosixFilePermission.OTHERS_WRITE);
}
public static void createFileWithPermission(String fileName) throws IOException{
// File parentFolder = new File(parentDir);
// PosixFileAttributes attrs = Files.readAttributes(parentFolder.toPath(), PosixFileAttributes.class);
// System.out.format("parentfolder permissions: %s %s %s%n",
// attrs.owner().getName(),
// attrs.group().getName(),
// PosixFilePermissions.toString(attrs.permissions()));
// FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(attrs.permissions());
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(defaultPosixPermissions);
File file = new File(fileName);
Files.createFile(file.toPath(), attr);
}
public static void main(String[] args) throws IOException{
String fileName = parentDir + "testPermission_" + System.currentTimeMillis();
createFileWithPermission(fileName);
}
}
I believe the catch here is
The check for the existence of the file and the creation of the new
file if it does not exist are a single operation that is atomic with
respect to all other filesystem activities that might affect the
directory.
as mentioned in Class Files
This might be because of the OS operations that happen after a file is being created. The following modification in code should get things work fine:
File file = new File(fileName);
Files.createFile(file.toPath(), attr);
Files.setPosixFilePermissions(file.toPath(), defaultPosixPermissions); //Assure the permissions again after the file is created
It turns out that the reason is that my os has a umask as 0027(u=rwx,g=rx,o=) which means application has no way to
set permission for others group.
Files.createFile(file.toPath(), attr);
in the above line instead of using Files.createFile
use file.createNewFile() and if it returns true then the file is created.
I have a code that parses through XML files, edits them and saves them (using dom for this). Now, I have a few files which have the .ftl extension. I have managed to process the ftl file with given answers (using freemarker template configuration) , However, I am unable to save the edited xml back as an FTL.
All of this is in Java. Any suggestions on how I can achieve the saving aspect of the problem?
Again, I want to process, edit and then save an FTL file in Java.
I am appending the code that I have for processing the ftl file.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class FTLReader {
public static void main(String[] args) {
//Freemarker configuration object
Configuration cfg = new Configuration();
try {
//Load template from source folder
Template template = cfg.getTemplate(filename);
// Build the data-model
Map<String,Object> data = new HashMap<String,Object>();
JsonParser parser = new JsonParser();
//write code to get answers
Object obj = parser.parse(new FileReader("src/answers.txt"));
JsonObject jsonObject = (JsonObject) obj;
data.put("element1", jsonObject.get("element1"));
// Console output
Writer out = new OutputStreamWriter(System.out);
template.process(data, out);
out.flush();
/*write code to edit and save the ftl file
*
*
*
*
* */
// File output (the processed FTL file)
Writer file = new FileWriter (new File("C:\\FTL_helloworld.txt"));
template.process(data, file);
file.flush();
file.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
}
After reading your question and comments few times, I am probably finally getting to grasp what you are aiming to. So, you have to "patch" the file behind the filename variable from the start of your code (Template template = cfg.getTemplate(filename);). FTL file is basically a text file, so you can process it line by line. Then you must re-initialize your template with the new file content, i.e. do template = cfg.getTemplate(filename); again.