import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,46 @@
[DEFAULT]
support-files =
browser_frame_elements.html
page_privatestorageevent.html
position.html
test-console-api.html
test_bug1004814.html
worker_bug1004814.js
geo_leak_test.html
dummy.html
test_largeAllocation.html
test_largeAllocation.html^headers^
!/dom/tests/mochitest/geolocation/network_geolocation.sjs
[browser_allocateGigabyte.js]
disabled = Does not reliably pass on 32-bit systems - bug 1314098
skip-if = !e10s
[browser_autofocus_background.js]
[browser_autofocus_preference.js]
[browser_beforeunload_between_chrome_content.js]
skip-if = !e10s
[browser_bug396843.js]
[browser_bug1004814.js]
[browser_bug1008941_dismissGeolocationHanger.js]
[browser_bug1238427.js]
[browser_ConsoleAPI_originAttributes.js]
[browser_ConsoleAPITests.js]
skip-if = e10s
[browser_ConsoleStorageAPITests.js]
[browser_ConsoleStoragePBTest_perwindowpb.js]
[browser_focus_steal_from_chrome.js]
[browser_focus_steal_from_chrome_during_mousedown.js]
[browser_frame_elements.js]
[browser_largeAllocation.js]
skip-if = !e10s # Large-Allocation requires e10s
[browser_localStorage_privatestorageevent.js]
[browser_test__content.js]
[browser_test_new_window_from_content.js]
tags = openwindow
skip-if = toolkit == 'android' || (os == "linux" && debug) # see bug 1261495 for Linux debug time outs
support-files =
test_new_window_from_content_child.html
[browser_test_toolbars_visibility.js]
support-files =
test_new_window_from_content_child.html
[browser_xhr_sandbox.js]

View file

@ -0,0 +1,522 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const TEST_URI = "http://example.com/browser/dom/tests/browser/test-console-api.html";
add_task(function*() {
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URI);
registerCleanupFunction(() => gBrowser.removeTab(tab));
let browser = gBrowser.selectedBrowser;
yield* consoleAPISanityTest(browser);
yield* observeConsoleTest(browser);
yield* startTraceTest(browser);
yield* startLocationTest(browser);
yield* startNativeCallbackTest(browser);
yield* startGroupTest(browser);
yield* startTimeTest(browser);
yield* startTimeEndTest(browser);
yield* startTimeStampTest(browser);
yield* startEmptyTimeStampTest(browser);
yield* startEmptyTimerTest(browser);
});
function spawnWithObserver(browser, observerFunc, func) {
// Build the observer generating function.
let source = [
"const TEST_URI = 'http://example.com/browser/dom/tests/browser/test-console-api.html';",
// Create a promise to be resolved when the text is complete. It is stored
// on content, such that it can be waited on by calling waitForResolve. This
// is done rather than returning it from this function such that the
// initialization can be yeilded on before yeilding on the conclusion of the
// test.
"content._promise = new Promise(_resolve => {",
// These are variables which are used by the test runner to communicate
// state to the observer.
" let gLevel, gArgs, gStyle;",
" let expect = function(level) {",
" gLevel = level;",
" gArgs = Array.slice(arguments, 1);",
" }",
// To ease the transition to the new format, content.window is avaliable as gWindow
// in the content.
" let gWindow = content.window;",
// This method is called rather than _resolve such that the observer is removed
// before exiting the test
" let resolve = () => {",
" Services.obs.removeObserver(ConsoleObserver, 'console-api-log-event');",
" _resolve();",
" };",
// This is the observer itself, it calls the passed-in function whenever
// it encounters an event
" let ConsoleObserver = {",
" QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),",
" observe: function(aSubject, aTopic, aData) {",
" try {",
" (" + observerFunc.toString() + ")(aSubject.wrappedJSObject);",
" } catch (ex) {",
" ok(false, 'Exception thrown in observe: ' + ex);",
" }",
" }",
" };",
" Services.obs.addObserver(ConsoleObserver, 'console-api-log-event', false);",
// Call the initialization function (if present)
func ? ("(" + func.toString() + ")();") : "",
"});",
].join('\n');
return ContentTask.spawn(browser, null, new Function(source));
}
function waitForResolve(browser) {
return ContentTask.spawn(browser, null, function() {
return content._promise;
});
}
function* consoleAPISanityTest(browser) {
yield ContentTask.spawn(browser, null, function() {
let win = XPCNativeWrapper.unwrap(content.window);
ok(win.console, "we have a console attached");
ok(win.console, "we have a console attached, 2nd attempt");
ok(win.console.log, "console.log is here");
ok(win.console.info, "console.info is here");
ok(win.console.warn, "console.warn is here");
ok(win.console.error, "console.error is here");
ok(win.console.exception, "console.exception is here");
ok(win.console.trace, "console.trace is here");
ok(win.console.dir, "console.dir is here");
ok(win.console.group, "console.group is here");
ok(win.console.groupCollapsed, "console.groupCollapsed is here");
ok(win.console.groupEnd, "console.groupEnd is here");
ok(win.console.time, "console.time is here");
ok(win.console.timeEnd, "console.timeEnd is here");
ok(win.console.timeStamp, "console.timeStamp is here");
ok(win.console.assert, "console.assert is here");
ok(win.console.count, "console.count is here");
});
}
function testConsoleData(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
is(aMessageObject.level, gLevel, "expected level received");
ok(aMessageObject.arguments, "we have arguments");
switch (gLevel) {
case "trace": {
is(aMessageObject.arguments.length, 0, "arguments.length matches");
is(aMessageObject.stacktrace.toSource(), gArgs.toSource(),
"stack trace is correct");
break;
}
case "count": {
is(aMessageObject.counter.label, gArgs[0].label, "label matches");
is(aMessageObject.counter.count, gArgs[0].count, "count matches");
break;
}
default: {
is(aMessageObject.arguments.length, gArgs.length, "arguments.length matches");
gArgs.forEach(function (a, i) {
// Waive Xray so that we don't get messed up by Xray ToString.
//
// It'd be nice to just use XPCNativeWrapper.unwrap here, but there are
// a number of dumb reasons we can't. See bug 868675.
var arg = aMessageObject.arguments[i];
if (Components.utils.isXrayWrapper(arg))
arg = arg.wrappedJSObject;
is(arg, a, "correct arg " + i);
});
if (gStyle) {
is(aMessageObject.styles.length, gStyle.length, "styles.length matches");
is(aMessageObject.styles + "", gStyle + "", "styles match");
} else {
ok(!aMessageObject.styles || aMessageObject.styles.length === 0,
"styles match");
}
}
}
}
function* observeConsoleTest(browser) {
yield spawnWithObserver(browser, testConsoleData, function(opts) {
let win = XPCNativeWrapper.unwrap(content.window);
expect("log", "arg");
win.console.log("arg");
expect("info", "arg", "extra arg");
win.console.info("arg", "extra arg");
expect("warn", "Lesson 1: PI is approximately equal to 3");
win.console.warn("Lesson %d: %s is approximately equal to %1.0f",
1,
"PI",
3.14159);
expect("warn", "Lesson 1: PI is approximately equal to 3.14");
win.console.warn("Lesson %d: %s is approximately equal to %1.2f",
1,
"PI",
3.14159);
expect("warn", "Lesson 1: PI is approximately equal to 3.141590");
win.console.warn("Lesson %d: %s is approximately equal to %f",
1,
"PI",
3.14159);
expect("warn", "Lesson 1: PI is approximately equal to 3.1415900");
win.console.warn("Lesson %d: %s is approximately equal to %0.7f",
1,
"PI",
3.14159);
expect("log", "%d, %s, %l");
win.console.log("%d, %s, %l");
expect("log", "%a %b %g");
win.console.log("%a %b %g");
expect("log", "%a %b %g", "a", "b");
win.console.log("%a %b %g", "a", "b");
expect("log", "2, a, %l", 3);
win.console.log("%d, %s, %l", 2, "a", 3);
// Bug #692550 handle null and undefined.
expect("log", "null, undefined");
win.console.log("%s, %s", null, undefined);
// Bug #696288 handle object as first argument.
let obj = { a: 1 };
expect("log", obj, "a");
win.console.log(obj, "a");
expect("dir", win.toString());
win.console.dir(win);
expect("error", "arg");
win.console.error("arg");
expect("exception", "arg");
win.console.exception("arg");
expect("log", "foobar");
gStyle = ["color:red;foobar;;"];
win.console.log("%cfoobar", gStyle[0]);
let obj4 = { d: 4 };
expect("warn", "foobar", obj4, "test", "bazbazstr", "last");
gStyle = [null, null, null, "color:blue;", "color:red"];
win.console.warn("foobar%Otest%cbazbaz%s%clast", obj4, gStyle[3], "str", gStyle[4]);
let obj3 = { c: 3 };
expect("info", "foobar", "bazbaz", obj3, "%comg", "color:yellow");
gStyle = [null, "color:pink;"];
win.console.info("foobar%cbazbaz", gStyle[1], obj3, "%comg", "color:yellow");
gStyle = null;
let obj2 = { b: 2 };
expect("log", "omg ", obj, " foo ", 4, obj2);
win.console.log("omg %o foo %o", obj, 4, obj2);
expect("assert", "message");
win.console.assert(false, "message");
expect("count", { label: "label a", count: 1 });
win.console.count("label a");
expect("count", { label: "label b", count: 1 });
win.console.count("label b");
expect("count", { label: "label a", count: 2 });
win.console.count("label a");
expect("count", { label: "label b", count: 2 });
win.console.count("label b");
dump("Resolving\n");
resolve();
});
dump("There\n");
}
function testTraceConsoleData(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
is(aMessageObject.level, gLevel, "expected level received");
ok(aMessageObject.arguments, "we have arguments");
is(gLevel, "trace", "gLevel should be trace");
is(aMessageObject.arguments.length, 0, "arguments.length matches");
dump(aMessageObject.stacktrace.toSource() + "\n" + gArgs.toSource() + "\n");
is(aMessageObject.stacktrace.toSource(), gArgs.toSource(),
"stack trace is correct");
resolve();
}
function* startTraceTest(browser) {
dump("HERE\n");
yield spawnWithObserver(browser, testTraceConsoleData, function(opts) {
dump("Observer attached\n");
gLevel = "trace";
gArgs = [
{columnNumber: 9, filename: TEST_URI, functionName: "window.foobar585956c", language: 2, lineNumber: 6},
{columnNumber: 16, filename: TEST_URI, functionName: "foobar585956b", language: 2, lineNumber: 11},
{columnNumber: 16, filename: TEST_URI, functionName: "foobar585956a", language: 2, lineNumber: 15},
{columnNumber: 1, filename: TEST_URI, functionName: "onclick", language: 2, lineNumber: 1}
];
});
BrowserTestUtils.synthesizeMouseAtCenter("#test-trace", {}, browser);
yield waitForResolve(browser);
}
function testLocationData(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
is(aMessageObject.level, gLevel, "expected level received");
ok(aMessageObject.arguments, "we have arguments");
is(aMessageObject.filename, gArgs[0].filename, "filename matches");
is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches");
is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches");
is(aMessageObject.arguments.length, gArgs[0].arguments.length, "arguments.length matches");
gArgs[0].arguments.forEach(function (a, i) {
is(aMessageObject.arguments[i], a, "correct arg " + i);
});
resolve();
}
function* startLocationTest(browser) {
yield spawnWithObserver(browser, testLocationData, function(opts) {
gLevel = "log";
gArgs = [
{filename: TEST_URI, functionName: "foobar646025", arguments: ["omg", "o", "d"], lineNumber: 19}
];
});
BrowserTestUtils.synthesizeMouseAtCenter("#test-location", {}, browser);
yield waitForResolve(browser);
}
function testNativeCallback(aMessageObject) {
is(aMessageObject.level, "log", "expected level received");
is(aMessageObject.filename, "", "filename matches");
is(aMessageObject.lineNumber, 0, "lineNumber matches");
is(aMessageObject.functionName, "", "functionName matches");
resolve();
}
function* startNativeCallbackTest(browser) {
yield spawnWithObserver(browser, testNativeCallback);
BrowserTestUtils.synthesizeMouseAtCenter("#test-nativeCallback", {}, browser);
yield waitForResolve(browser);
}
function testConsoleGroup(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
ok(aMessageObject.level == "group" ||
aMessageObject.level == "groupCollapsed" ||
aMessageObject.level == "groupEnd",
"expected level received");
is(aMessageObject.functionName, "testGroups", "functionName matches");
ok(aMessageObject.lineNumber >= 46 && aMessageObject.lineNumber <= 50,
"lineNumber matches");
if (aMessageObject.level == "groupCollapsed") {
is(aMessageObject.groupName, "a group", "groupCollapsed groupName matches");
is(aMessageObject.arguments[0], "a", "groupCollapsed arguments[0] matches");
is(aMessageObject.arguments[1], "group", "groupCollapsed arguments[0] matches");
}
else if (aMessageObject.level == "group") {
is(aMessageObject.groupName, "b group", "group groupName matches");
is(aMessageObject.arguments[0], "b", "group arguments[0] matches");
is(aMessageObject.arguments[1], "group", "group arguments[1] matches");
}
else if (aMessageObject.level == "groupEnd") {
let groupName = Array.prototype.join.call(aMessageObject.arguments, " ");
is(groupName,"b group", "groupEnd arguments matches");
is(aMessageObject.groupName, "b group", "groupEnd groupName matches");
}
if (aMessageObject.level == "groupEnd") {
resolve();
}
}
function* startGroupTest(browser) {
yield spawnWithObserver(browser, testConsoleGroup);
BrowserTestUtils.synthesizeMouseAtCenter("#test-groups", {}, browser);
yield waitForResolve(browser);
}
function testConsoleTime(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
is(aMessageObject.level, gLevel, "expected level received");
is(aMessageObject.filename, gArgs[0].filename, "filename matches");
is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches");
is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches");
is(aMessageObject.timer.name, gArgs[0].timer.name, "timer.name matches");
ok(aMessageObject.timer.started, "timer.started exists");
gArgs[0].arguments.forEach(function (a, i) {
is(aMessageObject.arguments[i], a, "correct arg " + i);
});
resolve();
}
function* startTimeTest(browser) {
yield spawnWithObserver(browser, testConsoleTime, function(opts) {
gLevel = "time";
gArgs = [
{filename: TEST_URI, lineNumber: 23, functionName: "startTimer",
arguments: ["foo"],
timer: { name: "foo" },
}
];
});
BrowserTestUtils.synthesizeMouseAtCenter("#test-time", {}, browser);
yield waitForResolve(browser);
}
function testConsoleTimeEnd(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
is(aMessageObject.level, gLevel, "expected level received");
ok(aMessageObject.arguments, "we have arguments");
is(aMessageObject.filename, gArgs[0].filename, "filename matches");
is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches");
is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches");
is(aMessageObject.arguments.length, gArgs[0].arguments.length, "arguments.length matches");
is(aMessageObject.timer.name, gArgs[0].timer.name, "timer name matches");
is(typeof aMessageObject.timer.duration, "number", "timer duration is a number");
info("timer duration: " + aMessageObject.timer.duration);
ok(aMessageObject.timer.duration >= 0, "timer duration is positive");
gArgs[0].arguments.forEach(function (a, i) {
is(aMessageObject.arguments[i], a, "correct arg " + i);
});
resolve();
}
function* startTimeEndTest(browser) {
yield spawnWithObserver(browser, testConsoleTimeEnd, function(opts) {
gLevel = "timeEnd";
gArgs = [
{filename: TEST_URI, lineNumber: 27, functionName: "stopTimer",
arguments: ["foo"],
timer: { name: "foo" },
},
];
});
BrowserTestUtils.synthesizeMouseAtCenter("#test-timeEnd", {}, browser);
yield waitForResolve(browser);
}
function testConsoleTimeStamp(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
is(aMessageObject.level, gLevel, "expected level received");
is(aMessageObject.filename, gArgs[0].filename, "filename matches");
is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches");
is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches");
ok(aMessageObject.timeStamp > 0, "timeStamp is a positive value");
gArgs[0].arguments.forEach(function (a, i) {
is(aMessageObject.arguments[i], a, "correct arg " + i);
});
resolve();
}
function* startTimeStampTest(browser) {
yield spawnWithObserver(browser, testConsoleTimeStamp, function() {
gLevel = "timeStamp";
gArgs = [
{filename: TEST_URI, lineNumber: 58, functionName: "timeStamp",
arguments: ["!!!"]
}
];
});
BrowserTestUtils.synthesizeMouseAtCenter("#test-timeStamp", {}, browser);
yield waitForResolve(browser);
}
function testEmptyConsoleTimeStamp(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
is(aMessageObject.level, gLevel, "expected level received");
is(aMessageObject.filename, gArgs[0].filename, "filename matches");
is(aMessageObject.lineNumber, gArgs[0].lineNumber, "lineNumber matches");
is(aMessageObject.functionName, gArgs[0].functionName, "functionName matches");
ok(aMessageObject.timeStamp > 0, "timeStamp is a positive value");
is(aMessageObject.arguments.length, 0, "we don't have arguments");
resolve();
}
function* startEmptyTimeStampTest(browser) {
yield spawnWithObserver(browser, testEmptyConsoleTimeStamp, function() {
gLevel = "timeStamp";
gArgs = [
{filename: TEST_URI, lineNumber: 58, functionName: "timeStamp",
arguments: []
}
];
});
BrowserTestUtils.synthesizeMouseAtCenter("#test-emptyTimeStamp", {}, browser);
yield waitForResolve(browser);
}
function testEmptyTimer(aMessageObject) {
let messageWindow = Services.wm.getOuterWindowWithId(aMessageObject.ID);
is(messageWindow, gWindow, "found correct window by window ID");
ok(aMessageObject.level == "time" || aMessageObject.level == "timeEnd",
"expected level received");
is(aMessageObject.arguments.length, 0, "we don't have arguments");
ok(!aMessageObject.timer, "we don't have a timer");
is(aMessageObject.functionName, "namelessTimer", "functionName matches");
ok(aMessageObject.lineNumber == 31 || aMessageObject.lineNumber == 32,
"lineNumber matches");
resolve();
}
function* startEmptyTimerTest(browser) {
yield spawnWithObserver(browser, testEmptyTimer);
BrowserTestUtils.synthesizeMouseAtCenter("#test-namelessTimer", {}, browser);
yield waitForResolve(browser);
}

