Saturday, February 27, 2016

Selenium : All About Reports


All ABout Reports :



http://examples.javacodegeeks.com/enterprise-java/testng/testng-html-xml-reports-example/
https://seleniumexperience.wordpress.com/2013/07/25/generating-custom-reports-with-testng/
http://kaczanowscy.pl/tomek/2009-11/testng-listeners-apache-velocity-and-css
https://solidsoft.wordpress.com/2011/01/23/better-looking-html-test-reports-for-testng-with-reportng-maven-guide/

Gradle :File Operations

Gradle :File Opertions 



https://www.safaribooksonline.com/library/view/gradle-beyond-the/9781449373801/ch01.html

Gradle: A trivial copy task configuration

task copyPoems(type: Copy) {
  from 'text-files'
  into 'build/poems'
}


Gradle: A copy task that copies all the poems except the one by Henley

task copyPoems(type: Copy) {
  from 'text-files'
  into 'build/poems'
  exclude '**/*henley*'
}


Gradle: A copy task that only copies Shakespeare and Shelley

task copyPoems(type: Copy) {
  from 'text-files'
  into 'build/poems'
  include '**/sh*.txt'
}


Gradle: A copy task taking files from more than one source directory

task complexCopy(type: Copy) {
  from('src/main/templates') {
    include '**/*.gtpl'
  }
  from('i18n')
  from('config') {
    exclude 'Development*.groovy'
  }
  into 'build/resources'
}


Gradle: A copy task mapping source directory structure onto a new destination structure

task complexCopy(type: Copy) {
  from('src/main/templates') {
    include '**/*.gtpl'
    into 'templates'
  }
  from('i18n')
  from('config') {
    exclude 'Development*.groovy'
    into 'config'
  }
  into 'build/resources'
}


Gradle: Renaming files using regular expressions

task rename(type: Copy) {
  from 'source'
  into 'dest'
  rename(/file-template-(\d+)/, 'production-file-$1.txt')
}


Gradle: Renaming files programmatically

task rename(type: Copy) {
  from 'source'
  into 'dest'
  rename { fileName ->
    "production-file${(fileName - 'file-template')}"
  }
}

 
Gradle: Copying a file with keyword expansion

versionId = '1.6'

task copyProductionConfig(type: Copy) {
  from 'source'
  include 'config.properties'
  into 'build/war/WEB-INF/config'
  expand([
    databaseHostname: 'db.company.com',
    version: versionId,
    buildNumber: (int)(Math.random() * 1000),
    date: new Date()
  ])
}

Java :Classpath and library error even when dependencies are added to Gradle

Classpath and library error even when dependencies are added to Gradle


I have added all dependencies in "build.gradle" required for a selenium project.But still i am getting error when i try to launch a firefox driver using : WebDriver driver = new FirefoxDriver();


Solution : 
 
1. Make sure that you have imported the FirefoxDriver class in your code. Add the following line in your import section.

    import org.openqa.selenium.firefox.FirefoxDriver;

