Bug 1541557: Part 4 - Stop relying on synchronous preference getters/setters. r=nika

The SpecialPowers set*Pref/get*Pref APIs currently use synchronous messaging
to set and get preference values from the parent process. Aside from directly
affecting callers of those APIs, it also affects callers of `pushPrefEnv`,
which is meant to be asynchronous, but is in practice usually synchronous due
to the synchronous messaging it uses.

This patch updates the getPref APIs to use the in-process preference service
(which most callers are expecting anyway), and also updates the callers of
the setPref and pushPrefEnv APIs to await the result if they're relying on it
taking effect immediately.

Unfortunately, there are some corner cases in tests that appear to only work
because of the quirks of the current sync messaging approach. The synchronous
setPref APIs, for instance, trigger preference changes in the parent
instantly, but don't update the values in the child until we've returned to
the event loop and had a chance to process the notifications from the parent.
The differnce in timing leads some tests to fail in strange ways, which this
patch works around by just adding timeouts.

There should be follow-ups for test owners to fix the flakiness.

Differential Revision: https://phabricator.services.mozilla.com/D35054

--HG--
extra : rebase_source : 941298157e7c82f420cf50ce057154ce9b85301c
extra : source : 189dc8a359815e059a4a217f788d183260bb2bfe
This commit is contained in:
Kris Maglione 2019-06-13 09:34:39 -07:00
Родитель fcb799ab11
Коммит f70e67ad2d
29 изменённых файлов: 263 добавлений и 231 удалений

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