View file

@ -0,0 +1,80 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"]
.getService(Ci.nsIConsoleAPIStorage);
const FAKE_ADDON_ID = "test-webext-addon@mozilla.org";
const EXPECTED_CONSOLE_ID = `addon/${FAKE_ADDON_ID}`;
const EXPECTED_CONSOLE_MESSAGE_CONTENT = "fake-webext-addon-test-log-message";
const ConsoleObserver = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
init() {
Services.obs.addObserver(this, "console-api-log-event", false);
},
uninit() {
Services.obs.removeObserver(this, "console-api-log-event", false);
},
observe(aSubject, aTopic, aData) {
if (aTopic == "console-api-log-event") {
let consoleAPIMessage = aSubject.wrappedJSObject;
is(consoleAPIMessage.arguments[0], EXPECTED_CONSOLE_MESSAGE_CONTENT,
"the consoleAPIMessage contains the expected message");
ok(consoleAPIMessage.originAttributes, "the consoleAPImessage contains originattributes");
is(consoleAPIMessage.originAttributes.addonId, FAKE_ADDON_ID,
"the consoleAPImessage's originAttributes contains the expected addonId");
let cachedMessages = ConsoleAPIStorage.getEvents().filter((msg) => {
return msg.originAttributes && msg.originAttributes.addonId == FAKE_ADDON_ID;
});
is(cachedMessages.length, 1, "found the expected cached console messages from the addon");
is(cachedMessages[0] && cachedMessages[0].originAttributes.addonId, FAKE_ADDON_ID,
"the cached message's originAttributes contains the expected addonId");
finish();
}
}
};
function test()
{
ConsoleObserver.init();
waitForExplicitFinish();
let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
let uuid = uuidGenerator.generateUUID().number;
uuid = uuid.slice(1, -1); // Strip { and } off the UUID.
let baseURI = Services.io.newURI("about:blank", null, null);
let originAttributes = {addonId: FAKE_ADDON_ID};
let principal = Services.scriptSecurityManager
.createCodebasePrincipal(baseURI, originAttributes);
let chromeWebNav = Services.appShell.createWindowlessBrowser(true);
let interfaceRequestor = chromeWebNav.QueryInterface(Ci.nsIInterfaceRequestor);
let docShell = interfaceRequestor.getInterface(Ci.nsIDocShell);
docShell.createAboutBlankContentViewer(principal);
info("fake webextension docShell created");
registerCleanupFunction(function() {
if (chromeWebNav) {
chromeWebNav.close();
chromeWebNav = null;
}
ConsoleObserver.uninit();
});
let window = docShell.contentViewer.DOMDocument.defaultView;
window.eval(`console.log("${EXPECTED_CONSOLE_MESSAGE_CONTENT}");`);
chromeWebNav.close();
chromeWebNav = null;
info("fake webextension page logged a console api message");
}

View file

