ch.fortysix.maven.plugin.postaman.surfire.SurefireMailMojo.groovy Maven / Gradle / Ivy
package ch.fortysix.maven.plugin.postaman.surfire
/**
*
*/
import java.io.File;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.List;
import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReportException;
import ch.fortysix.maven.plugin.postaman.AbstractSenderMojo;
import ch.fortysix.maven.report.support.HtmlExtractor;
import ch.fortysix.maven.report.support.SinkReporter;
/**
* Sends mails based on surefire (test) results.
*
* @author Domi
* @goal surefire-mail
* @phase site
*/
class SurefireMailMojo extends AbstractSenderMojo {
/**
* The file pattern to be used to search for the surefire reports in the 'testReportsDirectory'-directory.
*
* @parameter default-value="TEST-.*.xml"
*/
String reportFilePattern
/**
* This allows to redefine the condition to send the mail. e.g. one can define that there
* must not be more then 20 skipped test cases (skipped > 20
).
* The default condition sends mails if there are any errors.
* The following variables are available for usage in the condition:
*
* errors
: number of all errors while running surefire
* skipped
: number of all skipped test cases
* failures
: number of all failures in the test cases
* total
: number of all test cases
*
* Other (usefull or not...) examples:
*
* errors > 0
: sends a mail only if there are errors
* skipped > failures
: sends mails if there are more skipped then failed test cases
* total == skipped
: Sends mails if all tests are skipped
*
* To avoid problems with XML syntax, one can use a CDATA element.
* The default only send a mail if there are errors or failures, but ignores the skipped ones.
* @parameter default-value="errors > 0 || failures > 0"
*/
String groovyCondition
/**
* Base directory where all surefire test reports are read from.
* @parameter expression="${project.build.directory}/surefire-reports" default-value="${project.build.directory}/surefire-reports"
*/
File testReportsDirectory
/**
* The generated surefire html report (previously generated by 'maven-surefire-report-plugin').
* @parameter default-value="${project.build.directory}/site/surefire-report.html"
*/
File surefireReportHtml;
protected boolean prepareMojo(){
if(!testReportsDirectory || !testReportsDirectory.exists()){
getLog().error """
'testReportsDirectory' could not be found ($testReportsDirectory).
- Do you have the 'maven-surefire-plugin' configured or are the reports generated to a different directory?
- Is the 'maven-surefire-plugin' executed befor this plugin?
"""
return false
}
if(surefireReportHtml && !surefireReportHtml.exists()){
getLog().warn """
The postman-surefire mails will not contain HTML, because the surefire report could not be found.
- 'maven-surefire-report-plugin' must run befor 'maven-postman-plugin', set phase to 'site'!
"""
}
return true
}
public void executeMojo() throws MojoExecutionException, MojoFailureException {
// Analyze the test reports
TestReportUtil util = new TestReportUtil(log: getLog())
def suiteReports = util.getTestSuiteReport( testReportsDirectory, reportFilePattern)
////////////////////////////////////////////////////
//
// evaluate if the condition tells us to send the mails
// - prepare variables
def errors = suiteReports.inject(0) { count, suiteReport ->
count + suiteReport?.errors
}
log.debug "test ERRORS: "+ errors
def skipped = suiteReports.inject(0) { count, suiteReport ->
count + suiteReport?.skipped
}
log.debug "test SKIPPED: "+ skipped
def failures = suiteReports.inject(0) { count, suiteReport ->
count + suiteReport?.failures
}
log.debug "test FAILURES: "+ failures
def tests = suiteReports.inject(0) { count, suiteReport ->
count + suiteReport?.tests
}
log.debug "test TOTAL: "+ tests
// - bind the variables
Binding binding = new Binding();
binding.setVariable("errors", errors);
binding.setVariable("skipped", skipped);
binding.setVariable("failures", failures);
binding.setVariable("total", tests);
// - evaluate
log.info "evaluating groovy condition [$groovyCondition]"
GroovyShell shell = new GroovyShell(binding);
def value
try{
value = shell.evaluate(groovyCondition);
}catch (Exception e){
throw new MojoExecutionException("postman is not able to evaluate the configured 'groovyCondition': $groovyCondition", e)
}
boolean sendIt = value as Boolean
// we send the same report to all receivers
if(sendIt){
def mail = this.createMail(suiteReports)
context.run ([mail])
}else{
log.info "postman surfire report groovy condition [$groovyCondition] not fulfilled, don't send the mails..."
}
}
/**
* create the mail to be send/reported.
*/
public Map createMail(List suiteReports){
def html = htmlMessageFile?.text
html = html ? html : htmlMessage
def txt = textMessageFile?.text
txt = txt ? txt : textMessage
if(!html){
// if no html was configured in the plugin, we try to use the html report
if(surefireReportHtml && surefireReportHtml.exists()){
// get the html of the generated surefire report (maven-surefire-report-plugin)
if(surefireReportHtml.text){
HtmlExtractor htmlExtractor = new HtmlExtractor()
html = htmlExtractor.extractHTMLTagById(html: surefireReportHtml.text, tagName: "div", tagId: "bodyColumn")
}
} else{
log.warn "can't include HTML report to postman-surefire mail ($surefireReportHtml not found)"
}
}
if(!txt){
// if no text was configured in the plugin, we create a basic report our self
def body = new StringBuilder()
suiteReports.each{ report ->
body << "\n"
body << report.name << " (total: " << report.tests << ") errors: " << report.errors << ", failures: " << report.failures << ", skipped: " << report.skipped
}
txt = body.toString()
}
if(!html){
html = txt
}
return [receivers: receivers, from: from, subject: subject, text: txt, html: html]
}
}