Selenium, clicking a button and secound iteration of a loop failing - selenium

I have a test
public class SeleniumForh extends BaseTest {
private static List<String> FNR;
private static final int THREAD_COUNT = 1;
private static Set<String> THREADS = Collections.synchronizedSet(new HashSet<String>());
static {
List<String> fnr = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(SeleniumManntallskryss.class.getResourceAsStream("/fnr")));
String line;
while ((line = reader.readLine()) != null) {
fnr.add(line);
}
FNR = Collections.synchronizedList(fnr);
} catch (IOException e) {
e.printStackTrace();
}
}
public SeleniumForhandstemmer(String platform, String browserName, String browserVersion) {
super(platform, browserName, browserVersion);
}
#Parameterized.Parameters
public static LinkedList<String[]> getEnvironments() throws Exception {
LinkedList<String[]> env = new LinkedList<String[]>();
for (int i = 0; i <THREAD_COUNT; i++) {
env.add(new String[]{"ANY", "firefox", "35"});
}
return env;
}
#Test
public void testForhand() throws Exception {
try {
System.out.println(System.currentTimeMillis() + " - " + Thread.currentThread() + ": testForhand");
THREADS.add(Thread.currentThread().toString());
do {
System.out.println(System.currentTimeMillis() + " - " + Thread.currentThread() + ": THREADS.size() = " + THREADS.size());
Thread.sleep(5000);
} while (THREADS.size() < THREAD_COUNT);
System.out.println(System.currentTimeMillis() + " - " + Thread.currentThread() + ": testForhand - ready to run");
WebDriver driver = webDriverThreadLocal.get();
driver.get("https://kill");
Assert.assertTrue(driver.getTitle().equals("Ehh"));
WebElement element = driver.findElement(By.xpath("/html/body/div/div[3]/div/div[2]/div/div/div/a"));
element.click();
WebElement brukerid = driver.findElement(By.xpath("/html/body/form/input[1]"));
brukerid.clear();
brukerid.sendKeys(new CharSequence[]{"2333"});
WebElement logginnknapp = driver.findElement(By.cssSelector("input[value=\"Login\"]"));
logginnknapp.click();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
WebElement rolle = driver.findElement(By.cssSelector("#event33"));
rolle.click();
for (int i = 0; i < 10; i++) {
System.out.println("Re nr " + (i + 1));
WebElement fo = driver.findElement(By.linkText("Ree"));
fo.click();
WebElement sted = driver.findElement(By.xpath("//*[#id=\"form:panel:tabell_dd_data\"]/tr[1]/td"));
sted.click();
takeScreenshot("nod");
WebElement velg = driver.findElement(By.xpath("//*[#id=\"form:panel:tabeller\"]/div/div[2]"));
velg.click();
WebElement fnrFane = driver.findElement(By.xpath("//*[#id=\"mand:manntallsSokForm:tabView\"]/ul/li[2]"));
fnrFane.click();
WebElement velger = driver.findElement(By.xpath("//input[#data-aft=\"fodselsnummer\"]"));
velger.clear();
String fnr = FNR.remove(0);
velger.sendKeys(fnr);
WebElement sokknapp = driver.findElement(By.xpath("//*[#id=\"mad:tabView:searchSSN\"]"));
sokknapp.click();
Thread.sleep(10000);
WebElement fnrTxt = driver.findElement(By.xpath("//*[contains(text(), '" + fnr + "')]"));
System.out.println("Fnr tekstelement: " + fnrTxt);
WebElement regStemme = driver.findElement(By.xpath("//*[#id=\"stemmegivning:form:markOffAdvance\"]"));
System.out.println("Knd: " + regStemme);
regStemme.click();
driver.findElement(By.xpath("//*[contains(text(), 'bd')]"));
driver.get("https://y");
driver.findElement(By.xpath("//*[contains(text(), 'Min side')]"));
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
System.out.println(System.currentTimeMillis() + " - " + Thread.currentThread() + ": testSimple - test finished");
}
}
}
The problem is that when running the secound iteratoion the button I want to click is just marked with a square around it in the running browser, not cliked. This happens everu time on the second (not the first iteration), I have tried sleep between iterations and have also confirmed that the button i sfound, so the problem is the click function. And I can see it tries to click because a square is apperaring around the buttoon.

Related

How to store a webtable in arraylist then verify the data in selenium webdriver