@ -0,0 +1,98 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const TEST_URI_NAV = "http://example.com/browser/dom/tests/browser/";
function tearDown()
{
while (gBrowser.tabs.length > 1)
gBrowser.removeCurrentTab();
}
add_task(function*()
{
// Don't cache removed tabs, so "clear console cache on tab close" triggers.
yield SpecialPowers.pushPrefEnv({ set: [[ "browser.tabs.max_tabs_undo", 0 ]] });
registerCleanupFunction(tearDown);
// Open a keepalive tab in the background to make sure we don't accidentally
// kill the content process
var keepaliveTab = gBrowser.addTab("about:blank");
// Open the main tab to run the test in
var tab = gBrowser.addTab("about:blank");
gBrowser.selectedTab = tab;
var browser = gBrowser.selectedBrowser;
let observerPromise = ContentTask.spawn(browser, null, function* (opt) {
const TEST_URI = "http://example.com/browser/dom/tests/browser/test-console-api.html";
let ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"]
.getService(Ci.nsIConsoleAPIStorage);
let observerPromise = new Promise(resolve => {
let apiCallCount = 0;
let ConsoleObserver = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
observe: function(aSubject, aTopic, aData) {
if (aTopic == "console-storage-cache-event") {
apiCallCount++;
if (apiCallCount == 4) {
let windowId = content.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
Services.obs.removeObserver(this, "console-storage-cache-event");
ok(ConsoleAPIStorage.getEvents(windowId).length >= 4, "Some messages found in the storage service");
ConsoleAPIStorage.clearEvents();
is(ConsoleAPIStorage.getEvents(windowId).length, 0, "Cleared Storage");
resolve(windowId);
}
}
}
};
Services.obs.addObserver(ConsoleObserver, "console-storage-cache-event", false);
// Redirect the browser to the test URI
content.window.location = TEST_URI;
});
yield ContentTaskUtils.waitForEvent(this, "DOMContentLoaded");
content.console.log("this", "is", "a", "log message");
content.console.info("this", "is", "a", "info message");
content.console.warn("this", "is", "a", "warn message");
content.console.error("this", "is", "a", "error message");
return observerPromise;
});
let windowId = yield observerPromise;
yield ContentTask.spawn(browser, null, function() {
// make sure a closed window's events are in fact removed from
// the storage cache
content.console.log("adding a new event");
});
// Close the window.
gBrowser.removeTab(tab, {animate: false});
// Ensure actual window destruction is not delayed (too long).
SpecialPowers.DOMWindowUtils.garbageCollect();
// Spawn the check in the keepaliveTab, so that we can read the ConsoleAPIStorage correctly
gBrowser.selectedTab = keepaliveTab;
browser = gBrowser.selectedBrowser;
// Spin the event loop to make sure everything is cleared.
yield ContentTask.spawn(browser, null, function () {
return Promise.resolve();
});
yield ContentTask.spawn(browser, windowId, function(windowId) {
var ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"]
.getService(Ci.nsIConsoleAPIStorage);
is(ConsoleAPIStorage.getEvents(windowId).length, 0, "tab close is clearing the cache");
});
});

View file

@ -0,0 +1,89 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
// initialization
waitForExplicitFinish();
let windowsToClose = [];
let innerID;
let beforeEvents;
let afterEvents;
let storageShouldOccur;
let consoleObserver;
let testURI =
"http://example.com/browser/dom/tests/browser/test-console-api.html";
let ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"]
.getService(Ci.nsIConsoleAPIStorage);
function getInnerWindowId(aWindow) {
return aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.currentInnerWindowID;
}
function whenNewWindowLoaded(aOptions, aCallback) {
let win = OpenBrowserWindow(aOptions);
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
aCallback(win);
}, false);
}
function doTest(aIsPrivateMode, aWindow, aCallback) {
aWindow.gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
consoleObserver = {
observe: function(aSubject, aTopic, aData) {
if (aTopic == "console-api-log-event") {
afterEvents = ConsoleAPIStorage.getEvents(innerID);
is(beforeEvents.length == afterEvents.length - 1, storageShouldOccur,
"storage should" + (storageShouldOccur ? "" : " not") + " occur");
executeSoon(function() {
Services.obs.removeObserver(consoleObserver, "console-api-log-event");
aCallback();
});
}
}
};
aWindow.Services.obs.addObserver(
consoleObserver, "console-api-log-event", false);
aWindow.nativeConsole.log("foo bar baz (private: " + aIsPrivateMode + ")");
}, true);
// We expect that console API messages are always stored.
storageShouldOccur = true;
innerID = getInnerWindowId(aWindow);
beforeEvents = ConsoleAPIStorage.getEvents(innerID);
aWindow.gBrowser.selectedBrowser.loadURI(testURI);
}
function testOnWindow(aOptions, aCallback) {
whenNewWindowLoaded(aOptions, function(aWin) {
windowsToClose.push(aWin);
// execute should only be called when need, like when you are opening
// web pages on the test. If calling executeSoon() is not necesary, then
// call whenNewWindowLoaded() instead of testOnWindow() on your test.
executeSoon(() => aCallback(aWin));
});
};
// this function is called after calling finish() on the test.
registerCleanupFunction(function() {
windowsToClose.forEach(function(aWin) {
aWin.close();
});
});
// test first when not on private mode
testOnWindow({}, function(aWin) {
doTest(false, aWin, function() {
// then test when on private mode
testOnWindow({private: true}, function(aWin) {
doTest(true, aWin, finish);
});
});
});
}

View file

@ -0,0 +1,43 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const TEST_URI = "http://example.com/browser/dom/tests/browser/test_largeAllocation.html";
function expectProcessCreated() {
let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
return new Promise(resolve => {
let topic = "ipc:content-created";
function observer() {
os.removeObserver(observer, topic);
ok(true, "Expect process created");
resolve();
}
os.addObserver(observer, topic, /* weak = */ false);
});
}
add_task(function*() {
yield SpecialPowers.pushPrefEnv({
set: [
["dom.largeAllocationHeader.enabled", true],
]
});
// A toplevel tab should be able to navigate cross process!
yield BrowserTestUtils.withNewTab("about:blank", function*(aBrowser) {
let epc = expectProcessCreated();
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.document.location = TEST_URI;
});
// Wait for the new process to be created by the Large-Allocation header
yield epc;
// Allocate a gigabyte of memory in the content process
yield ContentTask.spawn(aBrowser, null, () => {
let arrayBuffer = new ArrayBuffer(1024*1024*1024);
ok(arrayBuffer, "Successfully allocated a gigabyte of memory in content process");
});
});
});

View file

@ -0,0 +1,37 @@
add_task(function* () {
let tabs = [ gBrowser.selectedTab, gBrowser.addTab() ];
// The first tab has an autofocused element.
// The second tab is exactly like the first one without the autofocus.
let testingList = [
{ uri: "data:text/html,<!DOCTYPE html><html><body><input autofocus id='target'></body></html>",
tagName: "INPUT"},
];
// Set the focus to the first tab.
tabs[0].linkedBrowser.focus();
// Load the second tab in the background.
let loadedPromise = BrowserTestUtils.browserLoaded(tabs[1].linkedBrowser);
tabs[1].linkedBrowser.loadURI(testingList[0].uri);
yield loadedPromise;
for (var i = 0; i < testingList.length; ++i) {
// Get active element in the tab.
let tagName = yield ContentTask.spawn(tabs[i + 1].linkedBrowser, null, function* () {
return content.document.activeElement.tagName;
});
is(tagName, testingList[i].tagName,
"The background tab's focused element should be " + testingList[i].tagName);
}
is(document.activeElement, tabs[0].linkedBrowser,
"The background tab's focused element should not cause the tab to be focused");
// Cleaning up.
for (let i = 1; i < tabs.length; i++) {
yield BrowserTestUtils.removeTab(tabs[i]);
}
});

View file

@ -0,0 +1,18 @@
add_task(function* () {
yield new Promise(resolve => {
SpecialPowers.pushPrefEnv({"set": [["browser.autofocus", false]]}, resolve);
});
const url = "data:text/html,<!DOCTYPE html><html><body><input autofocus><button autofocus></button><textarea autofocus></textarea><select autofocus></select></body></html>";
let loadedPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
gBrowser.selectedBrowser.loadURI(url);
yield loadedPromise;
yield new Promise(resolve => executeSoon(resolve));
yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
is(content.document.activeElement, content.document.body, "body focused");
});
});

View file

@ -0,0 +1,144 @@
const TEST_URL = "http://www.example.com/browser/dom/tests/browser/dummy.html";
function pageScript() {
window.addEventListener("beforeunload", function (event) {
var str = "Leaving?";
event.returnValue = str;
return str;
}, true);
}
function frameScript() {
content.window.addEventListener("beforeunload", function (event) {
sendAsyncMessage("Test:OnBeforeUnloadReceived");
var str = "Leaving?";
event.returnValue = str;
return str;
}, true);
}
// Wait for onbeforeunload dialog, and dismiss it immediately.
function awaitAndCloseBeforeUnloadDialog(doStayOnPage) {
return new Promise(resolve => {
function onDialogShown(node) {
Services.obs.removeObserver(onDialogShown, "tabmodal-dialog-loaded");
let button = doStayOnPage ? node.ui.button1 : node.ui.button0;
button.click();
resolve();
}
Services.obs.addObserver(onDialogShown, "tabmodal-dialog-loaded");
});
}
SpecialPowers.pushPrefEnv(
{"set": [["dom.require_user_interaction_for_beforeunload", false]]});
/**
* Test navigation from a content page to a chrome page. Also check that only
* one beforeunload event is fired.
*/
add_task(function* () {
let beforeUnloadCount = 0;
messageManager.addMessageListener("Test:OnBeforeUnloadReceived", function() {
beforeUnloadCount++;
});
// Open a content page.
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
let browser = tab.linkedBrowser;
ok(browser.isRemoteBrowser, "Browser should be remote.");
browser.messageManager.loadFrameScript(
"data:,(" + frameScript.toString() + ")();", true);
// Navigate to a chrome page.
let dialogShown1 = awaitAndCloseBeforeUnloadDialog(false);
yield BrowserTestUtils.loadURI(browser, "about:support");
yield Promise.all([
dialogShown1,
BrowserTestUtils.browserLoaded(browser)
]);
is(beforeUnloadCount, 1, "Should have received one beforeunload event.");
ok(!browser.isRemoteBrowser, "Browser should not be remote.");
// Go back to content page.
ok(gBrowser.webNavigation.canGoBack, "Should be able to go back.");
gBrowser.goBack();
yield BrowserTestUtils.browserLoaded(browser);
browser.messageManager.loadFrameScript(
"data:,(" + frameScript.toString() + ")();", true);
// Test that going forward triggers beforeunload prompt as well.
ok(gBrowser.webNavigation.canGoForward, "Should be able to go forward.");
let dialogShown2 = awaitAndCloseBeforeUnloadDialog(false);
gBrowser.goForward();
yield Promise.all([
dialogShown2,
BrowserTestUtils.browserLoaded(browser)
]);
is(beforeUnloadCount, 2, "Should have received two beforeunload events.");
yield BrowserTestUtils.removeTab(tab);
});
/**
* Test navigation from a chrome page to a content page. Also check that only
* one beforeunload event is fired.
*/
add_task(function* () {
let beforeUnloadCount = 0;
messageManager.addMessageListener("Test:OnBeforeUnloadReceived", function() {
beforeUnloadCount++;
});
// Open a chrome page.
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser,
"about:support");
let browser = tab.linkedBrowser;
ok(!browser.isRemoteBrowser, "Browser should not be remote.");
yield ContentTask.spawn(browser, null, function* () {
content.window.addEventListener("beforeunload", function (event) {
sendAsyncMessage("Test:OnBeforeUnloadReceived");
var str = "Leaving?";
event.returnValue = str;
return str;
}, true);
});
// Navigate to a content page.
let dialogShown1 = awaitAndCloseBeforeUnloadDialog(false);
yield BrowserTestUtils.loadURI(browser, TEST_URL);
yield Promise.all([
dialogShown1,
BrowserTestUtils.browserLoaded(browser)
]);
is(beforeUnloadCount, 1, "Should have received one beforeunload event.");
ok(browser.isRemoteBrowser, "Browser should be remote.");
// Go back to chrome page.
ok(gBrowser.webNavigation.canGoBack, "Should be able to go back.");
gBrowser.goBack();
yield BrowserTestUtils.browserLoaded(browser);
yield ContentTask.spawn(browser, null, function* () {
content.window.addEventListener("beforeunload", function (event) {
sendAsyncMessage("Test:OnBeforeUnloadReceived");
var str = "Leaving?";
event.returnValue = str;
return str;
}, true);
});
// Test that going forward triggers beforeunload prompt as well.
ok(gBrowser.webNavigation.canGoForward, "Should be able to go forward.");
let dialogShown2 = awaitAndCloseBeforeUnloadDialog(false);
gBrowser.goForward();
yield Promise.all([
dialogShown2,
BrowserTestUtils.browserLoaded(browser)
]);
is(beforeUnloadCount, 2, "Should have received two beforeunload events.");
yield BrowserTestUtils.removeTab(tab);
});

