Bug 1251139 - Support running a function in the parent with loadChromeScript. r=jmaher

MozReview-Commit-ID: 3t7g2bjaFmA

--HG--
rename : testing/mochitest/tests/Harness_sanity/test_SpecialPowersLoadChromeScript.html => testing/mochitest/tests/Harness_sanity/test_SpecialPowersLoadChromeScript_function.html
This commit is contained in:
Matthew Noorenberghe 2016-03-09 12:11:44 -08:00
Родитель 469bc2bed3
Коммит b539cc9f1b
5 изменённых файлов: 95 добавлений и 12 удалений

Просмотреть файл

@ -32,6 +32,7 @@ support-files =
[test_SimpletestGetTestFileURL.html]
[test_SpecialPowersLoadChromeScript.html]
support-files = SpecialPowersLoadChromeScript.js
[test_SpecialPowersLoadChromeScript_function.html]
[test_bug649012.html]
[test_bug816847.html]
skip-if = toolkit == 'android' || e10s #No test app installed

Просмотреть файл

@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for SpecialPowers extension</title>
<title>Test for SpecialPowers.loadChromeScript</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>

Просмотреть файл

@ -0,0 +1,63 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for SpecialPowers.loadChromeScript</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var script = SpecialPowers.loadChromeScript(function loadChromeScriptTest() {
// Copied from SpecialPowersLoadChromeScript.js
// Just receive 'foo' message and forward it back
// as 'bar' message
addMessageListener("foo", function (message) {
sendAsyncMessage("bar", message);
});
addMessageListener("valid-assert", function (message) {
assert.ok(true, "valid assertion");
assert.equal(1, 1, "another valid assertion");
sendAsyncMessage("valid-assert-done");
});
});
var MESSAGE = { bar: true };
script.addMessageListener("bar", function (message) {
is(JSON.stringify(message), JSON.stringify(MESSAGE),
"received back message from the chrome script");
checkAssert();
});
function checkAssert() {
script.sendAsyncMessage("valid-assert");
script.addMessageListener("valid-assert-done", endOfTest);
}
function endOfTest() {
script.destroy();
SimpleTest.finish();
}
script.sendAsyncMessage("foo", MESSAGE);
/*
* [0][0] is because we're using one real message listener in SpecialPowersObserverAPI.js
* and dispatching that to multiple _chromeScriptListeners. The outer array comes
* from the message manager since there can be multiple real listeners. The inner
* array is for the return values of _chromeScriptListeners.
*/
is(script.sendSyncMessage("sync-message")[0][0], "Received a synchronous message.",
"Check sync return value");
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -424,10 +424,20 @@ SpecialPowersObserverAPI.prototype = {
}
case "SPLoadChromeScript": {
let url = aMessage.json.url;
let id = aMessage.json.id;
let jsScript;
let scriptName;
let jsScript = this._readUrlAsString(url);
if (aMessage.json.url) {
jsScript = this._readUrlAsString(aMessage.json.url);
scriptName = aMessage.json.url;
} else if (aMessage.json.function) {
jsScript = aMessage.json.function.body;
scriptName = aMessage.json.function.name
|| "<loadChromeScript anonymous function>";
} else {
throw new SpecialPowersError("SPLoadChromeScript: Invalid script");
}
// Setup a chrome sandbox that has access to sendAsyncMessage
// and addMessageListener in order to communicate with
@ -451,8 +461,8 @@ SpecialPowersObserverAPI.prototype = {
let reporter = function (err, message, stack) {
// Pipe assertions back to parent process
mm.sendAsyncMessage("SPChromeScriptAssert",
{ id: id, url: url, err: err, message: message,
stack: stack });
{ id, name: scriptName, err, message,
stack });
};
Object.defineProperty(sb, "assert", {
get: function () {
@ -469,10 +479,10 @@ SpecialPowersObserverAPI.prototype = {
// Evaluate the chrome script
try {
Components.utils.evalInSandbox(jsScript, sb, "1.8", url, 1);
Components.utils.evalInSandbox(jsScript, sb, "1.8", scriptName, 1);
} catch(e) {
throw new SpecialPowersError(
"Error while executing chrome script '" + url + "':\n" +
"Error while executing chrome script '" + scriptName + "':\n" +
e + "\n" +
e.fileName + ":" + e.lineNumber);
}

Просмотреть файл

@ -453,15 +453,24 @@ SpecialPowersAPI.prototype = {
return MockPermissionPrompt;
},
loadChromeScript: function (url) {
loadChromeScript: function (urlOrFunction) {
// Create a unique id for this chrome script
let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator);
let id = uuidGenerator.generateUUID().toString();
// Tells chrome code to evaluate this chrome script
let scriptArgs = { id };
if (typeof(urlOrFunction) == "function") {
scriptArgs.function = {
body: "(" + urlOrFunction.toString() + ")();",
name: urlOrFunction.name,
};
} else {
scriptArgs.url = urlOrFunction;
}
this._sendSyncMessage("SPLoadChromeScript",
{ url: url, id: id });
scriptArgs);
// Returns a MessageManager like API in order to be
// able to communicate with this chrome script
@ -514,7 +523,7 @@ SpecialPowersAPI.prototype = {
let assert = json => {
// An assertion has been done in a mochitest chrome script
let {url, err, message, stack} = json;
let {name, err, message, stack} = json;
// Try to fetch a test runner from the mochitest
// in order to properly log these assertions and notify
@ -540,10 +549,10 @@ SpecialPowersAPI.prototype = {
", expected " + repr(err.expected) +
" (operator " + err.operator + ")";
}
var msg = [resultString, url, diagnostic].join(" | ");
var msg = [resultString, name, diagnostic].join(" | ");
if (parentRunner) {
if (err) {
parentRunner.addFailedTest(url);
parentRunner.addFailedTest(name);
parentRunner.error(msg);
} else {
parentRunner.log(msg);