I want to store Rows and Column of web table into array list, then will verify the data. I am available to print the rows but how I will store the rows.
public void verifyTable() {
String Test = driver.findElement(loggedinas).getText();
boolean isDue = false;
isDue = UtilClass.isElementPresent(driver, TableContent);
if (isDue) {
if (isDue = driver.findElement(TableContent).getText() != null)
;
System.out.println("Action Required = " + isDue);
WebElement table_element = driver.findElement(Table);
List<WebElement> tr_collection = table_element
.findElements(TableRow);
System.out.println("Number Of Due = " + tr_collection.size());
int row_num, col_num;
row_num = 1;
for (WebElement trElement : tr_collection) {
List<WebElement> td_collection = trElement.findElements(By.xpath("td"));
System.out.println("--NUMBER OF COLUMNS = "
+ td_collection.size() + "--");
col_num = 1;
for (WebElement tdElement : td_collection) {
// System.out.println("Pending # "+row_num+", col # "+col_num+
// "text="+tdElement.getText());
System.out.printf(" # " + tdElement.getText(), " ID "
+ tdElement.getText());
col_num++;
}
row_num++;
}
Thank you!
I had done something similar, please check this function bellow, this will give you an idea
public void manageUserDataGrid(WebDriver driver){
WebElement table = driver.findElement(By.xpath("//*[#id='ReportTable']"));
List<WebElement> rows = table.findElements(By.tagName("tr"));
List<WebElement> column = table.findElements(By.tagName("td"));
List<String> value = new ArrayList<String>();
System.out.println(rows.size());
for (int j=0; j<column.size(); j++){
System.out.println(column.get(j).getText());
value.add(column.get(j).getText());
}
if (value.contains("coadminss")){
System.out.println("Value found");
}
else{
System.out.println("Not Found");
}
}

How to make Selenium chrome web driver fast

#Before
public void setUpRestClient() throws InterruptedException {
try {
driver.manage().timeouts().implicitlyWait(200, TimeUnit.SECONDS);
List<String> indexSuburbStatePost = new ArrayList<String>();
indexSuburbStatePost.add("ABC");
indexSuburbStatePost.add("YYZ");
for (int j = 0; j < indexSuburbStatePost.size(); j++) {
System.out.println("for loop===>" + indexSuburbStatePost.get(j));
mySchoolDriver(indexSuburbStatePost.get(j));
Thread.sleep(10000);
List<String> indexNumberSchool = new ArrayList<String>();
List<String> indexNameSchool = new ArrayList<String>();
List<WebElement> elementsAdv = driver.findElements(By.xpath("//table[#id='SearchResults']/tbody/tr/td"));
System.out.println("Test advance elements number of elements: " + elementsAdv.size());
writeToFile(indexSuburbStatePost.get(j));
for (WebElement eleadv : elementsAdv) {
System.out.println("Text adv======>" + eleadv.getText());
if (eleadv.getText().equalsIgnoreCase("Primary")
|| eleadv.getText().equalsIgnoreCase("Secondary")
|| eleadv.getText().equalsIgnoreCase("Government")
|| eleadv.getText().equalsIgnoreCase("Combined")
|| eleadv.getText().equalsIgnoreCase("Special")
|| eleadv.getText().equalsIgnoreCase(
"Non-government")) {
} else {
indexNameSchool.add(eleadv.getText());
}
}
Iterator<String> indexNumberSchoolIteratorAA = indexNameSchool
.iterator();
for (int k = 0; k < indexNameSchool.size(); k++) {
System.out.println("indexNumberSchoolIterator AA===>"+ indexNumberSchoolIteratorAA.next());
writeToFile(indexNameSchool.get(k));
}
List<WebElement> elementscss = driver.findElements(By.cssSelector("#SearchResults tr a"));
for (WebElement e : elementscss) {
String url = e.getAttribute("href");
System.out.println(url.substring(url.length() - 5));
indexNumberSchool.add(url.substring(url.length() - 5));
}
for (int i = 0; i < indexNumberSchool.size(); i++) {
Thread.sleep(10000);
writeToFile(indexNumberSchool.get(i));
try {
driver.findElement(By.xpath("//a[#href=\"/Home/Index/"+ indexNumberSchool.get(i) + "\"]")).click();
driver.findElement(By.id("IAccept")).click();
driver.findElement(By.className("captch-submit")).click();
} catch (NoSuchElementException ex) {
do nothing, link is not present, assert is passed
System.out.println(" NoSuchElementException======>" + ex.getMessage());
mySchoolDriver(indexSuburbStatePost.get(j));
Thread.sleep(10000);
driver.findElement(By.xpath("//a[#href=\"/Home/Index/"+ indexNumberSchool.get(i) + "\"]")).click();
}
driver.findElement(By.id("NaplanMenuButton")).click();
try {
driver.findElement(By.xpath("//*[#id=\"NaplanMenu\"]/ul/li[2]/a")).click();
} catch (ElementNotVisibleException envex) {
System.out.println(" ElementNotVisibleException======>"+ envex.getMessage());
}
List<WebElement> elements = driver.findElements(By.xpath("//div[#id='ResultsInNumbersContainer']/table/tbody/tr"));
System.out.println("Test7 number of elements: " + elements.size());
BufferedWriter writer = null;
File f = null;
for (WebElement ele : elements) {
if (ele.getAttribute("class").equalsIgnoreCase( "selected-school-row")) {
writeToFile(ele.getText());
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
driver.close();
}
}
private void mySchoolDriver(String indxSuburbPost) {
driver.get("http://www.abc.xyz.com");
driver.findElement(By.id("SuburbTownPostcodeSearch")).sendKeys(indxSuburbPost);
driver.findElement(By.id("SuburbTownPostcodeSearchSubmit")).submit();
}
private void writeToFile(String indxSuburbPost) {
try{
String filename = "C:/logs/data.txt";
FileWriter fw = new FileWriter(filename, true);
fw.write(indxSuburbPost + "\n");
fw.write("\n");
fw.close();
}catch (Exception e) {
e.printStackTrace();
}
}
Hi Friends,
I have above code and it is working fine and getting the data which I need. My only problem is : it is very slow.
If you look at the code he place where it is very slow is where I am cathing errors:
catch (NoSuchElementException ex) AND
catch (ElementNotVisibleException envex)
it takes ages to error to get caught.Can some one please help.
It's because of the .implicitlyWait() set at 200s. When an element is being located and not found, it will wait for 200s. My suggestion is to remove the implicit wait (and Thread.sleep()s) and replace them with explicit waits using WebDriverWait and ExpectedConditions.
WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(...)).click();
// as long as you are OK with the time setting in the above WebDriverWait declaration
// (10 seconds), you can reuse the wait again and again with the same 10s wait.
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(...));
wait.until(ExpectedConditions.elementToBeClickable(...)).click();
Read more about explicit and implicit waits and why you shouldn't mix them.

Is it possible to run multiple of test in one unit in testng

I am reading data from excel and running my test cases.It is possible to run multiple of test method in one test unit using testNg and eclipse.Below is my code.I tried it but getting error
at org.testng.internal.MethodInvocationHelper.invokeDataProvider(MethodInvocationHelper.java:161)
at org.testng.internal.Parameters.handleParameters(Parameters.java:429)
at org.testng.internal.Invoker.handleParameters(Invoker.java:1383)
at org.testng.internal.Invoker.createParameters(Invoker.java:1075)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1180)
login.java
import com.thoughtworks.selenium.*;
import org.junit.AfterClass;
import org.openqa.selenium.server.SeleniumServer;
import org.testng.annotations.*;
import java.io.File;
import jxl.*;
public class login extends SeleneseTestCase {
#BeforeClass
public void setUp() throws Exception {
try {
System.out.println("in setup");
SeleniumServer seleniumserver = new SeleniumServer();
seleniumserver.boot();
seleniumserver.start();
// String
// firefoxPath="C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe";
setUp("http://localhost:8080/",
"*firefox C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
// selenium.open("/");
selenium.windowMaximize();
selenium.windowFocus();
} catch (Exception ex) {
System.out.println(ex);
}
}
#DataProvider(name = "DP1")
public Object[][] createData1() throws Exception {
System.out.println("in createData1");
Object[][] retObjArr = getTableArray(
"test\\Resources\\Data\\logins.xls", "loginSheet", "Login");
return (retObjArr);
}
#Test(dataProvider = "DP1",testName="checkLogin")
public void testLogin1(String userName, String Password,
String expectedResult) throws Exception {
System.out.println("in testLogin1");
System.out.println("userName: " + userName + " Password: " + Password
+ " expectedResult: " + expectedResult);
selenium.open("Banking/Login.jsp/");
Thread.sleep(1000);
selenium.type("id=fname", userName);
Thread.sleep(1000);
selenium.type("id=Lname", Password);
Thread.sleep(1000);
selenium.click("name=sub");
Thread.sleep(1000);
boolean res = selenium.isTextPresent(expectedResult);
System.out.println("ver: " + res);
verifyTrue(res);
Thread.sleep(1000);
}
#Test(dataProvider = "DP1" ,testName="homepage")
public void testLogin2(String userName, String Password,
String expectedResult) throws Exception {
System.out.println("in testLogin2");
}
#AfterClass
public void tearDown() {
selenium.close();
selenium.stop();
}
/* this method read the data from excel sheet */
public String[][] getTableArray(String xlFilePath, String sheetName,
String tableTagName) throws Exception {
String[][] tabArray = null;
System.out.println("in getTableArray");
System.out.println("table: " + tableTagName + " xlFilePath:"
+ xlFilePath + " sheetName: " + sheetName);
Workbook workbook = Workbook.getWorkbook(new File(xlFilePath));
Sheet sheet = workbook.getSheet(sheetName);
int startRow, startCol, endRow, endCol, ci, cj;
Cell tableStart = sheet.findCell(tableTagName);// find table name in
// excel
startRow = tableStart.getRow();
startCol = tableStart.getColumn();
Cell tableEnd = sheet.findCell(tableTagName, startCol + 1,
startRow + 1, 100, 64000, false);
endRow = tableEnd.getRow();
endCol = tableEnd.getColumn();
System.out.println("startRow=" + startRow + ", endRow=" + endRow + ", "
+ "startCol=" + startCol + ", endCol=" + endCol);
tabArray = new String[endRow - startRow - 1][endCol - startCol - 1];
ci = 0;
for (int i = startRow + 1; i < endRow; i++, ci++) {
cj = 0;
for (int j = startCol + 1; j < endCol; j++, cj++) {
tabArray[ci][cj] = sheet.getCell(j, i).getContents();
// System.out.println("tabArray: "+ tabArray[ci][cj]);
}
}
return (tabArray);
}
}

I have not getting clear result about this issue

Am New to selenium Webdriver i have one project called Smoke testing .ie testing all the websites links are working fine or not .if any link is broken or not working means that test report sending email to the specified url.Actually i have write some codes for testing all the links and all the websites are getting from excel sheet problem is if the link is not working bt it shows the result as it is working nu so i cannot know the exact solution.here am attaching that codes Especially all the websites are made up of Wordpress.
public class LinktestTest
{
public static WebDriver driver;
#Test
public void findurl() throws Throwable, IOException {
FileInputStream fi = new FileInputStream("D:\\sample.xls");
Workbook wb = Workbook.getWorkbook(fi);
//driver = new FirefoxDriver();
Sheet s = wb.getSheet(0);
System.out.println("Program Started"+s.getName());
System.out.println(s.getRows());
for (int row = 0; row <= s.getRows()-1; row++)
{
driver = new FirefoxDriver();
String Urllist = s.getCell(0, row).getContents().toString();
System.out.println("Urllist" + Urllist);
driver.get(Urllist);
List<WebElement> linkElements = driver.findElements(By.tagName("a"));
String[] linkTexts = new String[linkElements.size()];
driver.manage().timeouts().implicitlyWait(20, TimeUnit.MINUTES);
int j = 0;
for (WebElement e : linkElements) {
linkTexts[j] = e.getText();
j++;
}
// test each link
for (String t : linkTexts) {
if (t != null && !t.isEmpty()) {
driver.findElement(By.linkText(t)).click();
String title;
title = driver.getTitle();
System.out.println("title is"+title);
if((title.contains("You are not authorized to view this page"))||(title.contains("404")) ||
(title.contains("408"))|| (title.contains("400")) || (title.contains("401"))
|| (title.contains("403"))||(title.contains("Page not found"))||(title.contains("500"))||(title.contains("error"))||(title.contains("503 Service Unavailable")))
{
System.out.println(t + " the link is not working");
} else {
System.out.println("\"" + t + "\"" + " is working.");
driver.navigate().back();
}
}
}driver.quit();
}
}
}
Instead of getting link text(s) and clicking, you can just retrieve the "href" attribute of each "a" tag elements. Since the purpose is just to navigate to each url and check the links by opening and getting title, I recommend this as the better way. Below is the updated code, that worked.
Note: I have just tweaked the existing code for solving it
#Test
public void findurl() throws Throwable, IOException {
FileInputStream fi = new FileInputStream("D:\\sites.xls");
Workbook wb = Workbook.getWorkbook(fi);
//driver = new FirefoxDriver();
Sheet s = wb.getSheet(0);
System.out.println("Program Started"+s.getName());
System.out.println(s.getRows());
for (int row = 0; row < s.getRows(); row++)
{
driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(1, TimeUnit.MINUTES);
String Urllist = s.getCell(0, row).getContents().toString();
System.out.println("Url number "+(row+1)+": " + Urllist);
driver.get(Urllist);
List<WebElement> linkElements = driver.findElements(By.tagName("a"));
System.out.println("The number of links under URL number "+(row+1)+" is: "+linkElements.size());
String[] linkhrefs = new String[linkElements.size()];
int j = 0;
for (WebElement e : linkElements) {
linkhrefs[j] = e.getAttribute("href");
j++;
}
// test each link
int k=0;
for (String t : linkhrefs) {
try{
if (t != null && !t.isEmpty()) {
System.out.println("Navigating to link number "+(++k)+": '"+t+"'");
driver.navigate().to(t);
String title;
title = driver.getTitle();
System.out.println("title is: "+title);
if((title.contains("You are not authorized to view this page"))||(title.contains("404")) ||
(title.contains("408"))|| (title.contains("400")) || (title.contains("401"))
|| (title.contains("403"))||(title.contains("Page not found"))||(title.contains("500"))||(title.contains("error"))||(title.contains("503 Service Unavailable")))
{
System.err.println(t + " the link is not working because title is: "+title);
} else {
System.out.println("\"" + t + "\"" + " is working.");
//driver.navigate().back();
}
}else{
System.err.println("Link's href is null.");
}
}catch(Throwable e){
System.err.println("Error came while navigating to link: "+t);
}
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
}
System.out.println("-------------------------------------------------------------");
System.out.println("Closing the driver as the links under url: "+Urllist+" have been checked out");
driver.quit();
}
}

Customizing summary section of TestNG emailable report

TestNG generates an emailable report. I have seen that this report can be customized by using Listeners. But could not get what i wanted. My requirement is to include extra details in the summary section of this report. I want to be able to add may be a new table or extra columns to show the environment details of the test execution.
Trying to attach a screenshot but apparently missing something and it does not come up.
That is what I have on my framework. I'll try to explain it (sorry my English)
Copy ReporterListenerAdapter.java and rename as MyReporterListenerAdapter.java, put it on your java project (/listener folder for example)
public class MyReporterListenerAdapter implements IReporter {
public void generateReport(List<XmlSuite> xml, List<ISuite> suites, String outdir) {}
}
Next, copy ReporterListener.java and rename as MyReporterListener.java
Too much code to paste here, but on createWriter function change the report name. For example: "emailable-MyFramework-report".
MyReporterListener.java
public class MyReporterListener extends MyReporterListenerAdapter {
private static final Logger L = Logger.getLogger(MyReporterListener.class);
// ~ Instance fields ------------------------------------------------------
private PrintWriter m_out;
private int m_row;
private Integer m_testIndex;
private int m_methodIndex;
private Scanner scanner;
// ~ Methods --------------------------------------------------------------
/** Creates summary of the run */
#Override
public void generateReport(List<XmlSuite> xml, List<ISuite> suites,
String outdir) {
try {
m_out = createWriter(outdir);
} catch (IOException e) {
L.error("output file", e);
return;
}
startHtml(m_out);
generateSuiteSummaryReport(suites);
generateMethodSummaryReport(suites);
generateMethodDetailReport(suites);
endHtml(m_out);
m_out.flush();
m_out.close();
}
protected PrintWriter createWriter(String outdir) throws IOException {
java.util.Date now = new Date();
new File(outdir).mkdirs();
return new PrintWriter(new BufferedWriter(new FileWriter(new File(
outdir, "emailable-FON-report"
+ DateFunctions.dateToDayAndTimeForFileName(now)
+ ".html"))));
}
/**
* Creates a table showing the highlights of each test method with links to
* the method details
*/
protected void generateMethodSummaryReport(List<ISuite> suites) {
m_methodIndex = 0;
startResultSummaryTable("methodOverview");
int testIndex = 1;
for (ISuite suite : suites) {
if (suites.size() > 1) {
titleRow(suite.getName(), 5);
}
Map<String, ISuiteResult> r = suite.getResults();
for (ISuiteResult r2 : r.values()) {
ITestContext testContext = r2.getTestContext();
String testName = testContext.getName();
m_testIndex = testIndex;
resultSummary(suite, testContext.getFailedConfigurations(),
testName, "failed", " (configuration methods)");
resultSummary(suite, testContext.getFailedTests(), testName,
"failed", "");
resultSummary(suite, testContext.getSkippedConfigurations(),
testName, "skipped", " (configuration methods)");
resultSummary(suite, testContext.getSkippedTests(), testName,
"skipped", "");
resultSummary(suite, testContext.getPassedTests(), testName,
"passed", "");
testIndex++;
}
}
m_out.println("</table>");
}
/** Creates a section showing known results for each method */
protected void generateMethodDetailReport(List<ISuite> suites) {
m_methodIndex = 0;
for (ISuite suite : suites) {
Map<String, ISuiteResult> r = suite.getResults();
for (ISuiteResult r2 : r.values()) {
ITestContext testContext = r2.getTestContext();
if (r.values().size() > 0) {
m_out.println("<h1>" + testContext.getName() + "</h1>");
}
resultDetail(testContext.getFailedConfigurations());
resultDetail(testContext.getFailedTests());
resultDetail(testContext.getSkippedConfigurations());
resultDetail(testContext.getSkippedTests());
resultDetail(testContext.getPassedTests());
}
}
}
/**
* #param tests
*/
private void resultSummary(ISuite suite, IResultMap tests, String testname,
String style, String details) {
if (tests.getAllResults().size() > 0) {
StringBuffer buff = new StringBuffer();
String lastClassName = "";
int mq = 0;
int cq = 0;
for (ITestNGMethod method : getMethodSet(tests, suite)) {
m_row += 1;
m_methodIndex += 1;
ITestClass testClass = method.getTestClass();
String className = testClass.getName();
if (mq == 0) {
String id = (m_testIndex == null ? null : "t"
+ Integer.toString(m_testIndex));
titleRow(testname + " — " + style + details, 5, id);
m_testIndex = null;
}
if (!className.equalsIgnoreCase(lastClassName)) {
if (mq > 0) {
cq += 1;
m_out.print("<tr class=\"" + style
+ (cq % 2 == 0 ? "even" : "odd") + "\">"
+ "<td");
if (mq > 1) {
m_out.print(" rowspan=\"" + mq + "\"");
}
m_out.println(">" + lastClassName + "</td>" + buff);
}
mq = 0;
buff.setLength(0);
lastClassName = className;
}
Set<ITestResult> resultSet = tests.getResults(method);
long end = Long.MIN_VALUE;
long start = Long.MAX_VALUE;
for (ITestResult testResult : tests.getResults(method)) {
if (testResult.getEndMillis() > end) {
end = testResult.getEndMillis();
}
if (testResult.getStartMillis() < start) {
start = testResult.getStartMillis();
}
}
mq += 1;
if (mq > 1) {
buff.append("<tr class=\"" + style
+ (cq % 2 == 0 ? "odd" : "even") + "\">");
}
String description = method.getDescription();
String testInstanceName = resultSet
.toArray(new ITestResult[] {})[0].getTestName();
buff.append("<td><a href=\"#m"
+ m_methodIndex
+ "\">"
+ qualifiedName(method)
+ " "
+ (description != null && description.length() > 0 ? "(\""
+ description + "\")"
: "")
+ "</a>"
+ (null == testInstanceName ? "" : "<br>("
+ testInstanceName + ")") + "</td>"
+ "<td class=\"numi\">" + resultSet.size() + "</td>"
+ "<td>" + start + "</td>" + "<td class=\"numi\">"
+ (end - start) + "</td>" + "</tr>");
}
if (mq > 0) {
cq += 1;
m_out.print("<tr class=\"" + style
+ (cq % 2 == 0 ? "even" : "odd") + "\">" + "<td");
if (mq > 1) {
m_out.print(" rowspan=\"" + mq + "\"");
}
m_out.println(">" + lastClassName + "</td>" + buff);
}
}
}
/** Starts and defines columns result summary table */
private void startResultSummaryTable(String style) {
tableStart(style, "summary");
m_out.println("<tr><th>Class</th>"
+ "<th>Method</th><th># of<br/>Scenarios</th><th>Start</th><th>Time<br/>(ms)</th></tr>");
m_row = 0;
}
private String qualifiedName(ITestNGMethod method) {
StringBuilder addon = new StringBuilder();
String[] groups = method.getGroups();
int length = groups.length;
if (length > 0 && !"basic".equalsIgnoreCase(groups[0])) {
addon.append("(");
for (int i = 0; i < length; i++) {
if (i > 0) {
addon.append(", ");
}
addon.append(groups[i]);
}
addon.append(")");
}
return "<b>" + method.getMethodName() + "</b> " + addon;
}
private void resultDetail(IResultMap tests) {
for (ITestResult result : tests.getAllResults()) {
ITestNGMethod method = result.getMethod();
m_methodIndex++;
String cname = method.getTestClass().getName();
m_out.println("<h2 id=\"m" + m_methodIndex + "\">" + cname + ":"
+ method.getMethodName() + "</h2>");
Set<ITestResult> resultSet = tests.getResults(method);
generateForResult(result, method, resultSet.size());
m_out.println("<p class=\"totop\">back to summary</p>");
}
}
/**
* Write the first line of the stack trace
*
* #param tests
*/
private void getShortException(IResultMap tests) {
for (ITestResult result : tests.getAllResults()) {
m_methodIndex++;
Throwable exception = result.getThrowable();
List<String> msgs = Reporter.getOutput(result);
boolean hasReporterOutput = msgs.size() > 0;
boolean hasThrowable = exception != null;
if (hasThrowable) {
boolean wantsMinimalOutput = result.getStatus() == ITestResult.SUCCESS;
if (hasReporterOutput) {
m_out.print("<h3>"
+ (wantsMinimalOutput ? "Expected Exception"
: "Failure") + "</h3>");
}
// Getting first line of the stack trace
String str = Utils.stackTrace(exception, true)[0];
scanner = new Scanner(str);
String firstLine = scanner.nextLine();
m_out.println(firstLine);
}
}
}
/**
* Write all parameters
*
* #param tests
*/
private void getParameters(IResultMap tests) {
for (ITestResult result : tests.getAllResults()) {
m_methodIndex++;
Object[] parameters = result.getParameters();
boolean hasParameters = parameters != null && parameters.length > 0;
if (hasParameters) {
for (Object p : parameters) {
m_out.println(Utils.escapeHtml(Utils.toString(p)) + " | ");
}
}
}
}
private void generateForResult(ITestResult ans, ITestNGMethod method,
int resultSetSize) {
Object[] parameters = ans.getParameters();
boolean hasParameters = parameters != null && parameters.length > 0;
if (hasParameters) {
tableStart("result", null);
m_out.print("<tr class=\"param\">");
for (int x = 1; x <= parameters.length; x++) {
m_out.print("<th>Param." + x + "</th>");
}
m_out.println("</tr>");
m_out.print("<tr class=\"param stripe\">");
for (Object p : parameters) {
m_out.println("<td>" + Utils.escapeHtml(Utils.toString(p))
+ "</td>");
}
m_out.println("</tr>");
}
List<String> msgs = Reporter.getOutput(ans);
boolean hasReporterOutput = msgs.size() > 0;
Throwable exception = ans.getThrowable();
boolean hasThrowable = exception != null;
if (hasReporterOutput || hasThrowable) {
if (hasParameters) {
m_out.print("<tr><td");
if (parameters.length > 1) {
m_out.print(" colspan=\"" + parameters.length + "\"");
}
m_out.println(">");
} else {
m_out.println("<div>");
}
if (hasReporterOutput) {
if (hasThrowable) {
m_out.println("<h3>Test Messages</h3>");
}
for (String line : msgs) {
m_out.println(line + "<br/>");
}
}
if (hasThrowable) {
boolean wantsMinimalOutput = ans.getStatus() == ITestResult.SUCCESS;
if (hasReporterOutput) {
m_out.println("<h3>"
+ (wantsMinimalOutput ? "Expected Exception"
: "Failure") + "</h3>");
}
generateExceptionReport(exception, method);
}
if (hasParameters) {
m_out.println("</td></tr>");
} else {
m_out.println("</div>");
}
}
if (hasParameters) {
m_out.println("</table>");
}
}
protected void generateExceptionReport(Throwable exception,
ITestNGMethod method) {
m_out.print("<div class=\"stacktrace\">");
m_out.print(Utils.stackTrace(exception, true)[0]);
m_out.println("</div>");
}
/**
* Since the methods will be sorted chronologically, we want to return the
* ITestNGMethod from the invoked methods.
*/
private Collection<ITestNGMethod> getMethodSet(IResultMap tests,
ISuite suite) {
List<IInvokedMethod> r = Lists.newArrayList();
List<IInvokedMethod> invokedMethods = suite.getAllInvokedMethods();
for (IInvokedMethod im : invokedMethods) {
if (tests.getAllMethods().contains(im.getTestMethod())) {
r.add(im);
}
}
Arrays.sort(r.toArray(new IInvokedMethod[r.size()]), new TestSorter());
List<ITestNGMethod> result = Lists.newArrayList();
// Add all the invoked methods
for (IInvokedMethod m : r) {
result.add(m.getTestMethod());
}
// Add all the methods that weren't invoked (e.g. skipped) that we
// haven't added yet
for (ITestNGMethod m : tests.getAllMethods()) {
if (!result.contains(m)) {
result.add(m);
}
}
return result;
}
#SuppressWarnings("unused")
public void generateSuiteSummaryReport(List<ISuite> suites) {
tableStart("testOverview", null);
m_out.print("<tr>");
tableColumnStart("Test");
tableColumnStart("Methods<br/>Passed");
tableColumnStart("Scenarios<br/>Passed");
tableColumnStart("# skipped");
tableColumnStart("# failed");
tableColumnStart("Error messages");
tableColumnStart("Parameters");
tableColumnStart("Start<br/>Time");
tableColumnStart("End<br/>Time");
tableColumnStart("Total<br/>Time");
tableColumnStart("Included<br/>Groups");
tableColumnStart("Excluded<br/>Groups");
m_out.println("</tr>");
NumberFormat formatter = new DecimalFormat("#,##0.0");
int qty_tests = 0;
int qty_pass_m = 0;
int qty_pass_s = 0;
int qty_skip = 0;
int qty_fail = 0;
long time_start = Long.MAX_VALUE;
long time_end = Long.MIN_VALUE;
m_testIndex = 1;
for (ISuite suite : suites) {
if (suites.size() > 1) {
titleRow(suite.getName(), 8);
}
Map<String, ISuiteResult> tests = suite.getResults();
for (ISuiteResult r : tests.values()) {
qty_tests += 1;
ITestContext overview = r.getTestContext();
startSummaryRow(overview.getName());
int q = getMethodSet(overview.getPassedTests(), suite).size();
qty_pass_m += q;
summaryCell(q, Integer.MAX_VALUE);
q = overview.getPassedTests().size();
qty_pass_s += q;
summaryCell(q, Integer.MAX_VALUE);
q = getMethodSet(overview.getSkippedTests(), suite).size();
qty_skip += q;
summaryCell(q, 0);
q = getMethodSet(overview.getFailedTests(), suite).size();
qty_fail += q;
summaryCell(q, 0);
// NEW
// Insert error found
m_out.print("<td class=\"numi" + (true ? "" : "_attn") + "\">");
getShortException(overview.getFailedTests());
getShortException(overview.getSkippedTests());
m_out.println("</td>");
// NEW
// Add parameters for each test case (failed or passed)
m_out.print("<td class=\"numi" + (true ? "" : "_attn") + "\">");
// Write OS and Browser
// m_out.println(suite.getParameter("os").substring(0, 3) +
// " | "
// + suite.getParameter("browser").substring(0, 3) + " | ");
getParameters(overview.getFailedTests());
getParameters(overview.getPassedTests());
getParameters(overview.getSkippedTests());
m_out.println("</td>");
// NEW
summaryCell(
DateFunctions.dateToDayAndTime(overview.getStartDate()),
true);
m_out.println("</td>");
summaryCell(
DateFunctions.dateToDayAndTime(overview.getEndDate()),
true);
m_out.println("</td>");
time_start = Math.min(overview.getStartDate().getTime(),
time_start);
time_end = Math.max(overview.getEndDate().getTime(), time_end);
summaryCell(
formatter.format((overview.getEndDate().getTime() - overview
.getStartDate().getTime()) / 1000.)
+ " seconds", true);
summaryCell(overview.getIncludedGroups());
summaryCell(overview.getExcludedGroups());
m_out.println("</tr>");
m_testIndex++;
}
}
if (qty_tests > 1) {
m_out.println("<tr class=\"total\"><td>Total</td>");
summaryCell(qty_pass_m, Integer.MAX_VALUE);
summaryCell(qty_pass_s, Integer.MAX_VALUE);
summaryCell(qty_skip, 0);
summaryCell(qty_fail, 0);
summaryCell(" ", true);
summaryCell(" ", true);
summaryCell(" ", true);
summaryCell(" ", true);
summaryCell(
formatter.format(((time_end - time_start) / 1000.) / 60.)
+ " minutes", true);
m_out.println("<td colspan=\"3\"> </td></tr>");
}
m_out.println("</table>");
}
private void summaryCell(String[] val) {
StringBuffer b = new StringBuffer();
for (String v : val) {
b.append(v + " ");
}
summaryCell(b.toString(), true);
}
private void summaryCell(String v, boolean isgood) {
m_out.print("<td class=\"numi" + (isgood ? "" : "_attn") + "\">" + v
+ "</td>");
}
private void startSummaryRow(String label) {
m_row += 1;
m_out.print("<tr"
+ (m_row % 2 == 0 ? " class=\"stripe\"" : "")
+ "><td style=\"text-align:left;padding-right:2em\"><a href=\"#t"
+ m_testIndex + "\">" + label + "</a>" + "</td>");
}
private void summaryCell(int v, int maxexpected) {
summaryCell(String.valueOf(v), v <= maxexpected);
}
private void tableStart(String cssclass, String id) {
m_out.println("<table cellspacing=\"0\" cellpadding=\"0\""
+ (cssclass != null ? " class=\"" + cssclass + "\""
: " style=\"padding-bottom:2em\"")
+ (id != null ? " id=\"" + id + "\"" : "") + ">");
m_row = 0;
}
private void tableColumnStart(String label) {
m_out.print("<th>" + label + "</th>");
}
private void titleRow(String label, int cq) {
titleRow(label, cq, null);
}
private void titleRow(String label, int cq, String id) {
m_out.print("<tr");
if (id != null) {
m_out.print(" id=\"" + id + "\"");
}
m_out.println("><th colspan=\"" + cq + "\">" + label + "</th></tr>");
m_row = 0;
}
/** Starts HTML stream */
protected void startHtml(PrintWriter out) {
out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
out.println("<head>");
out.println("<title>Hector Flores - TestNG Report</title>");
out.println("<style type=\"text/css\">");
out.println("table {margin-bottom:10px;border-collapse:collapse;empty-cells:show}");
out.println("td,th {border:1px solid #009;padding:.25em .5em}");
out.println(".result th {vertical-align:bottom}");
out.println(".param th {padding-left:1em;padding-right:1em}");
out.println(".param td {padding-left:.5em;padding-right:2em}");
out.println(".stripe td,.stripe th {background-color: #E6EBF9}");
out.println(".numi,.numi_attn {text-align:right}");
out.println(".total td {font-weight:bold}");
out.println(".passedodd td {background-color: #0A0}");
out.println(".passedeven td {background-color: #3F3}");
out.println(".skippedodd td {background-color: #CCC}");
out.println(".skippedodd td {background-color: #DDD}");
out.println(".failedodd td,.numi_attn {background-color: #F33}");
out.println(".failedeven td,.stripe .numi_attn {background-color: #D00}");
out.println(".stacktrace {white-space:pre;font-family:monospace}");
out.println(".totop {font-size:85%;text-align:center;border-bottom:2px solid #000}");
out.println("</style>");
out.println("</head>");
out.println("<body>");
}
/** Finishes HTML stream */
protected void endHtml(PrintWriter out) {
out.println("<center> Report customized by Hector Flores [hectorfb#gmail.com] </center>");
out.println("</body></html>");
}
// ~ Inner Classes --------------------------------------------------------
/** Arranges methods by classname and method name */
private class TestSorter implements Comparator<IInvokedMethod> {
// ~ Methods
// -------------------------------------------------------------
/** Arranges methods by classname and method name */
#Override
public int compare(IInvokedMethod o1, IInvokedMethod o2) {
// System.out.println("Comparing " + o1.getMethodName() + " " +
// o1.getDate()
// + " and " + o2.getMethodName() + " " + o2.getDate());
return (int) (o1.getDate() - o2.getDate());
// int r = ((T) o1).getTestClass().getName().compareTo(((T)
// o2).getTestClass().getName());
// if (r == 0) {
// r = ((T) o1).getMethodName().compareTo(((T) o2).getMethodName());
// }
// return r;
}
}
}
With those steps you already have your listener ready to listen.
How to call it?
If you use testng.xml add the following lines:
<listeners>
<listener class-name='[your_class_path].MyReporterListener'/>
</listeners>
If you run your tests from a java class, add the following lines:
private final static MyReporterListener frl = new MyReporterListener();
TestNG testng = new TestNG();
testng.addListener(frl);
With those steps, when you execute your tests you'll have two emailable reports, customized and original.
Now it's time to pimp your report.
In my case I had to add error messages, parameters and times (start and end), because it's very useful if you want to paste on an excel file.
My customized report:
You have to mainly modify generateSuiteSummaryReport(List suites) function.
Play with that and ask me if you have any problem.
Make a you CSS and embed it in EmailableReporter.class. This class file can be found in TestNG folder> org.testNg.reporters> EmailableReporter.class.
There you can edit the Style of the TestNG report HTML file which starts with
protected void startHtml(PrintWriter out)
Better you can use extent report html reporting library jar file. However i am using extentreport1.4.jar jar file. So you will get summary details at right corner of your report
Using the above code, I am facing the below null pointer issue, HTML report works fine when fewer tests are included in testng.xml, but when I include more tests, the HTML report does not get generated and the below exception is thrown
[TestNG] Reporter report.MyListener#60e07aed failed
java.lang.NullPointerException: Cannot invoke "String.length()" because "s" is null
at java.base/java.io.StringReader.<init>(StringReader.java:51)
at java.base/java.util.Scanner.<init>(Scanner.java:766)
at report.MyListener.getShortException(MyListener.java:294)
at report.MyListener.generateSuiteSummaryReport(MyListener.java:473)
at report.MyListener.generateReport(MyListener.java:72)
at org.testng.TestNG.generateReports(TestNG.java:1093)
at org.testng.TestNG.run(TestNG.java:1036)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:115)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
To fix the above added a null check to avoid Null Pointer at line 295
if(str!=null) {
scanner = new Scanner(str);
String firstLine = scanner.nextLine()+"<br>";
m_out.println(firstLine);
}