View file

@ -0,0 +1,36 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
add_task(function*() {
yield BrowserTestUtils.withNewTab("about:blank", function*(aBrowser) {
let duration = yield ContentTask.spawn(aBrowser, null, function (opts) {
const TEST_URI = "http://example.com/browser/dom/tests/browser/test_bug1004814.html";
return new Promise(resolve => {
let ConsoleObserver = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
observe: function(aSubject, aTopic, aData) {
var obj = aSubject.wrappedJSObject;
if (obj.arguments.length != 1 || obj.arguments[0] != 'bug1004814' ||
obj.level != 'timeEnd') {
return;
}
Services.obs.removeObserver(this, "console-api-log-event");
resolve(obj.timer.duration);
}
};
Services.obs.addObserver(ConsoleObserver, "console-api-log-event", false);
// Redirect the browser to the correct document to start the test
content.document.location = TEST_URI;
});
});
ok(duration > 0, "ConsoleEvent.timer.duration > 0: " + duration + " ~ 200ms");
});
});

View file

@ -0,0 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
"use strict";
const TEST_URI = "http://example.com/" +
"browser/dom/tests/browser/position.html";
add_task(function testDismissHanger() {
info("Check that location is not shared when dismissing the geolocation hanger");
let promisePanelShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown", true);
yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URI);
yield promisePanelShown;
// click outside the Geolocation hanger to dismiss it
window.document.getElementById("nav-bar").click();
info("Clicked outside the Geolocation panel to dismiss it");
let hasLocation = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
return content.document.body.innerHTML.includes("location...");
});
ok(hasLocation, "Location is not shared");
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
});

View file

@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
"use strict";
const TEST_URI = "http://example.com/" +
"browser/dom/tests/browser/geo_leak_test.html";
const BASE_GEO_URL = "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs";
add_task(function* () {
Services.prefs.setBoolPref("geo.prompt.testing", true);
Services.prefs.setBoolPref("geo.prompt.testing.allow", true);
// Make the geolocation provider responder very slowly to ensure that
// it does not reply before we close the tab.
Services.prefs.setCharPref("geo.wifi.uri", BASE_GEO_URL + "?delay=100000");
// Open the test URI and close it. The test harness will make sure that the
// page is cleaned up after some GCs. If geolocation is not shut down properly,
// it will show up as a non-shutdown leak.
yield BrowserTestUtils.withNewTab({
gBrowser,
url: TEST_URI
}, function* (browser) { /* ... */ });
ok(true, "Need to do something in this test");
});

View file

@ -0,0 +1,287 @@
/** Test for Bug 396843 **/
function testInDocument(doc, documentID) {
var allNodes = [];
var XMLNodes = [];
// HTML
function HTML_TAG(name) {
allNodes.push(doc.createElement(name));
}
/* List copy/pasted from nsHTMLTagList.h */
HTML_TAG("a", "Anchor")
HTML_TAG("abbr", "Span")
HTML_TAG("acronym", "Span")
HTML_TAG("address", "Span")
HTML_TAG("applet", "SharedObject")
HTML_TAG("area", "Area")
HTML_TAG("b", "Span")
HTML_TAG("base", "Shared")
HTML_TAG("basefont", "Span")
HTML_TAG("bdo", "Span")
HTML_TAG("bgsound", "Span")
HTML_TAG("big", "Span")
HTML_TAG("blockquote", "Shared")
HTML_TAG("body", "Body")
HTML_TAG("br", "BR")
HTML_TAG("button", "Button")
HTML_TAG("canvas", "Canvas")
HTML_TAG("caption", "TableCaption")
HTML_TAG("center", "Span")
HTML_TAG("cite", "Span")
HTML_TAG("code", "Span")
HTML_TAG("col", "TableCol")
HTML_TAG("colgroup", "TableCol")
HTML_TAG("dd", "Span")
HTML_TAG("del", "Mod")
HTML_TAG("dfn", "Span")
HTML_TAG("dir", "Shared")
HTML_TAG("div", "Div")
HTML_TAG("dl", "SharedList")
HTML_TAG("dt", "Span")
HTML_TAG("em", "Span")
HTML_TAG("embed", "SharedObject")
HTML_TAG("fieldset", "FieldSet")
HTML_TAG("font", "Font")
HTML_TAG("form", "Form")
HTML_TAG("frame", "Frame")
HTML_TAG("frameset", "FrameSet")
HTML_TAG("h1", "Heading")
HTML_TAG("h2", "Heading")
HTML_TAG("h3", "Heading")
HTML_TAG("h4", "Heading")
HTML_TAG("h5", "Heading")
HTML_TAG("h6", "Heading")
HTML_TAG("head", "Head")
HTML_TAG("hr", "HR")
HTML_TAG("html", "Html")
HTML_TAG("i", "Span")
HTML_TAG("iframe", "IFrame")
HTML_TAG("image", "")
HTML_TAG("img", "Image")
HTML_TAG("input", "Input")
HTML_TAG("ins", "Mod")
HTML_TAG("isindex", "Unknown")
HTML_TAG("kbd", "Span")
HTML_TAG("keygen", "Span")
HTML_TAG("label", "Label")
HTML_TAG("legend", "Legend")
HTML_TAG("li", "LI")
HTML_TAG("link", "Link")
HTML_TAG("listing", "Span")
HTML_TAG("map", "Map")
HTML_TAG("marquee", "Div")
HTML_TAG("menu", "Shared")
HTML_TAG("meta", "Meta")
HTML_TAG("multicol", "Unknown")
HTML_TAG("nobr", "Span")
HTML_TAG("noembed", "Div")
HTML_TAG("noframes", "Div")
HTML_TAG("noscript", "Div")
HTML_TAG("object", "Object")
HTML_TAG("ol", "SharedList")
HTML_TAG("optgroup", "OptGroup")
HTML_TAG("option", "Option")
HTML_TAG("p", "Paragraph")
HTML_TAG("param", "Shared")
HTML_TAG("plaintext", "Span")
HTML_TAG("pre", "Pre")
HTML_TAG("q", "Shared")
HTML_TAG("s", "Span")
HTML_TAG("samp", "Span")
HTML_TAG("script", "Script")
HTML_TAG("select", "Select")
HTML_TAG("small", "Span")
HTML_TAG("spacer", "Unknown")
HTML_TAG("span", "Span")
HTML_TAG("strike", "Span")
HTML_TAG("strong", "Span")
HTML_TAG("style", "Style")
HTML_TAG("sub", "Span")
HTML_TAG("sup", "Span")
HTML_TAG("table", "Table")
HTML_TAG("tbody", "TableSection")
HTML_TAG("td", "TableCell")
HTML_TAG("textarea", "TextArea")
HTML_TAG("tfoot", "TableSection")
HTML_TAG("th", "TableCell")
HTML_TAG("thead", "TableSection")
HTML_TAG("template", "Template")
HTML_TAG("title", "Title")
HTML_TAG("tr", "TableRow")
HTML_TAG("tt", "Span")
HTML_TAG("u", "Span")
HTML_TAG("ul", "SharedList")
HTML_TAG("var", "Span")
HTML_TAG("wbr", "Shared")
HTML_TAG("xmp", "Span")
function SVG_TAG(name) {
allNodes.push(doc.createElementNS("http://www.w3.org/2000/svg", name));
}
// List sorta stolen from SVG element factory.
SVG_TAG("a")
SVG_TAG("polyline")
SVG_TAG("polygon")
SVG_TAG("circle")
SVG_TAG("ellipse")
SVG_TAG("line")
SVG_TAG("rect")
SVG_TAG("svg")
SVG_TAG("g")
SVG_TAG("foreignObject")
SVG_TAG("path")
SVG_TAG("text")
SVG_TAG("tspan")
SVG_TAG("image")
SVG_TAG("style")
SVG_TAG("linearGradient")
SVG_TAG("metadata")
SVG_TAG("radialGradient")
SVG_TAG("stop")
SVG_TAG("defs")
SVG_TAG("desc")
SVG_TAG("script")
SVG_TAG("use")
SVG_TAG("symbol")
SVG_TAG("marker")
SVG_TAG("title")
SVG_TAG("clipPath")
SVG_TAG("textPath")
SVG_TAG("filter")
SVG_TAG("feBlend")
SVG_TAG("feColorMatrix")
SVG_TAG("feComponentTransfer")
SVG_TAG("feComposite")
SVG_TAG("feFuncR")
SVG_TAG("feFuncG")
SVG_TAG("feFuncB")
SVG_TAG("feFuncA")
SVG_TAG("feGaussianBlur")
SVG_TAG("feMerge")
SVG_TAG("feMergeNode")
SVG_TAG("feMorphology")
SVG_TAG("feOffset")
SVG_TAG("feFlood")
SVG_TAG("feTile")
SVG_TAG("feTurbulence")
SVG_TAG("feConvolveMatrix")
SVG_TAG("feDistantLight")
SVG_TAG("fePointLight")
SVG_TAG("feSpotLight")
SVG_TAG("feDiffuseLighting")
SVG_TAG("feSpecularLighting")
SVG_TAG("feDisplacementMap")
SVG_TAG("feImage")
SVG_TAG("pattern")
SVG_TAG("mask")
SVG_TAG("svgSwitch")
// Toss in some other namespaced stuff too, for good measure
// XUL stuff might not be creatable in content documents
try {
allNodes.push(doc.createElementNS(
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
"window"));
} catch (e) {}
allNodes.push(doc.createElementNS("http://www.w3.org/1998/Math/MathML",
"math"));
allNodes.push(doc.createElementNS("http://www.w3.org/2001/xml-events",
"testname"));
allNodes.push(doc.createElementNS("bogus.namespace", "testname"));
var XMLDoc = doc.implementation.createDocument("", "", null);
// And non-elements
allNodes.push(doc.createTextNode("some text"));
allNodes.push(doc.createComment("some text"));
allNodes.push(doc.createDocumentFragment());
XMLNodes.push(XMLDoc.createCDATASection("some text"));
XMLNodes.push(XMLDoc.createProcessingInstruction("PI", "data"));
function runTestUnwrapped() {
if (!("wrappedJSObject" in doc)) {
return;
}
ok(doc.wrappedJSObject.nodePrincipal === undefined,
"Must not have document principal for " + documentID);
ok(doc.wrappedJSObject.baseURIObject === undefined,
"Must not have document base URI for " + documentID);
ok(doc.wrappedJSObject.documentURIObject === undefined,
"Must not have document URI for " + documentID);
for (var i = 0; i < allNodes.length; ++i) {
ok(allNodes[i].wrappedJSObject.nodePrincipal === undefined,
"Unexpected principal appears for " + allNodes[i].nodeName +
" in " + documentID);
ok(allNodes[i].wrappedJSObject.baseURIObject === undefined,
"Unexpected base URI appears for " + allNodes[i].nodeName +
" in " + documentID);
}
}
function runTestProps() {
isnot(doc.nodePrincipal, null,
"Must have document principal in " + documentID);
is(doc.nodePrincipal instanceof Components.interfaces.nsIPrincipal,
true, "document principal must be a principal in " + documentID);
isnot(doc.baseURIObject, null,
"Must have document base URI in" + documentID);
is(doc.baseURIObject instanceof Components.interfaces.nsIURI,
true, "document base URI must be a URI in " + documentID);
isnot(doc.documentURIObject, null,
"Must have document URI " + documentID);
is(doc.documentURIObject instanceof Components.interfaces.nsIURI,
true, "document URI must be a URI in " + documentID);
is(doc.documentURIObject.spec, doc.documentURI,
"document URI must be the right URI in " + documentID);
for (var i = 0; i < allNodes.length; ++i) {
is(allNodes[i].nodePrincipal, doc.nodePrincipal,
"Unexpected principal for " + allNodes[i].nodeName +
" in " + documentID);
is(allNodes[i].baseURIObject, doc.baseURIObject,
"Unexpected base URI for " + allNodes[i].nodeName +
" in " + documentID);
}
for (i = 0; i < XMLNodes.length; ++i) {
is(XMLNodes[i].nodePrincipal, doc.nodePrincipal,
"Unexpected principal for " + XMLNodes[i].nodeName +
" in " + documentID);
is(XMLNodes[i].baseURIObject.spec, "about:blank",
"Unexpected base URI for " + XMLNodes[i].nodeName +
" in " + documentID);
}
}
runTestUnwrapped();
runTestProps();
runTestUnwrapped();
}
add_task(function* test1() {
testInDocument(document, "browser window");
});
function* newTabTest(location) {
yield BrowserTestUtils.withNewTab({ gBrowser, url: location },
function* (browser) {
yield ContentTask.spawn(browser, { location, testInDocument_: testInDocument.toSource() },
function* ({ location, testInDocument_ }) {
let testInDocument = eval(`(() => (${testInDocument_}))()`);
testInDocument(content.document, location);
});
});
}
add_task(function* test2() {
yield newTabTest("about:blank");
});
add_task(function* test3() {
yield newTabTest("about:config");
});

