Permalink
Browse files

Adds the Ability To Define Custom Reporters (#299)

* Updates error message tested for when test suite fails on a syntax error

* Adds the ability to define Standard Out reporters through plugin configuration.

- Adds `reporters` property to support list of reports.
- Adds example project and cucumber test defining custom reporters
- Adds documentation for defining custom reporters.
- Allows `STANDARD` to be used as a reporter in the list defined
  reporters.
- Defaults to the `STANDARD` reporter if none are provided.
- Splits responsibilities out of classes that were growing large and
  difficult to test. `AbstractJasmineMojo` and `SpecRunnerExecutor`.

* Adds the ability to define File System reporters through plugin configuration.

    - Adds `fileSystemReporters` property to support list of reports.
    - Adds file system reporter to custom reporters example project.
    - Updates documentation for defining custom reporters.
    - Allows `JUNIT_XML` to be used as a file system reporter in the list of defined reporters.
    - Defaults to the `JUNIT_XML` reporter if none are provided.
1 parent 3621727 commit 88e4387b52361442b7a70c84cd2e3625258d4ae2 @samjonester samjonester committed with klieber Aug 11, 2016
Showing with 908 additions and 195 deletions.
  1. +3 −1 Gemfile.lock
  2. +15 −0 features/custom_reporters.feature
  3. +1 −1 features/halt_on_failure.feature
  4. +6 −0 src/main/java/com/github/searls/jasmine/config/JasmineConfiguration.java
  5. +16 −0 src/main/java/com/github/searls/jasmine/io/FileUtilsWrapper.java
  6. +21 −0 src/main/java/com/github/searls/jasmine/model/FileSystemReporter.java
  7. +1 −1 src/main/java/com/github/searls/jasmine/model/JasmineResult.java
  8. +18 −0 src/main/java/com/github/searls/jasmine/model/Reporter.java
  9. +69 −29 src/main/java/com/github/searls/jasmine/mojo/AbstractJasmineMojo.java
  10. +61 −0 src/main/java/com/github/searls/jasmine/mojo/ReporterRetriever.java
  11. +41 −0 src/main/java/com/github/searls/jasmine/mojo/ResourceRetriever.java
  12. +3 −10 src/main/java/com/github/searls/jasmine/mojo/TestMojo.java
  13. +21 −0 src/main/java/com/github/searls/jasmine/runner/ConsoleErrorChecker.java
  14. +38 −63 src/main/java/com/github/searls/jasmine/runner/SpecRunnerExecutor.java
  15. +43 −0 src/main/java/com/github/searls/jasmine/runner/WebDriverWaiter.java
  16. +2 −2 src/main/resources/lib/createJunitXml.js
  17. +87 −0 src/site/markdown/custom-reporters.md.vm
  18. +51 −37 src/test/java/com/github/searls/jasmine/mojo/AbstractJasmineMojoTest.java
  19. +97 −0 src/test/java/com/github/searls/jasmine/mojo/ReporterRetrieverTest.java
  20. +61 −0 src/test/java/com/github/searls/jasmine/mojo/ResourceRetrieverTest.java
  21. +65 −0 src/test/java/com/github/searls/jasmine/runner/ConsoleErrorCheckerTest.java
  22. +40 −51 src/test/java/com/github/searls/jasmine/runner/SpecRunnerExecutorTest.java
  23. +68 −0 src/test/java/com/github/searls/jasmine/runner/WebDriverWaiterTest.java
  24. +49 −0 src/test/resources/examples/jasmine-webapp-custom-reporters/pom.xml
  25. +5 −0 src/test/resources/examples/jasmine-webapp-custom-reporters/src/main/javascript/HelloWorld.js
  26. +11 −0 src/test/resources/examples/jasmine-webapp-custom-reporters/src/test/javascript/ExampleTestSpec.js
  27. +8 −0 src/test/resources/examples/jasmine-webapp-custom-reporters/src/test/resources/logger.js
  28. +7 −0 src/test/resources/examples/jasmine-webapp-custom-reporters/src/test/resources/reporter.js
View
@@ -33,7 +33,6 @@ GEM
domain_name (~> 0.5)
json (1.8.3)
mime-types (2.99)
- mime-types-data (3.2015.1120)
mini_portile (0.6.0)
multi_json (1.11.2)
multi_test (0.1.2)
@@ -89,3 +88,6 @@ DEPENDENCIES
relish
rspec
selenium-webdriver (~> 2.48.1)
+
+BUNDLED WITH
+ 1.12.5
@@ -0,0 +1,15 @@
+Feature: Support custom reporter
+
+ In order to support advanced reporting
+ I want the maven build to allow a custom reporter
+ So that values can be stored in tests, and used later by the reporter
+
+ Scenario: project with javascript using a custom reporter
+
+ Given I am currently in the "jasmine-webapp-custom-reporters" project
+ When I run "mvn clean test"
+ Then the build should succeed
+ And I should see "Results: 2 specs, 0 failures, 0 pending"
+ And I should see "Hello World"
+ And the file "target/jasmine/TEST-jasmine.xml" should have XML "/testsuite[@errors=0 and @tests=2 and @failures=0 and @skipped=0]"
+ And the file "target/jasmine/TEST-jasmine.log" should contain "Hello World"
@@ -25,7 +25,7 @@ Feature: halt the build when a spec failure occurs
When I run "mvn clean test"
Then the build should fail
And I should see ".*JavaScript Console Errors:"
- And I should see ".*SyntaxError: Parse error"
+ And I should see ".*SyntaxError:"
Scenario: project with no failures
@@ -1,5 +1,7 @@
package com.github.searls.jasmine.config;
+import com.github.searls.jasmine.model.FileSystemReporter;
+import com.github.searls.jasmine.model.Reporter;
import com.github.searls.jasmine.model.ScriptSearch;
import com.github.searls.jasmine.mojo.Context;
import com.github.searls.jasmine.runner.SpecRunnerTemplate;
@@ -36,6 +38,10 @@
File getCustomRunnerConfiguration();
+ List<Reporter> getReporters();
+
+ List<FileSystemReporter> getFileSystemReporters();
+
int getAutoRefreshInterval();
boolean isCoffeeScriptCompilationEnabled();
@@ -0,0 +1,16 @@
+package com.github.searls.jasmine.io;
+
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+
+public class FileUtilsWrapper {
+ public String readFileToString(final File file) throws IOException {
+ return FileUtils.readFileToString(file, "UTF-8");
+ }
+
+ public void writeStringToFile(final File file, final String contents) throws IOException {
+ FileUtils.writeStringToFile(file, contents, "UTF-8");
+ }
+}
@@ -0,0 +1,21 @@
+package com.github.searls.jasmine.model;
+
+import java.io.File;
+
+public class FileSystemReporter extends Reporter {
+ public String fileName;
+ public File file;
+
+ public FileSystemReporter() {
+ }
+
+ public FileSystemReporter(String fileName, String reporter) {
+ super(reporter);
+ this.fileName = fileName;
+ }
+
+ public FileSystemReporter(File file, File reporterFile) {
+ super(reporterFile);
+ this.file = file;
+ }
+}
@@ -2,7 +2,7 @@
public class JasmineResult {
- private String details;
+ private String details = "";
public String getDescription() {
return last(getDetails().split("\n"));
@@ -0,0 +1,18 @@
+package com.github.searls.jasmine.model;
+
+import java.io.File;
+
+public class Reporter {
+ public String reporterName;
+ public File reporterFile;
+
+ public Reporter() {}
+
+ public Reporter(String reporterName) {
+ this.reporterName = reporterName;
+ }
+
+ public Reporter(File reporterFile) {
+ this.reporterFile = reporterFile;
+ }
+}
@@ -3,6 +3,8 @@
import com.github.searls.jasmine.config.JasmineConfiguration;
import com.github.searls.jasmine.exception.StringifiesStackTraces;
import com.github.searls.jasmine.io.ScansDirectory;
+import com.github.searls.jasmine.model.FileSystemReporter;
+import com.github.searls.jasmine.model.Reporter;
import com.github.searls.jasmine.model.ScriptSearch;
import com.github.searls.jasmine.runner.SpecRunnerTemplate;
import com.github.searls.jasmine.thirdpartylibs.ProjectClassLoaderFactory;
@@ -13,7 +15,6 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.resource.ResourceManager;
-import org.codehaus.plexus.resource.loader.FileResourceLoader;
import org.eclipse.jetty.server.Connector;
import java.io.File;
@@ -23,8 +24,6 @@
public abstract class AbstractJasmineMojo extends AbstractMojo implements JasmineConfiguration {
- private static final String ERROR_FILE_DNE = "Invalid value for parameter '%s'. File does not exist: %s";
-
// Properties in order of most-to-least interesting for client projects to override
/**
@@ -103,6 +102,42 @@
protected String customRunnerConfiguration;
/**
+ * <p> Specify a custom reporter to be used to print the test report.</p>
+ * <p>Example usage:</p>
+ * <pre>
+ * &lt;reporters&gt;
+ * &lt;reporter&gt;
+ * &lt;reporterName&gt;${project.basedir}/src/test/resources/myCustomReporter.js&lt;/reporterName&gt;
+ * &lt;/reporter&gt;
+ * &lt;reporter&gt;
+ * &lt;reporterName&gt;STANDARD&lt;/reporterName&gt;
+ * &lt;/reporter&gt;
+ * &lt;/reporters&gt;
+ * </pre>
+ */
+ @Parameter
+ protected List<Reporter> reporters = new ArrayList<Reporter>();
+
+ /**
+ * <p> Specify a custom file system reporter to be used to store the test report.</p>
+ * <p>Example usage:</p>
+ * <pre>
+ * &lt;fileSystemReporters&gt;
+ * &lt;reporter&gt;
+ * &lt;fileName&gt;MyFile.log&lt;/fileName&gt;
+ * &lt;reporterName&gt;${project.basedir}/src/test/resources/myCustomReporter.js&lt;/reporterName&gt;
+ * &lt;/reporter&gt;
+ * &lt;reporter&gt;
+ * &lt;fileName&gt;Test-jasmine.xml&lt;/fileName&gt;
+ * &lt;reporterName&gt;JUNIT_XML&lt;/reporterName&gt;
+ * &lt;/reporter&gt;
+ * &lt;/fileSystemReporters&gt;
+ * </pre>
+ */
+ @Parameter
+ protected List<FileSystemReporter> fileSystemReporters = new ArrayList<FileSystemReporter>();
+
+ /**
* Target directory for files created by the plugin.
*
* @since 1.1.0
@@ -364,20 +399,21 @@
protected MavenProject mavenProject;
@Component
- protected ResourceManager locator;
+ ResourceManager resourceManager;
- protected ScriptSearch sources;
- protected ScriptSearch specs;
+ protected ResourceRetriever resourceRetriever;
+ protected ReporterRetriever reporterRetriever;
protected StringifiesStackTraces stringifiesStackTraces = new StringifiesStackTraces();
+ protected ScriptSearch sources;
+ protected ScriptSearch specs;
+
private File customRunnerTemplateFile;
private File customRunnerConfigurationFile;
-
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
-
this.loadResources();
this.sources = new ScriptSearch(this.jsSrcDir, this.sourceIncludes, this.sourceExcludes);
@@ -459,6 +495,16 @@ public File getCustomRunnerConfiguration() {
}
@Override
+ public List<Reporter> getReporters() {
+ return this.reporters;
+ }
+
+ @Override
+ public List<FileSystemReporter> getFileSystemReporters() {
+ return this.fileSystemReporters;
+ }
+
+ @Override
public File getBasedir() {
return this.mavenProject.getBasedir();
}
@@ -496,29 +542,23 @@ protected boolean isSkipTests() {
}
private void loadResources() throws MojoExecutionException {
- this.customRunnerTemplateFile = this.getResourceAsFile("customRunnerTemplate", this.customRunnerTemplate);
- this.customRunnerConfigurationFile = this.getResourceAsFile("customRunnerConfiguration", this.customRunnerConfiguration);
+ this.customRunnerTemplateFile = getResourceRetriever().getResourceAsFile("customRunnerTemplate", this.customRunnerTemplate, this.mavenProject);
+ this.customRunnerConfigurationFile = getResourceRetriever().getResourceAsFile("customRunnerConfiguration", this.customRunnerConfiguration, this.mavenProject);
+ this.reporters = getReporterRetriever().retrieveReporters(this.reporters, this.mavenProject);
+ this.fileSystemReporters = getReporterRetriever().retrieveFileSystemReporters(this.fileSystemReporters, this.getJasmineTargetDir(), this.mavenProject);
+ }
+
+ private ResourceRetriever getResourceRetriever() {
+ if (resourceRetriever == null) {
+ resourceRetriever = new ResourceRetriever(resourceManager);
+ }
+ return resourceRetriever;
}
- private File getResourceAsFile(String parameter, String resourceLocation) throws MojoExecutionException {
- File file = null;
-
- if (resourceLocation != null) {
- this.locator.addSearchPath("url", "");
- this.locator.addSearchPath(FileResourceLoader.ID, this.mavenProject.getFile().getParentFile().getAbsolutePath());
-
- ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
- try {
- Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
- try {
- file = this.locator.getResourceAsFile(resourceLocation);
- } catch (Exception e) {
- throw new MojoExecutionException(String.format(ERROR_FILE_DNE, parameter, resourceLocation));
- }
- } finally {
- Thread.currentThread().setContextClassLoader(origLoader);
- }
+ private ReporterRetriever getReporterRetriever() {
+ if (reporterRetriever == null) {
+ reporterRetriever = new ReporterRetriever(getResourceRetriever());
}
- return file;
+ return reporterRetriever;
}
}
@@ -0,0 +1,61 @@
+package com.github.searls.jasmine.mojo;
+
+import com.github.searls.jasmine.model.FileSystemReporter;
+import com.github.searls.jasmine.model.Reporter;
+import com.google.inject.Inject;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+
+import java.io.File;
+import java.util.List;
+
+public class ReporterRetriever {
+ public static final String STANDARD_REPORTER = "/lib/buildReport.js";
+ private static final String STANDARD_REPORTER_KEY = "STANDARD";
+
+ private static final String JUNIT_XML_FILENAME = "TEST-jasmine.xml";
+ private static final String JUNIT_XML_KEY = "JUNIT_XML";
+ public static final String JUNIT_XML_REPORTER = "lib/createJunitXml.js";
+
+ private final ResourceRetriever resourceRetriever;
+
+ @Inject
+ public ReporterRetriever(final ResourceRetriever resourceRetriever) {
+ this.resourceRetriever = resourceRetriever;
+ }
+
+ List<FileSystemReporter> retrieveFileSystemReporters(final List<FileSystemReporter> reporters, final File targetDirectory, final MavenProject mavenProject) throws MojoExecutionException {
+ if (reporters.isEmpty()) {
+ reporters.add(new FileSystemReporter(JUNIT_XML_FILENAME, JUNIT_XML_KEY));
+ }
+
+ for (FileSystemReporter reporter : reporters) {
+ if (JUNIT_XML_KEY.equals(reporter.reporterName)) {
+ reporter.reporterName = JUNIT_XML_REPORTER;
+ }
+ reporter.reporterFile = getReporter(reporter.reporterName, mavenProject);
+ reporter.file = new File(targetDirectory, reporter.fileName);
+ }
+
+ return reporters;
+ }
+
+ List<Reporter> retrieveReporters(final List<Reporter> reporters, final MavenProject mavenProject) throws MojoExecutionException {
+ if (reporters.isEmpty()) {
+ reporters.add(new Reporter(STANDARD_REPORTER_KEY));
+ }
+
+ for (Reporter reporter : reporters) {
+ if (STANDARD_REPORTER_KEY.equals(reporter.reporterName)) {
+ reporter.reporterName = STANDARD_REPORTER;
+ }
+ reporter.reporterFile = getReporter(reporter.reporterName, mavenProject);
+ }
+
+ return reporters;
+ }
+
+ private File getReporter(final String reporter, final MavenProject mavenProject) throws MojoExecutionException {
+ return resourceRetriever.getResourceAsFile("reporter", reporter, mavenProject);
+ }
+}
@@ -0,0 +1,41 @@
+package com.github.searls.jasmine.mojo;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.resource.ResourceManager;
+import org.codehaus.plexus.resource.loader.FileResourceLoader;
+
+import java.io.File;
+
+public class ResourceRetriever {
+
+ private final ResourceManager locator;
+
+ private static final String ERROR_FILE_DNE = "Invalid value for parameter '%s'. File does not exist: %s";
+
+ public ResourceRetriever(final ResourceManager locator) {
+ this.locator = locator;
+ }
+
+ public File getResourceAsFile(final String parameter, final String resourceLocation, final MavenProject mavenProject) throws MojoExecutionException {
+ File file = null;
+
+ if (resourceLocation != null) {
+ locator.addSearchPath("url", "");
+ locator.addSearchPath(FileResourceLoader.ID, mavenProject.getFile().getParentFile().getAbsolutePath());
+
+ ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ file = locator.getResourceAsFile(resourceLocation);
+ } catch (Exception e) {
+ throw new MojoExecutionException(String.format(ERROR_FILE_DNE, parameter, resourceLocation));
+ }
+ } finally {
+ Thread.currentThread().setContextClassLoader(origLoader);
+ }
+ }
+ return file;
+ }
+}
Oops, something went wrong.

0 comments on commit 88e4387

Please sign in to comment.