Writing Test Results to Excel using Selenium - java

I've done plenty of research on this question and have tried many different methods, but none of them do what I'd like, or the explanations to implement them into my own code are really vague.
I need to export the test results (TestID, Expected Result, Pass or Fail) into an excel sheet. I am currently using TestNG and Apache POI.
I know how to write to an excel sheet, but I am absolutely lost on how to write whether or not something passed or failed. I am currently using some code that doesn't exactly work - sometimes it will write it, sometimes it won't. I need the most simple, easy way to do this, with a good explanation.
I'll show you my current #BeforeClass, #AfterClass, and two #Test blocks.
#BeforeClass:
#BeforeClass(alwaysRun = true)
public void setupBeforeSuite(ITestContext context) throws IOException {
//create a new work book
workbook = new HSSFWorkbook();
//create a new work sheet
sheet = workbook.createSheet("Test Result");
testresultdata = new LinkedHashMap < String, Object[] > ();
//add test result excel file column header
//write the header in the first row
testresultdata.put("1", new Object[] {
"Test Step Id", "Action", "Expected Result", "Actual Result"
});
}
#AfterClass:
#AfterClass
public void setupAfterSuite(ITestContext context) {
//write excel file and file name is TestResult.xls
Set<String> keyset = testresultdata.keySet();
int rownum = 0;
for (String key : keyset) {
Row row = sheet.createRow(rownum++);
Object [] objArr = testresultdata.get(key);
int cellnum = 0;
for (Object obj : objArr) {
Cell cell = row.createCell(cellnum++);
if(obj instanceof Date)
cell.setCellValue((Date)obj);
else if(obj instanceof Boolean)
cell.setCellValue((Boolean)obj);
else if(obj instanceof String)
cell.setCellValue((String)obj);
else if(obj instanceof Double)
cell.setCellValue((Double)obj);
}
}
try {
FileOutputStream out =new FileOutputStream(new File("C:/Users/PathToFile/LoginCombinations.xls"));
workbook.write(out);
out.close();
System.out.println("Excel written successfully..");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
#Test blocks:
#Test(priority=0)
public void successfulLogin() throws InterruptedException {
Properties prop = new Properties();
InputStream config = null;
InputStream signinpage;
try {
// First we iterate over and read the config file
config = new FileInputStream("C:/Users/PathToFile/src/ConfigFiles/config");
prop.load(config);
signinpage = new FileInputStream("C:/Users/PathToFile/src/ObjectRepositories/signinpage");
prop.load(signinpage);
// Next we initiate the driver, and navigate to the Web Application
driver = new FirefoxDriver();
driver.get(prop.getProperty("url"));
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
// Now we run the first step, "enterValidCredentials"
// In this test, this is actually the only step.
LoginPage.enterValidCredentials.run(driver);
// Assert that we landed on the Product Select page.
// assertEquals(driver.findElement(By.xpath(prop.getProperty("tempproductselect"))).getText(), "SELECT PRODUCT");
try{
assertEquals(driver.findElement(By.xpath(prop.getProperty("tempproductselect"))).getText(), "SELECT PRODUCT");
//add pass entry to the excel sheet
testresultdata.put("2", new Object[] {1d, "User can login with a valid username and password", "Login successful","Pass"});
}
catch(Exception e)
{
//add fail entry to the excel sheet
testresultdata.put("2", new Object[] {1d, "User can login with a valid username and password", "Login successful","Fail"});
}
// Write the test result to the sheet.
driver.close();
Alert alert = driver.switchTo().alert();
alert.accept();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (config != null) {
try {
config.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
#Test(priority=1)
public void invalidCredentialsOne() throws InterruptedException {
Properties prop = new Properties();
InputStream config = null;
InputStream signinpage;
try {
// First we iterate over and read the config file
config = new FileInputStream("C:/Users/PathToFile/src/ConfigFiles/config");
prop.load(config);
signinpage = new FileInputStream("C:/Users/PathToFile/src/ObjectRepositories/signinpage");
prop.load(signinpage);
// Next we initiate the driver, and navigate to the Web Application
WebDriver driver;
driver = new FirefoxDriver();
driver.get(prop.getProperty("url"));
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
// Now we run the first step, "invalidCredentialsOne"
// In this test, this is actually the only step.
LoginPage.invalidCredentialsOne.run(driver);
Thread.sleep(5000);
try{
assertEquals(driver.findElement(By.xpath(prop.getProperty("failedlogin"))).getText(), "LOG IN");
//add pass entry to the excel sheet
testresultdata.put("3", new Object[] {2d, "User should not be able to login with an invalid password", "Login failed","Pass"});
}
catch(Exception e)
{
//add fail entry to the excel sheet
testresultdata.put("3", new Object[] {2d, "User should not be able to login with an invalid password", "Login failed","Fail"});
}
// Write the test result to the sheet.
// After the test, we close the driver.
driver.close();
Alert alert = driver.switchTo().alert();
alert.accept();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (config != null) {
try {
config.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The second test, invalidCredentialsOne, never writes to the excel, whether I make it pass or fail.
Java is also new to me, so forgive any formatting/lingo/whatever errors I have in there. I'm very open-minded to suggestion, I'm trying to improve.

Here is the structure as i see it:
1) A part where you have a DriverFactory defined.
public class BrowserFactory {
public static WebDriver localDriver(Capabilities capabilities) {
String browserType = capabilities.getBrowserName();
if (browserType.equals("firefox"))
return new FirefoxDriver(capabilities);
if (browserType.startsWith("internet explorer"))
return new InternetExplorerDriver(capabilities);
if (browserType.equals("chrome"))
return new ChromeDriver(capabilities);
throw new Error("Unrecognized browser type: " + browserType);
}
Then you can simply initialize it anytime you need it :
Example:
driver = BrowserFactory.localDriver(DesiredCapabilities.firefox());
2) Your test classes, where you use this factory. Then there will be no need in #BeforeClass annotations. You write your tests in those classes. And at the end of every test, you make an assert (if test result failed or not). To check if the test passes, use the Assert.true();
Example: I i use the wrokg credentials on login, the allert: Wrong Password will appear.
Solution: You make an Assert.true(errorMessagePresent)
3) Your output writer class - to make it accessible for your tests
3) In case the test passes - you add the string you want to the output, using the buffer reader, else you throw an exception

Related

How to click on mail using selenium webdriver?

I want to open the mail by clicking on it, after receiving the activation mail.
For that I am using keyword driven framework.
So can anyone please let me know that how can we click on element without using List<>.
Because in my coding structure I am returning the object of Webelement instead of List<> object.
Note: Please suggest the solution without using JavaMail Api or if suggest please let me know according to the keyword driven framework.
Way of code structure where I find the elements in one method and in another method after getting an element perform the operations:
private boolean operateWebDriver(String operation, String Locator,
String value, String objectName) throws Exception {
boolean testCaseStep = false;
try {
System.out.println("Operation execution in progress");
WebElement temp = getElement(Locator, objectName);
System.out.println("Get Element ::"+temp);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
//For performing click event on any of the button, radio button, drop-down etc.
if (operation.equalsIgnoreCase("Click")) {
temp.click();
}
/*Trying to click on subject line of "Email"*/
if (operation.equalsIgnoreCase("Click_anElement")) {
Thread.sleep(6000L);
Select select = new Select(temp);
List<WebElement> options= select.getOptions();
for(WebElement option:options){
System.out.println(option.getText());
}
/*try
{
if(temp.getText().equals(value)){
temp.click();
}
}
catch(Exception e){
System.out.println(e.getCause());
}*/
/*if (value != null) {
temp.click();
}*/
}
}
testCaseStep = true;
} catch (Exception e) {
System.out.println("Exception occurred operateWebDriver"
+ e.getMessage());
System.out.println("Taking Screen Shot");
TakesScreenshot ts=(TakesScreenshot)driver;
File source=ts.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("./Screenshots/"+screenshotName+".png"));
System.out.println("Screenshot taken");
}
return testCaseStep;
}
public WebElement getElement(String locator, String objectName) throws Exception {
WebElement temp = null;
System.out.println("Locator-->" + locator);
if (locator.equalsIgnoreCase("id")) {
temp = driver.findElement(By.id(objectName));
} else if (locator.equalsIgnoreCase("xpath")) {
temp = driver.findElement(By.xpath(objectName));
System.out.println("xpath temp ----->" + temp);
} else if (locator.equalsIgnoreCase("name")) {
temp = driver.findElement(By.name(objectName));
}else if (locator.equalsIgnoreCase("cssSelector")) {
temp = driver.findElement(By.cssSelector(objectName));
}
return temp;
}

If it can't be null, but it needs to be initialized, what do I make it?

I have a problem accessing some of my xpaths. We use a hybrid testing framework.
public class logoutMenu {
public static void run(WebDriver driver) {
Properties prop = new Properties();
InputStream selectproductsidebarobjectrepository;
try {
selectproductsidebarobjectrepository = new FileInputStream(
"C:/thisisthepath/ObjectRepositories/SignInPageObjectRepository");
prop.load(selectproductsidebarobjectrepository);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement logoutNormal = driver.findElement(By.xpath(prop.getProperty("logoutnormal")));
Actions actions = new Actions(driver);
actions.moveToElement(logoutNormal).build().perform();
WebElement logoutHover = driver.findElement(By.xpath(prop.getProperty("logouthover")));
logoutHover.click();
WebElement logoutPushed = driver.findElement(By.xpath(prop.getProperty("logoutpushed")));
logoutPushed.click();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (selectproductsidebarobjectrepository != null) {
try {
selectproductsidebarobjectrepository.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
ORIGINAL PROBLEM:
It tells me that the xpath cannot be accessed if it is null. It's null because of this line: InputStream selectproductsidebarobjectrepository = null;. If I take away the = null; part of it, I get a different error: "The local variable selectproductsidebarobjectrepository may not have been initialized" which also makes sense.
What can I make selectproductsidebarobjectrepository equal to that isn't null?
NEW ISSUE:
Cleaned up the code. Got rid of the null. Got rid of the extra bracket. Still coming up as:
java.lang.IllegalArgumentException: Cannot find elements when the XPath expression is null.
at org.openqa.selenium.By.xpath(By.java:113)
at SelectProductSidebar.logoutMenu.run(logoutMenu.java:29)
at CommonFunctions.FunctionCheck.test(FunctionCheck.java:19)
Here is the script that calls this class:
public class FunctionCheck {
#Test
public void test() throws Exception {
WebDriver driver;
String baseUrl;
driver = new FirefoxDriver();
baseUrl = "http://www.MATTDAMON.com/";
driver.get(baseUrl + "MATT/MATT/MATT/MATT");
Thread.sleep(3000);
LoginPage.enterValidCredentials.run(driver);
SelectProductSidebar.logoutMenu.run(driver);
In case I'm screwing up a lot more than I initially though (probably true), here is the text file selectproductsidebarobjectrepository:
logoutnormal=//img[contains(#src,'log_out_normal')]
logouthover=//img[contains(#src,'log_out_hover')]
logoutpushed=//img[contains(#src,'log_out_pushed')]
I'm probably doing something really stupid but I'm absolutely blind to what it is right now.
This works fine for me after removing the extra brace.
public class logoutMenu {
public static void run(WebDriver driver) {
Properties prop = new Properties();
InputStream selectproductsidebarobjectrepository;
try {
selectproductsidebarobjectrepository = new FileInputStream(
"C:/thisisthepath/ObjectRepositories/SignInPageObjectRepository");
prop.load(selectproductsidebarobjectrepository);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement logoutNormal = driver.findElement(By.xpath(prop.getProperty("log_out_normal")));
Actions actions = new Actions(driver);
actions.moveToElement(logoutNormal).build().perform();
WebElement logoutHover = driver.findElement(By.xpath(prop.getProperty("log_out_hover")));
logoutHover.click();
WebElement logoutPushed = driver.findElement(By.xpath(prop.getProperty("log_out_pushed")));
logoutPushed.click();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (selectproductsidebarobjectrepository != null) {
try {
selectproductsidebarobjectrepository.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Export data generated in JPanel to excel

I have a Java Application that creates a JPanel menu and part of the program is to export data provided by the user inside JPanel to excel.
I want to create excel file and provide certain formatting inside my program.
I have tried using Apache POI, my code for the function is below. The function is called with a press of a button inside the JPanel when the application is running.
private static void processExcelInformation() throws FileNotFoundException
{
JOptionPane.showMessageDialog(panel, "stuck before workbook", "Display",
JOptionPane.WARNING_MESSAGE);
HSSFWorkbook workbook = new HSSFWorkbook(); // <---- I cannot seem to initialize new workbook
JOptionPane.showMessageDialog(panel, "created workbook", "Display",
JOptionPane.WARNING_MESSAGE); // <---- This message is not displayed when the application runs
HSSFSheet sheet = workbook.createSheet("Sample sheet");
JOptionPane.showMessageDialog(panel, "created sheet", "Display",
JOptionPane.WARNING_MESSAGE);
Map<String, Object[]> data = new HashMap<String, Object[]>();
data.put("1", new Object[] {"Emp No.", "Name", "Salary"});
data.put("2", new Object[] {1d, "John", 1500000d});
data.put("3", new Object[] {2d, "Sam", 800000d});
data.put("4", new Object[] {3d, "Dean", 700000d});
Set<String> keyset = data.keySet();
int rownum = 0;
for (String key : keyset) {
Row row = sheet.createRow(rownum++);
Object [] objArr = data.get(key);
int cellnum = 0;
for (Object obj : objArr) { // <---- This statement does not allow the application to run, I get an error
Cell cell = row.createCell(cellnum++);
if(obj instanceof Date)
cell.setCellValue((Date)obj);
else if(obj instanceof Boolean)
cell.setCellValue((Boolean)obj);
else if(obj instanceof String)
cell.setCellValue((String)obj);
else if(obj instanceof Double)
cell.setCellValue((Double)obj);
}
}
try {
JOptionPane.showMessageDialog(panel, "stuck before xls", "Display",
JOptionPane.WARNING_MESSAGE);
FileOutputStream out =
new FileOutputStream(new File("new.xls"));
workbook.write(out);
out.close();
System.out.println("Excel written successfully..");
JOptionPane.showMessageDialog(panel, "Excel written", "Display",
JOptionPane.WARNING_MESSAGE);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Check for comments where I have issues with my code.
Maybe someone can recommend me another way to complete my task or provide me a solution to my issues.
Thanks
Here's more to my code...
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
soccerStock = new ArrayList<Soccer>();
childrenStock = new ArrayList<Children>();
miniSoccerStock = new ArrayList<MiniSoccer>();
tennisStock = new ArrayList<Tennis>();
universalStock = new ArrayList<Universal>();
try {
// processExcelInformation();
parseXMLInput();
initializeGrassChoices();
} catch (JAXBException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Calculator ex = new Calculator();
ex.setVisible(true);
}
});
}
public Calculator() {
initUI();
}
public final void initUI() {
initGrassRollChoices();
initPanel();
createMenu();
}
This is the button that calls processExcelInformation() function...
JMenuItem xls = new JMenuItem("Excel", null);
xls.setMnemonic(KeyEvent.VK_E);
xls.setToolTipText("Export Excel");
xls.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
processExcelInformation();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
When I call processExcelInformation() during compilation from main function it creates the excel file as asked. However, when I write my code to call processExcelInformation() function using a button I get an error when launching my application.
There is an open source package called Jexcel which might provide the tools you need. See this Source Forge site for the source packages. For tutorials and API docs you can look here.
Additional: I've just read some reviews. Seems JExcel doesn't enjoy a very good rep and doesn't support xlsx format.
Looking at your code I can see that there may be a problem with the for-loop you've indicated. You haven't mentioned what the error is, but I suspect you cannot simply treat an array as a collection. I'd be inclined to try something more traditional like this:
for (int i = 0; i < objArr.length; i++){
...
}
Take a look at JExcel. It´s pretty easy to use if you don´t need overly complicated spreadsheets and there are a lot examples and HowTos if you ask our friend Google.

JavaScript button can only be clicked once with selenium Webdriver

I am trying to use Selenium with JUnit and I am having trouble completing my tests because it seems like my button execution is only occurring once. here's some of the code:
JQueryUITab navTab = new JQueryUITab(driver.findElement(By.cssSelector("nav ul.tabs")));
try {
navTab.selectTab("Tab1");
} catch (Exception e) {
e.printStackTrace();
}
try {
navTab.selectTab("Tab2");
} catch (Exception e) {
e.printStackTrace();
}
System.out.print(navTab.getSelectedTab());
the console print out will read "Tab1". this JQueryUITab object is a custom object. here are the inner workings:
public String getSelectedTab() {
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab"));
for (WebElement tab : tabs) {
if (tab.getAttribute("class").equals("tab selected")) {
return tab.getText();
}
}
return null;
}
public void selectTab(String tabName) throws Exception {
boolean found = false;
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab"));
for (WebElement tab : tabs) {
if(tabName.equals(tab.getText().toString())) {
tab.click();
found = true;
break;
}
}
if (!found) {
throw new Exception("Could not find tab '" + tabName + "'");
}
}
There are no exceptions thrown. At least pertaining before or at this part of the code.
There were a couple problems wrong with my implementation. Firstly, it could have been improved by selecting not the li.tab object, but the a class inside of it. From there, there were 2 solutions that worked for me. First was using
webElement.sendKeys(Keys.ENTER);
and the second (imho more elegant solution) was to get the instance of the selenium driver object controlling the object and then get it to execute the command to click the tab. Here's the full corrected method.
public void selectTab(String tabName) throws Exception {
boolean found = false;
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab a"));
for (WebElement tab : tabs) {
if(tabName.equals(tab.getText().toString())) {
// tab.sendKeys(Keys.ENTER);
WrapsDriver wrappedElement = (WrapsDriver) jQueryUITab;
JavascriptExecutor driver = (JavascriptExecutor) wrappedElement.getWrappedDriver();
driver.executeScript("$(arguments[0]).click();", tab);
found = true;
break;
}
}
if (!found) {
throw new Exception("Could not find tab '" + tabName + "'");
}
}

A properties file I created in the 1st run gets blanked in the 2nd run

Okay, I'm trying to create a custom client for Minecraft (don't worry, my question has nothing to do with Minecraft in particular), and I added an abstract class to manage a configuration file using Java's built-in Properties system. I have a method that loads a properties file or creates it if it doesn't already exist. This method is called at the beginning of all my other methods (although it only does anything the first time its called).
The properties file gets created just fine when I run Minecraft the first time, but somehow when I run it the second time, the file gets blanked out. I'm not sure where or why or how I'm wiping the file clean, can someone please help me? Here's my code; the offending method is loadConfig():
package net.minecraft.src;
import java.util.*;
import java.util.regex.*;
import java.io.*;
/**
* Class for managing my custom client's properties
*
* #author oxguy3
*/
public abstract class OxProps
{
public static boolean configloaded = false;
private static Properties props = new Properties();
private static String[] usernames;
public static void loadConfig() {
System.out.println("loadConfig() called");
if (!configloaded) {
System.out.println("loading config for the first time");
File cfile = new File("oxconfig.properties");
boolean configisnew;
if (!cfile.exists()) {
System.out.println("cfile failed exists(), creating blank file");
try {
configisnew = cfile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
configisnew=true;
}
} else {
System.out.println("cfile passed exists(), proceding");
configisnew=false;
}
FileInputStream cin = null;
FileOutputStream cout = null;
try {
cin = new FileInputStream(cfile);
cout = new FileOutputStream(cfile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (!configisnew) { //if the config already existed
System.out.println("config already existed");
try {
props.load(cin);
} catch (IOException e) {
e.printStackTrace();
}
} else { //if it doesn't exist, and therefore needs to be created
System.out.println("creating new config");
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
try {
props.store(cout, "OXGUY3'S CUSTOM CLIENT\n\ncloak_url is the URL to get custom cloaks from\nnames are the usernames to give cloaks to\n");
cout.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
String names = props.getProperty("names");
System.out.println("names: "+names);
try {
usernames = Pattern.compile(", ").split(names);
} catch (NullPointerException npe) {
npe.printStackTrace();
}
System.out.println("usernames: "+Arrays.toString(usernames));
configloaded=true;
}
}
public static boolean checkUsername(String username) {
loadConfig();
System.out.println("Checking username...");
for (int i=0; i<usernames.length; i++) {
System.out.println("comparing "+username+" with config value "+usernames[i]);
if (username.startsWith(usernames[i])){
System.out.println("we got a match!");
return true;
}
}
System.out.println("no match found");
return false;
}
public static String getCloakUrl() {
loadConfig();
return props.getProperty("cloak_url", "http://s3.amazonaws.com/MinecraftCloaks/akronman1.png");
}
}
If it's too hard to read here, it's also on Pastebin: http://pastebin.com/9UscXWap
Thanks!
You are unconditionally creating new FileOutputStream(cfile). This will overwrite the existing file with an empty one. You should only invoke the FileOutputStream constructor when writing a new config file.
if (configloaded)
return;
File cfile = new File("oxconfig.properties");
try {
if (cfile.createNewFile()) {
try {
FileOutputStream cout = new FileOutputStream(cfile);
props.setProperty("names", "oxguy3, Player");
props.setProperty("cloak_url", "http://...");
...
cout.flush();
} finally {
cout.close();
}
} else {
FileInputStream cin = new FileInputStream(cfile);
try {
props.load(cin);
} finally {
cin.close();
}
}
configloaded=true;
} catch(IOException ex) {
e.printStackTrace();
}

Categories