2. Clean the Gradle project (https://www.jetbrains.com/idea/help/gradle-tool-window.html)
3. Refresh the project (File>Synchronize)
4. Use the refresh button in Gradle Tool Window if ".gradle" file is edited
https://www.jetbrains.com/idea/help/gradle-tool-window.html


Note :All Dependencies add should appear in Gradle Tool Window >Dependencies

Java : Ivy (Gradle)

Java : Ivy



Apache Ivy was developed as an extension to the Ant build tool to provide Maven-style binary artifact management. It was never deployed as widely as Maven-style repos

Gradle :Declaring an Ivy repository using the default Maven layout

repositories {
  ivy {
    url 'http://build.megacorp.com/ivy/repo'
  }
}

Java :Maven Repositories(Gradle)

Java :Maven Repositories


https://www.safaribooksonline.com/library/view/gradle-beyond-the/9781449373801/ch04.html

Since a Maven repository is nothing more than a website containing downloadable POM files and modules in a predictable directory structure, declaring a Maven repository in Gradle begins with telling Gradle the URL of the repo. '

The most common Maven repository http://repo1.maven.org/maven2/ ( to avoid scripting that URL directly into your build).

Gradle: Declaring the Central repository
repositories {
  mavenCentral()
}


Other open-source Maven repositories exist on the Internet, Sonatype’s Nexus and JFrog’s Artifactory

Gradle : Declaring Maven repositories in general
repositories {
  maven {
    url = 'http://download.java.net/maven/2'
  }
  maven {
    name = 'JBoss Repo'  //optional name
    url = 'https://repository.jboss.org/nexus/content/repositories/releases'
  }
}


To download build artifacts from a mirrored copy of the repo somewhere else in the network

Gradle: Setting the artifact URL as distinct from the default POM URL

repositories {
  // Overriding artifacts for an internal repo
  maven {
    url = 'http://central.megacorp.com/main/repo'
    artifactUrls = [ 'http://dept.megacorp.com/local/repo' ]
  }
  // Obtain Maven Central artifacts locally
  mavenCentral artifactUrls: ['http://dept.megacorp.com/maven/central']
}

-----------------

Friday, February 26, 2016

Java :IS-A and HAS-A

IS-A and HAS-A

http://stackoverflow.com/questions/9677545/what-do-has-a-and-is-a-mean?lq=1
http://stackoverflow.com/questions/2218937/has-a-is-a-terminology-in-object-oriented-language


Has-a means that the Class in question 'has a' field of a type.

Is-a means that the Class extends from a superclass or implements an interface. The instanceof operator would return true if tested against a class in the this case.

Example

class SteeringWheel{}

class Vehicle{}
 
interface transport 

class Car extends Vehicle implements transport
{
    SteeringWheel  sWheel;
   
}

  • A car is-a vehicle and it is for transport
  • A car has-a steering wheel

Java : Why multiple inheritance not allowed in Java (Diamond Problem) and Solution

Why multiple inheritance not allowed in Java (Diamond Problem) and Solution 


Problem :

class A { 
int i; 
void msg() {
        System.out.println("From A");
    } 
}

class B { 
  int i;   
void msg() {
        System.out.println("From B");
    } 
}

class C extends A,B {         // suppose if this was possible
    public static void main(String[] args) { 

        super.msg();                 // which msg() method would be invoked?   

 }
}

Solution 1: Using interface’s reference
interface Moveable{
    default void run(){
        System.out.println("I am running, kid !!");
    }
}
  
interface Crawlable{
    default void run(){
        System.out.println("I am running, daddy !!");
    }
}
  
public class Animal implements Moveable, Crawlable {
    public static void main(String[] args)
    {
        Moveable.super.run(); 
         Crawlable.super.run();
    }
}
So solve above conflict, caller class must decide which run() method it want to invoke and then call using

 
Solution 2 : Using Tree pattern

public class Canine extends Animal{}
public class Dog extends Canine{}

Solution 3 : Creating Object Instances 

class mobile_phone { void call(){}}
class tablet {void big_screen(){} }

class phablet {
                mobile_phone m;
                tablet  t;

phablet(){
                m= new mobile_phone ();
                t=  new tablet  ();
}
test(){
m.call();
t.big_screen();
}

Wednesday, February 24, 2016

Java :Method Chaining (Builder Pattern)

Method Chaining (Builder Pattern)


While writing codes , ever wondered how Java codes (Selenium) or vbs (QTP) allows user todo something like : Object.method().method() .... and so on .

Eg :
Browser("Jobs").Page("QTP").WebElement(" ") //In QTP
Webdriver.FindElement("xxxx").sendkeys("123) ; //In Selenium

The above style uses a pattern called Builder pattern  internally.

Example :

public class test1 {
    public static void main(String[] args){
        animal a =new animal();
        a.set_name("dog").bites(false);
    }
}



public class animal {
    String animal_name;
    boolean Bites;

    public animal set_name(String animal_name){
        this.animal_name=animal_name;
        return this;
    }

    public animal bites(boolean Bites){
        this.Bites=Bites;
        return this;
    }
}


Thing to notice :
1. Each method uses "this" keyword while returning
2. Each method returns an object of the class type.

End Result :
 a.set_name("dog").bites(false);

What it means ?

Tuesday, February 23, 2016

Java:Gradle Tut

Gradle



http://www.vogella.com/tutorials/Gradle/article.html
https://docs.gradle.org/current/userguide/tutorial_using_tasks.html
https://develosapiens.wordpress.com/2015/05/08/playing-with-gradle/
http://blog.bbv.ch/2012/09/12/the-gradle-build-system-a-short-overview/
http://www.drdobbs.com/jvm/writing-build-scripts-with-gradle/240168648?pgno=1

Java : IntelliJ gitIgnore

IntelliJ gitIgnore


download : https://plugins.jetbrains.com/plugin/7495?pr=idea

This is used to ignore those files that user does not want to merge ,copy or store it in Git.
  1. Download jar file to your local
  2. Open IntelliJ >File>Settings >Plugins
  3. Click button "Install plugin from disk"
  4. Select the file in the file browser 
  5. Click apply
  6. Restart IntelliJ

After restart , goto you main project right click >New > ignorefile>gitIgnore file

Java : Gradle Advantages

Gradle Advantages


Advantages of Maven:
- configure and intercept all build phases of your project with the use of plugins
- dependeny management
- distribution management
- scm integration
- well integrated with Continous Integration environments such as Jenkins.

Disadvantages of Maven:
 - XML syntax
 - extending maven with your own plugin can be too much expensive.
 - it is focused on Java projects
Advantages of Gradle: 

 - Possibility to write your own tasks in Groovy (tasks are based on task Ant model).
 - POM generation.
 - reuse of all Maven repositories
 - integration with Ivy repositories
 - polyglot build system to integrate projects with different tenchnologies and programmin languages.

- Gradle has goodness of Ant and Maven put together
- minus the noise of XML.

Java : Wrapper

Wrapper


Use : 
  1. To convert simple data types into objects
  2.  To convert strings into data types
Example :
int k = 100;
Integer obj = new Integer(k); 

 int m = obj.intValue(); //UnWrapp

The int data type k is converted into an object, obj using Integer class. The obj object can be used in Java programming wherever k is required an object.

Primitive datatype and     Wrapper and class

  • byte     and     Byte
  • short     and     Short
  • int     and     Integer
  • long     and     Long
  • float     and     Float
  • double     and     Double
  • char     and     Character
  • boolean and     Boolean

Code :

public class WrappingUnwrapping
{
  public static void main(String args[])
  {                                  //  data types
    byte grade = 2;
    int marks = 50;
    float price = 8.6f;                         // observe a suffix of <strong>f</strong> for float
    double rate = 50.5;
                                           // data types to objects      
    Byte g1 = new Byte(grade);                    // wrapping 
    Integer m1 = new Integer(marks);
    Float f1 = new Float(price);
    Double r1 = new Double(rate);
                                                                    // let us print the values from objects  
    System.out.println("Values of Wrapper objects (printing as objects)");
    System.out.println("Byte object g1:  " + g1);
    System.out.println("Integer object m1:  " + m1);
    System.out.println("Float object f1:  " + f1);
    System.out.println("Double object r1:  " + r1);
            // objects to data types (retrieving data types from objects)
    byte bv = g1.byteValue();                 // unwrapping
    int iv = m1.intValue();
    float fv = f1.floatValue();
    double dv = r1.doubleValue();
                                                                    // let us print the values from data types  
    System.out.println("Unwrapped values (printing as data types)");
    System.out.println("byte value, bv: " + bv);
    System.out.println("int value, iv: " + iv);
    System.out.println("float value, fv: " + fv);
    System.out.println("double value, dv: " + dv);
  }
}










Friday, February 19, 2016

Notepad++ : Remove Empty Lines from text

Remove Empty Lines from text Notepad++



Edit -> Line Operations -> Remove Empty Lines or Remove Empty Lines (Containing Blank characters )

Or Use "EditPad" Lie

  1. At the bottm click on the magnifying glass
  2. To replace new lines with "," - Search="\n" , replace ","
or
EditPad > Extra >Delete Blank Lines 

Thursday, February 18, 2016

Selenium : Create Custom TestNG Report

Create Custom TestNG Report

http://www.testingdiaries.com/testng-reports-atu-reporter/ 

http://www.seleniumeasy.com/testng-tutorials/testng-customize-emailable-html-report-example


testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Main Test Suite" verbose="5">

<parameter name="appURL" value="https://www.google.co.in/"/>
<parameter name="browserType" value="firefox"/>

   <listeners>
         <listener class-name="com.easy.TestNGCustomReportListener" />
    </listeners>
    <test name="TestNG Test Group">
        <packages>
            <package name="com.tests" />
        </packages>
    </test>
</suite>

Project Tree
Customized TestNG Report



 Code :
package com.custom;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

import org.testng.IInvokedMethod;
import org.testng.IReporter;
import org.testng.IResultMap;
import org.testng.ISuite;
import org.testng.ISuiteResult;
import org.testng.ITestClass;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.collections.Lists;
import org.testng.internal.Utils;
import org.testng.xml.XmlSuite;

public class TestNGCustomReportListener implements IReporter{

    private PrintWriter writer;
    private int m_row;
    private Integer m_testIndex;
    private int m_methodIndex;
    private String reportTitle= "TestNG Customized Report";
    private String reportFileName = "custom-report.html";

    /** Creates summary of the run */
    @Override
    public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites,
                               String outdir) {
        try {
            writer = createWriter(outdir);
        } catch (IOException e) {
            System.err.println("Unable to create output file");
            e.printStackTrace();
            return;
        }

        startHtml(writer);
        writeReportTitle(reportTitle);
        generateSuiteSummaryReport(suites);
        generateMethodSummaryReport(suites);
        generateMethodDetailReport(suites);
        endHtml(writer);
        writer.flush();
        writer.close();
    }

    protected PrintWriter createWriter(String outdir) throws IOException {
        new File(outdir).mkdirs();
        return new PrintWriter(new BufferedWriter(new FileWriter(new File(outdir, reportFileName))));
    }

    /**
     * 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++;
            }
        }
        writer.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) {
                    writer.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 + " &#8212; " + style + details, 5, id);
                    m_testIndex = null;
                }
                if (!className.equalsIgnoreCase(lastClassName)) {
                    if (mq > 0) {
                        cq += 1;
                        writer.print("<tr class=\"\"" + style + (cq % 2 == 0 ? "even" : "odd") + ">" + "<td");
                        if (mq > 1) {
                            writer.print(" rowspan=\"\" + mq + \"\"");
                        }
                        writer.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;
                long startMS=0;
                String firstLine="";

                for (ITestResult testResult : tests.getResults(method)) {
                    if (testResult.getEndMillis() > end) {
                        end = testResult.getEndMillis()/1000;
                    }
                    if (testResult.getStartMillis() < start) {
                        startMS = testResult.getStartMillis();
                        start =startMS/1000;
                    }

                    Throwable exception=testResult.getThrowable();
                    boolean hasThrowable = exception != null;
                    if(hasThrowable){
                        String str = Utils.stackTrace(exception, true)[0];
                        Scanner scanner = new Scanner(str);
                        firstLine = scanner.nextLine();
                    }
                }
                DateFormat formatter = new SimpleDateFormat("hh:mm:ss");
                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(startMS);

                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\" style=\"text-align:left;padding-right:2em\">" + firstLine+"<br/></td>"
                        + "<td style=\"text-align:right\">" + formatter.format(calendar.getTime()) + "</td>" + "<td class=\"numi\">"
                        + timeConversion(end - start) + "</td>" + "</tr>");

            }
            if (mq > 0) {
                cq += 1;
                writer.print("<tr class=\"" + style + (cq % 2 == 0 ? "even" : "odd") + "\">" + "<td");
                if (mq > 1) {
                    writer.print(" rowspan=\"" + mq + "\"");
                }
                writer.println(">" + lastClassName + "</td>" + buff);
            }
        }
    }


    private String timeConversion(long seconds) {

        final int MINUTES_IN_AN_HOUR = 60;
        final int SECONDS_IN_A_MINUTE = 60;

        int minutes = (int) (seconds / SECONDS_IN_A_MINUTE);
        seconds -= minutes * SECONDS_IN_A_MINUTE;

        int hours = minutes / MINUTES_IN_AN_HOUR;
        minutes -= hours * MINUTES_IN_AN_HOUR;

        return prefixZeroToDigit(hours) + ":" + prefixZeroToDigit(minutes) + ":" + prefixZeroToDigit((int)seconds);
    }

    private String prefixZeroToDigit(int num){
        int number=num;
        if(number<=9){
            String sNumber="0"+number;
            return sNumber;
        }
        else
            return ""+number;

    }

    /** Starts and defines columns result summary table */
    private void startResultSummaryTable(String style) {
        tableStart(style, "summary");
        writer.println("<tr><th>Class</th>"
                + "<th>Method</th><th>Exception Info</th><th>Start Time </th><th>Execution Time<br/>(hh:mm:ss)</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) {
        Set<ITestResult> testResults=tests.getAllResults();
        List<ITestResult> testResultsList = new ArrayList<ITestResult>(testResults);
        System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
        System.setProperty("java.util.Collections.useLegacyMergeSort", "true");
        Collections.sort(testResultsList, new TestResultsSorter());
        for (ITestResult result : testResultsList) {
            ITestNGMethod method = result.getMethod();
            m_methodIndex++;
            String cname = method.getTestClass().getName();
            writer.println("<h2 id=\"m" + m_methodIndex + "\">" + cname + ":"
                    + method.getMethodName() + "</h2>");
            Set<ITestResult> resultSet = tests.getResults(method);
            generateResult(result, method, resultSet.size());
            writer.println("<p class=\"totop\"><a href=\"#summary\">back to summary</a></p>");

        }
    }

    private void generateResult(ITestResult ans, ITestNGMethod method,
                                int resultSetSize) {
        Object[] parameters = ans.getParameters();
        boolean hasParameters = parameters != null && parameters.length > 0;
        if (hasParameters) {
            tableStart("result", null);
            writer.print("<tr class=\"param\">");
            for (int x = 1; x <= parameters.length; x++) {
                writer.print("<th>Param." + x + "</th>");
            }
            writer.println("</tr>");
            writer.print("<tr class=\"param stripe\">");
            for (Object p : parameters) {
                writer.println("<td>" + Utils.escapeHtml(Utils.toString(p))
                        + "</td>");
            }
            writer.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) {
                writer.print("<tr><td");
                if (parameters.length > 1) {
                    writer.print(" colspan=\"\" + parameters.length + \"\"");
                }
                writer.println(">");
            } else {
                writer.println("<div>");
            }
            if (hasReporterOutput) {
                if (hasThrowable) {
                    writer.println("<h3>Test Messages</h3>");
                }
                for (String line : msgs) {
                    writer.println(line + "<br/>");
                }
            }
            if (hasThrowable) {
                boolean wantsMinimalOutput = ans.getStatus() == ITestResult.SUCCESS;
                if (hasReporterOutput) {
                    writer.println("<h3>"
                            + (wantsMinimalOutput ? "Expected Exception"
                            : "Failure") + "</h3>");
                }
                generateExceptionReport(exception, method);
            }
            if (hasParameters) {
                writer.println("</td></tr>");
            } else {
                writer.println("</div>");
            }
        }
        if (hasParameters) {
            writer.println("</table>");
        }
    }

    protected void generateExceptionReport(Throwable exception, ITestNGMethod method) {
        writer.print("<div class=\"stacktrace\">");
        writer.print(Utils.stackTrace(exception, true)[0]);
        writer.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);
            }
        }

        System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
        System.setProperty("java.util.Collections.useLegacyMergeSort", "true");
        Collections.sort(r,new TestSorter());
        List<ITestNGMethod> result = Lists.newArrayList();

        // Add all the invoked methods
        for (IInvokedMethod m : r) {
            for (ITestNGMethod temp : result) {
                if (!temp.equals(m.getTestMethod()))
                    result.add(m.getTestMethod());
            }
        }

        // Add all the methods that weren't invoked (e.g. skipped) that we
        // haven't added yet
        Collection<ITestNGMethod> allMethodsCollection=tests.getAllMethods();
        List<ITestNGMethod> allMethods=new ArrayList<ITestNGMethod>(allMethodsCollection);
        Collections.sort(allMethods, new TestMethodSorter());

        for (ITestNGMethod m : allMethods) {
            if (!result.contains(m)) {
                result.add(m);
            }
        }
        return result;
    }

    @SuppressWarnings("unused")
    public void generateSuiteSummaryReport(List<ISuite> suites) {
        tableStart("testOverview", null);
        writer.print("<tr>");
        tableColumnStart("Test");
        tableColumnStart("Methods<br/>Passed");
        tableColumnStart("# skipped");
        tableColumnStart("# failed");
        tableColumnStart("Browser");
        tableColumnStart("Start<br/>Time");
        tableColumnStart("End<br/>Time");
        tableColumnStart("Total<br/>Time(hh:mm:ss)");
        tableColumnStart("Included<br/>Groups");
        tableColumnStart("Excluded<br/>Groups");

        writer.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;
        long time_start = Long.MAX_VALUE;
        int qty_fail = 0;
        long time_end = Long.MIN_VALUE;
        m_testIndex = 1;
        for (ISuite suite : suites) {
            if (suites.size() >= 1) {
                titleRow(suite.getName(), 10);
            }
            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 = getMethodSet(overview.getSkippedTests(), suite).size();
                qty_skip += q;
                summaryCell(q, 0);
                q = getMethodSet(overview.getFailedTests(), suite).size();
                qty_fail += q;
                summaryCell(q, 0);

                // Write OS and Browser
                summaryCell(suite.getParameter("browserType"), true);
                writer.println("</td>");

                SimpleDateFormat summaryFormat = new SimpleDateFormat("hh:mm:ss");
                summaryCell(summaryFormat.format(overview.getStartDate()),true);
                writer.println("</td>");

                summaryCell(summaryFormat.format(overview.getEndDate()),true);
                writer.println("</td>");

                time_start = Math.min(overview.getStartDate().getTime(), time_start);
                time_end = Math.max(overview.getEndDate().getTime(), time_end);
                summaryCell(timeConversion((overview.getEndDate().getTime() - overview.getStartDate().getTime()) / 1000), true);

                summaryCell(overview.getIncludedGroups());
                summaryCell(overview.getExcludedGroups());
                writer.println("</tr>");
                m_testIndex++;
            }
        }
        if (qty_tests > 1) {
            writer.println("<tr class=\"total\"><td>Total</td>");
            summaryCell(qty_pass_m, Integer.MAX_VALUE);
            summaryCell(qty_skip, 0);
            summaryCell(qty_fail, 0);
            summaryCell(" ", true);
            summaryCell(" ", true);
            summaryCell(" ", true);
            summaryCell(timeConversion(((time_end - time_start) / 1000)), true);
            writer.println("<td colspan=\"3\">&nbsp;</td></tr>");
        }
        writer.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) {
        writer.print("<td class=\"numi" + (isgood ? "" : "_attn") + "\">" + v
                + "</td>");
    }

    private void startSummaryRow(String label) {
        m_row += 1;
        writer.print("<tr" + (m_row % 2 == 0 ? " class=\"stripe\"" : "") + "><td style=\"text-align:left;padding-right:2em\"><a href=\"#t"
                + m_testIndex +"\"><b>" + label + "</b></a>" + "</td>");

    }

    private void summaryCell(int v, int maxexpected) {
        summaryCell(String.valueOf(v), v <= maxexpected);
    }

    private void tableStart(String cssclass, String id) {
        writer.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) {
        writer.print("<th>" + label + "</th>");
    }

    private void titleRow(String label, int cq) {
        titleRow(label, cq, null);
    }

    private void titleRow(String label, int cq, String id) {
        writer.print("<tr");
        if (id != null) {
            writer.print(" id=\"" + id + "\"");
        }
        writer.println("><th colspan=\"" + cq + "\">" + label + "</th></tr>");
        m_row = 0;
    }

    protected void writeReportTitle(String title) {
        writer.print("<center><h1>" + title + " - " + getDateAsString() + "</h1></center>");
    }


    /*
     * Method to get Date as String
     */
    private String getDateAsString() {
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date = new Date();
        return dateFormat.format(date);
    }

    /** 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(“<html xmlns=\”http://www.w3.org/1999/xhtml\”>”);
        out.println("<head>");
        out.println("<title>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> TestNG Report </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 obj1, IInvokedMethod obj2) {
            int r = obj1.getTestMethod().getTestClass().getName().compareTo(obj2.getTestMethod().getTestClass().getName());
            return r;
        }
    }

    private class TestMethodSorter implements Comparator<ITestNGMethod> {
        @Override
        public int compare(ITestNGMethod obj1, ITestNGMethod obj2) {
            int r = obj1.getTestClass().getName().compareTo(obj2.getTestClass().getName());
            if (r == 0) {
                r = obj1.getMethodName().compareTo(obj2.getMethodName());
            }
            return r;
        }
    }

    private class TestResultsSorter implements Comparator<ITestResult> {
        @Override
        public int compare(ITestResult obj1, ITestResult obj2) {
            int result = obj1.getTestClass().getName().compareTo(obj2.getTestClass().getName());
            if (result == 0) {
                result = obj1.getMethod().getMethodName().compareTo(obj2.getMethod().getMethodName());
            }
            return result;
        }
    }

}