Bug 1614462: Part 2d - Fix tests that don't need to use mozbrowser. r=mccr8

These tests used <iframe mozbrowser> for convenience, mostly forcing
themselves to only run in non-e10s mode in the process, but none of them
really have any need to.

Differential Revision: https://phabricator.services.mozilla.com/D70745
This commit is contained in:
Kris Maglione 2020-04-20 20:11:43 +00:00
parent 6a5589ef4f
commit d1639bbfcd
32 changed files with 1241 additions and 1448 deletions

View File

@ -76,7 +76,10 @@
openDatabase()
.then(retrieveKey).then(generateKey).then(storeKey)
.then(() => alert("ok")).catch(alert);
.then(() => parent.postMessage("ok", "*"))
.catch(error => {
parent.postMessage(String(error), "*");
});
</script>
</body>
</html>

View File

@ -9,6 +9,7 @@ support-files =
util.js
[test_indexedDB.html]
skip-if = !fission # Requires iframes to run in separate processes.
[test_WebCrypto.html]
[test_WebCrypto_DH.html]
[test_WebCrypto_ECDH.html]

View File

@ -18,42 +18,31 @@
const TEST_URI = "https://example.com/tests/" +
"dom/crypto/test/file_indexedDB.html";
SimpleTest.waitForExplicitFinish();
function createMozBrowserFrame(cb) {
function createFrame() {
let frame = document.createElement("iframe");
SpecialPowers.wrap(frame).mozbrowser = true;
frame.src = TEST_URI;
frame.addEventListener("mozbrowsershowmodalprompt", function(e) {
cb(frame, e.detail.message);
}, {once: true});
return new Promise(resolve => {
addEventListener("message", event => {
is(event.source.frameElement, frame,
"Message must come from the correct iframe");
resolve([frame, event.data]);
}, { once: true });
document.body.appendChild(frame);
}
function runTest() {
// Load the test app once, to generate and store keys.
createMozBrowserFrame((frame, result) => {
is(result, "ok", "stored keys successfully");
frame.remove();
// Load the test app again to retrieve stored keys.
createMozBrowserFrame((recFrame, recResult) => {
is(recResult, "ok", "retrieved keys successfully");
recFrame.remove();
SimpleTest.finish();
});
document.body.appendChild(frame);
});
}
addEventListener("load", function() {
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({set: [
["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
]}, runTest);
add_task(async function() {
// Load the test app once, to generate and store keys.
let [frame, result] = await createFrame();
is(result, "ok", "stored keys successfully");
frame.remove();
// Load the test app again to retrieve stored keys.
let [recFrame, recResult] = await createFrame();
is(recResult, "ok", "retrieved keys successfully");
recFrame.remove();
});
</script>
</body>

View File

@ -1 +0,0 @@
<!DOCTYPE HTML><html><body></body></html>

View File

@ -21,8 +21,6 @@ support-files =
[test_blobconstructor.html]
[test_blobURL_expiring.html]
[test_file_from_blob.html]
[test_ipc_messagemanager_blob.html]
support-files = file_ipc_messagemanager_blob.html
[test_nonascii_blob_url.html]
[test_file_negative_date.html]
[test_fileapi_basic.html]

View File

@ -1,143 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for OOP Blobs in MessageManager</title>
<script src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
const childFrameURL = "file_ipc_messagemanager_blob.html";
function childFrameScript() {
"use strict";
Cu.importGlobalProperties(["Blob"]);
addMessageListener("test:ipcClonedMessage", function(message) {
if (!Blob.isInstance(message.json)) {
sendAsyncMessage(message.name, message.json);
return;
}
let reader = new FileReader();
reader.addEventListener("load", function() {
let response = reader.result == "this is a great success!" ?
message.json :
"error";
sendAsyncMessage(message.name, response);
});
reader.readAsText(message.json);
});
}
function runTests() {
function done() {
SpecialPowers.removePermission("browser", document);
SimpleTest.finish();
}
ok("Browser prefs set.");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src = childFrameURL;
iframe.addEventListener("mozbrowserloadend", function() {
ok(true, "Got iframe load event.");
const blobString = "this is a great success!";
const messages = [
"hi!",
"",
2,
-.04,
3432987324987239872948732982,
true,
false,
null,
0,
// Make sure this one is always last.
new Blob(["this ", "is ", "a ", "great ", "success!"],
{"type" : "text\/plain"}),
];
let receivedMessageIndex = 0;
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.addMessageListener("test:ipcClonedMessage", SpecialPowers.wrapCallback(function(message) {
let data = message.json;
if (SpecialPowers.call_Instanceof(data, Blob)) {
is(receivedMessageIndex, messages.length - 1, "Blob is last");
is (data.size,
messages[receivedMessageIndex].size,
"Correct blob size");
is (data.type,
messages[receivedMessageIndex].type,
"Correct blob type");
let result1, result2;
let reader1 = new FileReader();
reader1.onload = function() {
result1 = reader1.result == blobString ? reader1.result : "bad1";
if (result2) {
is(result1, result2, "Same results");
done();
}
};
let reader2 = new FileReader();
reader2.onload = function() {
result2 = reader2.result == blobString ? reader2.result : "bad2";
if (result1) {
is(result1, result2, "Same results");
done();
}
};
SpecialPowers.wrap(reader1).readAsText(data);
reader2.readAsText(messages[receivedMessageIndex]);
return;
}
is(message.json,
messages[receivedMessageIndex++],
"Got correct round-tripped response");
}));
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
false);
for (let message of messages) {
mm.sendAsyncMessage("test:ipcClonedMessage", message);
}
});
document.body.appendChild(iframe);
}
addEventListener("load", function() {
info("Got load event.");
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({
"set": [
["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true]
]
}, runTests);
});
</script>
</body>
</html>

View File

@ -0,0 +1,101 @@
"use strict";
const { ExtensionTestUtils } = ChromeUtils.import(
"resource://testing-common/ExtensionXPCShellUtils.jsm"
);
ExtensionTestUtils.init(this);
function childFrameScript() {
addMessageListener("test:ipcClonedMessage", function(message) {
if (!Blob.isInstance(message.json)) {
sendAsyncMessage(message.name, message.json);
return;
}
let reader = new FileReader();
reader.addEventListener("load", function() {
let response =
reader.result == "this is a great success!" ? message.json : "error";
sendAsyncMessage(message.name, response);
});
reader.readAsText(message.json);
});
}
add_task(async function test() {
let page = await ExtensionTestUtils.loadContentPage("about:blank", {
remote: true,
});
page.loadFrameScript(childFrameScript);
const blobString = "this is a great success!";
const messages = [
"hi!",
"",
2,
-0.04,
3432987324987239872948732982,
true,
false,
null,
0,
// Make sure this one is always last.
new Blob(["this ", "is ", "a ", "great ", "success!"], {
type: "text/plain",
}),
];
let receivedMessageIndex = 0;
let mm = page.browser.messageManager;
let done = new Promise(resolve => {
mm.addMessageListener("test:ipcClonedMessage", async message => {
let data = message.json;
if (Blob.isInstance(data)) {
equal(receivedMessageIndex, messages.length - 1, "Blob is last");
equal(
data.size,
messages[receivedMessageIndex].size,
"Correct blob size"
);
equal(
data.type,
messages[receivedMessageIndex].type,
"Correct blob type"
);
let reader1 = new FileReader();
reader1.readAsText(data);
let reader2 = new FileReader();
reader2.readAsText(messages[receivedMessageIndex]);
await Promise.all([
new Promise(res => (reader1.onload = res)),
new Promise(res => (reader2.onload = res)),
]);
equal(reader1.result, blobString, "Result 1");
equal(reader2.result, blobString, "Result 2");
resolve();
} else {
equal(
data,
messages[receivedMessageIndex++],
"Got correct round-tripped response"
);
}
});
});
for (let message of messages) {
mm.sendAsyncMessage("test:ipcClonedMessage", message);
}
await page.close();
});

View File

@ -2,3 +2,4 @@
[test_bloburi.js]
[test_createFile.js]
[test_ipc_messagemanager_blob.js]

View File

@ -215,8 +215,6 @@ skip-if = true
[test_leaving_page.html]
[test_maximal_serialized_object_size.html]
[test_message_manager_ipc.html]
# This test is only supposed to run in the main process.
skip-if = e10s
[test_multientry.html]
[test_names_sorted.html]
[test_objectCursors.html]

View File

@ -6,201 +6,217 @@
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="setup();">
<body>
<script type="application/javascript">
"use strict";
function childFrameScript() {
/* eslint-env mozilla/frame-script */
"use strict";
async function chromeScriptFunc() {
function childFrameScript() {
/* eslint-env mozilla/frame-script */
"use strict";
const mmName = "test:idb-and-mm";
const mmName = "test:idb-and-mm";
const dbName = "test_message_manager_ipc.html - CHILD";
const dbVersion = 1;
const objStoreName = "bar";
const key = 1;
const dbName = "test_message_manager_ipc.html - CHILD";
const dbVersion = 1;
const objStoreName = "bar";
const key = 1;
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
Cu.importGlobalProperties(["indexedDB"]);
Cu.importGlobalProperties(["indexedDB"]);
function info(msg) {
sendAsyncMessage(mmName, { op: "info", msg });
function info(msg) {
sendAsyncMessage(mmName, { op: "info", msg });
}
function ok(condition, name, diag) {
sendAsyncMessage(mmName,
{ op: "ok",
condition,
name,
diag });
}
function is(a, b, name) {
let pass = a == b;
let diag = pass ? "" : "got " + a + ", expected " + b;
ok(pass, name, diag);
}
function finish(result) {
sendAsyncMessage(mmName, { op: "done", result });
}
function grabAndContinue(arg) {
testGenerator.next(arg);
}
function errorHandler(event) {
ok(false,
event.target + " received error event: '" + event.target.error.name +
"'");
finish();
}
function* testSteps() {
addMessageListener(mmName, grabAndContinue);
let message = yield undefined;
let blob = message.data;
ok(Blob.isInstance(blob), "Message manager sent a blob");
is(blob.size, blobText.length, "Blob has correct length");
is(blob.type, blobType, "Blob has correct type");
info("Reading blob");
let reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(blob);
yield undefined;
is(reader.result, blobText, "Blob has correct data");
let slice = blob.slice(0, blobData[0].length, blobType);
ok(Blob.isInstance(slice), "Slice returned a blob");
is(slice.size, blobData[0].length, "Slice has correct length");
is(slice.type, blobType, "Slice has correct type");
info("Reading slice");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[0], "Slice has correct data");
info("Deleting database");
let req = indexedDB.deleteDatabase(dbName);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
let event = yield undefined;
is(event.type, "success", "Got success event");
info("Opening database");
req = indexedDB.open(dbName, dbVersion);
req.onerror = errorHandler;
req.onupgradeneeded = grabAndContinue;
req.onsuccess = grabAndContinue;
event = yield undefined;
is(event.type, "upgradeneeded", "Got upgradeneeded event");
event.target.result.createObjectStore(objStoreName);
event = yield undefined;
is(event.type, "success", "Got success event");
let db = event.target.result;
info("Storing blob from message manager in database");
let objectStore =
db.transaction(objStoreName, "readwrite").objectStore(objStoreName);
req = objectStore.add(blob, key);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
event = yield undefined;
info("Getting blob from database");
objectStore = db.transaction(objStoreName).objectStore(objStoreName);
req = objectStore.get(key);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
event = yield undefined;
blob = event.target.result;
ok(Blob.isInstance(blob), "Database gave us a blob");
is(blob.size, blobText.length, "Blob has correct length");
is(blob.type, blobType, "Blob has correct type");
info("Reading blob");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(blob);
yield undefined;
is(reader.result, blobText, "Blob has correct data");
info("Storing slice from message manager in database");
objectStore =
db.transaction(objStoreName, "readwrite").objectStore(objStoreName);
req = objectStore.put(slice, key);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
event = yield undefined;
info("Getting slice from database");
objectStore = db.transaction(objStoreName).objectStore(objStoreName);
req = objectStore.get(key);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
event = yield undefined;
slice = event.target.result;
ok(Blob.isInstance(slice), "Database gave us a blob");
is(slice.size, blobData[0].length, "Slice has correct length");
is(slice.type, blobType, "Slice has correct type");
info("Reading Slice");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[0], "Slice has correct data");
info("Sending blob and slice from database to message manager");
finish([blob, slice]);
}
let testGenerator = testSteps();
testGenerator.next();
}
function ok(condition, name, diag) {
sendAsyncMessage(mmName,
{ op: "ok",
condition,
name,
diag });
/* globals Services, createWindowlessBrowser */
let { windowlessBrowser, browser } = await createWindowlessBrowser();
const system = Services.scriptSecurityManager.getSystemPrincipal();
browser.loadURI(
"data:text/html,<!DOCTYPE HTML><html><body></body></html>",
{ triggeringPrincipal: system }
);
function finish() {
sendAsyncMessage("done");
windowlessBrowser.close();
}
function is(a, b, name) {
let pass = a == b;
let diag = pass ? "" : "got " + a + ", expected " + b;
ok(pass, name, diag);
}
let mm = browser.messageManager;
function finish(result) {
sendAsyncMessage(mmName, { op: "done", result });
}
function grabAndContinue(arg) {
testGenerator.next(arg);
}
function errorHandler(event) {
ok(false,
event.target + " received error event: '" + event.target.error.name +
"'");
finish();
}
function* testSteps() {
addMessageListener(mmName, grabAndContinue);
let message = yield undefined;
let blob = message.data;
ok(Blob.isInstance(blob), "Message manager sent a blob");
is(blob.size, blobText.length, "Blob has correct length");
is(blob.type, blobType, "Blob has correct type");
info("Reading blob");
let reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(blob);
yield undefined;
is(reader.result, blobText, "Blob has correct data");
let slice = blob.slice(0, blobData[0].length, blobType);
ok(Blob.isInstance(slice), "Slice returned a blob");
is(slice.size, blobData[0].length, "Slice has correct length");
is(slice.type, blobType, "Slice has correct type");
info("Reading slice");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[0], "Slice has correct data");
info("Deleting database");
let req = indexedDB.deleteDatabase(dbName);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
let event = yield undefined;
is(event.type, "success", "Got success event");
info("Opening database");
req = indexedDB.open(dbName, dbVersion);
req.onerror = errorHandler;
req.onupgradeneeded = grabAndContinue;
req.onsuccess = grabAndContinue;
event = yield undefined;
is(event.type, "upgradeneeded", "Got upgradeneeded event");
event.target.result.createObjectStore(objStoreName);
event = yield undefined;
is(event.type, "success", "Got success event");
let db = event.target.result;
info("Storing blob from message manager in database");
let objectStore =
db.transaction(objStoreName, "readwrite").objectStore(objStoreName);
req = objectStore.add(blob, key);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
event = yield undefined;
info("Getting blob from database");
objectStore = db.transaction(objStoreName).objectStore(objStoreName);
req = objectStore.get(key);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
event = yield undefined;
blob = event.target.result;
ok(Blob.isInstance(blob), "Database gave us a blob");
is(blob.size, blobText.length, "Blob has correct length");
is(blob.type, blobType, "Blob has correct type");
info("Reading blob");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(blob);
yield undefined;
is(reader.result, blobText, "Blob has correct data");
info("Storing slice from message manager in database");
objectStore =
db.transaction(objStoreName, "readwrite").objectStore(objStoreName);
req = objectStore.put(slice, key);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
event = yield undefined;
info("Getting slice from database");
objectStore = db.transaction(objStoreName).objectStore(objStoreName);
req = objectStore.get(key);
req.onerror = errorHandler;
req.onsuccess = grabAndContinue;
event = yield undefined;
slice = event.target.result;
ok(Blob.isInstance(slice), "Database gave us a blob");
is(slice.size, blobData[0].length, "Slice has correct length");
is(slice.type, blobType, "Slice has correct type");
info("Reading Slice");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[0], "Slice has correct data");
info("Sending blob and slice from database to message manager");
finish([blob, slice]);
}
let testGenerator = testSteps();
testGenerator.next();
}
function parentFrameScript(mm) {
const messageName = "test:idb-and-mm";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
@ -214,16 +230,16 @@ function parentFrameScript(mm) {
function* testSteps() {
let result = yield undefined;
is(SpecialPowers.Cu.getClassName(result, true), "Array", "Child delivered an array of results");
is(Cu.getClassName(result, true), "Array", "Child delivered an array of results");
is(result.length, 2, "Child delivered two results");
let blob = result[0];
is(SpecialPowers.call_Instanceof(blob, Blob), true, "Child delivered a blob");
is(Blob.isInstance(blob), true, "Child delivered a blob");
is(blob.size, blobText.length, "Blob has correct size");
is(blob.type, blobType, "Blob has correct type");
let slice = result[1];
is(SpecialPowers.call_Instanceof(slice, Blob), true, "Child delivered a slice");
is(Blob.isInstance(slice), true, "Child delivered a slice");
is(slice.size, blobData[0].length, "Slice has correct size");
is(slice.type, blobType, "Slice has correct type");
@ -231,7 +247,7 @@ function parentFrameScript(mm) {
let reader = new FileReader();
reader.onload = grabAndContinue;
SpecialPowers.wrap(reader).readAsText(blob);
reader.readAsText(blob);
yield undefined;
is(reader.result, blobText, "Blob has correct data");
@ -240,14 +256,14 @@ function parentFrameScript(mm) {
reader = new FileReader();
reader.onload = grabAndContinue;
SpecialPowers.wrap(reader).readAsText(slice);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[0], "Slice has correct data");
slice = blob.slice(0, blobData[0].length, blobType);
is(SpecialPowers.call_Instanceof(slice, Blob), true, "Child delivered a slice");
is(Blob.isInstance(slice), true, "Child delivered a slice");
is(slice.size, blobData[0].length, "Second slice has correct size");
is(slice.type, blobType, "Second slice has correct type");
@ -255,18 +271,18 @@ function parentFrameScript(mm) {
reader = new FileReader();
reader.onload = grabAndContinue;
SpecialPowers.wrap(reader).readAsText(slice);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[0], "Second slice has correct data");
SimpleTest.finish();
finish();
}
let testGenerator = testSteps();
testGenerator.next();
mm.addMessageListener(messageName, SpecialPowers.wrapCallback(function(message) {
mm.addMessageListener(messageName, function(message) {
let data = message.data;
switch (data.op) {
case "info": {
@ -286,54 +302,22 @@ function parentFrameScript(mm) {
default: {
ok(false, "Unknown op: " + data.op);
SimpleTest.finish();
finish();
}
}
}));
});
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
mm.loadFrameScript(`data:,(${childFrameScript})();`,
false);
mm.sendAsyncMessage(messageName, blob);
}
function setup() {
info("Got load event");
SpecialPowers.pushPrefEnv(
{ set: [ ["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true] ] },
function() {
info("Prefs set");
SpecialPowers.pushPermissions(
[ { type: "browser", allow: true, context: document } ],
function() {
info("Permissions set");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
iframe.addEventListener("mozbrowserloadend", function() {
info("Starting tests");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
parentFrameScript(mm);
});
document.body.appendChild(iframe);
}
);
}
);
}
SimpleTest.waitForExplicitFinish();
add_task(async function() {
let chromeScript = SpecialPowers.loadChromeScript(chromeScriptFunc);
await chromeScript.promiseOneMessage("done");
await chromeScript.destroy();
});
</script>
</body>
</html>

View File

@ -57,11 +57,7 @@ function deactivateDomainPolicy() {
add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [
["dom.ipc.browser_frames.oop_by_default", false],
["browser.pagethumbnails.capturing_disabled", false],
["dom.mozBrowserFramesEnabled", false],
],
set: [["browser.pagethumbnails.capturing_disabled", false]],
});
registerCleanupFunction(() => {

View File

@ -1,16 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1086684
-->
<head>
<title>Test for Bug 1086684</title>
<meta charset="UTF-8">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1086684">Mozilla Bug 1086684</a>
<div id="content">
<input type="file" id="f">
</div>
</body>
</html>

View File

@ -1,19 +1,5 @@
[DEFAULT]
support-files =
file_bug1086684.html
[test_blob_sliced_from_child_process.html]
# This test is only supposed to run in the main process.
skip-if = e10s
[test_blob_sliced_from_parent_process.html]
# This test is only supposed to run in the main process.
skip-if = e10s
[test_bug1086684.html]
# This test is only supposed to run in the main process
skip-if = e10s
[test_cpow_cookies.html]
[test_child_docshell.html]
skip-if = toolkit == 'cocoa' # cocoa: disabled due to hangs, see changeset 6852e7c47edf
[test_CrashService_crash.html]
skip-if = !(crashreporter && !e10s && (toolkit == 'gtk' || toolkit == 'cocoa' || toolkit == 'windows'))
[test_temporaryfile_stream.html]

View File

@ -1,180 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Test for slicing blobs that originated in a child process</title>
<script src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="setup();">
<script type="application/javascript">
"use strict";
/* eslint-env mozilla/frame-script */
function childFrameScript() {
"use strict";
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobType = "text/plain";
let blob = new Blob(blobData, { type: blobType });
let firstSliceStart = blobData[0].length + blobData[1].length;
let firstSliceEnd = firstSliceStart + blobData[2].length;
let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
let secondSliceStart = blobData[2].indexOf("a");
let secondSliceEnd = secondSliceStart + 2;
slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);
sendAsyncMessage(messageName, { blob });
sendAsyncMessage(messageName, { slice });
}
function parentFrameScript(mm) {
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
const sliceText = "an";
let receivedBlob = false;
let receivedSlice = false;
let finishedTestingBlob = false;
let finishedTestingSlice = false;
mm.addMessageListener(messageName, SpecialPowers.wrapCallback(function(message) {
if ("blob" in message.data) {
is(receivedBlob, false, "Have not yet received Blob");
is(receivedSlice, false, "Have not yet received Slice");
is(finishedTestingBlob, false, "Have not yet finished testing Blob");
is(finishedTestingSlice, false, "Have not yet finished testing Slice");
receivedBlob = true;
let blob = message.data.blob;
ok(SpecialPowers.call_Instanceof(blob, Blob), "Received a Blob");
is(blob.size, blobText.length, "Blob has correct size");
is(blob.type, blobType, "Blob has correct type");
let slice = blob.slice(blobText.length -
blobData[blobData.length - 1].length,
blob.size,
blobType);
ok(SpecialPowers.call_Instanceof(slice, Blob), "Slice returned a Blob");
is(slice.size,
blobData[blobData.length - 1].length,
"Slice has correct size");
is(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = function() {
is(reader.result,
blobData[blobData.length - 1],
"Slice has correct data");
finishedTestingBlob = true;
if (finishedTestingSlice) {
SimpleTest.finish();
}
};
SpecialPowers.wrap(reader).readAsText(slice);
return;
}
if ("slice" in message.data) {
is(receivedBlob, true, "Already received Blob");
is(receivedSlice, false, "Have not yet received Slice");
is(finishedTestingSlice, false, "Have not yet finished testing Slice");
receivedSlice = true;
let slice = message.data.slice;
ok(SpecialPowers.call_Instanceof(slice, Blob), "Received a Blob for slice");
is(slice.size, sliceText.length, "Slice has correct size");
is(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = function() {
is(reader.result, sliceText, "Slice has correct data");
let slice2 = slice.slice(1, 2, blobType);
ok(SpecialPowers.call_Instanceof(slice2, Blob), "Slice returned a Blob");
is(slice2.size, 1, "Slice has correct size");
is(slice2.type, blobType, "Slice has correct type");
let reader2 = new FileReader();
reader2.onload = function() {
is(reader2.result, sliceText[1], "Slice has correct data");
finishedTestingSlice = true;
if (finishedTestingBlob) {
SimpleTest.finish();
}
};
SpecialPowers.wrap(reader2).readAsText(slice2);
};
SpecialPowers.wrap(reader).readAsText(slice);
return;
}
ok(false, "Received a bad message: " + JSON.stringify(message.data));
}));
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
false);
}
function setup() {
info("Got load event");
SpecialPowers.pushPrefEnv(
{ set: [ ["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true] ] },
function() {
info("Prefs set");
SpecialPowers.pushPermissions(
[ { type: "browser", allow: true, context: document } ],
function() {
info("Permissions set");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
iframe.addEventListener("mozbrowserloadend", function() {
info("Starting tests");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
parentFrameScript(mm);
});
document.body.appendChild(iframe);
}
);
}
);
}
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

View File

@ -0,0 +1,140 @@
"use strict";
/* eslint-env mozilla/frame-script */
const { ExtensionTestUtils } = ChromeUtils.import(
"resource://testing-common/ExtensionXPCShellUtils.jsm"
);
ExtensionTestUtils.init(this);
function childFrameScript() {
"use strict";
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobType = "text/plain";
let blob = new Blob(blobData, { type: blobType });
let firstSliceStart = blobData[0].length + blobData[1].length;
let firstSliceEnd = firstSliceStart + blobData[2].length;
let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
let secondSliceStart = blobData[2].indexOf("a");
let secondSliceEnd = secondSliceStart + 2;
slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);
sendAsyncMessage(messageName, { blob });
sendAsyncMessage(messageName, { slice });
}
add_task(async function test() {
let page = await ExtensionTestUtils.loadContentPage(
"data:text/html,<!DOCTYPE HTML><html><body></body></html>",
{
remote: true,
}
);
page.loadFrameScript(childFrameScript);
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
const sliceText = "an";
let receivedBlob = false;
let receivedSlice = false;
let resolveBlob, resolveSlice;
let blobPromise = new Promise(resolve => {
resolveBlob = resolve;
});
let slicePromise = new Promise(resolve => {
resolveSlice = resolve;
});
let mm = page.browser.messageManager;
mm.addMessageListener(messageName, function(message) {
if ("blob" in message.data) {
equal(receivedBlob, false, "Have not yet received Blob");
equal(receivedSlice, false, "Have not yet received Slice");
receivedBlob = true;
let blob = message.data.blob;
ok(Blob.isInstance(blob), "Received a Blob");
equal(blob.size, blobText.length, "Blob has correct size");
equal(blob.type, blobType, "Blob has correct type");
let slice = blob.slice(
blobText.length - blobData[blobData.length - 1].length,
blob.size,
blobType
);
ok(Blob.isInstance(slice), "Slice returned a Blob");
equal(
slice.size,
blobData[blobData.length - 1].length,
"Slice has correct size"
);
equal(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = function() {
equal(
reader.result,
blobData[blobData.length - 1],
"Slice has correct data"
);
resolveBlob();
};
reader.readAsText(slice);
} else if ("slice" in message.data) {
equal(receivedBlob, true, "Already received Blob");
equal(receivedSlice, false, "Have not yet received Slice");
receivedSlice = true;
let slice = message.data.slice;
ok(Blob.isInstance(slice), "Received a Blob for slice");
equal(slice.size, sliceText.length, "Slice has correct size");
equal(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = function() {
equal(reader.result, sliceText, "Slice has correct data");
let slice2 = slice.slice(1, 2, blobType);
ok(Blob.isInstance(slice2), "Slice returned a Blob");
equal(slice2.size, 1, "Slice has correct size");
equal(slice2.type, blobType, "Slice has correct type");
let reader2 = new FileReader();
reader2.onload = function() {
equal(reader2.result, sliceText[1], "Slice has correct data");
resolveSlice();
};
reader2.readAsText(slice2);
};
reader.readAsText(slice);
} else {
ok(false, "Received a bad message: " + JSON.stringify(message.data));
}
});
await blobPromise;
await slicePromise;
await page.close();
});

View File

@ -1,207 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Test for slicing blobs that originated in a parent process</title>
<script src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="setup();">
<script type="application/javascript">
"use strict";
/* eslint-env mozilla/frame-script */
function childFrameScript() {
"use strict";
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
const sliceText = "an";
function info(msg) {
sendAsyncMessage(messageName, { op: "info", msg });
}
function ok(condition, name, diag) {
sendAsyncMessage(messageName,
{ op: "ok",
condition,
name,
diag });
}
function is(a, b, name) {
let pass = a == b;
let diag = pass ? "" : "got " + a + ", expected " + b;
ok(pass, name, diag);
}
function finish(result) {
sendAsyncMessage(messageName, { op: "done", result });
}
function grabAndContinue(arg) {
testGenerator.next(arg);
}
function* testSteps() {
addMessageListener(messageName, grabAndContinue);
let message = yield undefined;
let blob = message.data;
ok(Blob.isInstance(blob), "Received a Blob");
is(blob.size, blobText.length, "Blob has correct length");
is(blob.type, blobType, "Blob has correct type");
info("Reading blob");
let reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(blob);
yield undefined;
is(reader.result, blobText, "Blob has correct data");
let firstSliceStart = blobData[0].length + blobData[1].length;
let firstSliceEnd = firstSliceStart + blobData[2].length;
let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
ok(Blob.isInstance(slice), "Slice returned a Blob");
is(slice.size, blobData[2].length, "Slice has correct length");
is(slice.type, blobType, "Slice has correct type");
info("Reading slice");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[2], "Slice has correct data");
let secondSliceStart = blobData[2].indexOf("a");
let secondSliceEnd = secondSliceStart + sliceText.length;
slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);
ok(Blob.isInstance(slice), "Second slice returned a Blob");
is(slice.size, sliceText.length, "Second slice has correct length");
is(slice.type, blobType, "Second slice has correct type");
info("Sending second slice");
finish(slice);
}
let testGenerator = testSteps();
testGenerator.next();
}
function parentFrameScript(mm) {
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobType = "text/plain";
const sliceText = "an";
function grabAndContinue(arg) {
testGenerator.next(arg);
}
function* testSteps() {
let slice = yield undefined;
ok(SpecialPowers.call_Instanceof(slice, Blob), "Received a Blob");
is(slice.size, sliceText.length, "Slice has correct size");
is(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = grabAndContinue;
SpecialPowers.wrap(reader).readAsText(slice);
yield undefined;
is(reader.result, sliceText, "Slice has correct data");
SimpleTest.finish();
}
let testGenerator = testSteps();
testGenerator.next();
mm.addMessageListener(messageName, SpecialPowers.wrapCallback(function(message) {
let data = message.data;
switch (data.op) {
case "info": {
info(data.msg);
break;
}
case "ok": {
ok(data.condition, data.name + " - " + data.diag);
break;
}
case "done": {
testGenerator.next(data.result);
break;
}
default: {
ok(false, "Unknown op: " + data.op);
SimpleTest.finish();
}
}
}));
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
false);
let blob = new Blob(blobData, { type: blobType });
mm.sendAsyncMessage(messageName, blob);
}
function setup() {
info("Got load event");
SpecialPowers.pushPrefEnv(
{ set: [ ["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true] ] },
function() {
info("Prefs set");
SpecialPowers.pushPermissions(
[ { type: "browser", allow: true, context: document } ],
function() {
info("Permissions set");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
iframe.addEventListener("mozbrowserloadend", function() {
info("Starting tests");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
parentFrameScript(mm);
});
document.body.appendChild(iframe);
}
);
}
);
}
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

View File

@ -0,0 +1,167 @@
"use strict";
/* eslint-env mozilla/frame-script */
const { ExtensionTestUtils } = ChromeUtils.import(
"resource://testing-common/ExtensionXPCShellUtils.jsm"
);
ExtensionTestUtils.init(this);
function childFrameScript() {
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
const sliceText = "an";
function info(msg) {
sendAsyncMessage(messageName, { op: "info", msg });
}
function ok(condition, name, diag) {
sendAsyncMessage(messageName, { op: "ok", condition, name, diag });
}
function is(a, b, name) {
let pass = a == b;
let diag = pass ? "" : "got " + a + ", expected " + b;
ok(pass, name, diag);
}
function finish(result) {
sendAsyncMessage(messageName, { op: "done", result });
}
function grabAndContinue(arg) {
testGenerator.next(arg);
}
function* testSteps() {
addMessageListener(messageName, grabAndContinue);
let message = yield undefined;
let blob = message.data;
ok(Blob.isInstance(blob), "Received a Blob");
is(blob.size, blobText.length, "Blob has correct length");
is(blob.type, blobType, "Blob has correct type");
info("Reading blob");
let reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(blob);
yield undefined;
is(reader.result, blobText, "Blob has correct data");
let firstSliceStart = blobData[0].length + blobData[1].length;
let firstSliceEnd = firstSliceStart + blobData[2].length;
let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
ok(Blob.isInstance(slice), "Slice returned a Blob");
is(slice.size, blobData[2].length, "Slice has correct length");
is(slice.type, blobType, "Slice has correct type");
info("Reading slice");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[2], "Slice has correct data");
let secondSliceStart = blobData[2].indexOf("a");
let secondSliceEnd = secondSliceStart + sliceText.length;
slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);
ok(Blob.isInstance(slice), "Second slice returned a Blob");
is(slice.size, sliceText.length, "Second slice has correct length");
is(slice.type, blobType, "Second slice has correct type");
info("Sending second slice");
finish(slice);
}
let testGenerator = testSteps();
testGenerator.next();
}
add_task(async function test() {
let page = await ExtensionTestUtils.loadContentPage(
"data:text/html,<!DOCTYPE HTML><html><body></body></html>",
{
remote: true,
}
);
page.loadFrameScript(childFrameScript);
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobType = "text/plain";
const sliceText = "an";
await new Promise(resolve => {
function grabAndContinue(arg) {
testGenerator.next(arg);
}
function* testSteps() {
let slice = yield undefined;
ok(Blob.isInstance(slice), "Received a Blob");
equal(slice.size, sliceText.length, "Slice has correct size");
equal(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = grabAndContinue;
reader.readAsText(slice);
yield undefined;
equal(reader.result, sliceText, "Slice has correct data");
resolve();
}
let testGenerator = testSteps();
testGenerator.next();
let mm = page.browser.messageManager;
mm.addMessageListener(messageName, function(message) {
let data = message.data;
switch (data.op) {
case "info": {
info(data.msg);
break;
}
case "ok": {
ok(data.condition, data.name + " - " + data.diag);
break;
}
case "done": {
testGenerator.next(data.result);
break;
}
default: {
ok(false, "Unknown op: " + data.op);
resolve();
}
}
});
let blob = new Blob(blobData, { type: blobType });
mm.sendAsyncMessage(messageName, blob);
});
await page.close();
});

View File

@ -1,108 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for recursive CPOW-getting-cookie bug</title>
<script src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript">
"use strict";
/* eslint-env mozilla/frame-script */
SimpleTest.waitForExplicitFinish();
const childFrameURL =
"http://mochi.test:8888/tests/dom/ipc/tests/file_bug1086684.html";
function childFrameScript() {
"use strict";
let { MockFilePicker } =
ChromeUtils.import("resource://specialpowers/MockFilePicker.jsm");
function parentReady(message) {
MockFilePicker.init(content);
MockFilePicker.setFiles([message.data.file]);
MockFilePicker.returnValue = MockFilePicker.returnOK;
let input = content.document.getElementById("f");
input.addEventListener("change", () => {
MockFilePicker.cleanup();
let value = input.value;
message.target.sendAsyncMessage("testBug1086684:childDone", { value });
});
input.focus();
input.click();
}
addMessageListener("testBug1086684:parentReady", function(message) {
parentReady(message);
});
}
let test;
function* testStructure(mm) {
let value;
function testDone(msg) {
test.next(msg.data.value);
}
mm.addMessageListener("testBug1086684:childDone",
SpecialPowers.wrapCallback(testDone));
let blob = new Blob([]);
let file = new File([blob], "helloworld.txt", { type: "text/plain" });
mm.sendAsyncMessage("testBug1086684:parentReady", { file });
value = yield;
// Note that the "helloworld.txt" passed in above doesn't affect the
// 'value' getter. Because we're mocking a file using a blob, we ask the
// blob for its path, which is the empty string.
is(value, "", "got the right answer and didn't crash");
SimpleTest.finish();
}
function runTests() {
info("Browser prefs set.");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src = childFrameURL;
iframe.addEventListener("mozbrowserloadend", function() {
info("Got iframe load event.");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.loadFrameScript("data:,(" + encodeURI(childFrameScript.toString()) + ")();",
false);
test = testStructure(mm);
test.next();
});
document.body.appendChild(iframe);
}
addEventListener("load", function() {
info("Got load event.");
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({
"set": [
["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true],
],
}, runTests);
});
</script>
</body>
</html>

View File

@ -0,0 +1,103 @@
"use strict";
/* eslint-env mozilla/frame-script */
const { AddonTestUtils } = ChromeUtils.import(
"resource://testing-common/AddonTestUtils.jsm"
);
const { ExtensionTestUtils } = ChromeUtils.import(
"resource://testing-common/ExtensionXPCShellUtils.jsm"
);
AddonTestUtils.init(this);
ExtensionTestUtils.init(this);
ChromeUtils.import(
"resource://gre/modules/ContentPrefServiceParent.jsm"
).ContentPrefServiceParent.init();
const childFramePath = "/file_bug1086684.html";
const childFrameURL = "http://example.com" + childFramePath;
const childFrameContents = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="content">
<input type="file" id="f">
</div>
</body>
</html>`;
const server = AddonTestUtils.createHttpServer({ hosts: ["example.com"] });
server.registerPathHandler(childFramePath, (request, response) => {
response.write(childFrameContents);
});
function childFrameScript() {
"use strict";
let { MockFilePicker } = ChromeUtils.import(
"resource://testing-common/MockFilePicker.jsm"
);
function parentReady(message) {
MockFilePicker.init(content);
MockFilePicker.setFiles([message.data.file]);
MockFilePicker.returnValue = MockFilePicker.returnOK;
let input = content.document.getElementById("f");
input.addEventListener("change", () => {
MockFilePicker.cleanup();
let value = input.value;
message.target.sendAsyncMessage("testBug1086684:childDone", { value });
});
input.focus();
input.click();
}
addMessageListener("testBug1086684:parentReady", function(message) {
parentReady(message);
});
}
add_task(async function() {
let page = await ExtensionTestUtils.loadContentPage(childFrameURL, {
remote: true,
});
page.loadFrameScript(childFrameScript);
await new Promise(resolve => {
let test;
function* testStructure(mm) {
let value;
function testDone(msg) {
test.next(msg.data.value);
}
mm.addMessageListener("testBug1086684:childDone", testDone);
let blob = new Blob([]);
let file = new File([blob], "helloworld.txt", { type: "text/plain" });
mm.sendAsyncMessage("testBug1086684:parentReady", { file });
value = yield;
// Note that the "helloworld.txt" passed in above doesn't affect the
// 'value' getter. Because we're mocking a file using a blob, we ask the
// blob for its path, which is the empty string.
equal(value, "", "got the right answer and didn't crash");
resolve();
}
test = testStructure(page.browser.messageManager);
test.next();
});
await page.close();
});

View File

@ -1,90 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
-->
<head>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript">
"use strict";
/* eslint-env mozilla/frame-script */
SimpleTest.waitForExplicitFinish();
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({"set": [
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["dom.ipc.tabs.disabled", false],
]}, function() {
var iframe = document.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
iframe.setAttribute("remote", "true");
SpecialPowers.wrap(iframe).mozbrowser = true;
document.documentElement.appendChild(iframe);
var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.addMessageListener("chromeEventHandler", function(msg) {
msg = SpecialPowers.wrap(msg);
var result = msg.json;
is(result.processType, SpecialPowers.Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT,
"The frame script is running in a real distinct child process");
ok(result.hasCorrectInterface,
"docshell.chromeEventHandler has EventTarget interface");
});
mm.addMessageListener("DOMWindowCreatedReceived", function(msg) {
msg = SpecialPowers.wrap(msg);
ok(true, "the chrome event handler looks functional");
var result = msg.json;
ok(result.stableChromeEventHandler, "docShell.chromeEventHandler is stable");
ok(result.iframeHasNewDocShell, "iframe spawns a new docShell");
ok(result.iframeHasSameChromeEventHandler, "but iframe has the same chrome event handler");
SimpleTest.finish();
});
// Inject a frame script in the child process:
mm.loadFrameScript("data:,new " + function ContentScriptScope() {
var chromeEventHandler = docShell.chromeEventHandler;
sendAsyncMessage("chromeEventHandler", {
processType: Services.appinfo.processType,
hasCorrectInterface: chromeEventHandler &&
EventTarget.isInstance(chromeEventHandler),
});
/*
Ensure that this chromeEventHandler actually works,
by creating a new window and listening for its DOMWindowCreated event
*/
chromeEventHandler.addEventListener("DOMWindowCreated", function listener(evt) {
if (evt.target == content.document) {
return;
}
chromeEventHandler.removeEventListener("DOMWindowCreated", listener);
let new_win = evt.target.defaultView;
let new_docShell = new_win.docShell;
sendAsyncMessage("DOMWindowCreatedReceived", {
stableChromeEventHandler: chromeEventHandler === docShell.chromeEventHandler,
iframeHasNewDocShell: new_docShell !== docShell,
iframeHasSameChromeEventHandler: new_docShell.chromeEventHandler === chromeEventHandler,
});
});
function go() {
let i = content.document.createElement("iframe");
i.setAttribute("src", "data:text/html,foo");
content.document.documentElement.appendChild(i);
}
if (content.document.readyState == "complete") {
go();
} else {
addEventListener("load", go, { once: true, capture: true });
}
}, false);
});
</script>
</body>
</html>

View File

@ -0,0 +1,89 @@
"use strict";
/* eslint-env mozilla/frame-script */
const { ExtensionTestUtils } = ChromeUtils.import(
"resource://testing-common/ExtensionXPCShellUtils.jsm"
);
ExtensionTestUtils.init(this);
add_task(async function test() {
let page = await ExtensionTestUtils.loadContentPage("about:blank", {
remote: true,
});
await new Promise(resolve => {
let mm = page.browser.messageManager;
mm.addMessageListener("chromeEventHandler", function(msg) {
var result = msg.json;
equal(
result.processType,
Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT,
"The frame script is running in a real distinct child process"
);
ok(
result.hasCorrectInterface,
"docshell.chromeEventHandler has EventTarget interface"
);
});
mm.addMessageListener("DOMWindowCreatedReceived", function(msg) {
ok(true, "the chrome event handler looks functional");
var result = msg.json;
ok(
result.stableChromeEventHandler,
"docShell.chromeEventHandler is stable"
);
ok(result.iframeHasNewDocShell, "iframe spawns a new docShell");
ok(
result.iframeHasSameChromeEventHandler,
"but iframe has the same chrome event handler"
);
resolve();
});
// Inject a frame script in the child process:
page.loadFrameScript(async function() {
var chromeEventHandler = docShell.chromeEventHandler;
sendAsyncMessage("chromeEventHandler", {
processType: Services.appinfo.processType,
hasCorrectInterface:
chromeEventHandler && EventTarget.isInstance(chromeEventHandler),
});
/*
Ensure that this chromeEventHandler actually works,
by creating a new window and listening for its DOMWindowCreated event
*/
chromeEventHandler.addEventListener("DOMWindowCreated", function listener(
evt
) {
if (evt.target == content.document) {
return;
}
chromeEventHandler.removeEventListener("DOMWindowCreated", listener);
let new_win = evt.target.defaultView;
let new_docShell = new_win.docShell;
sendAsyncMessage("DOMWindowCreatedReceived", {
stableChromeEventHandler:
chromeEventHandler === docShell.chromeEventHandler,
iframeHasNewDocShell: new_docShell !== docShell,
iframeHasSameChromeEventHandler:
new_docShell.chromeEventHandler === chromeEventHandler,
});
});
if (content.document.readyState != "complete") {
await new Promise(res =>
addEventListener("load", res, { once: true, capture: true })
);
}
let iframe = content.document.createElement("iframe");
iframe.setAttribute("src", "data:text/html,foo");
content.document.documentElement.appendChild(iframe);
});
});
await page.close();
});

View File

@ -1,90 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for recursive CPOW-getting-cookie bug</title>
<script src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript">
"use strict";
/* eslint-env mozilla/frame-script */
SimpleTest.waitForExplicitFinish();
const childFrameURL =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
function childFrameScript() {
"use strict";
function test1(message) {
// NB: This is a no-op because we're a data: document with a null
// principal.
content.document.cookie = "a=b";
message.target.sendAsyncMessage("testCPOWCookies:test1Finished", { pass: true });
}
addMessageListener("testCPOWCookies:test1", function(message) {
test1(message);
});
}
let test;
function* testStructure(mm) {
let lastResult;
function testDone(msg) {
test.next(msg.data);
}
mm.addMessageListener("testCPOWCookies:test1Finished",
SpecialPowers.wrapCallback(testDone));
mm.sendAsyncMessage("testCPOWCookies:test1", {});
lastResult = yield;
ok(lastResult.pass, "got the right answer and didn't crash");
SimpleTest.finish();
}
function runTests() {
info("Browser prefs set.");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src = childFrameURL;
iframe.addEventListener("mozbrowserloadend", function() {
info("Got iframe load event.");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.loadFrameScript("data:,(" + encodeURI(childFrameScript.toString()) + ")();",
false);
test = testStructure(mm);
test.next();
});
document.body.appendChild(iframe);
}
addEventListener("load", function() {
info("Got load event.");
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({
"set": [
["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true],
["security.data_uri.block_toplevel_data_uri_navigations", false],
],
}, runTests);
});
</script>
</body>
</html>

View File

@ -1,2 +1,10 @@
[test_sharedMap.js]
skip-if = os == "android" && processor == "x86_64"
[test_blob_sliced_from_child_process.js]
skip-if = os == "android" && processor == "x86_64"
[test_blob_sliced_from_parent_process.js]
skip-if = os == "android" && processor == "x86_64"
[test_bug1086684.js]
skip-if = os == "android" && processor == "x86_64"
[test_child_docshell.js]
skip-if = os == "android" && processor == "x86_64"

View File

@ -2,6 +2,7 @@
support-files =
tcpsocket_test.jsm
test_tcpsocket_client_and_server_basics.js
file_postMessage_opener.html
file_udpsocket_iframe.html
[test_tcpsocket_jsm.html]

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script>
opener.postMessage("hello", "*");
</script>
</head>
<body>
</body>
</html>

View File

@ -321,38 +321,44 @@ function testOpenWithoutClose() {
return Promise.all(closed);
}
function testBFCache() {
function awaitEvent(target, event) {
return new Promise(resolve => {
target.addEventListener(event, resolve, { once: true });
});
}
async function testBFCache() {
info('test for bfcache behavior');
let socket = new UDPSocket();
return socket.opened.then(function() {
let iframe = document.getElementById('iframe');
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.src = 'file_udpsocket_iframe.html?' + socket.localPort;
await socket.opened;
return new Promise(function(resolve, reject) {
socket.addEventListener('message', function(msg) {
iframe.src = 'about:blank';
iframe.addEventListener('load', function() {
socket.send(HELLO_WORLD, '127.0.0.1', msg.remotePort);
let win = window.open(`file_udpsocket_iframe.html?${socket.localPort}`);
function recv_again_callback(message) {
socket.removeEventListener('message', recv_again_callback);
ok(false, 'should not receive packet after page unload');
}
let msg = await awaitEvent(socket, "message");
socket.addEventListener('message', recv_again_callback);
win.location = "file_postMessage_opener.html";
await awaitEvent(window, "message");
let timeout = setTimeout(function() {
socket.removeEventListener('message', recv_again_callback);
socket.close();
resolve();
}, 5000);
}, {once: true});
}, {once: true});
});
socket.send(HELLO_WORLD, '127.0.0.1', msg.remotePort);
await new Promise(resolve => {
function recv_again_callback(message) {
socket.removeEventListener('message', recv_again_callback);
ok(false, 'should not receive packet after page unload');
}
socket.addEventListener('message', recv_again_callback);
let timeout = setTimeout(function() {
socket.removeEventListener('message', recv_again_callback);
socket.close();
resolve();
}, 5000);
});
win.close();
}
function runTest() {

View File

@ -17,7 +17,10 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
// Allow stuff from this scope to be accessed from non-privileged scopes. This
// would crash if used outside of automation.
Cu.forcePermissiveCOWs();
/* globals __URI__ */
if (__URI__.includes("specialpowers")) {
Cu.forcePermissiveCOWs();
}
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
var oldClassID;

View File

@ -71,6 +71,55 @@ function doPrefEnvOp(fn) {
}
}
async function createWindowlessBrowser({ isPrivate = false } = {}) {
const {
promiseDocumentLoaded,
promiseEvent,
promiseObserved,
} = ChromeUtils.import(
"resource://gre/modules/ExtensionUtils.jsm"
).ExtensionUtils;
let windowlessBrowser = Services.appShell.createWindowlessBrowser(true);
if (isPrivate) {
let loadContext = windowlessBrowser.docShell.QueryInterface(
Ci.nsILoadContext
);
loadContext.usePrivateBrowsing = true;
}
let chromeShell = windowlessBrowser.docShell.QueryInterface(
Ci.nsIWebNavigation
);
const system = Services.scriptSecurityManager.getSystemPrincipal();
chromeShell.createAboutBlankContentViewer(system, system);
chromeShell.useGlobalHistory = false;
chromeShell.loadURI("chrome://extensions/content/dummy.xhtml", {
triggeringPrincipal: system,
});
await promiseObserved(
"chrome-document-global-created",
win => win.document == chromeShell.document
);
let chromeDoc = await promiseDocumentLoaded(chromeShell.document);
let browser = chromeDoc.createXULElement("browser");
browser.setAttribute("type", "content");
browser.setAttribute("disableglobalhistory", "true");
browser.setAttribute("remote", "true");
let promise = promiseEvent(browser, "XULFrameLoaderCreated");
chromeDoc.documentElement.appendChild(browser);
await promise;
return { windowlessBrowser, browser };
}
// Supplies the unique IDs for tasks created by SpecialPowers.spawn(),
// used to bounce assertion messages back down to the correct child.
let nextTaskID = 1;
@ -821,6 +870,7 @@ class SpecialPowersParent extends JSWindowActorParent {
);
Object.assign(sb.sandbox, {
createWindowlessBrowser,
sendAsyncMessage: (name, message) => {
this.sendAsyncMessage("SPChromeScriptMessage", {
id,

View File

@ -24,6 +24,7 @@ ChromeUtils.defineModuleGetter(
const SANDBOX_GLOBALS = [
"Blob",
"ChromeUtils",
"FileReader",
"TextDecoder",
"TextEncoder",
"URL",

View File

@ -26,5 +26,9 @@ FINAL_TARGET_FILES.content += [
'content/WrapPrivileged.jsm',
]
TESTING_JS_MODULES += [
'content/MockFilePicker.jsm',
]
with Files("**"):
BUG_COMPONENT = ("Testing", "Mochitest")

View File

@ -1,4 +1,3 @@
[DEFAULT]
[test_remoteContentPrefs.html]
skip-if = e10s # bug 783513

View File

@ -11,339 +11,328 @@
<script type="application/javascript">
"use strict";
let Cu = SpecialPowers.Cu;
let loadContext = Cu.createLoadContext();
let privateLoadContext = Cu.createPrivateLoadContext();
async function chromeScriptFunc() {
let loadContext = Cu.createLoadContext();
let privateLoadContext = Cu.createPrivateLoadContext();
SimpleTest.waitForExplicitFinish();
const childFrameURL =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
const childFrameURL =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
function childFrameScript(isFramePrivate) {
"use strict";
/* global addMessageListener */
function childFrameScript(isFramePrivate) {
"use strict";
/* global addMessageListener */
dump("Hallo am child.\n")
/* eslint no-shadow: 0 */
function Defer() {
let d = {};
d.promise = new Promise((resolve, reject) => {
d.resolve = resolve;
d.reject = reject;
});
return d;
}
function Tester(mm) {
this.mm = mm;
}
Tester.prototype.is =
function(a, b, note) {
this.mm.sendAsyncMessage("testRemoteContentPrefs:ok", { test: [a === b, note + " (" + a + ", " + b + ")"] });
};
Tester.prototype.ok =
function(b, note) {
this.mm.sendAsyncMessage("testRemoteContentPrefs:ok", { test: [!!b, note] });
};
Tester.prototype.info =
function(note) {
this.mm.sendAsyncMessage("testRemoteContentPrefs:info", { note });
};
var cps = Cc["@mozilla.org/content-pref/service;1"]
.getService(Ci.nsIContentPrefService2);
async function test1(mm) {
let tester = new Tester(mm);
tester.ok(cps !== null, "got the content pref service");
let setPref = Defer();
cps.setGlobal("testing", 42, null, {
handleCompletion(reason) {
tester.is(reason, 0, "set a pref?");
setPref.resolve();
},
});
await setPref.promise;
let numResults = 0;
let gotGlobal = Defer();
cps.getGlobal("testing", null, {
handleResult(pref) {
numResults++;
tester.is(pref.name, "testing", "pref has the right name");
tester.is(pref.value, 42, "pref has the right value");
},
handleCompletion(reason) {
tester.is(reason, 0, "get a pref?");
tester.is(numResults, 1, "got the right number of prefs");
gotGlobal.resolve();
},
});
await gotGlobal.promise;
}
async function test2(mm) {
let tester = new Tester(mm);
let observer;
let removed = false;
let gotSet = Defer();
let gotRemoved = Defer();
cps.addObserverForName("testName", observer = {
onContentPrefSet(group, name, value, isPrivate) {
tester.info("received prefSet notification");
if (removed) {
mm.sendAsyncMessage("testRemoteContentPrefs:fail",
{ reason: "unexpected notification" });
}
tester.is(group, null, "group should be null");
tester.is(name, "testName", "should only see testName");
tester.is(value, 42, "value should be correct");
tester.is(isPrivate, isFramePrivate, "privacy should match");
gotSet.resolve();
},
onContentPrefRemoved(group, name, isPrivate) {
tester.info("received prefRemoved notification");
tester.is(group, null, "group should be null");
tester.is(name, "testName", "name should match");
tester.is(isPrivate, isFramePrivate, "privacy should match");
cps.removeObserverForName("testName", observer);
removed = true;
gotRemoved.resolve();
},
});
mm.sendAsyncMessage("testRemoteContentPrefs:test2poke", {});
await gotSet.promise;
mm.sendAsyncMessage("testRemoteContentPrefs:test2poke2", {});
await gotRemoved.promise;
}
async function test3(mm) {
let tester = new Tester(mm);
let setGlobalDone = Defer();
cps.setGlobal("testName", 42, null, {
handleCompletion(reason) {
tester.is(reason, 0, "set a pref");
cps.set("http://mochi.test", "testpref", "str", null, {
/* eslint no-shadow: 0 */
handleCompletion(reason) {
tester.is(reason, 0, "set a pref");
setGlobalDone.resolve();
},
});
},
});
await setGlobalDone.promise;
let removeDone = Defer();
cps.removeByDomain("http://mochi.test", null, {
handleCompletion(reason) {
tester.is(reason, 0, "remove succeeded");
cps.getByDomainAndName("http://mochi.test", "testpref", null, {
handleResult() {
mm.sendAsyncMessage("testRemoteContentPrefs:fail",
{ reason: "got removed pref in test3" });
},
handleCompletion() {
removeDone.resolve();
},
handleError(rv) {
mm.sendAsyncMessage("testRemoteContentPrefs:fail",
{ reason: `got a pref error ${rv}` });
},
});
},
});
await removeDone.promise;
}
async function test4(mm) {
let tester = new Tester(mm);
let observed = Defer();
let prefObserver = {
onContentPrefSet(group, name, value, isPrivate) {
observed.resolve({ group, name, value, isPrivate });
},
onContentPrefRemoved(group, name, isPrivate) {
observed.reject("got unexpected notification");
},
};
cps.addObserverForName("test", prefObserver);
let privateLoadContext = Cu.createPrivateLoadContext();
cps.set("http://mochi.test", "test", 42, privateLoadContext);
let event = await observed.promise;
tester.is(event.name, "test", "got the right event");
tester.is(event.isPrivate, true, "the event was for an isPrivate pref");
mm.sendAsyncMessage("testRemoteContentPrefs:getPref",
{ group: "http://mochi.test", name: "test" });
let results = await new Promise(resolve => {
addMessageListener("testRemoteContentPrefs:prefResults",
(msg) => { resolve(msg.data.results); });
});
tester.is(results.length, 0, "should not have seen the pb pref");
}
var tests = { test1, test2, test3, test4 };
function testHandler(mm, testName) {
tests[testName](mm).then(() => {
mm.sendAsyncMessage(`testRemoteContentPrefs:${testName}Finished`, {});
}).catch((e) => {
mm.sendAsyncMessage("testRemoteContentPrefs:fail", { reason: e });
});
}
for (let test of Object.getOwnPropertyNames(tests)) {
addMessageListener(`testRemoteContentPrefs:${test}`, function(message) {
dump("Hallo am child message.\n")
testHandler(message.target, test);
});
}
}
/* eslint no-shadow: 0 */
function Defer() {
let d = {};
var d = {};
d.promise = new Promise((resolve, reject) => {
d.resolve = resolve;
d.reject = reject;
});
return d;
}
function Tester(mm) {
this.mm = mm;
}
Tester.prototype.is =
function(a, b, note) {
this.mm.sendAsyncMessage("testRemoteContentPrefs:ok", { test: [a === b, note + " (" + a + ", " + b + ")"] });
};
Tester.prototype.ok =
function(b, note) {
this.mm.sendAsyncMessage("testRemoteContentPrefs:ok", { test: [!!b, note] });
};
Tester.prototype.info =
function(note) {
this.mm.sendAsyncMessage("testRemoteContentPrefs:info", { note });
async function testStructure(mm, isPrivate) {
var curTest;
function testDone(msg) {
info(`in testDone ${msg.name}`);
curTest.resolve();
};
var cps = Cc["@mozilla.org/content-pref/service;1"]
.getService(Ci.nsIContentPrefService2);
mm.addMessageListener("testRemoteContentPrefs:test1Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test2Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test3Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test4Finished", testDone);
async function test1(mm) {
let tester = new Tester(mm);
tester.ok(cps !== null, "got the content pref service");
let setPref = Defer();
cps.setGlobal("testing", 42, null, {
handleCompletion(reason) {
tester.is(reason, 0, "set a pref?");
setPref.resolve();
},
mm.addMessageListener("testRemoteContentPrefs:fail", function(msg) {
ok(false, msg.data.reason);
SimpleTest.finish();
});
await setPref.promise;
let numResults = 0;
let gotGlobal = Defer();
cps.getGlobal("testing", null, {
handleResult(pref) {
numResults++;
tester.is(pref.name, "testing", "pref has the right name");
tester.is(pref.value, 42, "pref has the right value");
},
handleCompletion(reason) {
tester.is(reason, 0, "get a pref?");
tester.is(numResults, 1, "got the right number of prefs");
gotGlobal.resolve();
},
mm.addMessageListener("testRemoteContentPrefs:ok", (msg) => {
let test = msg.data.test;
ok(...test);
});
mm.addMessageListener("testRemoteContentPrefs:info", (msg) => {
info(msg.data.note);
});
await gotGlobal.promise;
curTest = Defer();
mm.sendAsyncMessage("testRemoteContentPrefs:test1", {});
await curTest.promise;
curTest = Defer();
var cps = Cc["@mozilla.org/content-pref/service;1"]
.getService(Ci.nsIContentPrefService2);
mm.addMessageListener("testRemoteContentPrefs:test2poke", function() {
info(`received test2poke isPrivate: ${isPrivate}`);
cps.setGlobal("testName", 42, isPrivate ? privateLoadContext : loadContext);
});
mm.addMessageListener("testRemoteContentPrefs:test2poke2", function() {
info(`received test2poke2 isPrivate: ${isPrivate}`);
cps.removeGlobal("testName", isPrivate ? privateLoadContext : loadContext);
});
mm.sendAsyncMessage("testRemoteContentPrefs:test2", {});
await curTest.promise;
curTest = Defer();
mm.sendAsyncMessage("testRemoteContentPrefs:test3", {});
await curTest.promise;
curTest = Defer();
mm.addMessageListener("testRemoteContentPrefs:getPref", function(msg) {
let results = [];
cps.getByDomainAndName(msg.data.group, msg.data.name, null, {
handleResult(pref) {
info("received handleResult");
results.push(pref);
},
handleCompletion(reason) {
mm.sendAsyncMessage("testRemoteContentPrefs:prefResults",
{ results });
},
handleError(rv) {
ok(false, `failed to get pref ${rv}`);
curTest.reject("got unexpected error");
},
});
});
mm.sendAsyncMessage("testRemoteContentPrefs:test4", {});
await curTest.promise;
}
async function test2(mm) {
let tester = new Tester(mm);
async function runTest(isPrivate) {
/* globals Services, createWindowlessBrowser */
info("testing with isPrivate=" + isPrivate);
let { windowlessBrowser, browser } = await createWindowlessBrowser({ isPrivate });
let observer;
let removed = false;
let gotSet = Defer();
let gotRemoved = Defer();
cps.addObserverForName("testName", observer = {
onContentPrefSet(group, name, value, isPrivate) {
tester.info("received prefSet notification");
if (removed) {
mm.sendAsyncMessage("testRemoteContentPrefs:fail",
{ reason: "unexpected notification" });
}
tester.is(group, null, "group should be null");
tester.is(name, "testName", "should only see testName");
tester.is(value, 42, "value should be correct");
tester.is(isPrivate, isFramePrivate, "privacy should match");
const system = Services.scriptSecurityManager.getSystemPrincipal();
gotSet.resolve();
},
browser.loadURI(childFrameURL, { triggeringPrincipal: system });
onContentPrefRemoved(group, name, isPrivate) {
tester.info("received prefRemoved notification");
tester.is(group, null, "group should be null");
tester.is(name, "testName", "name should match");
tester.is(isPrivate, isFramePrivate, "privacy should match");
cps.removeObserverForName("testName", observer);
removed = true;
gotRemoved.resolve();
},
});
mm.sendAsyncMessage("testRemoteContentPrefs:test2poke", {});
await gotSet.promise;
mm.sendAsyncMessage("testRemoteContentPrefs:test2poke2", {});
await gotRemoved.promise;
}
async function test3(mm) {
let tester = new Tester(mm);
let setGlobalDone = Defer();
cps.setGlobal("testName", 42, null, {
handleCompletion(reason) {
tester.is(reason, 0, "set a pref");
cps.set("http://mochi.test", "testpref", "str", null, {
/* eslint no-shadow: 0 */
handleCompletion(reason) {
tester.is(reason, 0, "set a pref");
setGlobalDone.resolve();
},
});
},
});
await setGlobalDone.promise;
let removeDone = Defer();
cps.removeByDomain("http://mochi.test", null, {
handleCompletion(reason) {
tester.is(reason, 0, "remove succeeded");
cps.getByDomainAndName("http://mochi.test", "testpref", null, {
handleResult() {
mm.sendAsyncMessage("testRemoteContentPrefs:fail",
{ reason: "got removed pref in test3" });
},
handleCompletion() {
removeDone.resolve();
},
handleError(rv) {
mm.sendAsyncMessage("testRemoteContentPrefs:fail",
{ reason: `got a pref error ${rv}` });
},
});
},
});
await removeDone.promise;
}
async function test4(mm) {
let tester = new Tester(mm);
let observed = Defer();
let prefObserver = {
onContentPrefSet(group, name, value, isPrivate) {
observed.resolve({ group, name, value, isPrivate });
},
onContentPrefRemoved(group, name, isPrivate) {
observed.reject("got unexpected notification");
},
};
cps.addObserverForName("test", prefObserver);
let privateLoadContext = Cu.createPrivateLoadContext();
cps.set("http://mochi.test", "test", 42, privateLoadContext);
let event = await observed.promise;
tester.is(event.name, "test", "got the right event");
tester.is(event.isPrivate, true, "the event was for an isPrivate pref");
mm.sendAsyncMessage("testRemoteContentPrefs:getPref",
{ group: "http://mochi.test", name: "test" });
let results = await new Promise(resolve => {
addMessageListener("testRemoteContentPrefs:prefResults",
(msg) => { resolve(msg.data.results); });
});
tester.is(results.length, 0, "should not have seen the pb pref");
}
var tests = { test1, test2, test3, test4 };
function testHandler(mm, testName) {
tests[testName](mm).then(() => {
mm.sendAsyncMessage(`testRemoteContentPrefs:${testName}Finished`, {});
}).catch((e) => {
mm.sendAsyncMessage("testRemoteContentPrefs:fail", { reason: e });
});
}
for (let test of Object.getOwnPropertyNames(tests)) {
addMessageListener(`testRemoteContentPrefs:${test}`, function(message) {
testHandler(message.target, test);
});
}
}
function Defer() {
var d = {};
d.promise = new Promise((resolve, reject) => {
d.resolve = resolve;
d.reject = reject;
});
return d;
}
async function testStructure(mm, isPrivate) {
var curTest;
var testDone = SpecialPowers.wrapCallback(function testDone(msg) {
info(`in testDone ${msg.name}`);
curTest.resolve();
});
mm.addMessageListener("testRemoteContentPrefs:test1Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test2Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test3Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:test4Finished", testDone);
mm.addMessageListener("testRemoteContentPrefs:fail", SpecialPowers.wrapCallback(function(msg) {
ok(false, msg.data.reason);
SimpleTest.finish();
}));
mm.addMessageListener("testRemoteContentPrefs:ok", SpecialPowers.wrapCallback((msg) => {
let test = msg.data.test;
ok(...test);
}));
mm.addMessageListener("testRemoteContentPrefs:info", SpecialPowers.wrapCallback((msg) => {
info(msg.data.note);
}));
curTest = Defer();
mm.sendAsyncMessage("testRemoteContentPrefs:test1", {});
await curTest.promise;
curTest = Defer();
var cps = SpecialPowers.Cc["@mozilla.org/content-pref/service;1"]
.getService(SpecialPowers.Ci.nsIContentPrefService2);
mm.addMessageListener("testRemoteContentPrefs:test2poke", function() {
info(`received test2poke isPrivate: ${isPrivate}`);
cps.setGlobal("testName", 42, isPrivate ? privateLoadContext : loadContext);
});
mm.addMessageListener("testRemoteContentPrefs:test2poke2", function() {
info(`received test2poke2 isPrivate: ${isPrivate}`);
cps.removeGlobal("testName", isPrivate ? privateLoadContext : loadContext);
});
mm.sendAsyncMessage("testRemoteContentPrefs:test2", {});
await curTest.promise;
curTest = Defer();
mm.sendAsyncMessage("testRemoteContentPrefs:test3", {});
await curTest.promise;
curTest = Defer();
mm.addMessageListener("testRemoteContentPrefs:getPref", SpecialPowers.wrapCallback(function(msg) {
let results = [];
cps.getByDomainAndName(msg.data.group, msg.data.name, null, {
handleResult(pref) {
info("received handleResult");
results.push(pref);
},
handleCompletion(reason) {
mm.sendAsyncMessage("testRemoteContentPrefs:prefResults",
{ results });
},
handleError(rv) {
ok(false, `failed to get pref ${rv}`);
curTest.reject("got unexpected error");
},
});
}));
mm.sendAsyncMessage("testRemoteContentPrefs:test4", {});
await curTest.promise;
document.getElementById("iframe").remove();
}
function runTest(isPrivate) {
info("testing with isPrivate=" + isPrivate);
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
if (isPrivate) {
SpecialPowers.wrap(iframe).mozprivatebrowsing = true;
}
iframe.id = "iframe";
iframe.src = childFrameURL;
let deferred = Defer();
iframe.addEventListener("mozbrowserloadend", function() {
info("Got iframe load event.");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")(" + isPrivate + ");",
let mm = browser.messageManager;
mm.loadFrameScript(`data:,` + encodeURI(`(${childFrameScript})(${isPrivate})`),
false);
// Chain testStructure to runTests's promise.
testStructure(mm, isPrivate).then(deferred.resolve)
.catch((e) => { info(`caught failing test ${e}`); });
});
await testStructure(mm, isPrivate);
document.body.appendChild(iframe);
return deferred.promise;
windowlessBrowser.close();
}
try {
await runTest(false);
await runTest(true);
} catch (e) {
Cu.reportError(e);
ok(false, "Test task threw exception");
}
/* globals sendAsyncMessage */
sendAsyncMessage("done");
}
function runTests() {
info("Browser prefs set.");
add_task(() => { return runTest(false); });
add_task(() => { return runTest(true); });
}
addEventListener("load", function() {
info("Got load event.");
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({
"set": [
["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["browser.pagethumbnails.capturing_disabled", true],
],
}, runTests);
add_task(async function() {
let chromeScript = SpecialPowers.loadChromeScript(chromeScriptFunc);
await chromeScript.promiseOneMessage("done");
await chromeScript.destroy();
});
</script>
</body>