@ -10,6 +10,8 @@
<label value="CPOWs"/>
<script type="application/javascript"><![CDATA[
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var test_state = "remote";
var test_node = null;
var reentered = false;
@ -400,7 +402,7 @@
let failed = false;
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
try {
msg.objects.f();
} catch (e) {
@ -416,7 +418,7 @@
function recvSafe(msg) {
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
try {
msg.objects.f();
} catch (e) {

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

@ -13,12 +13,14 @@
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
SimpleTest.waitForExplicitFinish();
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, false);
Services.prefs.setBoolPref(PREF_UNSAFE_FORBIDDEN, false);
SimpleTest.registerCleanupFunction(() => {
SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN);
Services.prefs.clearUserPref(PREF_UNSAFE_FORBIDDEN);
});
function done() {

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

@ -23,7 +23,8 @@
<script class="testbody" type="application/javascript">
<![CDATA[
var SpecialPowers = window.opener.wrappedJSObject.SpecialPowers;
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var SimpleTest = window.opener.wrappedJSObject.SimpleTest;
SimpleTest.waitForFocus(runTests, window);
@ -1480,7 +1481,7 @@ function runReleaseTests()
// Release the TIP
TIP = null;
// Needs to run GC forcibly for testing this.
SpecialPowers.gc();
Cu.forceGC();
is(input.value, "",
description + "the input should be empty because the composition should be canceled");
@ -1770,7 +1771,7 @@ function runCompositionWithKeyEventTests()
var convertKeyEvent = new KeyboardEvent("", { key: "Convert", code: "Convert", keyCode: KeyboardEvent.DOM_VK_CONVERT });
var backspaceKeyEvent = new KeyboardEvent("", { key: "Backspace", code: "Backspace", keyCode: KeyboardEvent.DOM_VK_BACK_SPACE });
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
// nsITextInputProcessor.startComposition()
reset();
@ -2004,7 +2005,7 @@ function runCompositionWithKeyEventTests()
is(input.value, "FOobarbuzzboo!",
description + "committing text directly should append the committing text to the focused editor");
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
// Even if "dom.keyboardevent.dispatch_during_composition" is true, keypress event shouldn't be fired during composition
reset();
@ -2108,7 +2109,7 @@ function runCompositionWithKeyEventTests()
is(events[1].type, "compositionend",
description + "TIP.cancelComposition(escKeydownEvent) should cause compositionend (keyup event shouldn't be fired)");
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
window.removeEventListener("compositionstart", handler, false);
window.removeEventListener("compositionupdate", handler, false);
@ -2155,7 +2156,7 @@ function runConsumingKeydownBeforeCompositionTests()
var enterKeyEvent = new KeyboardEvent("", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN });
var escKeyEvent = new KeyboardEvent("", { key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE });
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
// If keydown before compositionstart is consumed, composition shouldn't be started.
reset();
@ -2205,7 +2206,7 @@ function runConsumingKeydownBeforeCompositionTests()
is(input.value, "",
description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) shouldn't cause inserting text");
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
// If composition is already started, TIP.flushPendingComposition(printableKeyEvent) shouldn't be canceled.
TIP.startComposition();
@ -2273,7 +2274,7 @@ function runConsumingKeydownBeforeCompositionTests()
is(input.value, "",
description + "TIP.cancelComposition(escKeyEvent) should cancel composition even if preceding keydown is consumed because there was a composition already");
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
window.removeEventListener("compositionstart", handler, false);
window.removeEventListener("compositionupdate", handler, false);
@ -2594,7 +2595,7 @@ function runKeyTests()
// key events during composition
try {
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", false);
ok(TIP.startComposition(), "TIP.startComposition() should start composition");
@ -2608,7 +2609,7 @@ function runKeyTests()
is(events.length, 0,
description + "TIP.keyup(keyA) shouldn't cause key events during composition if it's disabled by the pref");
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
reset();
TIP.keydown(keyA);
is(events.length, 1,
@ -2624,7 +2625,7 @@ function runKeyTests()
} finally {
TIP.cancelComposition();
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
}
// Test .location computation

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

@ -23,30 +23,31 @@ let seenClick = false;
SpecialPowers.pushPrefEnv(
{ set: [[HACK_PREF, document.domain]] },
SimpleTest.waitForFocus(() => {
// Test seeing the non-primary 'click'
document.addEventListener("click", (e) => {
ok(true, "Saw 'click' event");
seenClick = true;
}, { once: true });
document.addEventListener("auxclick", (e) => {
ok(true, "Saw 'auxclick' event");
ok(seenClick, "Saw 'click' event before 'auxclick' event");
}, { once: true });
synthesizeMouseAtCenter(testEl, { button: 1 });
() => {
SimpleTest.waitForFocus(() => {
// Test seeing the non-primary 'click'
document.addEventListener("click", (e) => {
ok(true, "Saw 'click' event");
seenClick = true;
}, { once: true });
document.addEventListener("auxclick", (e) => {
ok(true, "Saw 'auxclick' event");
ok(seenClick, "Saw 'click' event before 'auxclick' event");
}, { once: true });
synthesizeMouseAtCenter(testEl, { button: 1 });
// Test preventDefaulting on non-primary 'click'
document.addEventListener("click", (e) => {
is(e.target, linkEl, "Saw 'click' on link");
e.preventDefault();
SimpleTest.finish();
}, { once: true, capture: true });
document.addEventListener("auxclick", (e) => {
ok(false, "Shouldn't have got 'auxclick' after preventDefaulting 'click'");
}, { once: true });
synthesizeMouseAtCenter(linkEl, { button: 1 });
})
);
// Test preventDefaulting on non-primary 'click'
document.addEventListener("click", (e) => {
is(e.target, linkEl, "Saw 'click' on link");
e.preventDefault();
SimpleTest.finish();
}, { once: true, capture: true });
document.addEventListener("auxclick", (e) => {
ok(false, "Shouldn't have got 'auxclick' after preventDefaulting 'click'");
}, { once: true });
synthesizeMouseAtCenter(linkEl, { button: 1 });
});
});
</script>
</body>
</html>

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

@ -12,32 +12,34 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1414077
/** Test for Bug 1414077 **/
SimpleTest.waitForExplicitFinish();
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
SpecialPowers.pushPrefEnv({"set":[["browser.enable_automatic_image_resizing", true]]}, function() {
var testWin = document.querySelector("iframe");
testWin.height = 0;
testWin.width = 0;
testWin.src = "image.png";
testWin.onload = function() {
var testDoc = testWin.contentDocument;
add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["browser.enable_automatic_image_resizing", true]]});
// testDoc should be a image document.
ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(testDoc.imageIsResized, "image is resized to fit visible area by default");
return new Promise(resolve => {
var testWin = document.querySelector("iframe");
testWin.src = "image.png";
testWin.onload = function() {
var testDoc = testWin.contentDocument;
// Restore image to original size.
testDoc.restoreImage();
ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(!testDoc.imageIsResized, "image is restored to original size");
// testDoc should be a image document.
ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(testDoc.imageIsResized, "image is resized to fit visible area by default");
// Resize the image to fit visible area
testDoc.shrinkToFit();
ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(testDoc.imageIsResized, "image is resized to fit visible area");
// Restore image to original size.
testDoc.restoreImage();
ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(!testDoc.imageIsResized, "image is restored to original size");
SimpleTest.finish();
};
// Resize the image to fit visible area
testDoc.shrinkToFit();
ok(testDoc.imageIsOverflowing, "image is overflowing");
ok(testDoc.imageIsResized, "image is resized to fit visible area");
resolve();
};
})
});
</script>
@ -45,6 +47,6 @@ SpecialPowers.pushPrefEnv({"set":[["browser.enable_automatic_image_resizing", tr
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1414077">Mozilla Bug 1414077</a>
<iframe></iframe>
<iframe width="0" height="0"></iframe>
</body>
</html>

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

@ -8,12 +8,12 @@ var NotificationTest = (function() {
function setup_testing_env() {
SimpleTest.waitForExplicitFinish();
// turn on testing pref (used by notification.cpp, and mock the alerts
SpecialPowers.setBoolPref("notification.prompt.testing", true);
return SpecialPowers.setBoolPref("notification.prompt.testing", true);
}
function teardown_testing_env() {
SpecialPowers.clearUserPref("notification.prompt.testing");
SpecialPowers.clearUserPref("notification.prompt.testing.allow");
async function teardown_testing_env() {
await SpecialPowers.clearUserPref("notification.prompt.testing");
await SpecialPowers.clearUserPref("notification.prompt.testing.allow");
SimpleTest.finish();
}
@ -78,9 +78,10 @@ var NotificationTest = (function() {
// NotificationTest API
return {
run(tests, callback) {
setup_testing_env();
let ready = setup_testing_env();
addLoadEvent(function() {
addLoadEvent(async function() {
await ready;
executeTests(tests, function() {
teardown_testing_env();
callback && callback();
@ -89,11 +90,11 @@ var NotificationTest = (function() {
},
allowNotifications() {
SpecialPowers.setBoolPref("notification.prompt.testing.allow", true);
return SpecialPowers.setBoolPref("notification.prompt.testing.allow", true);
},
denyNotifications() {
SpecialPowers.setBoolPref("notification.prompt.testing.allow", false);
return SpecialPowers.setBoolPref("notification.prompt.testing.allow", false);
},
clickNotification(notification) {

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

@ -32,13 +32,13 @@
Notification.requestPermission();
},
function(done) {
async function(done) {
info("Test requestPermission deny");
function assertPermissionDenied(perm) {
is(perm, "denied", "Permission should be denied.");
is(Notification.permission, "denied", "Permission should be denied.");
}
NotificationTest.denyNotifications();
await NotificationTest.denyNotifications();
Notification.requestPermission()
.then(assertPermissionDenied)
.then(_ => Notification.requestPermission(assertPermissionDenied))
@ -48,13 +48,13 @@
.then(done);
},
function(done) {
async function(done) {
info("Test requestPermission grant");
function assertPermissionGranted(perm) {
is(perm, "granted", "Permission should be granted.");
is(Notification.permission, "granted", "Permission should be granted");
}
NotificationTest.allowNotifications();
await NotificationTest.allowNotifications();
Notification.requestPermission()
.then(assertPermissionGranted)
.then(_ => Notification.requestPermission(assertPermissionGranted))

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

@ -19,6 +19,8 @@
</body>
<script class="testbody" type="application/javascript">
<![CDATA[
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
SimpleTest.waitForExplicitFinish();
SimpleTest.expectChildProcessCrash();
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
@ -89,9 +91,9 @@ function finishTest() {
os.removeObserver(testObserver, "plugin-crashed");
--obsCount;
}
SpecialPowers.clearUserPref(hangUITimeoutPref);
SpecialPowers.clearUserPref(hangUIMinDisplayPref);
SpecialPowers.clearUserPref(timeoutPref);
Services.prefs.clearUserPref(hangUITimeoutPref);
Services.prefs.clearUserPref(hangUIMinDisplayPref);
Services.prefs.clearUserPref(timeoutPref);
SimpleTest.finish();
}
@ -151,9 +153,9 @@ function test9b() {
function test9a() {
resetVars();
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
SpecialPowers.setIntPref(timeoutPref, 45);
Services.prefs.setIntPref(hangUITimeoutPref, 1);
Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
Services.prefs.setIntPref(timeoutPref, 45);
hanguiContinue("test9a: Continue button works with checkbox", true, "test9b");
p.stall(STALL_DURATION);
}
@ -165,8 +167,8 @@ function test9() {
function test8a() {
resetVars();
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
SpecialPowers.setIntPref(hangUIMinDisplayPref, 4);
Services.prefs.setIntPref(hangUITimeoutPref, 1);
Services.prefs.setIntPref(hangUIMinDisplayPref, 4);
hanguiExpect("test8a: Plugin Hang UI is not showing (disabled due to hangUIMinDisplaySecs)", false, false, "test9");
var exceptionThrown = false;
try {
@ -184,7 +186,7 @@ function test8() {
function test7a() {
resetVars();
SpecialPowers.setIntPref(hangUITimeoutPref, 0);
Services.prefs.setIntPref(hangUITimeoutPref, 0);
hanguiExpect("test7a: Plugin Hang UI is not showing (disabled)", false, false, "test8");
var exceptionThrown = false;
try {
@ -201,9 +203,9 @@ function test7() {
}
function test6() {
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
SpecialPowers.setIntPref(timeoutPref, 3);
Services.prefs.setIntPref(hangUITimeoutPref, 1);
Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
Services.prefs.setIntPref(timeoutPref, 3);
hanguiExpect("test6: Plugin Hang UI is showing", true, true, "test7");
var exceptionThrown = false;
try {
@ -250,9 +252,9 @@ function test2() {
}
function test1() {
SpecialPowers.setIntPref(hangUITimeoutPref, 1);
SpecialPowers.setIntPref(hangUIMinDisplayPref, 1);
SpecialPowers.setIntPref(timeoutPref, 45);
Services.prefs.setIntPref(hangUITimeoutPref, 1);
Services.prefs.setIntPref(hangUIMinDisplayPref, 1);
Services.prefs.setIntPref(timeoutPref, 45);
hanguiExpect("test1: Plugin Hang UI is showing", true, true, "test2");
p.stall(STALL_DURATION);
}

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

@ -33,7 +33,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388
}
var secureTestsStarted = false;
function checkTestsCompleted() {
async function checkTestsCompleted() {
for (var prop in testsToRunInsecure) {
// some test hasn't run yet so we're not done
if (!testsToRunInsecure[prop])
@ -60,7 +60,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840388
}
//call to change the preferences
counter++;
SpecialPowers.setBoolPref("security.mixed_content.block_active_content", false);
await SpecialPowers.setBoolPref("security.mixed_content.block_active_content", false);
blockActive = SpecialPowers.getBoolPref("security.mixed_content.block_active_content");
log("blockActive set to "+blockActive+".");
secureTestsStarted = false;

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

@ -3,12 +3,12 @@
var GamepadService;
function setGamepadPreferenceAndCreateIframe(iframeSrc) {
SpecialPowers.pushPrefEnv({"set" : [["dom.gamepad.test.enabled", true]]}, () => {
let iframe = document.createElement("iframe");
iframe.src = iframeSrc;
document.body.appendChild(iframe);
});
async function setGamepadPreferenceAndCreateIframe(iframeSrc) {
await SpecialPowers.pushPrefEnv({"set" : [["dom.gamepad.test.enabled", true]]});
let iframe = document.createElement("iframe");
iframe.src = iframeSrc;
document.body.appendChild(iframe);
}
function runGamepadTest (callback) {

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

@ -43,11 +43,11 @@ function pressButton() {
GamepadService.newButtonEvent(gamepad_index, 0, false, false);
}
function startTest() {
SpecialPowers.pushPrefEnv({ "set": [
["dom.gamepad.extensions.enabled", true],
["dom.gamepad.extensions.lightindicator", true],
["dom.gamepad.extensions.multitouch", true]] });
async function startTest() {
await SpecialPowers.pushPrefEnv({ "set": [
["dom.gamepad.extensions.enabled", true],
["dom.gamepad.extensions.lightindicator", true],
["dom.gamepad.extensions.multitouch", true]] });
// Add a gamepad
GamepadService.addGamepad("test gamepad", // id
GamepadService.standardMapping,

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

@ -52,13 +52,14 @@ function pressButton() {
}
let frames_loaded = 0;
function startTest() {
async function startTest() {
frames_loaded++;
SpecialPowers.pushPrefEnv({ "set": [
let promise = SpecialPowers.pushPrefEnv({ "set": [
["dom.gamepad.extensions.enabled", true],
["dom.gamepad.extensions.lightindicator", true],
["dom.gamepad.extensions.multitouch", true]] });
if (frames_loaded == 2) {
await promise;
// Add a gamepad
GamepadService.addGamepad("test gamepad", // id
GamepadService.standardMapping,

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

@ -17,7 +17,7 @@ async function setup() {
winUtils.advanceTimeAndRefresh(100);
}
function* runTests() {
async function* runTests() {
var e = document.getElementById("edit");
var doc = e.contentDocument;
var win = e.contentWindow;
@ -181,9 +181,9 @@ function* runTests() {
is(testPageSelectCommand("cmd_selectPageUp", 0), 22 - lineNum, "cmd_selectPageUp");
};
yield SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", false]]});
await SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", false]]});
runSelectionTests(body, 1);
yield SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", true]]});
await SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", true]]});
runSelectionTests(node(2), 0);
}
@ -196,7 +196,7 @@ async function testRunner() {
let curTest = runTests();
while (true) {
winUtils.advanceTimeAndRefresh(100);
if (curTest.next().done) {
if ((await curTest.next()).done) {
break;
}
winUtils.advanceTimeAndRefresh(100);

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

@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1121643
/** Test for Bug 1121643 **/
SimpleTest.requestFlakyTimeout("This test is flaky.");
const InspectorUtils = SpecialPowers.InspectorUtils;
// Given an element id, returns the first font face name encountered.
@ -53,6 +55,7 @@ let testFontWhitelist = async function(useMono, useSans, useSerif) {
}
await SpecialPowers.pushPrefEnv({"set": [["font.system.whitelist",
whitelist.join(", ")]]});
await new Promise(resolve => setTimeout(resolve, 2000));
// If whitelist is empty, then whitelisting is considered disabled
// and all fonts are allowed.
info("font whitelist: " + JSON.stringify(whitelist));

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

@ -13,27 +13,30 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1124898
/** Test for Bug 1124898 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
SimpleTest.expectAssertions(0, 1); // Dumb unrelated widget assertion - see bug 1126023.
var w = window.open("about:blank", "w", "chrome");
is(w.eval('typeof getAttention'), 'function', 'getAttention exists on regular chrome window');
is(w.eval('typeof messageManager'), 'object', 'messageManager exists on regular chrome window');
var contentURL = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html";
w.location = contentURL;
tryWindow();
(async () => {
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", true]]});
function tryWindow() {
if (w.document.title != 'empty test page') {
info("Document not loaded yet - retrying");
SimpleTest.executeSoon(tryWindow);
return;
SimpleTest.expectAssertions(0, 1); // Dumb unrelated widget assertion - see bug 1126023.
var w = window.open("about:blank", "w", "chrome");
is(w.eval('typeof getAttention'), 'function', 'getAttention exists on regular chrome window');
is(w.eval('typeof messageManager'), 'object', 'messageManager exists on regular chrome window');
var contentURL = "http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html";
w.location = contentURL;
tryWindow();
function tryWindow() {
if (w.document.title != 'empty test page') {
info("Document not loaded yet - retrying");
SimpleTest.executeSoon(tryWindow);
return;
}
is(w.eval('typeof getAttention'), 'undefined', 'getAttention doesnt exist on content-in-chrome window');
is(w.eval('typeof messageManager'), 'undefined', 'messageManager doesnt exist on content-in-chrome window');
w.close();
SimpleTest.finish();
}
is(w.eval('typeof getAttention'), 'undefined', 'getAttention doesnt exist on content-in-chrome window');
is(w.eval('typeof messageManager'), 'undefined', 'messageManager doesnt exist on content-in-chrome window');
w.close();
SimpleTest.finish();
}
})();
</script>
</head>

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

@ -14,36 +14,38 @@
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
SimpleTest.waitForExplicitFinish();
function init() {
var f = new Function("let test = 'let is ok'; return test;");
is(f(), 'let is ok', 'let should be ok');
SimpleTest.finish();
}
Test = {
include: function(p) {
var sawError = false;
try {
Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci["mozIJSSubScriptLoader"]).
loadSubScript(p);
} catch (e) {
sawError = true;
}
ok(sawError, 'should receive an error loading a not-found file');
}
};
(async () => {
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
Test = {
include: function(p) {
var sawError = false;
try {
Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci["mozIJSSubScriptLoader"]).
loadSubScript(p);
} catch (e) {
sawError = true;
}
ok(sawError, 'should receive an error loading a not-found file');
}
};
// If the include method is defined as a global function, it works.
// try to load a non existing file to produce the error
Test.include("notfound.js");
// If the include method is defined as a global function, it works.
// try to load a non existing file to produce the error
Test.include("notfound.js");
// If init is called directly, it works.
setTimeout('init();', 0);
SimpleTest.waitForExplicitFinish();
// If init is called directly, it works.
setTimeout('init();', 0);
})();
]]></script>
</window>

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

@ -18,8 +18,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732665
<script type="application/javascript">
<![CDATA[
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
add_task(async () => {
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
//
// Important! If this test starts failing after a tricky platform-y change,
// the stack quota numbers in XPCJSContext probably need twiddling. We want
@ -76,7 +77,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732665
contentSb.nnslChrome = chromeSb.nearNativeStackLimit;
var nestedLimit = Cu.evalInSandbox("nearNativeStackLimit(1, function() { nestedLimit = nnslChrome(0);}); nestedLimit;", contentSb);
ok(nestedLimit >= 11, "Chrome should be invokable from content script with an exhausted stack: " + nestedLimit);
});
]]>
</script>
</window>

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

@ -17,12 +17,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=500931
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
add_task(async () => {
var sandbox = new Cu.Sandbox("about:blank");
var test_utils = window.windowUtils;
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
function getCOW(x) {
if (typeof x != 'object' && typeof x != 'function')
@ -224,5 +225,6 @@ try {
todo(false, "COWs should be unwrapped when entering chrome space, " +
"not raise " + e);
}
});
]]></script>
</window>

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

@ -14,10 +14,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1223372
/** Test for Bug 1223372 **/
const {TestUtils} = ChromeUtils.import("resource://testing-common/TestUtils.jsm");
function go() {
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
async function go() {
SimpleTest.waitForExplicitFinish();
await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
var frame = $('subframe');
frame.onload = null;

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

@ -18,9 +18,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
<script type="application/javascript">
<![CDATA[
SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
true]]});
/** Test for ES constructors on Xrayed globals. **/
SimpleTest.waitForExplicitFinish();
let global = Cu.getGlobalForObject.bind(Cu);
@ -479,73 +476,70 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
}
// We will need arraysEqual and testArrayIterators both in this global scope
// and in sandboxes, so define them as strings up front.
var arraysEqualSource = `function arraysEqual(arr1, arr2, reason) {
is(arr1.length, arr2.length, \`\${reason}; lengths should be equal\`)
// and in sandboxes.
function arraysEqual(arr1, arr2, reason) {
is(arr1.length, arr2.length, `${reason}; lengths should be equal`)
for (var i = 0; i < arr1.length; ++i) {
if (Array.isArray(arr2[i])) {
arraysEqual(arr1[i], arr2[i], \`\${reason}; item at index \${i}\`);
arraysEqual(arr1[i], arr2[i], `${reason}; item at index ${i}`);
} else {
is(arr1[i], arr2[i], \`\${reason}; item at index \${i} should be equal\`);
is(arr1[i], arr2[i], `${reason}; item at index ${i} should be equal`);
}
}
}`;
eval(arraysEqualSource);
}
var testArrayIteratorsSource = `
function testArrayIterators(arrayLike, equivalentArray, reason) {
arraysEqual([...arrayLike], equivalentArray, \`\${reason}; spread operator\`);
function testArrayIterators(arrayLike, equivalentArray, reason) {
arraysEqual([...arrayLike], equivalentArray, `${reason}; spread operator`);
arraysEqual([...arrayLike.entries()], [...equivalentArray.entries()],
\`\${reason}; entries\`);
`${reason}; entries`);
arraysEqual([...arrayLike.keys()], [...equivalentArray.keys()],
\`\${reason}; keys\`);
`${reason}; keys`);
if (arrayLike.values) {
arraysEqual([...arrayLike.values()], equivalentArray,
\`\${reason}; values\`);
`${reason}; values`);
}
var forEachCopy = [];
arrayLike.forEach(function(arg) { forEachCopy.push(arg); });
arraysEqual(forEachCopy, equivalentArray, \`\${reason}; forEach copy\`);
arraysEqual(forEachCopy, equivalentArray, `${reason}; forEach copy`);
var everyCopy = [];
arrayLike.every(function(arg) { everyCopy.push(arg); return true; });
arraysEqual(everyCopy, equivalentArray, \`\${reason}; every() copy\`);
arraysEqual(everyCopy, equivalentArray, `${reason}; every() copy`);
var filterCopy = [];
var filterResult = arrayLike.filter(function(arg) {
filterCopy.push(arg);
return true;
});
arraysEqual(filterCopy, equivalentArray, \`\${reason}; filter copy\`);
arraysEqual([...filterResult], equivalentArray, \`\${reason}; filter result\`);
arraysEqual(filterCopy, equivalentArray, `${reason}; filter copy`);
arraysEqual([...filterResult], equivalentArray, `${reason}; filter result`);
var findCopy = [];
arrayLike.find(function(arg) { findCopy.push(arg); return false; });
arraysEqual(findCopy, equivalentArray, \`\${reason}; find() copy\`);
arraysEqual(findCopy, equivalentArray, `${reason}; find() copy`);
var findIndexCopy = [];
arrayLike.findIndex(function(arg) { findIndexCopy.push(arg); return false; });
arraysEqual(findIndexCopy, equivalentArray, \`\${reason}; findIndex() copy\`);
arraysEqual(findIndexCopy, equivalentArray, `${reason}; findIndex() copy`);
var mapCopy = [];
var mapResult = arrayLike.map(function(arg) { mapCopy.push(arg); return arg});
arraysEqual(mapCopy, equivalentArray, \`\${reason}; map() copy\`);
arraysEqual([...mapResult], equivalentArray, \`\${reason}; map() result\`);
arraysEqual(mapCopy, equivalentArray, `${reason}; map() copy`);
arraysEqual([...mapResult], equivalentArray, `${reason}; map() result`);
var reduceCopy = [];
arrayLike.reduce(function(_, arg) { reduceCopy.push(arg); }, 0);
arraysEqual(reduceCopy, equivalentArray, \`\${reason}; reduce() copy\`);
arraysEqual(reduceCopy, equivalentArray, `${reason}; reduce() copy`);
var reduceRightCopy = [];
arrayLike.reduceRight(function(_, arg) { reduceRightCopy.unshift(arg); }, 0);
arraysEqual(reduceRightCopy, equivalentArray, \`\${reason}; reduceRight() copy\`);
arraysEqual(reduceRightCopy, equivalentArray, `${reason}; reduceRight() copy`);
var someCopy = [];
arrayLike.some(function(arg) { someCopy.push(arg); return false; });
arraysEqual(someCopy, equivalentArray, \`\${reason}; some() copy\`);
}`;
eval(testArrayIteratorsSource);
arraysEqual(someCopy, equivalentArray, `${reason}; some() copy`);
}
function testDate() {
// toGMTString is handled oddly in the engine. We don't bother to support
@ -800,7 +794,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
// Can create TypedArray from content ArrayBuffer
var buffer = new iwin.ArrayBuffer(8);
eval(`new ${c}(buffer);`);
new window[c](buffer);
var xray = new iwin[c](0);
var xrayTypedArrayProto = Object.getPrototypeOf(Object.getPrototypeOf(xray));
@ -813,8 +807,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
// they'll just run with our principal anyway.
//
// But we do want to export is(), since we want ours called.
wesb.eval(arraysEqualSource);
wesb.eval(testArrayIteratorsSource);
wesb.eval(String(arraysEqual));
wesb.eval(String(testArrayIterators));
Cu.exportFunction(is, wesb,
{ defineAs: "is" });
wesb.eval('testArrayIterators(t, [0, 0, 3, 0, 0, 0, 0, 0, 0, 0])');

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

@ -15,9 +15,9 @@ const Cc = SpecialPowers.Cc, Ci = SpecialPowers.Ci, Cr = SpecialPowers.Cr;
var remainder = 4;
var observer;
function doTest()
async function doTest()
{
SpecialPowers.setBoolPref("network.http.debug-observations", true);
await SpecialPowers.setBoolPref("network.http.debug-observations", true);
observer = SpecialPowers.wrapCallback(function(subject, topic, data) {
remainder--;

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

@ -31,26 +31,26 @@ function dispatchTestEvent() {
dump("\nSPECIALPTEST:::Test script loaded " + (new Date).getTime() + "\n");
SimpleTest.waitForExplicitFinish();
var startTime = new Date();
function starttest(){
async function starttest(){
dump("\nSPECIALPTEST:::Test script running after load " + (new Date).getTime() + "\n");
/** Test for SpecialPowers extension **/
is(SpecialPowers.sanityCheck(), "foo", "check to see whether the Special Powers extension is installed.");
// Test a sync call into chrome
SpecialPowers.setBoolPref('extensions.checkCompatibility', true);
await SpecialPowers.setBoolPref('extensions.checkCompatibility', true);
is(SpecialPowers.getBoolPref('extensions.checkCompatibility'), true, "Check to see if we can set a preference properly");
SpecialPowers.clearUserPref('extensions.checkCompatibility');
await SpecialPowers.clearUserPref('extensions.checkCompatibility');
// Test a int pref
SpecialPowers.setIntPref('extensions.foobar', 42);
await SpecialPowers.setIntPref('extensions.foobar', 42);
is(SpecialPowers.getIntPref('extensions.foobar'), 42, "Check int pref");
SpecialPowers.clearUserPref('extensions.foobar');
await SpecialPowers.clearUserPref('extensions.foobar');
// Test a string pref
SpecialPowers.setCharPref("extensions.foobaz", "hi there");
await SpecialPowers.setCharPref("extensions.foobaz", "hi there");
is(SpecialPowers.getCharPref("extensions.foobaz"), "hi there", "Check string pref");
SpecialPowers.clearUserPref("extensions.foobaz");
await SpecialPowers.clearUserPref("extensions.foobaz");
// Test an invalid pref
var retVal = null;
@ -59,7 +59,8 @@ function starttest(){
} catch (ex) {
retVal = ex;
}
is(retVal.message, "Error getting pref 'extensions.checkCompat0123456789'", "received an exception trying to get an unset preference value");
is(retVal.result, SpecialPowers.Cr.NS_ERROR_UNEXPECTED,
"received an exception trying to get an unset preference value");
SpecialPowers.addChromeEventListener("TestEvent", testEventListener, true, true);
SpecialPowers.addChromeEventListener("TestEvent", testEventListener2, true, false);

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

@ -9,19 +9,19 @@
<pre id="test">
<script class="testbody" type="text/javascript">
function starttest() {
async function starttest() {
try {
SpecialPowers.setBoolPref("test.bool", 1);
await SpecialPowers.setBoolPref("test.bool", 1);
} catch(e) {
SpecialPowers.setBoolPref("test.bool", true);
await SpecialPowers.setBoolPref("test.bool", true);
}
try {
SpecialPowers.setIntPref("test.int", true);
await SpecialPowers.setIntPref("test.int", true);
} catch(e) {
SpecialPowers.setIntPref("test.int", 1);
await SpecialPowers.setIntPref("test.int", 1);
}
SpecialPowers.setCharPref("test.char", 'test');
SpecialPowers.setBoolPref("test.cleanup", false);
await SpecialPowers.setCharPref("test.char", 'test');
await SpecialPowers.setBoolPref("test.cleanup", false);
setTimeout(test1, 0, 0);
}

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

@ -1000,19 +1000,29 @@ class SpecialPowersAPI {
}
// Mimic the get*Pref API
getBoolPref(prefName, defaultValue) {
return this._getPref(prefName, "BOOL", { defaultValue });
getBoolPref(...args) {
return Services.prefs.getBoolPref(...args);
}
getIntPref(prefName, defaultValue) {
return this._getPref(prefName, "INT", { defaultValue });
getIntPref(...args) {
return Services.prefs.getIntPref(...args);
}
getCharPref(prefName, defaultValue) {
return this._getPref(prefName, "CHAR", { defaultValue });
getCharPref(...args) {
return Services.prefs.getCharPref(...args);
}
getComplexValue(prefName, iid) {
return this._getPref(prefName, "COMPLEX", { iid });
}
getParentBoolPref(prefName, defaultValue) {
return this._getParentPref(prefName, "BOOL", { defaultValue });
}
getParentIntPref(prefName, defaultValue) {
return this._getParentPref(prefName, "INT", { defaultValue });
}
getParentCharPref(prefName, defaultValue) {
return this._getParentPref(prefName, "CHAR", { defaultValue });
}
// Mimic the set*Pref API
setBoolPref(prefName, value) {
return this._setPref(prefName, "BOOL", value);

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

@ -39,12 +39,12 @@ classifierHelper.waitForInit = function() {
classifierHelper.allowCompletion = function(lists, url) {
for (var list of lists) {
// Add test db to provider
var pref = SpecialPowers.getCharPref(PREFS.PROVIDER_LISTS);
var pref = await SpecialPowers.getParentCharPref(PREFS.PROVIDER_LISTS);
pref += "," + list;
SpecialPowers.setCharPref(PREFS.PROVIDER_LISTS, pref);
// Rename test db so we will not disallow it from completions
pref = SpecialPowers.getCharPref(PREFS.DISALLOW_COMPLETIONS);
pref = await SpecialPowers.getParentCharPref(PREFS.DISALLOW_COMPLETIONS);
pref = pref.replace(list, list + "-backup");
SpecialPowers.setCharPref(PREFS.DISALLOW_COMPLETIONS, pref);
}

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

@ -80,8 +80,8 @@ function reset() {
function testNegativeCache() {
shouldLoad = true;
function setup() {
classifierHelper.allowCompletion([MALWARE_LIST, UNWANTED_LIST], GETHASH_URL);
async function setup() {
await classifierHelper.allowCompletion([MALWARE_LIST, UNWANTED_LIST], GETHASH_URL);
// Only add prefix to database. not server, so gethash will not return
// result.
@ -108,8 +108,8 @@ function testNegativeCache() {
function testPositiveCache() {
shouldLoad = false;
function setup() {
classifierHelper.allowCompletion([MALWARE_LIST, UNWANTED_LIST], GETHASH_URL);
async function setup() {
await classifierHelper.allowCompletion([MALWARE_LIST, UNWANTED_LIST], GETHASH_URL);
return Promise.all([
addPrefixToDB(MALWARE_LIST, MALWARE_HOST),

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

@ -23,8 +23,8 @@
const TP_ENABLE_PREF = "privacy.trackingprotection.enabled";
const RETRY_TIMEOUT_MS = 200;
function testPingNonBlacklist() {
SpecialPowers.setBoolPref(TP_ENABLE_PREF, true);
async function testPingNonBlacklist() {
await SpecialPowers.setBoolPref(TP_ENABLE_PREF, true);
var msg = "ping should reach page not in blacklist";
var expectPing = true;
@ -37,8 +37,8 @@
});
}
function testPingBlacklistSafebrowsingOff() {
SpecialPowers.setBoolPref(TP_ENABLE_PREF, false);
async function testPingBlacklistSafebrowsingOff() {
await SpecialPowers.setBoolPref(TP_ENABLE_PREF, false);
var msg = "ping should reach page in blacklist when tracking protection is off";
var expectPing = true;
@ -51,8 +51,8 @@
});
}
function testPingBlacklistSafebrowsingOn() {
SpecialPowers.setBoolPref(TP_ENABLE_PREF, true);
async function testPingBlacklistSafebrowsingOn() {
await SpecialPowers.setBoolPref(TP_ENABLE_PREF, true);
var msg = "ping should not reach page in blacklist when tracking protection is on";
var expectPing = false;

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

@ -11,6 +11,8 @@
<script type="application/javascript">
<![CDATA[
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const PREFS = ['tests.onsyncfrompreference.pref1',
'tests.onsyncfrompreference.pref2',
'tests.onsyncfrompreference.pref3'];
@ -18,7 +20,7 @@
SimpleTest.waitForExplicitFinish();
for (let pref of PREFS) {
SpecialPowers.setIntPref(pref, 1);
Services.prefs.setIntPref(pref, 1);
}
let counter = 0;
@ -26,7 +28,7 @@
SimpleTest.registerCleanupFunction(() => {
for (let pref of PREFS) {
SpecialPowers.clearUserPref(pref);
Services.prefs.clearUserPref(pref);
}
prefWindow.close();
});
@ -36,7 +38,7 @@
for (let pref of PREFS) {
// The `value` field of each <preference> element should be initialized by now.
is(SpecialPowers.getIntPref(pref), prefWindow.Preferences.get(pref).value,
is(Services.prefs.getIntPref(pref), prefWindow.Preferences.get(pref).value,
"Pref constructor was called correctly")
}

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

@ -44,6 +44,8 @@
<script class="testbody" type="application/javascript">
<![CDATA[
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
window.opener.wrappedJSObject.SimpleTest.waitForFocus(runTest, window);
function ok(aCondition, aMessage)
@ -6058,7 +6060,7 @@ function runIsComposingTest()
// XXX These cases shouldn't occur in actual native key events because we
// don't dispatch key events while composition (bug 354358).
SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
Services.prefs.setBoolPref("dom.keyboardevent.dispatch_during_composition", true);
description = "events before dispatching compositionstart";
synthesizeKey("KEY_ArrowLeft");
@ -6088,7 +6090,7 @@ function runIsComposingTest()
description = "events after dispatching compositioncommitasis";
synthesizeKey("KEY_Enter", {type: "keyup"});
SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition");
Services.prefs.clearUserPref("dom.keyboardevent.dispatch_during_composition");
textarea.removeEventListener("keydown", eventHandler, true);
textarea.removeEventListener("keypress", eventHandler, true);
@ -6386,7 +6388,7 @@ function runNativeLineBreakerTest()
result[aEvent.type] = aEvent.data;
}
SpecialPowers.setBoolPref("dom.compositionevent.allow_control_characters", false);
Services.prefs.setBoolPref("dom.compositionevent.allow_control_characters", false);
textarea.addEventListener("compositionupdate", handler, true);
textarea.addEventListener("compositionend", handler, true);
@ -6502,7 +6504,7 @@ function runNativeLineBreakerTest()
textarea.removeEventListener("compositionupdate", handler, true);
textarea.removeEventListener("compositionend", handler, true);
SpecialPowers.clearUserPref("dom.compositionevent.allow_control_characters");
Services.prefs.clearUserPref("dom.compositionevent.allow_control_characters");
}
function runControlCharTest()
@ -6564,7 +6566,7 @@ function runControlCharTest()
clearResult();
SpecialPowers.setBoolPref("dom.compositionevent.allow_control_characters", true);
Services.prefs.setBoolPref("dom.compositionevent.allow_control_characters", true);
// input string contains control characters, allowing control characters
clearResult();
@ -6592,7 +6594,7 @@ function runControlCharTest()
is(result.compositionend, data.replace(/\r/g, "\n"), "runControlCharTest: control characters in event.data should not be removed in compositionend event #4");
is(textarea.value, data.replace(/\r/g, "\n"), "runControlCharTest: control characters should appear in textarea #4");
SpecialPowers.clearUserPref("dom.compositionevent.allow_control_characters");
Services.prefs.clearUserPref("dom.compositionevent.allow_control_characters");
textarea.removeEventListener("compositionupdate", handler, true);
textarea.removeEventListener("compositionend", handler, true);