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

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);
}
}

Related

migrating CQ 5.6.1(jdk 1.7) to AEM 6.4(jdk 1.8), Unable to deserialze byte array while reading session from Cassandra using Serializer<SimpleSession>

i am migrating java bundles from CQ 5.6.1 to AEM 6.4, bundle is working in jdk 1.7,
code is using apache shiro to serealize and deserialize session, here is the code to save and read session stored in Cassandra
it works good with AEM 5.6.1 and 6.1 (works in jdk 1.7) when i migrate it to AEM 6.4 (working in jdk 1.8) code is
giving exception in "method doReadSession" when it is trying to deserialize session in bite array
it throw an exception
In method doReadSession where it return "serializer.deserialize(bytes)"
exception thrown is
Caused by: org.apache.shiro.io.SerializationException: Unable to deserialze argument byte array.
at org.apache.shiro.io.DefaultSerializer.deserialize(DefaultSerializer.java:82)
at com.xyz.web.platform.common.security.shiro.cassandra.CassandraSessionDAO.doReadSession(CassandraSessionDAO.java:252)
at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:168)
at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSessionFromDataSource(DefaultSessionManager.java:236)
import com.xyz.web.platform.common.security.shiro.session.idgenerator.UUIDSessionIdGenerator;
import com.xyz.web.platform.common.tracelogging.TMTraceLogger;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Collections;
import org.apache.shiro.ShiroException;
import org.apache.shiro.io.DefaultSerializer;
import org.apache.shiro.io.Serializer;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.apache.shiro.util.Destroyable;
import org.apache.shiro.util.Initializable;
import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
public class CassandraSessionDAO extends AbstractSessionDAO implements Initializable, Destroyable {
private static final TMTraceLogger CASSANDRA_LOGGER = TMTraceLogger
.getLogger("cassandraLogger" + "." + CassandraSessionDAO.class.getName());
private String DEFAULT_CONSISTENCY_LEVEL = ConsistencyLevel.LOCAL_QUORUM.toString();
private static final String DEFAULT_CACHING = "ROWS_ONLY";
private static final String DEFAULT_DATA_CENTER = "DC1";
private String keyspaceName;
private String tableName;
private Cluster cluster;
private Serializer<SimpleSession> serializer;
private String readConsistencyLevel;
private String writeConsistencyLevel;
private String defaultTTL;
private String gc_grace_seconds;
private String caching = DEFAULT_CACHING;
private String dataCenter = DEFAULT_DATA_CENTER;
private PreparedStatement deletePreparedStatement;
private PreparedStatement savePreparedStatement;
private PreparedStatement readPreparedStatement;
private com.datastax.driver.core.Session cassandraSession;
public CassandraSessionDAO() {
setSessionIdGenerator(new UUIDSessionIdGenerator());
this.serializer = new DefaultSerializer<SimpleSession>();
}
private SimpleSession assertSimpleSession(Session session) {
if (!(session instanceof SimpleSession)) {
throw new IllegalArgumentException(CassandraSessionDAO.class.getName() + " implementations only support "
+ SimpleSession.class.getName() + " instances.");
}
return (SimpleSession) session;
}
public Cluster getCluster() {
return cluster;
}
public void setCluster(Cluster cluster) {
this.cluster = cluster;
}
public String getKeyspaceName() {
return keyspaceName;
}
public void setKeyspaceName(String keyspaceName) {
this.keyspaceName = keyspaceName;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getReadConsistencyLevel() {
return readConsistencyLevel;
}
public void setReadConsistencyLevel(String readConsistencyLevel) {
this.readConsistencyLevel = readConsistencyLevel;
}
public String getWriteConsistencyLevel() {
return writeConsistencyLevel;
}
public void setWriteConsistencyLevel(String writeConsistencyLevel) {
this.writeConsistencyLevel = writeConsistencyLevel;
}
public String getDefaultTTL() {
return defaultTTL;
}
public void setDefaultTTL(String defaultTTL) {
this.defaultTTL = defaultTTL;
}
public String getGc_grace_seconds() {
return gc_grace_seconds;
}
public void setGc_grace_seconds(String gc_grace_seconds) {
this.gc_grace_seconds = gc_grace_seconds;
}
public String getCaching() {
return caching;
}
public void setCaching(String caching) {
this.caching = caching;
}
public String getDataCenter() {
return dataCenter;
}
public void setDataCenter(String dataCenter) {
this.dataCenter = dataCenter;
}
public void init() throws ShiroException {
com.datastax.driver.core.Session systemSession = cluster.connect();
boolean create = false;
try {
if (!isKeyspacePresent(systemSession)) {
create = true;
createKeyspace(systemSession);
if (!isKeyspacePresent(systemSession)) {
throw new IllegalStateException("Unable to create keyspace " + keyspaceName);
}
}
} finally {
systemSession.shutdown();
}
cassandraSession = cluster.connect(keyspaceName);
if (create) {
createTable();
}
prepareReadStatement();
prepareSaveStatement();
prepareDeleteStatement();
}
public void destroy() throws Exception {
if (cassandraSession != null) {
cassandraSession.shutdown();
cluster.shutdown();
}
}
protected boolean isKeyspacePresent(com.datastax.driver.core.Session systemSession) {
PreparedStatement ps = systemSession.prepare("select * from system.schema_keyspaces");
BoundStatement bs = new BoundStatement(ps);
ResultSet results = systemSession.execute(bs);
// ResultSet results = systemSession.execute("select * from
// system.schema_keyspaces");
for (Row row : results) {
if (row.getString("keyspace_name").equalsIgnoreCase(keyspaceName)) {
return true;
}
}
return false;
}
protected void createKeyspace(com.datastax.driver.core.Session systemSession) {
String query = "create keyspace " + this.keyspaceName
+ " with replication = {'class' : 'NetworkTopologyStrategy', '" + dataCenter + "': 2};";
systemSession.execute(query);
}
protected void createTable() {
long defaultTTLLong = Long.parseLong(defaultTTL);
long gc_grace_secondsLong = Long.parseLong(gc_grace_seconds);
String query = "CREATE TABLE " + tableName + " ( " + " id varchar PRIMARY KEY, " + " start_ts timestamp, "
+ " stop_ts timestamp, " + " last_access_ts timestamp, " + " timeout bigint, "
+ " expired boolean, " + " host varchar, " + " serialized_value blob " + ") " + "WITH "
+ " gc_grace_seconds = " + gc_grace_secondsLong + " AND default_time_to_live = " + defaultTTLLong
+ " AND caching = '" + caching + "' AND " + " compaction = {'class':'LeveledCompactionStrategy'};";
cassandraSession.execute(query);
}
#Override
protected Serializable doCreate(Session session) {
SimpleSession ss = assertSimpleSession(session);
Serializable timeUuid = generateSessionId(session);
assignSessionId(ss, timeUuid);
save(ss);
return timeUuid;
}
#Override
protected Session doReadSession(Serializable sessionId) {
long startTime = System.currentTimeMillis();
if (CASSANDRA_LOGGER.isDebugEnabled()) {
CASSANDRA_LOGGER.logDebug("In the doReadSession()..");
CASSANDRA_LOGGER.logDebug("The start time is " + startTime + " ms");
}
// put a not-null & not-empty check
if (sessionId != null && !sessionId.equals("")) {
String id = sessionId.toString();
PreparedStatement ps = prepareReadStatement();
/*
* String query = "SELECT * from " + tableName + " where id = ?";
* PreparedStatement ps = cassandraSession.prepare(query);
*/
BoundStatement bs = new BoundStatement(ps);
bs.bind(id);
if (readConsistencyLevel == null) {
readConsistencyLevel = DEFAULT_CONSISTENCY_LEVEL;
}
bs.setConsistencyLevel(ConsistencyLevel.valueOf(readConsistencyLevel));
ResultSet results = cassandraSession.execute(bs);
for (Row row : results) {
String rowId = row.getString("id");
if (id.equals(rowId)) {
ByteBuffer buffer = row.getBytes("serialized_value");
if (buffer != null) {
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
return serializer.deserialize(bytes);
}
}
}
}
long endTime = System.currentTimeMillis();
long timeTaken = endTime - startTime;
if (CASSANDRA_LOGGER.isDebugEnabled()) {
CASSANDRA_LOGGER.logDebug("The total time taken is " + timeTaken + " ms");
}
return null;
}
private PreparedStatement prepareReadStatement() {
if (this.readPreparedStatement == null) {
String query = "SELECT * from " + tableName + " where id = ?";
this.readPreparedStatement = cassandraSession.prepare(query);
}
return this.readPreparedStatement;
}
// In CQL, insert and update are effectively the same, so we can use a single
// query for both:
protected void save(SimpleSession ss) {
// long timeoutInSeconds = ss.getTimeout() / 1000;
/*
* String query = "UPDATE " + tableName + " SET " + "start_ts = ?, " +
* "stop_ts = ?, " + "last_access_ts = ?, " + "timeout = ?, " + "expired = ?, "
* + "host = ?, " + "serialized_value = ? " + "WHERE " + "id = ?";
* PreparedStatement ps = cassandraSession.prepare(query);
*/
long startTime = System.currentTimeMillis();
if (CASSANDRA_LOGGER.isDebugEnabled()) {
CASSANDRA_LOGGER.logDebug("In the save()..");
CASSANDRA_LOGGER.logDebug("The start time is " + startTime + " ms");
}
PreparedStatement ps = prepareSaveStatement();
BoundStatement bs = new BoundStatement(ps);
byte[] serialized = serializer.serialize(ss);
ByteBuffer bytes = ByteBuffer.wrap(serialized);
bs.bind(ss.getStartTimestamp(), ss.getStopTimestamp() != null ? ss.getStartTimestamp() : null,
ss.getLastAccessTime(), ss.getTimeout(), ss.isExpired(), ss.getHost(), bytes, ss.getId().toString());
if (writeConsistencyLevel == null) {
writeConsistencyLevel = DEFAULT_CONSISTENCY_LEVEL;
}
bs.setConsistencyLevel(ConsistencyLevel.valueOf(writeConsistencyLevel));
cassandraSession.execute(bs);
long endTime = System.currentTimeMillis();
long timeTaken = endTime - startTime;
if (CASSANDRA_LOGGER.isDebugEnabled()) {
CASSANDRA_LOGGER.logDebug("The total time taken is " + timeTaken + " ms");
}
}
private PreparedStatement prepareSaveStatement() {
if (this.savePreparedStatement == null) {
String query = "UPDATE " + tableName + " SET " + "start_ts = ?, " + "stop_ts = ?, " + "last_access_ts = ?, "
+ "timeout = ?, " + "expired = ?, " + "host = ?, " + "serialized_value = ? " + "WHERE " + "id = ?";
this.savePreparedStatement = cassandraSession.prepare(query);
}
return this.savePreparedStatement;
}
public void update(Session session) throws UnknownSessionException {
SimpleSession ss = assertSimpleSession(session);
save(ss);
}
public void delete(Session session) {
/*
* String query = "DELETE from " + tableName + " where id = ?";
* PreparedStatement ps = cassandraSession.prepare(query);
*/
long startTime = System.currentTimeMillis();
if (CASSANDRA_LOGGER.isDebugEnabled()) {
CASSANDRA_LOGGER.logDebug("In the delete()..");
CASSANDRA_LOGGER.logDebug("The start time is " + startTime + " ms");
}
PreparedStatement ps = prepareDeleteStatement();
BoundStatement bs = new BoundStatement(ps);
bs.bind(session.getId().toString());
cassandraSession.execute(bs);
long endTime = System.currentTimeMillis();
long timeTaken = endTime - startTime;
if (CASSANDRA_LOGGER.isDebugEnabled()) {
CASSANDRA_LOGGER.logDebug("The total time taken is " + timeTaken + " ms");
}
}
private PreparedStatement prepareDeleteStatement() {
if (this.deletePreparedStatement == null) {
String query = "DELETE from " + tableName + " where id = ?";
this.deletePreparedStatement = cassandraSession.prepare(query);
}
return this.deletePreparedStatement;
}
public Collection<Session> getActiveSessions() {
return Collections.emptyList();
}
}
Need to add your class or pacakge in the configuration in whitelist section
https://helpx.adobe.com/experience-manager/6-4/sites/administering/using/mitigating-serialization-issues.html

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

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.

Run Multiple test cases with multiple test data sheet

I need help in selenium. I am trying to run multiple test cases with multiple test data sheets with TestNG and Data Provider concept. But I am having issue in running the test data. If I return array in Test, after getting the test data from sheet then starting from the one row of test cases again so it always run 1st row of the Data driven function.
If I return at the end of the DataDriven then last row will print the value in Test rest would get overnight.
Please let me know what I have to do to run the my test cases. I am attaching the code and Test cases and Test data sheet.
Test Cases & test data sheet
package testCases;
import java.util.Properties;
import operation.ReadObject;
import operation.UIOperation;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Iterator;
import java.lang.reflect.Method;
import excelExportAndFileIO.ReadExcelFile;
public class Test1 {
private static final Boolean True = null;
//WebDriver webdriver = null;
public static WebDriver driver;
private Cell Cell;
private Cell TCCellValue;
/* #BeforeSuite
public static void firefoxSetUp() {
driver = new FirefoxDriver();
driver.manage().window().maximize();
}
#AfterSuite
public static void closeFirefox(){
driver.quit();
}*/
#Test(dataProvider = "hybridData")
public void Permittee_Registration(String Status, String TC, String Module1, String Module2 ) { //String Status, String TCName, String TCDesc) throws Exception {
System.out.println("Status:"+Status +" ; TC:"+TC + " ; Module1:"+Module1 + " ; Module2:"+Module2);
}
// Call the test data sheet ----- PR = Permittee Registration
#Test(dataProvider = "hybridData")
public void PR_Applicant_Information(String TestCase, String URL, String objPermittee, String objPR, String PR_TITLE, String objLegal_Entity_Type, String Permittee_Legal_Name, String EIN ) {
System.out.println("PR_Applicant_Information Test");
if (TestCase!=null){
System.out.println("");
System.out.println("TestCase:"+TestCase + " ; PR_Applicant_Information URL:"+URL + " ; objPermittee: "+objPermittee + " ; objPR: " +objPR + " ; PR_TITLE: " +PR_TITLE + " ; objLegal_Entity_Type: " +objLegal_Entity_Type + " ; Permittee_Legal_Name: " + " ; EIN: " +EIN + "; dd: dd") ;
}
}
#Test(dataProvider = "hybridData")
public void PR_Choose_Qualification(String TC, String URL){
if (TC!=null){
System.out.println("");
System.out.println("PR_Choose_Qualification TC:"+TC + " ; URL: "+ URL);
}
}
#DataProvider(name = "hybridData")
public Iterator[] loginData(Method method) {
//System.out.println("Hybrid");
String TCName="";
Object[][] result = null;
Object[][] testData = new String[10][10];
Object[][] arrayObject = getExcelData(("user.dir") + "\\TestCaseSheet.xlsx", "TestCases_Modules",TCName);
//K=Row and L=Column
for (int k=0; k < arrayObject.length; k++){
int colCount=arrayObject[k].length;
//System.out.println("Column=arrayObject[k].length:"+arrayObject[k].length);
if ("YES".equals(arrayObject[k][0])){
//System.out.println("arrayObject[k][L]:"+arrayObject[k][L]+" ; K="+k+" ; L="+L);
//System.out.println("arrayObject[k][0]----:"+arrayObject[k][0] +" ; K = "+k );
for (int L=0; L< colCount ; L++){
//"Permittee_Registration"
//System.out.println("Permittee_Registration"+arrayObject[k][2]);
if ((arrayObject[k][L] !=null) && ((String)arrayObject[k][L]).indexOf(",") > 0) {
String[] pr = ((String)arrayObject[k][L] ).split(",");
//System.out.println("pr:"+pr.length + " ; PRValue:"+pr[0]);
for (int prN=0; prN < pr.length; prN++ ){
//System.out.println("for (int prN=0; prN < pr.length; prN++ )");
//pr=Applicant_Information
TCName=(String) arrayObject[k][1]; //fetching the Test Case Name
//System.out.println("TCName:"+TCName + " ; equals(pr[prN]) = "+equals(pr[prN]) + " ; pr.length="+pr.length + " ; pr[prN]="+ pr[prN]);
if ("Applicant_Information".equals(pr[prN])){
System.out.println("if (Applicant_Information.equals(pr[prN]))"+pr[prN] + " ; pr.length="+pr.length );
if (method.getName().equals("PR_Applicant_Information")) {
System.out.println("Applicant_Information Moni before calling excel sheet function:"+" ; result.length"+result.length);
//result = getExcelData(("user.dir") + "\\TestCaseSheet.xlsx", "Applicant_Information",TCName);
result = getExcelData(("user.dir") + "\\TestCaseSheet.xlsx", pr[prN] ,TCName);
//AI(result);
//System.out.println("Applicant_Information Moni afte calling excel sheet function:"+" ; result.length"+result.length);
//return result;
};
}
else if ("Choose_Qualification".equals(pr[prN])){
if (method.getName().equals("PR_Choose_Qualification")) {
//System.out.println("Choose_Qualification Moni before calling excel sheet function:"+pr[prN] +" ; result.length"+result.length);
result = getExcelData(("user.dir") + "\\TestCaseSheet.xlsx", "Choose_Qualification",TCName);
System.out.println("Choose_Qualification Moni after calling excel sheet function:"+pr[prN] +" ; result.length"+result.length);
};
}
}
//return result;
}
}
}
}
return result;
}
public void AI(Object result){
System.out.println("resultAI:"+result);
}
/**
* #param File
* Name
* #param Sheet
* Name
* #return
*/
public String[][] getExcelData(String fileName, String sheetName, String TCName) {
//public List<String> getExcelData(String fileName, String sheetName, String TCName) {
String[][] arrayExcelData = null;
int a=0;
int b=0;
try {
ReadExcelFile file = new ReadExcelFile();
// UIOperation operation = new UIOperation(driver);
// Read keyword sheet
Sheet testCaseSheet = file.readExcel(System.getProperty("user.dir") + "\\", "TestCaseSheet.xlsx", sheetName);
// Find number of rows in excel file
int rowCount = testCaseSheet.getLastRowNum() - testCaseSheet.getFirstRowNum();
int coulmnCount = testCaseSheet.getRow(0).getLastCellNum();
int firstCoulmnCount = testCaseSheet.getRow(0).getFirstCellNum();
arrayExcelData=new String[rowCount+1][coulmnCount];
//System.out.println("rowCount:"+rowCount);
//System.out.println("coulmnCount:"+coulmnCount);
//Looping the row
for (int i = testCaseSheet.getFirstRowNum(); i < (testCaseSheet.getLastRowNum()+1) ; i++) {
// Loop over all the rows
//Row row=testCaseSheet.getRow(i + 1);
int j;
if ("" != (TCName)){
//Object TCCellValues = null;
}
for (j = firstCoulmnCount; j < coulmnCount ; j++) {
Cell = testCaseSheet.getRow(i).getCell(j);
//System.out.println("TCName in recurring function :"+TCName);
//System.out.println("Cell:"+Cell);
//if TCName is equal to particular row then pick only that cell data.
TCCellValue = testCaseSheet.getRow(i).getCell(0);
String TCCellValues = TCCellValue.getStringCellValue();
//System.out.println("if ( != (TCCellValue)): " +TCCellValue + " ; TCName=" + TCName + " ; i="+i);
String CellData="";
//System.out.println("Cell inside:"+Cell);
if (Cell!=null){
CellData = Cell.getStringCellValue();
//System.out.println(i+":"+CellData);
}
if (TCName.equals("")||(TCName.equals(TCCellValues))){
arrayExcelData[i][j]=CellData;
//System.out.println("arrayExcelData[i][j]=CellData;"+CellData + " ; i="+i +" ; j="+j + " ; TCName="+TCName + " ; a="+a +" ; b="+b );
}
}
}
} catch (Exception e) {
System.out.println("Error " + e);
}
//System.out.println("Stop_arrayExcelData:");
return arrayExcelData;
//return new List<String>{{arrayExcelData}};
}
}

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);
}