View file

@ -0,0 +1,151 @@
add_task(function* () {
requestLongerTimeout(2);
let testingList = [
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><input id='target'></body>",
tagName: "INPUT", methodName: "focus" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').select(); }, 10);\"><input id='target'></body>",
tagName: "INPUT", methodName: "select" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><a href='about:blank' id='target'>anchor</a></body>",
tagName: "A", methodName: "focus" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><button id='target'>button</button></body>",
tagName: "BUTTON", methodName: "focus" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><select id='target'><option>item1</option></select></body>",
tagName: "SELECT", methodName: "focus" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><textarea id='target'>textarea</textarea></body>",
tagName: "TEXTAREA", methodName: "focus" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').select(); }, 10);\"><textarea id='target'>textarea</textarea></body>",
tagName: "TEXTAREA", methodName: "select" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><label id='target'><input></label></body>",
tagName: "INPUT", methodName: "focus of label element" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><fieldset><legend id='target'>legend</legend><input></fieldset></body>",
tagName: "INPUT", methodName: "focus of legend element" },
{ uri: "data:text/html,<body onload=\"setTimeout(function () {" +
" var element = document.getElementById('target');" +
" var event = document.createEvent('MouseEvent');" +
" event.initMouseEvent('click', true, true, window," +
" 1, 0, 0, 0, 0, false, false, false, false, 0, element);" +
" element.dispatchEvent(event); }, 10);\">" +
"<label id='target'><input></label></body>",
tagName: "INPUT", methodName: "click event on the label element" },
];
yield BrowserTestUtils.withNewTab("about:blank", function*(bg) {
yield BrowserTestUtils.withNewTab("about:blank", function*(fg) {
for (let test of testingList) {
// Focus the foreground tab's content
fg.focus();
// Load the URIs.
yield BrowserTestUtils.loadURI(bg, test.uri);
yield BrowserTestUtils.browserLoaded(bg);
yield BrowserTestUtils.loadURI(fg, test.uri);
yield BrowserTestUtils.browserLoaded(fg);
ok(true, "Test1: Both of the tabs are loaded");
// Confirm that the contents should be able to steal focus from content.
yield ContentTask.spawn(fg, test, test => {
return new Promise(res => {
function f() {
let e = content.document.activeElement;
if (e.tagName != test.tagName) {
setTimeout(f, 10);
} else {
is(Services.focus.focusedElement, e,
"the foreground tab's " + test.tagName +
" element isn't focused by the " + test.methodName +
" (Test1: content can steal focus)");
res();
}
}
f();
});
});
yield ContentTask.spawn(bg, test, test => {
return new Promise(res => {
function f() {
let e = content.document.activeElement;
if (e.tagName != test.tagName) {
setTimeout(f, 10);
} else {
isnot(Services.focus.focusedElement, e,
"the background tab's " + test.tagName +
" element is focused by the " + test.methodName +
" (Test1: content can steal focus)");
res();
}
}
f();
});
});
if (fg.isRemoteBrowser) {
is(Services.focus.focusedElement, fg,
"Focus should be on the content in the parent process");
}
// Focus chrome
document.getElementById("urlbar").focus();
let originalFocus = Services.focus.focusedElement;
// Load about:blank just to make sure that everything works nicely
yield BrowserTestUtils.loadURI(bg, "about:blank");
yield BrowserTestUtils.browserLoaded(bg);
yield BrowserTestUtils.loadURI(fg, "about:blank");
yield BrowserTestUtils.browserLoaded(fg);
// Load the URIs.
yield BrowserTestUtils.loadURI(bg, test.uri);
yield BrowserTestUtils.browserLoaded(bg);
yield BrowserTestUtils.loadURI(fg, test.uri);
yield BrowserTestUtils.browserLoaded(fg);
ok(true, "Test2: Both of the tabs are loaded");
// Confirm that the contents should be able to steal focus from content.
yield ContentTask.spawn(fg, test, test => {
return new Promise(res => {
function f() {
let e = content.document.activeElement;
if (e.tagName != test.tagName) {
setTimeout(f, 10);
} else {
isnot(Services.focus.focusedElement, e,
"the foreground tab's " + test.tagName +
" element is focused by the " + test.methodName +
" (Test2: content can NOT steal focus)");
res();
}
}
f();
});
});
yield ContentTask.spawn(bg, test, test => {
return new Promise(res => {
function f() {
let e = content.document.activeElement;
if (e.tagName != test.tagName) {
setTimeout(f, 10);
} else {
isnot(Services.focus.focusedElement, e,
"the background tab's " + test.tagName +
" element is focused by the " + test.methodName +
" (Test2: content can NOT steal focus)");
res();
}
}
f();
});
});
is(Services.focus.focusedElement, originalFocus,
"The parent process's focus has shifted " +
"(methodName = " + test.methodName + ")" +
" (Test2: content can NOT steal focus)");
}
});
});
});

View file

@ -0,0 +1,45 @@
add_task(function* test() {
const kTestURI =
"data:text/html," +
"<script type=\"text/javascript\">" +
" function onMouseDown(aEvent) {" +
" document.getElementById('willBeFocused').focus();" +
" aEvent.preventDefault();" +
" }" +
"</script>" +
"<body id=\"body\">" +
"<button onmousedown=\"onMouseDown(event);\" style=\"width: 100px; height: 100px;\">click here</button>" +
"<input id=\"willBeFocused\"></body>";
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, kTestURI);
let fm = Components.classes["@mozilla.org/focus-manager;1"].
getService(Components.interfaces.nsIFocusManager);
for (var button = 0; button < 3; button++) {
// Set focus to a chrome element before synthesizing a mouse down event.
document.getElementById("urlbar").focus();
is(fm.focusedElement, document.getElementById("urlbar").inputField,
"Failed to move focus to search bar: button=" + button);
// Synthesize mouse down event on browser object over the button, such that
// the event propagates through both processes.
EventUtils.synthesizeMouse(tab.linkedBrowser, 20, 20, { "button": button }, null);
isnot(fm.focusedElement, document.getElementById("urlbar").inputField,
"Failed to move focus away from search bar: button=" + button);
yield ContentTask.spawn(tab.linkedBrowser, button, function (button) {
let fm = Components.classes["@mozilla.org/focus-manager;1"].
getService(Components.interfaces.nsIFocusManager);
Assert.equal(content.document.activeElement.id, "willBeFocused",
"The input element isn't active element: button=" + button);
Assert.equal(fm.focusedElement, content.document.activeElement,
"The active element isn't focused element in App level: button=" + button);
});
}
gBrowser.removeTab(tab);
});

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Frame Element Tests</title>
</head>
<body>
<h1>Frame Element Tests</h1>
<iframe id="iframe-blank" src="about:blank"></iframe>
<iframe id="iframe-data-url" src="data:text/html;charset=utf-8,%3Chtml%3E%3Cbody%3Eiframe%3C/body%3E%3C/html%3E"></iframe>
<object id="object-data-url" type="text/html" data="data:text/html;charset=utf-8,%3Chtml%3E%3Cbody%3Eobject%3C/body%3E%3C/html%3E"></object>
</body>

View file

