private boolean test(Actions.EventExpecter expecter) {
    final JSONObject eventData;
    try {
      eventData = new JSONObject(expecter.blockForEventData());
    } catch (Exception ex) {
      // Log and ignore
      getAsserter().ok(false, "JS Test", "Error decoding data " + ex);
      return false;
    }

    if (eventData.has("result")) {
      getAsserter().ok(eventData.optBoolean("result"), "JS Test", eventData.optString("msg"));
    }

    EventDispatcher.sendResponse(eventData, new JSONObject());
    return eventData.optBoolean("done", false);
  }
  protected void doTestJavascript() throws Exception {
    // We want to be waiting for Robocop messages before the page is loaded
    // because the test harness runs each test in the suite (and possibly
    // completes testing) before the page load event is fired.
    final Actions.EventExpecter expecter = mActions.expectGeckoEvent(EVENT_TYPE);
    mAsserter.dumpLog("Registered listener for " + EVENT_TYPE);

    final String url = getAbsoluteUrl(StringHelper.getHarnessUrlForJavascript(javascriptUrl));
    mAsserter.dumpLog("Loading JavaScript test from " + url);
    loadUrl(url);

    final JavascriptMessageParser testMessageParser = new JavascriptMessageParser(mAsserter, false);
    try {
      while (!testMessageParser.isTestFinished()) {
        if (logVerbose) {
          Log.v(LOGTAG, "Waiting for " + EVENT_TYPE);
        }
        String data = expecter.blockForEventData();
        if (logVerbose) {
          Log.v(LOGTAG, "Got event with data '" + data + "'");
        }

        JSONObject o = new JSONObject(data);
        String innerType = o.getString("innerType");
        if (!"progress".equals(innerType)) {
          throw new Exception("Unexpected event innerType " + innerType);
        }

        String message = o.getString("message");
        if (message == null) {
          throw new Exception("Progress message must not be null");
        }
        testMessageParser.logMessage(message);
      }

      if (logDebug) {
        Log.d(LOGTAG, "Got test finished message");
      }
    } finally {
      expecter.unregisterListener();
      mAsserter.dumpLog("Unregistered listener for " + EVENT_TYPE);
    }
  }