gecko-dev/testing/mochitest/BrowserTestUtils/ContentTask.jsm
Steven MacLeod 4d239d923a Bug 1107609 - Implement ContentTask.spawn; r=Gijs r=mconley
This introduces a new medule ContentTask, which includes a spawn method.
This new method can be used to spawn a task in the content process of a
browser. When called, a promise will be returned which resolves to the
value returned by the task.

This allows you to quickly write test code which can touch the content
and return information without having to write custom framescripts all
the time (The content code can be written inline as a simple generator
definition). ContentTask is automatically included in the scope of
mochitests.

An example use follows:

yield ContentTask.spawn(browser, {}, function* gen_replaceState() {
  content.window.history.replaceState({}, "", 'test-entry/');
  return "Value that the promise will resolve with";
});

--HG--
extra : rebase_source : 9b6ae71407da582cdaa8087b5e367c72fa08a337
2015-02-11 17:28:44 -05:00

96 lines
2.7 KiB
JavaScript

/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = [
"ContentTask"
];
const Cu = Components.utils;
Cu.import("resource://gre/modules/Promise.jsm");
/**
* Set of browsers which have loaded the content-task frame script.
*/
let gScriptLoadedSet = new WeakSet();
/**
* Mapping from message id to associated promise.
*/
let gPromises = new Map();
/**
* Incrementing integer to generate unique message id.
*/
let gMessageID = 1;
/**
* This object provides the public module functions.
*/
this.ContentTask = {
/**
* Creates and starts a new task in a browser's content.
*
* @param browser A xul:browser
* @param arg A single serializable argument that will be passed to the
* task when executed on the content process.
* @param task
* - A generator or function which will be serialized and sent to
* the remote browser to be executed. Unlike Task.spawn, this
* argument may not be an iterator as it will be serialized and
* sent to the remote browser.
* @return A promise object where you can register completion callbacks to be
* called when the task terminates.
* @resolves With the final returned value of the task if it executes
* successfully.
* @rejects An error message if execution fails.
*/
spawn: function ContentTask_spawn(browser, arg, task) {
if(!gScriptLoadedSet.has(browser)) {
let mm = browser.messageManager;
mm.addMessageListener("content-task:complete", ContentMessageListener);
mm.loadFrameScript(
"chrome://mochikit/content/tests/BrowserTestUtils/content-task.js", true);
gScriptLoadedSet.add(browser);
}
let deferred = {};
deferred.promise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
let id = gMessageID++;
gPromises.set(id, deferred);
browser.messageManager.sendAsyncMessage(
"content-task:spawn",
{
id: id,
runnable: task.toString(),
arg: arg,
});
return deferred.promise;
},
};
let ContentMessageListener = {
receiveMessage(aMessage) {
let id = aMessage.data.id
let deferred = gPromises.get(id);
gPromises.delete(id);
if (aMessage.data.error) {
deferred.reject(aMessage.data.error);
} else {
deferred.resolve(aMessage.data.result);
}
},
};