@ -0,0 +1,89 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const TEST_URI = "http://example.com/browser/dom/tests/browser/browser_frame_elements.html";
function getWindowUtils(window) {
return window.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
}
add_task(function* test() {
yield BrowserTestUtils.withNewTab({ gBrowser, url: TEST_URI }, function* (browser) {
if (!browser.isRemoteBrowser) {
// Non-e10s, access contentWindow and confirm its container is the browser:
let windowUtils = getWindowUtils(browser.contentWindow);
is (windowUtils.containerElement, browser,
"Container element for main window is xul:browser");
}
yield ContentTask.spawn(browser, null, startTests);
yield Task.spawn(mozBrowserTests(browser));
});
});
function startTests() {
function getWindowUtils(window) {
return window.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
}
info("Frame tests started");
info("Checking top window");
let gWindow = content;
Assert.equal(gWindow.top, gWindow, "gWindow is top");
Assert.equal(gWindow.parent, gWindow, "gWindow is parent");
info("Checking about:blank iframe");
let iframeBlank = gWindow.document.querySelector("#iframe-blank");
Assert.ok(iframeBlank, "Iframe exists on page");
let iframeBlankUtils = getWindowUtils(iframeBlank.contentWindow);
Assert.equal(iframeBlankUtils.containerElement, iframeBlank, "Container element for iframe window is iframe");
Assert.equal(iframeBlank.contentWindow.top, gWindow, "gWindow is top");
Assert.equal(iframeBlank.contentWindow.parent, gWindow, "gWindow is parent");
info("Checking iframe with data url src");
let iframeDataUrl = gWindow.document.querySelector("#iframe-data-url");
Assert.ok(iframeDataUrl, "Iframe exists on page");
let iframeDataUrlUtils = getWindowUtils(iframeDataUrl.contentWindow);
Assert.equal(iframeDataUrlUtils.containerElement, iframeDataUrl, "Container element for iframe window is iframe");
Assert.equal(iframeDataUrl.contentWindow.top, gWindow, "gWindow is top");
Assert.equal(iframeDataUrl.contentWindow.parent, gWindow, "gWindow is parent");
info("Checking object with data url data attribute");
let objectDataUrl = gWindow.document.querySelector("#object-data-url");
Assert.ok(objectDataUrl, "Object exists on page");
let objectDataUrlUtils = getWindowUtils(objectDataUrl.contentWindow);
Assert.equal(objectDataUrlUtils.containerElement, objectDataUrl, "Container element for object window is the object");
Assert.equal(objectDataUrl.contentWindow.top, gWindow, "gWindow is top");
Assert.equal(objectDataUrl.contentWindow.parent, gWindow, "gWindow is parent");
}
function* mozBrowserTests(browser) {
info("Granting special powers for mozbrowser");
SpecialPowers.addPermission("browser", true, TEST_URI);
SpecialPowers.setBoolPref('dom.mozBrowserFramesEnabled', true);
SpecialPowers.setBoolPref('network.disable.ipc.security', true);
yield ContentTask.spawn(browser, null, function() {
info("Checking mozbrowser iframe");
let mozBrowserFrame = content.document.createElement("iframe");
mozBrowserFrame.setAttribute("mozbrowser", "");
content.document.body.appendChild(mozBrowserFrame);
Assert.equal(mozBrowserFrame.contentWindow.top, mozBrowserFrame.contentWindow,
"Mozbrowser top == iframe window");
Assert.equal(mozBrowserFrame.contentWindow.parent, mozBrowserFrame.contentWindow,
"Mozbrowser parent == iframe window");
});
info("Revoking special powers for mozbrowser");
SpecialPowers.clearUserPref('dom.mozBrowserFramesEnabled');
SpecialPowers.clearUserPref('network.disable.ipc.security');
SpecialPowers.removePermission("browser", TEST_URI);
}

View file

@ -0,0 +1,214 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const TEST_URI = "http://example.com/browser/dom/tests/browser/test_largeAllocation.html";
function expectProcessCreated() {
let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
return new Promise(resolve => {
let topic = "ipc:content-created";
function observer() {
os.removeObserver(observer, topic);
ok(true, "Expect process created");
resolve();
}
os.addObserver(observer, topic, /* weak = */ false);
});
}
function expectNoProcess() {
let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
let topic = "ipc:content-created";
function observer() {
ok(false, "A process was created!");
os.removeObserver(observer, topic);
}
os.addObserver(observer, topic, /* weak = */ false);
return () => os.removeObserver(observer, topic);
}
function getPID(aBrowser) {
return ContentTask.spawn(aBrowser, null, () => {
const appinfo = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULRuntime);
return appinfo.processID;
});
}
add_task(function*() {
// I'm terrible and put this set of tests into a single file, so I need a longer timeout
requestLongerTimeout(2);
yield SpecialPowers.pushPrefEnv({
set: [
["dom.largeAllocationHeader.enabled", true],
]
});
// A toplevel tab should be able to navigate cross process!
yield BrowserTestUtils.withNewTab("about:blank", function*(aBrowser) {
ok(true, "Starting test 0");
let pid1 = yield getPID(aBrowser);
let epc = expectProcessCreated();
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.document.location = TEST_URI;
});
// Wait for the new process to be created
yield epc;
let pid2 = yield getPID(aBrowser);
isnot(pid1, pid2, "The pids should be different between the initial load and the new load");
});
// When a Large-Allocation document is loaded in an iframe, the header should
// be ignored, and the tab should stay in the current process.
yield BrowserTestUtils.withNewTab("about:blank", function*(aBrowser) {
ok(true, "Starting test 1");
let pid1 = yield getPID(aBrowser);
// Fail the test if we create a process
let stopExpectNoProcess = expectNoProcess();
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.document.body.innerHTML = `<iframe src='${TEST_URI}'></iframe>`;
return new Promise(resolve => {
content.document.body.querySelector('iframe').onload = () => {
ok(true, "Iframe finished loading");
resolve();
};
});
});
let pid2 = yield getPID(aBrowser);
is(pid1, pid2, "The PID should not have changed");
stopExpectNoProcess();
});
// If you have an opener cross process navigation shouldn't work
yield BrowserTestUtils.withNewTab("http://example.com", function*(aBrowser) {
ok(true, "Starting test 2");
let pid1 = yield getPID(aBrowser);
// Fail the test if we create a process
let stopExpectNoProcess = expectNoProcess();
let loaded = ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.document.body.innerHTML = '<button>CLICK ME</button>';
return new Promise(resolve => {
content.document.querySelector('button').onclick = e => {
let w = content.window.open(TEST_URI, '_blank');
w.onload = () => {
ok(true, "Window finished loading");
w.close();
resolve();
};
};
});
});
yield BrowserTestUtils.synthesizeMouseAtCenter("button", {}, aBrowser);
yield loaded;
let pid2 = yield getPID(aBrowser);
is(pid1, pid2, "The PID should not have changed");
stopExpectNoProcess();
});
// Load Large-Allocation twice with about:blank load in between
yield BrowserTestUtils.withNewTab("about:blank", function*(aBrowser) {
ok(true, "Starting test 3");
let pid1 = yield getPID(aBrowser);
let epc = expectProcessCreated();
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.document.location = TEST_URI;
});
yield epc;
let pid2 = yield getPID(aBrowser);
isnot(pid1, pid2);
epc = expectProcessCreated();
yield BrowserTestUtils.browserLoaded(aBrowser);
yield ContentTask.spawn(aBrowser, null, () => content.document.location = "about:blank");
yield BrowserTestUtils.browserLoaded(aBrowser);
let pid3 = yield getPID(aBrowser);
is(pid2, pid3);
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.document.location = TEST_URI;
});
yield epc;
let pid4 = yield getPID(aBrowser);
isnot(pid1, pid4);
isnot(pid2, pid4);
});
// Load Large-Allocation then about:blank load, then back button press should load from bfcache.
yield BrowserTestUtils.withNewTab("about:blank", function*(aBrowser) {
ok(true, "Starting test 4");
let pid1 = yield getPID(aBrowser);
let epc = expectProcessCreated();
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.document.location = TEST_URI;
});
yield epc;
let pid2 = yield getPID(aBrowser);
isnot(pid1, pid2, "PIDs 1 and 2 should not match");
let stopExpectNoProcess = expectNoProcess();
yield BrowserTestUtils.browserLoaded(aBrowser);
// Switch to about:blank, so we can navigate back
yield ContentTask.spawn(aBrowser, null, () => {
content.document.location = "about:blank";
});
yield BrowserTestUtils.browserLoaded(aBrowser);
let pid3 = yield getPID(aBrowser);
is(pid2, pid3, "PIDs 2 and 3 should match");
// Navigate back to the previous page, loading it from bfcache
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.window.history.back();
});
let pid4 = yield getPID(aBrowser);
isnot(pid1, pid4, "PID 4 shouldn't match PID 1");
is(pid2, pid4, "PID 4 should match PID 2");
stopExpectNoProcess();
});
});

View file

@ -0,0 +1,76 @@
add_task(function *() {
var privWin = OpenBrowserWindow({private: true});
yield new privWin.Promise(resolve => {
privWin.addEventListener('load', function onLoad() {
privWin.removeEventListener('load', onLoad, false);
resolve();
});
});
var pubWin = OpenBrowserWindow({private: false});
yield new pubWin.Promise(resolve => {
pubWin.addEventListener('load', function onLoad() {
pubWin.removeEventListener('load', onLoad, false);
resolve();
});
});
var URL = "http://mochi.test:8888/browser/dom/tests/browser/page_privatestorageevent.html";
var privTab = privWin.gBrowser.addTab(URL);
yield BrowserTestUtils.browserLoaded(privWin.gBrowser.getBrowserForTab(privTab));
var privBrowser = gBrowser.getBrowserForTab(privTab);
var pubTab = pubWin.gBrowser.addTab(URL);
yield BrowserTestUtils.browserLoaded(pubWin.gBrowser.getBrowserForTab(pubTab));
var pubBrowser = gBrowser.getBrowserForTab(pubTab);
// Check if pubWin can see privWin's storage events
yield ContentTask.spawn(pubBrowser, null, function(opts) {
content.window.gotStorageEvent = false;
content.window.addEventListener('storage', ev => {
content.window.gotStorageEvent = true;
});
});
yield ContentTask.spawn(privBrowser, null, function(opts) {
content.window.localStorage['key'] = 'ablooabloo';
});
let pubSaw = yield ContentTask.spawn(pubBrowser, null, function(opts) {
return content.window.gotStorageEvent;
});
ok(!pubSaw, "pubWin shouldn't be able to see privWin's storage events");
yield ContentTask.spawn(privBrowser, null, function(opts) {
content.window.gotStorageEvent = false;
content.window.addEventListener('storage', ev => {
content.window.gotStorageEvent = true;
});
});
// Check if privWin can see pubWin's storage events
yield ContentTask.spawn(privBrowser, null, function(opts) {
content.window.gotStorageEvent = false;
content.window.addEventListener('storage', ev => {
content.window.gotStorageEvent = true;
});
});
yield ContentTask.spawn(pubBrowser, null, function(opts) {
content.window.localStorage['key'] = 'ablooabloo';
});
let privSaw = yield ContentTask.spawn(privBrowser, null, function(opts) {
return content.window.gotStorageEvent;
});
ok(!privSaw, "privWin shouldn't be able to see pubWin's storage events");
yield BrowserTestUtils.removeTab(privTab);
yield BrowserTestUtils.closeWindow(privWin);
yield BrowserTestUtils.removeTab(pubTab);
yield BrowserTestUtils.closeWindow(pubWin);
});

