Bug 996313 - Add boolean for ending test on assertion failure in JavascriptMessageParser. r=nalexander
authorMichael Comella <michael.l.comella@gmail.com>
Thu, 24 Apr 2014 12:23:20 -0700
changeset 198613 96eefe2070206a8da2d18063f23089b07957cf94
parent 198612 4e1172fa51ea4994152f5b711ad09eaecf9f536e
child 198614 542f5fb83cece04982f8beea8f6919b285da3e89
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs996313
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 996313 - Add boolean for ending test on assertion failure in JavascriptMessageParser. r=nalexander
mobile/android/base/tests/JavascriptTest.java
mobile/android/base/tests/helpers/JavascriptBridge.java
mobile/android/base/tests/helpers/JavascriptMessageParser.java
--- a/mobile/android/base/tests/JavascriptTest.java
+++ b/mobile/android/base/tests/JavascriptTest.java
@@ -32,17 +32,18 @@ public class JavascriptTest extends Base
             mActions.expectGeckoEvent(EVENT_TYPE);
         mAsserter.dumpLog("Registered listener for " + EVENT_TYPE);
 
         final String url = getAbsoluteUrl(StringHelper.ROBOCOP_JS_HARNESS_URL +
                                           "?path=" + javascriptUrl);
         mAsserter.dumpLog("Loading JavaScript test from " + url);
         loadUrl(url);
 
-        final JavascriptMessageParser testMessageParser = new JavascriptMessageParser(mAsserter);
+        final JavascriptMessageParser testMessageParser =
+                new JavascriptMessageParser(mAsserter, false);
         try {
             while (!testMessageParser.isTestFinished()) {
                 if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
                     Log.v(LOGTAG, "Waiting for " + EVENT_TYPE);
                 }
                 String data = expecter.blockForEventData();
                 if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
                     Log.v(LOGTAG, "Got event with data '" + data + "'");
--- a/mobile/android/base/tests/helpers/JavascriptBridge.java
+++ b/mobile/android/base/tests/helpers/JavascriptBridge.java
@@ -105,18 +105,20 @@ public final class JavascriptBridge {
     /* package */ static void init(final UITestContext context) {
         sActions = context.getActions();
         sAsserter = context.getAsserter();
     }
 
     public JavascriptBridge(final Object target) {
         mTarget = target;
         mMethods = target.getClass().getMethods();
-        mLogParser = new JavascriptMessageParser(sAsserter);
         mExpecter = sActions.expectGeckoEvent(EVENT_TYPE);
+        // The JS here is unrelated to a test harness, so we
+        // have our message parser end on assertion failure.
+        mLogParser = new JavascriptMessageParser(sAsserter, true);
     }
 
     /**
      * Synchronously calls a method in Javascript.
      *
      * @param method Name of the method to call
      * @param args Arguments to pass to the Javascript method; must be a list of
      *             values allowed by JSONObject.
--- a/mobile/android/base/tests/helpers/JavascriptMessageParser.java
+++ b/mobile/android/base/tests/helpers/JavascriptMessageParser.java
@@ -29,19 +29,32 @@ public final class JavascriptMessagePars
     private static final Pattern testMessagePattern =
         Pattern.compile("TEST-([A-Z\\-]+) \\| (.*?) \\| (.*)", Pattern.DOTALL);
 
     private final Assert asserter;
     // Used to help print stack traces neatly.
     private String lastTestName = "";
     // Have we seen a message saying the test is finished?
     private boolean testFinishedMessageSeen = false;
+    private final boolean endOnAssertionFailure;
 
-    public JavascriptMessageParser(final Assert asserter) {
+    /**
+     * Constructs a message parser for test result messages sent from JavaScript. When seeing an
+     * assertion failure, the message parser can use the given {@link org.mozilla.gecko.Assert}
+     * instance to immediately end the test (typically if the underlying JS framework is not able
+     * to end the test itself) or to swallow the Errors - this functionality is determined by the
+     * <code>endOnAssertionFailure</code> parameter.
+     *
+     * @param asserter The Assert instance to which test results should be passed.
+     * @param endOnAssertionFailure
+     *        true if the test should end if we see a JS assertion failure, false otherwise.
+     */
+    public JavascriptMessageParser(final Assert asserter, final boolean endOnAssertionFailure) {
         this.asserter = asserter;
+        this.endOnAssertionFailure = endOnAssertionFailure;
     }
 
     public boolean isTestFinished() {
         return testFinishedMessageSeen;
     }
 
     public void logMessage(final String str) {
         final Matcher m = testMessagePattern.matcher(str.trim());
@@ -56,18 +69,25 @@ public final class JavascriptMessagePars
                 testFinishedMessageSeen = testFinishedMessageSeen ||
                                           "exiting test".equals(message);
             } else if ("PASS".equals(type)) {
                 asserter.ok(true, name, message);
             } else if ("UNEXPECTED-FAIL".equals(type)) {
                 try {
                     asserter.ok(false, name, message);
                 } catch (AssertionFailedError e) {
-                    // Swallow this exception.  We want to see all the
-                    // Javascript failures, not die on the very first one!
+                    // Above, we call the assert, allowing it to log.
+                    // Now we can end the test, if applicable.
+                    if (this.endOnAssertionFailure) {
+                        throw e;
+                    }
+                    // Otherwise, swallow the Error. The JS framework we're
+                    // logging messages from is likely capable of ending tests
+                    // when it needs to, and we want to see all of its failures,
+                    // not just the first one!
                 }
             } else if ("KNOWN-FAIL".equals(type)) {
                 asserter.todo(false, name, message);
             } else if ("UNEXPECTED-PASS".equals(type)) {
                 asserter.todo(true, name, message);
             }
 
             lastTestName = name;