KeyTyped being called twice in this code?

There is a bug somewhere here. For some reason, when I am sending the message to the server, every message is received twice for any single keystroke! for instance, i type "a", and the server receives "INSERT 0 1 a" "INSERT 0 1 a". I'm not sure why it happens twice do you know?
package client;
import javax.swing.*;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class JTextAreaListen extends JFrame implements KeyListener,
CaretListener {
private static final long serialVersionUID = 6950001634065526391L;
private JTextArea textArea;
protected final PrintWriter out;
protected final int id;
protected final BufferedReader in;
protected static int caretPos;
private static int cMark;
protected static boolean text_selected;
/*
* Connecting to server. (1337 is the port we are going to use).
*
* socket = new Socket(InetAddress.getByName("127.0.0.1"), 1337);
*
* (Open a new outStream, you can save this instead of opening on every time
* you want to send a message. If the connection is lost your should to
* out.close();
*
* out = new PrintWriter(socket.getOutputStream(), true);
*
* out.print("message"); to send something to the server.
*/
public JTextAreaListen(PrintWriter out, BufferedReader in, int id) {
super("JTextAreaListen");
this.id = id;
this.out = out;
this.in = in;
TextEditor.document.addCaretListener(this);
TextEditor.document.addKeyListener(this);
}
// Listener methods
public void changedUpdate(DocumentEvent ev) {
}
public void removeUpdate(DocumentEvent ev) {
}
public void insertUpdate(DocumentEvent ev) {
}
#Override
public void keyPressed(KeyEvent arg0) {
System.out.print("KeyPressedd");
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent ev) {
System.out.println(ev.KEY_PRESSED);
System.out.println("Sth happening!");
System.out.println(ev.getKeyCode());
int evID = ev.getID();
String keyString;
int keyCode;
if (evID == KeyEvent.KEY_TYPED) {
if (ev.getKeyChar() == KeyEvent.CHAR_UNDEFINED) {
keyCode = ev.getKeyCode();
if (keyCode == 8) {
if (text_selected) {
if (caretPos > cMark) {
for (int i = caretPos; i >= cMark; i--) {
System.out.println("sm1");
sendMessage("DELETE" + " " + String.valueOf(id)
+ " " + String.valueOf(cMark + 1));
}
} else if (caretPos < cMark) {
for (int i = caretPos; i >= cMark; i++) {
System.out.println("sm2");
sendMessage("DELETE" + " " + String.valueOf(id)
+ " " + String.valueOf(cMark + 1));
}
}
} else {
System.out.println("sm3");
sendMessage("DELETE" + " " + String.valueOf(id) + " "
+ String.valueOf(caretPos + 1));
}
}
} else {
char c = ev.getKeyChar();
boolean capital = ev.isShiftDown();
String charString = String.valueOf(c);
if (capital) {
charString.toUpperCase();
}
if (text_selected) {
if (caretPos > cMark) {
for (int i = caretPos; i >= cMark; i--) {
System.out.println("sm4");
sendMessage("DELETE" + " " + String.valueOf(id)
+ " " + String.valueOf(cMark + 1));
}
System.out.println("sm5");
sendMessage("INSERT" + " " + String.valueOf(id) + " "
+ String.valueOf(cMark) + " " + charString);
} else if (caretPos < cMark) {
for (int i = caretPos; i >= cMark; i++) {
System.out.println("sm6");
sendMessage("DELETE" + " " + String.valueOf(id)
+ " " + String.valueOf(caretPos + 1));
}
System.out.println("sm7");
sendMessage("INSERT" + " " + String.valueOf(id) + " "
+ String.valueOf(caretPos) + " " + charString);
}
} else {
System.out.println("sm8");
sendMessage("INSERT" + " " + String.valueOf(id) + " "
+ String.valueOf(caretPos) + " " + charString);
}
}
}
}
public void sendMessage(String s) {
System.out.println("smReal");
out.println(s);
}
#Override
public void caretUpdate(CaretEvent cev) {
int dot = cev.getDot();
int mark = cev.getMark();
caretPos = dot;
cMark = mark;
if (dot == mark) {
text_selected = false;
} else if ((dot < mark) | (dot > mark)) {
text_selected = true;
}
}
}
Here is the code for the client containing the TextArea which calls this Listener.
package client;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.text.DefaultEditorKit;
public class TextEditor extends JFrame {
private static final long serialVersionUID = 5991470239888613993L;
protected static JTextArea document = new JTextArea(20, 120);
private JFileChooser dialog = new JFileChooser(
System.getProperty("user.dir"));
private String currentFile = "Untitled";
private boolean changed = false;
private int id;
private final BufferedReader in;
private final PrintWriter out;
public TextEditor(final PrintWriter out, final BufferedReader in, int id) {
this.out = out;
this.in = in;
this.id = id;
document.setFont(new Font("Monospaced", Font.PLAIN, 12));
JScrollPane scroll = new JScrollPane(document,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
this.add(scroll, BorderLayout.CENTER);
JMenuBar JMB = new JMenuBar();
this.setJMenuBar(JMB);
JMenu file = new JMenu("File");
JMenu edit = new JMenu("Edit");
JMB.add(file);
JMB.add(edit);
file.add(Open);
file.add(Save);
file.add(Quit);
file.add(SaveAs);
file.addSeparator();
for (int i = 0; i < 4; i++)
file.getItem(i).setIcon(null);
edit.add("Cut");
edit.add("Copy");
edit.add("Paste");
edit.getItem(0).setText("Cut");
edit.getItem(1).setText("Copy");
edit.getItem(2).setText("Paste");
JToolBar tool = new JToolBar();
this.add(tool, BorderLayout.NORTH);
tool.add(Open);
tool.add(Save);
tool.addSeparator();
JButton cut = tool.add(Cut), copy = tool.add(Copy), paste = tool
.add(Paste);
cut.setText(null);
cut.setIcon(new ImageIcon("cut.png"));
copy.setText(null);
copy.setIcon(new ImageIcon("copy.png"));
paste.setText(null);
paste.setIcon(new ImageIcon("paste.png"));
Save.setEnabled(false);
SaveAs.setEnabled(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
document.addKeyListener(new JTextAreaListen(out, in, id));
setTitle(currentFile);
setVisible(true);
final int id2 = id;
Thread t = new Thread(new Runnable() {
public void run() {
out.println("GET " + id2);
while (true) {
out.println("GET " + id2);
String line = null;
do {
try {
line = in.readLine();
} catch (IOException e) {
JOptionPane.showMessageDialog(null,
"Connection Lost", "Error",
JOptionPane.ERROR_MESSAGE);
System.exit(-1);
}
} while (line == null);
int temp = JTextAreaListen.caretPos;
document.setText(line);
document.setCaretPosition(temp);
}
}
});
t.start();
}
private KeyListener keyPressed = new KeyAdapter() {
public void keyPressed(KeyEvent e) {
changed = true;
Save.setEnabled(true);
SaveAs.setEnabled(true);
}
};
Action Open = new AbstractAction("Open", new ImageIcon("open.png")) {
private static final long serialVersionUID = -474289105133169886L;
public void actionPerformed(ActionEvent e) {
saveOld();
if (dialog.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
readInFile(dialog.getSelectedFile().getAbsolutePath());
}
SaveAs.setEnabled(true);
}
};
Action Save = new AbstractAction("Save", new ImageIcon("save.png")) {
private static final long serialVersionUID = 2064233284536910855L;
public void actionPerformed(ActionEvent e) {
if (!currentFile.equals("Untitled"))
saveFile(currentFile);
else
saveFileAs();
}
};
Action SaveAs = new AbstractAction("Save as...") {
private static final long serialVersionUID = -5473532525926088880L;
public void actionPerformed(ActionEvent e) {
saveFileAs();
}
};
Action Quit = new AbstractAction("Quit") {
private static final long serialVersionUID = -5339245808869817726L;
public void actionPerformed(ActionEvent e) {
saveOld();
System.exit(0);
}
};
ActionMap m = document.getActionMap();
Action Cut = m.get(DefaultEditorKit.cutAction);
Action Copy = m.get(DefaultEditorKit.copyAction);
Action Paste = m.get(DefaultEditorKit.pasteAction);
private void saveFileAs() {
if (dialog.showSaveDialog(null) == JFileChooser.APPROVE_OPTION)
saveFile(dialog.getSelectedFile().getAbsolutePath());
}
private void saveOld() {
if (changed) {
if (JOptionPane.showConfirmDialog(this, "Save " + currentFile
+ " ?", "Save", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
saveFile(currentFile);
}
}
private void readInFile(String fileName) {
try {
FileReader r = new FileReader(fileName);
document.read(r, null);
r.close();
currentFile = fileName;
setTitle(currentFile);
changed = false;
} catch (IOException e) {
Toolkit.getDefaultToolkit().beep();
JOptionPane.showMessageDialog(this, "Could not find " + fileName);
}
}
private void saveFile(String fileName) {
try {
FileWriter w = new FileWriter(fileName);
document.write(w);
w.close();
currentFile = fileName;
setTitle(currentFile);
changed = false;
Save.setEnabled(false);
} catch (IOException e) {
JOptionPane
.showMessageDialog(this,
"An error has occurred. Your document may not have been saved");
}
}
}