View file

@ -0,0 +1,4 @@
function test() {
is(window._content, window.content,
"_content needs to work, since extensions use it");
}

View file

@ -0,0 +1,202 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/*
We have three ways for content to open new windows:
1) window.open (with the default features)
2) window.open (with non-default features)
3) target="_blank" in <a> tags
We also have two prefs that modify our window opening behaviours:
1) browser.link.open_newwindow
This has a numeric value that allows us to set our window-opening behaviours from
content in three ways:
1) Open links that would normally open a new window in the current tab
2) Open links that would normally open a new window in a new window
3) Open links that would normally open a new window in a new tab (default)
2) browser.link.open_newwindow.restriction
This has a numeric value that allows us to fine tune the browser.link.open_newwindow
pref so that it can discriminate between different techniques for opening windows.
0) All things that open windows should behave according to browser.link.open_newwindow.
1) No things that open windows should behave according to browser.link.open_newwindow
(essentially rendering browser.link.open_newwindow inert).
2) Most things that open windows should behave according to browser.link.open_newwindow,
_except_ for window.open calls with the "feature" parameter. This will open in a new
window regardless of what browser.link.open_newwindow is set at. (default)
This file attempts to test each window opening technique against all possible settings for
each preference.
*/
Cu.import("resource://gre/modules/Task.jsm");
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kContentDoc = "http://www.example.com/browser/dom/tests/browser/test_new_window_from_content_child.html";
const kNewWindowPrefKey = "browser.link.open_newwindow";
const kNewWindowRestrictionPrefKey = "browser.link.open_newwindow.restriction";
const kSameTab = "same tab";
const kNewWin = "new window";
const kNewTab = "new tab";
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
requestLongerTimeout(3);
// The following "matrices" represent the result of content attempting to
// open a window with window.open with the default feature set. The key of
// the kWinOpenDefault object represents the value of browser.link.open_newwindow.
// The value for each key is an array that represents the result (either opening
// the link in the same tab, a new window, or a new tab), where the index of each
// result maps to the browser.link.open_newwindow.restriction pref. I've tried
// to illustrate this more clearly in the kWinOpenDefault object.
const kWinOpenDefault = {
// open_newwindow.restriction
// 0 1 2
// open_newwindow
1: [kSameTab, kNewWin, kSameTab],
2: [kNewWin, kNewWin, kNewWin],
3: [kNewTab, kNewWin, kNewTab],
};
const kWinOpenNonDefault = {
1: [kSameTab, kNewWin, kNewWin],
2: [kNewWin, kNewWin, kNewWin],
3: [kNewTab, kNewWin, kNewWin],
};
const kTargetBlank = {
1: [kSameTab, kSameTab, kSameTab],
2: [kNewWin, kNewWin, kNewWin],
3: [kNewTab, kNewTab, kNewTab],
};
// We'll be changing these preferences a lot, so we'll stash their original
// values and make sure we restore them at the end of the test.
var originalNewWindowPref = Services.prefs.getIntPref(kNewWindowPrefKey);
var originalNewWindowRestrictionPref =
Services.prefs.getIntPref(kNewWindowRestrictionPrefKey);
registerCleanupFunction(function() {
Services.prefs.setIntPref(kNewWindowPrefKey, originalNewWindowPref);
Services.prefs.setIntPref(kNewWindowRestrictionPrefKey,
originalNewWindowRestrictionPref);
});
/**
* For some expectation when a link is clicked, creates and
* returns a Promise that resolves when that expectation is
* fulfilled. For example, aExpectation might be kSameTab, which
* will cause this function to return a Promise that resolves when
* the current tab attempts to browse to about:blank.
*
* This function also takes care of cleaning up once the result has
* occurred - for example, if a new window was opened, this function
* closes it before resolving.
*
* @param aBrowser the <xul:browser> with the test document
* @param aExpectation one of kSameTab, kNewWin, or kNewTab.
* @return a Promise that resolves when the expectation is fulfilled,
* and cleaned up after.
*/
function prepareForResult(aBrowser, aExpectation) {
let expectedSpec = kContentDoc.replace(/[^\/]*$/, "dummy.html");
switch(aExpectation) {
case kSameTab:
return Task.spawn(function*() {
yield BrowserTestUtils.browserLoaded(aBrowser);
is(aBrowser.currentURI.spec, expectedSpec, "Should be at dummy.html");
// Now put the browser back where it came from
yield BrowserTestUtils.loadURI(aBrowser, kContentDoc);
yield BrowserTestUtils.browserLoaded(aBrowser);
});
break;
case kNewWin:
return Task.spawn(function*() {
let newWin = yield BrowserTestUtils.waitForNewWindow();
let newBrowser = newWin.gBrowser.selectedBrowser;
yield BrowserTestUtils.browserLoaded(newBrowser);
is(newBrowser.currentURI.spec, expectedSpec, "Should be at dummy.html");
yield BrowserTestUtils.closeWindow(newWin);
});
break;
case kNewTab:
return Task.spawn(function*() {
let newTab = yield BrowserTestUtils.waitForNewTab(gBrowser);
is(newTab.linkedBrowser.currentURI.spec, expectedSpec,
"Should be at dummy.html");
yield BrowserTestUtils.removeTab(newTab);
});
break;
default:
ok(false, "prepareForResult can't handle an expectation of " + aExpectation)
return;
}
return deferred.promise;
}
/**
* Ensure that clicks on a link with ID aLinkID cause us to
* perform as specified in the supplied aMatrix (kWinOpenDefault,
* for example).
*
* @param aLinkSelector a selector for the link within the testing page to click.
* @param aMatrix a testing matrix for the
* browser.link.open_newwindow and browser.link.open_newwindow.restriction
* prefs to test against. See kWinOpenDefault for an example.
*/
function testLinkWithMatrix(aLinkSelector, aMatrix) {
return BrowserTestUtils.withNewTab({
gBrowser,
url: kContentDoc,
}, function*(browser) {
// This nested for-loop is unravelling the matrix const
// we set up, and gives us three things through each tick
// of the inner loop:
// 1) newWindowPref: a browser.link.open_newwindow pref to try
// 2) newWindowRestPref: a browser.link.open_newwindow.restriction pref to try
// 3) expectation: what we expect the click outcome on this link to be,
// which will either be kSameTab, kNewWin or kNewTab.
for (let newWindowPref in aMatrix) {
let expectations = aMatrix[newWindowPref];
for (let i = 0; i < expectations.length; ++i) {
let newWindowRestPref = i;
let expectation = expectations[i];
Services.prefs.setIntPref("browser.link.open_newwindow", newWindowPref);
Services.prefs.setIntPref("browser.link.open_newwindow.restriction", newWindowRestPref);
info("Clicking on " + aLinkSelector);
info("Testing with browser.link.open_newwindow = " + newWindowPref + " and " +
"browser.link.open_newwindow.restriction = " + newWindowRestPref);
info("Expecting: " + expectation);
let resultPromise = prepareForResult(browser, expectation);
BrowserTestUtils.synthesizeMouseAtCenter(aLinkSelector, {}, browser);
yield resultPromise;
info("Got expectation: " + expectation);
}
}
});
}
add_task(function* test_window_open_with_defaults() {
yield testLinkWithMatrix("#winOpenDefault", kWinOpenDefault);
});
add_task(function* test_window_open_with_non_defaults() {
yield testLinkWithMatrix("#winOpenNonDefault", kWinOpenNonDefault);
});
add_task(function* test_window_open_dialog() {
yield testLinkWithMatrix("#winOpenDialog", kWinOpenNonDefault);
});
add_task(function* test_target__blank() {
yield testLinkWithMatrix("#targetBlank", kTargetBlank);
});

View file

@ -0,0 +1,224 @@
// Tests that toolbars have proper visibility when opening a new window
// in either content or chrome context.
const ROOT = "http://www.example.com/browser/dom/tests/browser/";
const CONTENT_PAGE = ROOT + "test_new_window_from_content_child.html";
const TARGET_PAGE = ROOT + "dummy.html";
/**
* This function retrieves the visibility state of the toolbars of a
* window within the content context.
*
* @param aBrowser (<xul:browser>)
* The browser to query for toolbar visibility states
* @returns Promise
* A promise that resolves when the toolbar state is retrieved
* within the content context, which value is an object that holds
* the visibility state of the toolbars
*/
function getToolbarsFromBrowserContent(aBrowser) {
return ContentTask.spawn(aBrowser, {}, function*() {
return {
toolbar: content.toolbar.visible,
menubar: content.menubar.visible,
personalbar: content.personalbar.visible,
statusbar: content.statusbar.visible,
locationbar: content.locationbar.visible,
};
});
}
/**
* This function retrieves the visibility state of the toolbars of a
* window within the chrome context.
*
* @param win
* the chrome privileged window
* @returns object
* an object that holds the visibility state of the toolbars
*/
function getToolbarsFromWindowChrome(win) {
return {
toolbar: win.toolbar.visible,
menubar: win.menubar.visible,
personalbar: win.personalbar.visible,
statusbar: win.statusbar.visible,
locationbar: win.locationbar.visible,
}
}
/**
* Tests toolbar visibility when opening a window with default parameters.
*
* @param toolbars
* the visibility state of the toolbar elements
*/
function testDefaultToolbars(toolbars) {
ok(toolbars.locationbar,
"locationbar should be visible on default window.open()");
ok(toolbars.menubar,
"menubar be visible on default window.open()");
ok(toolbars.personalbar,
"personalbar should be visible on default window.open()");
ok(toolbars.statusbar,
"statusbar should be visible on default window.open()");
ok(toolbars.toolbar,
"toolbar should be visible on default window.open()");
}
/**
* Tests toolbar visibility when opening a window with non default parameters
* on the content context.
*
* Ensure that locationbar can't be hidden in the content context, see bug#337344.
*
* @param toolbars
* the visibility state of the toolbar elements
*/
function testNonDefaultContentToolbars(toolbars) {
// Locationbar should always be visible on content context
ok(toolbars.locationbar,
"locationbar should be visible even with location=no");
ok(!toolbars.menubar,
"menubar shouldn't be visible when menubar=no");
ok(!toolbars.personalbar,
"personalbar shouldn't be visible when personalbar=no");
// statusbar will report visible=true even when it's hidden because of bug#55820
todo(!toolbars.statusbar,
"statusbar shouldn't be visible when status=no");
ok(!toolbars.toolbar,
"toolbar shouldn't be visible when toolbar=no");
}
/**
* Tests toolbar visibility when opening a window with non default parameters
* on the chrome context.
*
* @param toolbars
* the visibility state of the toolbar elements
*/
function testNonDefaultChromeToolbars(toolbars) {
// None of the toolbars should be visible if hidden with chrome privileges
ok(!toolbars.locationbar,
"locationbar should not be visible with location=no");
ok(!toolbars.menubar,
"menubar should not be visible with menubar=no");
ok(!toolbars.personalbar,
"personalbar should not be visible with personalbar=no");
ok(!toolbars.statusbar,
"statusbar should not be visible with status=no");
ok(!toolbars.toolbar,
"toolbar should not be visible with toolbar=no");
}
/**
* Ensure that toolbars of a window opened in the content context have the
* correct visibility.
*
* A window opened with default parameters should have all toolbars visible.
*
* A window opened with "location=no, personalbar=no, toolbar=no, scrollbars=no,
* menubar=no, status=no", should only have location visible.
*/
add_task(function*() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: CONTENT_PAGE,
}, function*(browser) {
// First, call the default window.open() which will open a new tab
let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
yield BrowserTestUtils.synthesizeMouseAtCenter("#winOpenDefault", {}, browser);
let tab = yield newTabPromise;
// Check that all toolbars are visible
let toolbars = yield getToolbarsFromBrowserContent(gBrowser.selectedBrowser);
testDefaultToolbars(toolbars);
// Cleanup
yield BrowserTestUtils.removeTab(tab);
// Now let's open a window with toolbars hidden
let winPromise = BrowserTestUtils.waitForNewWindow();
yield BrowserTestUtils.synthesizeMouseAtCenter("#winOpenNonDefault", {}, browser);
let popupWindow = yield winPromise;
let popupBrowser = popupWindow.gBrowser.selectedBrowser;
yield BrowserTestUtils.browserLoaded(popupBrowser);
// Test toolbars visibility
let popupToolbars = yield getToolbarsFromBrowserContent(popupBrowser);
testNonDefaultContentToolbars(popupToolbars);
// Ensure that chrome toolbars agree with content
let chromeToolbars = getToolbarsFromWindowChrome(popupWindow);
testNonDefaultContentToolbars(chromeToolbars);
// Close the new window
yield BrowserTestUtils.closeWindow(popupWindow);
});
});
/**
* Ensure that toolbars of a window opened to about:blank in the content context
* have the correct visibility.
*
* A window opened with "location=no, personalbar=no, toolbar=no, scrollbars=no,
* menubar=no, status=no", should only have location visible.
*/
add_task(function*() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: CONTENT_PAGE,
}, function*(browser) {
// Open a blank window with toolbars hidden
let winPromise = BrowserTestUtils.waitForNewWindow();
yield BrowserTestUtils.synthesizeMouseAtCenter("#winOpenNoURLNonDefault", {}, browser);
let popupWindow = yield winPromise;
// No need to wait for this window to load, since it's loading about:blank
let popupBrowser = popupWindow.gBrowser.selectedBrowser;
let popupToolbars = yield getToolbarsFromBrowserContent(popupBrowser);
testNonDefaultContentToolbars(popupToolbars);
// Ensure that chrome toolbars agree with content
let chromeToolbars = getToolbarsFromWindowChrome(popupWindow);
testNonDefaultContentToolbars(chromeToolbars);
// Close the new window
yield BrowserTestUtils.closeWindow(popupWindow);
});
});
/**
* Ensure that toolbars of a window opened in the chrome context have the
* correct visibility.
*
* A window opened with default parameters should have all toolbars visible.
*
* A window opened with "location=no, personalbar=no, toolbar=no, scrollbars=no,
* menubar=no, status=no", should not have any toolbar visible.
*/
add_task(function* () {
// First open a default window from this chrome context
let defaultWindowPromise = BrowserTestUtils.waitForNewWindow();
window.open(TARGET_PAGE, "_blank");
let defaultWindow = yield defaultWindowPromise;
// Check that all toolbars are visible
let toolbars = getToolbarsFromWindowChrome(defaultWindow);
testDefaultToolbars(toolbars);
// Now lets open a window with toolbars hidden from this chrome context
let features = "location=no, personalbar=no, toolbar=no, scrollbars=no, menubar=no, status=no";
let popupWindowPromise = BrowserTestUtils.waitForNewWindow();
window.open(TARGET_PAGE, "_blank", features);
let popupWindow = yield popupWindowPromise;
// Test none of the tooolbars are visible
let hiddenToolbars = getToolbarsFromWindowChrome(popupWindow);
testNonDefaultChromeToolbars(hiddenToolbars);
// Cleanup
yield BrowserTestUtils.closeWindow(defaultWindow);
yield BrowserTestUtils.closeWindow(popupWindow);
});

View file

@ -0,0 +1,50 @@
// This code is evaluated in a sandbox courtesy of toSource();
var sandboxCode = (function() {
let req = new XMLHttpRequest();
req.open("GET", "http://mochi.test:8888/browser/dom/tests/browser/", true);
req.onreadystatechange = function() {
if (req.readyState === 4) {
// If we get past the problem above, we end up with a req.status of zero
// (ie, blocked due to CORS) even though we are fetching from the same
// origin as the window itself.
let result;
if (req.status != 200) {
result = "ERROR: got request status of " + req.status;
} else if (req.responseText.length == 0) {
result = "ERROR: got zero byte response text";
} else {
result = "ok";
}
postMessage({result: result}, "*");
}
};
req.send(null);
}).toSource() + "();";
function test() {
waitForExplicitFinish();
let appShell = Cc["@mozilla.org/appshell/appShellService;1"]
.getService(Ci.nsIAppShellService);
let doc = appShell.hiddenDOMWindow.document;
let frame = doc.createElement("iframe");
frame.setAttribute("type", "content");
frame.setAttribute("src", "http://mochi.test:8888/browser/dom/tests/browser/browser_xhr_sandbox.js");
frame.addEventListener("load", function () {
let workerWindow = frame.contentWindow;
workerWindow.addEventListener("message", function(evt) {
is(evt.data.result, "ok", "check the sandbox code was happy");
frame.remove();
finish();
}, true);
let sandbox = new Cu.Sandbox(workerWindow);
// inject some functions from the window into the sandbox.
// postMessage so the async code in the sandbox can report a result.
sandbox.importFunction(workerWindow.postMessage.bind(workerWindow), "postMessage");
sandbox.importFunction(workerWindow.XMLHttpRequest, "XMLHttpRequest");
Cu.evalInSandbox(sandboxCode, sandbox, "1.8");
}, true);
let container = doc.body ? doc.body : doc.documentElement;
container.appendChild(frame);
}

View file

@ -0,0 +1,9 @@
<html>
<head>
<title>Dummy test page</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
</head>
<body>
<p>Dummy test page</p>
</body>
</html>

View file

@ -0,0 +1,17 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Geolocation incomplete position leak test</title>
<script type="text/javascript">
function successCallback(position) {}
function errorCallback() {}
function init() {
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
}
</script>
</head>
<body onload="init()">
</body>
</html>

View file

@ -0,0 +1,5 @@
<html>
<body>
la la la la
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<script type="text/javascript">
var result = null;
function handlePosition(position) {
result.innerHTML = position.coords.latitude + " " + position.coords.longitude;
}
function handleError(error) {
result.innerHTML = error.message;
}
function init() {
result = document.getElementById("result");
if (navigator.geolocation)
navigator.geolocation.getCurrentPosition(handlePosition, handleError);
else
result.innerHTML = "not available";
}
</script>
</head>
<body onload="init()">
<p id="result">location...</p>
</body>
</html>

View file

@ -0,0 +1,75 @@
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US"><head>
<title>Console API test page</title>
<script type="text/javascript">
window.foobar585956c = function(a) {
console.trace();
return a+"c";
};
function foobar585956b(a) {
return foobar585956c(a+"b");
}
function foobar585956a(omg) {
return foobar585956b(omg + "a");
}
function foobar646025(omg) {
console.log(omg, "o", "d");
}
function startTimer(timer) {
console.time(timer);
}
function stopTimer(timer) {
console.timeEnd(timer);
}
function namelessTimer() {
console.time();
console.timeEnd();
}
function test() {
var str = "Test Message."
console.foobar(str); // if this throws, we don't execute following funcs
console.log(str);
console.info(str);
console.warn(str);
console.error(str);
console.exception(str);
console.assert(false, str);
console.count(str);
}
function testGroups() {
console.groupCollapsed("a", "group");
console.group("b", "group");
console.groupEnd("b", "group");
}
function nativeCallback() {
new Promise(function(resolve, reject) { resolve(42); }).then(console.log.bind(console));
}
function timeStamp(val) {
console.timeStamp(val);
}
</script>
</head>
<body>
<h1>Console API Test Page</h1>
<button onclick="test();">Log stuff</button>
<button id="test-trace" onclick="foobar585956a('omg');">Test trace</button>
<button id="test-location" onclick="foobar646025('omg');">Test location</button>
<button id="test-nativeCallback" onclick="nativeCallback();">Test nativeCallback</button>
<button id="test-groups" onclick="testGroups();">Test groups</button>
<button id="test-time" onclick="startTimer('foo');">Test time</button>
<button id="test-timeEnd" onclick="stopTimer('foo');">Test timeEnd</button>
<button id="test-namelessTimer" onclick="namelessTimer();">Test namelessTimer</button>
<button id="test-timeStamp" onclick="timeStamp('!!!')">Test timeStamp</button>
<button id="test-emptyTimeStamp" onclick="timeStamp();">Test emptyTimeStamp</button>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Console API test bug 1004814</title>
</head>
<body>
<script>
var w = new Worker('worker_bug1004814.js');
w.postMessage(true);
</script>
</body>
</html>

View file

@ -0,0 +1,4 @@
<!doctype html>
<html>
<body>Loaded in a new process!</body>
</html>

View file

@ -0,0 +1 @@
Large-Allocation: 0

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Test popup window opening behaviour</title>
</head>
<body>
<p><a id="winOpenDefault" href="#" onclick="return openWindow();">Open a new window via window.open with default features.</a></p>
<p><a id="winOpenNonDefault" href="#" onclick="return openWindow('resizable=no, location=no, personalbar=no, toolbar=no, scrollbars=no, menubar=no, status=no, directories=no, height=100, width=500');">Open a new window via window.open with non-default features.</a></p>
<p><a id="winOpenDialog" href="#" onclick="return openWindow('dialog=yes');">Open a new window via window.open with dialog=1.</a></p>
<p><a id="winOpenNoURLNonDefault" href="#" onclick="return openBlankWindow('location=no, toolbar=no, height=100, width=100');">Open a blank new window via window.open with non-default features.</a></p>
<p><a id="targetBlank" href="dummy.html" target="_blank">Open a new window via target="_blank".</a></p>
</body>
</html>
<script>
function openWindow(aFeatures="") {
window.open("dummy.html", "_blank", aFeatures);
return false;
}
function openBlankWindow(aFeatures="") {
window.open("", "_blank", aFeatures);
return false;
}
</script>

View file

@ -0,0 +1,6 @@
onmessage = function(evt) {
console.time('bug1004814');
setTimeout(function() {
console.timeEnd('bug1004814');
}, 200);
}