Bug 1561435 - Format docshell/, a=automatic-formatting

# ignore-this-changeset

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

--HG--
extra : source : b08f475f1140b9e650b316ee2813c13ec9947678
This commit is contained in:
Victor Porof 2019-07-05 09:59:46 +02:00
parent a6c398f85c
commit bcdc3a9567
83 changed files with 3727 additions and 2043 deletions

View file

@ -45,7 +45,6 @@ module.exports = {
"overrides": [{ "overrides": [{
"files": [ "files": [
"devtools/**", "devtools/**",
"docshell/**",
"dom/**", "dom/**",
"editor/**", "editor/**",
"extensions/**", "extensions/**",

View file

@ -40,7 +40,6 @@ toolkit/components/telemetry/datareporting-prefs.js
toolkit/components/telemetry/healthreport-prefs.js toolkit/components/telemetry/healthreport-prefs.js
# Ignore all top-level directories for now. # Ignore all top-level directories for now.
docshell/**
dom/** dom/**
editor/** editor/**
extensions/** extensions/**

View file

@ -1,267 +1,282 @@
// Error url MUST be formatted like this: // Error url MUST be formatted like this:
// moz-neterror:page?e=error&u=url&d=desc // moz-neterror:page?e=error&u=url&d=desc
// //
// or optionally, to specify an alternate CSS class to allow for // or optionally, to specify an alternate CSS class to allow for
// custom styling and favicon: // custom styling and favicon:
// //
// moz-neterror:page?e=error&u=url&s=classname&d=desc // moz-neterror:page?e=error&u=url&s=classname&d=desc
// Note that this file uses document.documentURI to get // Note that this file uses document.documentURI to get
// the URL (with the format from above). This is because // the URL (with the format from above). This is because
// document.location.href gets the current URI off the docshell, // document.location.href gets the current URI off the docshell,
// which is the URL displayed in the location bar, i.e. // which is the URL displayed in the location bar, i.e.
// the URI that the user attempted to load. // the URI that the user attempted to load.
function getErrorCode() { function getErrorCode() {
var url = document.documentURI; var url = document.documentURI;
var error = url.search(/e\=/); var error = url.search(/e\=/);
var duffUrl = url.search(/\&u\=/); var duffUrl = url.search(/\&u\=/);
return decodeURIComponent(url.slice(error + 2, duffUrl)); return decodeURIComponent(url.slice(error + 2, duffUrl));
} }
function getCSSClass() { function getCSSClass() {
var url = document.documentURI; var url = document.documentURI;
var matches = url.match(/s\=([^&]+)\&/); var matches = url.match(/s\=([^&]+)\&/);
// s is optional, if no match just return nothing // s is optional, if no match just return nothing
if (!matches || matches.length < 2) if (!matches || matches.length < 2) {
return ""; return "";
}
// parenthetical match is the second entry // parenthetical match is the second entry
return decodeURIComponent(matches[1]); return decodeURIComponent(matches[1]);
} }
function getDescription() { function getDescription() {
var url = document.documentURI; var url = document.documentURI;
var desc = url.search(/d\=/); var desc = url.search(/d\=/);
// desc == -1 if not found; if so, return an empty string // desc == -1 if not found; if so, return an empty string
// instead of what would turn out to be portions of the URI // instead of what would turn out to be portions of the URI
if (desc == -1) if (desc == -1) {
return ""; return "";
}
return decodeURIComponent(url.slice(desc + 2)); return decodeURIComponent(url.slice(desc + 2));
} }
function retryThis(buttonEl) { function retryThis(buttonEl) {
// Note: The application may wish to handle switching off "offline mode" // Note: The application may wish to handle switching off "offline mode"
// before this event handler runs, but using a capturing event handler. // before this event handler runs, but using a capturing event handler.
// Session history has the URL of the page that failed // Session history has the URL of the page that failed
// to load, not the one of the error page. So, just call // to load, not the one of the error page. So, just call
// reload(), which will also repost POST data correctly. // reload(), which will also repost POST data correctly.
try { try {
location.reload(); location.reload();
} catch (e) { } catch (e) {
// We probably tried to reload a URI that caused an exception to // We probably tried to reload a URI that caused an exception to
// occur; e.g. a nonexistent file. // occur; e.g. a nonexistent file.
} }
buttonEl.disabled = true; buttonEl.disabled = true;
} }
function initPage() { function initPage() {
var err = getErrorCode(); var err = getErrorCode();
// if it's an unknown error or there's no title or description // if it's an unknown error or there's no title or description
// defined, get the generic message // defined, get the generic message
var errTitle = document.getElementById("et_" + err); var errTitle = document.getElementById("et_" + err);
var errDesc = document.getElementById("ed_" + err); var errDesc = document.getElementById("ed_" + err);
if (!errTitle || !errDesc) { if (!errTitle || !errDesc) {
errTitle = document.getElementById("et_generic"); errTitle = document.getElementById("et_generic");
errDesc = document.getElementById("ed_generic"); errDesc = document.getElementById("ed_generic");
} }
var title = document.getElementById("errorTitleText"); var title = document.getElementById("errorTitleText");
if (title) { if (title) {
title.parentNode.replaceChild(errTitle, title); title.parentNode.replaceChild(errTitle, title);
// change id to the replaced child's id so styling works // change id to the replaced child's id so styling works
errTitle.id = "errorTitleText"; errTitle.id = "errorTitleText";
} }
var sd = document.getElementById("errorShortDescText"); var sd = document.getElementById("errorShortDescText");
if (sd) if (sd) {
sd.textContent = getDescription(); sd.textContent = getDescription();
}
var ld = document.getElementById("errorLongDesc"); var ld = document.getElementById("errorLongDesc");
if (ld) { if (ld) {
ld.parentNode.replaceChild(errDesc, ld); ld.parentNode.replaceChild(errDesc, ld);
// change id to the replaced child's id so styling works // change id to the replaced child's id so styling works
errDesc.id = "errorLongDesc"; errDesc.id = "errorLongDesc";
} }
// remove undisplayed errors to avoid bug 39098 // remove undisplayed errors to avoid bug 39098
var errContainer = document.getElementById("errorContainer"); var errContainer = document.getElementById("errorContainer");
errContainer.remove(); errContainer.remove();
var className = getCSSClass(); var className = getCSSClass();
if (className && className != "expertBadCert") { if (className && className != "expertBadCert") {
// Associate a CSS class with the root of the page, if one was passed in, // Associate a CSS class with the root of the page, if one was passed in,
// to allow custom styling. // to allow custom styling.
// Not "expertBadCert" though, don't want to deal with the favicon // Not "expertBadCert" though, don't want to deal with the favicon
document.documentElement.className = className; document.documentElement.className = className;
// Also, if they specified a CSS class, they must supply their own // Also, if they specified a CSS class, they must supply their own
// favicon. In order to trigger the browser to repaint though, we // favicon. In order to trigger the browser to repaint though, we
// need to remove/add the link element. // need to remove/add the link element.
var favicon = document.getElementById("favicon"); var favicon = document.getElementById("favicon");
var faviconParent = favicon.parentNode; var faviconParent = favicon.parentNode;
faviconParent.removeChild(favicon); faviconParent.removeChild(favicon);
favicon.setAttribute("href", "chrome://global/skin/icons/" + className + "_favicon.png"); favicon.setAttribute(
faviconParent.appendChild(favicon); "href",
} "chrome://global/skin/icons/" + className + "_favicon.png"
if (className == "expertBadCert") { );
showSecuritySection(); faviconParent.appendChild(favicon);
} }
if (className == "expertBadCert") {
showSecuritySection();
}
if (err == "remoteXUL") { if (err == "remoteXUL") {
// Remove the "Try again" button for remote XUL errors given that // Remove the "Try again" button for remote XUL errors given that
// it is useless. // it is useless.
document.getElementById("errorTryAgain").style.display = "none"; document.getElementById("errorTryAgain").style.display = "none";
} }
if (err == "cspBlocked") { if (err == "cspBlocked") {
// Remove the "Try again" button for CSP violations, since it's // Remove the "Try again" button for CSP violations, since it's
// almost certainly useless. (Bug 553180) // almost certainly useless. (Bug 553180)
document.getElementById("errorTryAgain").style.display = "none"; document.getElementById("errorTryAgain").style.display = "none";
} }
if (err == "nssBadCert") { if (err == "nssBadCert") {
// Remove the "Try again" button for security exceptions, since it's // Remove the "Try again" button for security exceptions, since it's
// almost certainly useless. // almost certainly useless.
document.getElementById("errorTryAgain").style.display = "none"; document.getElementById("errorTryAgain").style.display = "none";
document.getElementById("errorPageContainer").setAttribute("class", "certerror"); document
addDomainErrorLink(); .getElementById("errorPageContainer")
} else { .setAttribute("class", "certerror");
// Remove the override block for non-certificate errors. CSS-hiding addDomainErrorLink();
// isn't good enough here, because of bug 39098 } else {
var secOverride = document.getElementById("securityOverrideDiv"); // Remove the override block for non-certificate errors. CSS-hiding
secOverride.remove(); // isn't good enough here, because of bug 39098
} var secOverride = document.getElementById("securityOverrideDiv");
secOverride.remove();
}
if (err == "inadequateSecurityError" || err == "blockedByPolicy") { if (err == "inadequateSecurityError" || err == "blockedByPolicy") {
// Remove the "Try again" button from pages that don't need it. // Remove the "Try again" button from pages that don't need it.
// For HTTP/2 inadequate security or pages blocked by policy, trying // For HTTP/2 inadequate security or pages blocked by policy, trying
// again won't help. // again won't help.
document.getElementById("errorTryAgain").style.display = "none"; document.getElementById("errorTryAgain").style.display = "none";
var container = document.getElementById("errorLongDesc"); var container = document.getElementById("errorLongDesc");
for (var span of container.querySelectorAll("span.hostname")) { for (var span of container.querySelectorAll("span.hostname")) {
span.textContent = document.location.hostname; span.textContent = document.location.hostname;
} }
} }
if (document.getElementById("errorTryAgain").style.display != "none") if (document.getElementById("errorTryAgain").style.display != "none") {
addAutofocus("errorTryAgain"); addAutofocus("errorTryAgain");
} }
}
function showSecuritySection() { function showSecuritySection() {
// Swap link out, content in // Swap link out, content in
document.getElementById("securityOverrideContent").style.display = ""; document.getElementById("securityOverrideContent").style.display = "";
document.getElementById("securityOverrideLink").style.display = "none"; document.getElementById("securityOverrideLink").style.display = "none";
} }
/* In the case of SSL error pages about domain mismatch, see if /* In the case of SSL error pages about domain mismatch, see if
we can hyperlink the user to the correct site. We don't want we can hyperlink the user to the correct site. We don't want
to do this generically since it allows MitM attacks to redirect to do this generically since it allows MitM attacks to redirect
users to a site under attacker control, but in certain cases users to a site under attacker control, but in certain cases
it is safe (and helpful!) to do so. Bug 402210 it is safe (and helpful!) to do so. Bug 402210
*/ */
function addDomainErrorLink() { function addDomainErrorLink() {
// Rather than textContent, we need to treat description as HTML // Rather than textContent, we need to treat description as HTML
var sd = document.getElementById("errorShortDescText"); var sd = document.getElementById("errorShortDescText");
if (sd) { if (sd) {
var desc = getDescription(); var desc = getDescription();
// sanitize description text - see bug 441169 // sanitize description text - see bug 441169
// First, find the index of the <a> tag we care about, being careful not to // First, find the index of the <a> tag we care about, being careful not to
// use an over-greedy regex // use an over-greedy regex
var re = /<a id="cert_domain_link" title="([^"]+)">/; var re = /<a id="cert_domain_link" title="([^"]+)">/;
var result = re.exec(desc); var result = re.exec(desc);
if (!result) if (!result) {
return; return;
}
// Remove sd's existing children // Remove sd's existing children
sd.textContent = ""; sd.textContent = "";
// Everything up to the link should be text content // Everything up to the link should be text content
sd.appendChild(document.createTextNode(desc.slice(0, result.index))); sd.appendChild(document.createTextNode(desc.slice(0, result.index)));
// Now create the link itself // Now create the link itself
var anchorEl = document.createElement("a"); var anchorEl = document.createElement("a");
anchorEl.setAttribute("id", "cert_domain_link"); anchorEl.setAttribute("id", "cert_domain_link");
anchorEl.setAttribute("title", result[1]); anchorEl.setAttribute("title", result[1]);
anchorEl.appendChild(document.createTextNode(result[1])); anchorEl.appendChild(document.createTextNode(result[1]));
sd.appendChild(anchorEl); sd.appendChild(anchorEl);
// Finally, append text for anything after the closing </a> // Finally, append text for anything after the closing </a>
sd.appendChild(document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length))); sd.appendChild(
} document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length))
);
}
var link = document.getElementById("cert_domain_link"); var link = document.getElementById("cert_domain_link");
if (!link) if (!link) {
return; return;
}
var okHost = link.getAttribute("title"); var okHost = link.getAttribute("title");
var thisHost = document.location.hostname; var thisHost = document.location.hostname;
var proto = document.location.protocol; var proto = document.location.protocol;
// If okHost is a wildcard domain ("*.example.com") let's // If okHost is a wildcard domain ("*.example.com") let's
// use "www" instead. "*.example.com" isn't going to // use "www" instead. "*.example.com" isn't going to
// get anyone anywhere useful. bug 432491 // get anyone anywhere useful. bug 432491
okHost = okHost.replace(/^\*\./, "www."); okHost = okHost.replace(/^\*\./, "www.");
/* case #1: /* case #1:
* example.com uses an invalid security certificate. * example.com uses an invalid security certificate.
* *
* The certificate is only valid for www.example.com * The certificate is only valid for www.example.com
* *
* Make sure to include the "." ahead of thisHost so that * Make sure to include the "." ahead of thisHost so that
* a MitM attack on paypal.com doesn't hyperlink to "notpaypal.com" * a MitM attack on paypal.com doesn't hyperlink to "notpaypal.com"
* *
* We'd normally just use a RegExp here except that we lack a * We'd normally just use a RegExp here except that we lack a
* library function to escape them properly (bug 248062), and * library function to escape them properly (bug 248062), and
* domain names are famous for having '.' characters in them, * domain names are famous for having '.' characters in them,
* which would allow spurious and possibly hostile matches. * which would allow spurious and possibly hostile matches.
*/ */
if (endsWith(okHost, "." + thisHost)) if (endsWith(okHost, "." + thisHost)) {
link.href = proto + okHost; link.href = proto + okHost;
}
/* case #2: /* case #2:
* browser.garage.maemo.org uses an invalid security certificate. * browser.garage.maemo.org uses an invalid security certificate.
* *
* The certificate is only valid for garage.maemo.org * The certificate is only valid for garage.maemo.org
*/ */
if (endsWith(thisHost, "." + okHost)) if (endsWith(thisHost, "." + okHost)) {
link.href = proto + okHost; link.href = proto + okHost;
} }
}
function endsWith(haystack, needle) { function endsWith(haystack, needle) {
return haystack.slice(-needle.length) == needle; return haystack.slice(-needle.length) == needle;
} }
/* Only do autofocus if we're the toplevel frame; otherwise we /* Only do autofocus if we're the toplevel frame; otherwise we
don't want to call attention to ourselves! The key part is don't want to call attention to ourselves! The key part is
that autofocus happens on insertion into the tree, so we that autofocus happens on insertion into the tree, so we
can remove the button, add @autofocus, and reinsert the can remove the button, add @autofocus, and reinsert the
button. button.
*/ */
function addAutofocus(buttonId, position = "afterbegin") { function addAutofocus(buttonId, position = "afterbegin") {
if (window.top == window) { if (window.top == window) {
var button = document.getElementById(buttonId); var button = document.getElementById(buttonId);
var parent = button.parentNode; var parent = button.parentNode;
button.remove(); button.remove();
button.setAttribute("autofocus", "true"); button.setAttribute("autofocus", "true");
parent.insertAdjacentElement(position, button); parent.insertAdjacentElement(position, button);
} }
} }
let errorTryAgain = document.getElementById("errorTryAgain"); let errorTryAgain = document.getElementById("errorTryAgain");
errorTryAgain.addEventListener("click", function() { errorTryAgain.addEventListener("click", function() {
retryThis(this); retryThis(this);
}); });
// Note: It is important to run the script this way, instead of using // Note: It is important to run the script this way, instead of using
// an onload handler. This is because error pages are loaded as // an onload handler. This is because error pages are loaded as
// LOAD_BACKGROUND, which means that onload handlers will not be executed. // LOAD_BACKGROUND, which means that onload handlers will not be executed.
initPage(); initPage();

View file

@ -6,75 +6,69 @@
const URL = "about:blank"; const URL = "about:blank";
async function getBrowsingContextId(browser, id) { async function getBrowsingContextId(browser, id) {
return ContentTask.spawn( return ContentTask.spawn(browser, id, async function(id) {
browser, let contextId = content.window.docShell.browsingContext.id;
id,
async function(id) {
let contextId = content.window.docShell.browsingContext.id;
let frames = [content.window]; let frames = [content.window];
while (frames.length) { while (frames.length) {
let frame = frames.pop(); let frame = frames.pop();
let target = frame.document.getElementById(id); let target = frame.document.getElementById(id);
if (target) { if (target) {
contextId = target.docShell.browsingContext.id; contextId = target.docShell.browsingContext.id;
break; break;
}
frames = frames.concat(Array.from(frame.frames));
} }
return contextId; frames = frames.concat(Array.from(frame.frames));
}); }
return contextId;
});
} }
async function addFrame(browser, id, parentId) { async function addFrame(browser, id, parentId) {
return ContentTask.spawn( return ContentTask.spawn(browser, { parentId, id }, async function({
browser, parentId,
{parentId, id},
async function({ parentId, id }) {
let parent = null;
if (parentId) {
let frames = [content.window];
while (frames.length) {
let frame = frames.pop();
let target = frame.document.getElementById(parentId);
if (target) {
parent = target.contentWindow.document.body;
break;
}
frames = frames.concat(Array.from(frame.frames));
}
} else {
parent = content.document.body;
}
let frame = content.document.createElement("iframe");
frame.id = id || "";
frame.url = "about:blank";
parent.appendChild(frame);
return frame.contentWindow.docShell.browsingContext.id;
});
}
async function removeFrame(browser, id) {
return ContentTask.spawn(
browser,
id, id,
async function(id) { }) {
let parent = null;
if (parentId) {
let frames = [content.window]; let frames = [content.window];
while (frames.length) { while (frames.length) {
let frame = frames.pop(); let frame = frames.pop();
let target = frame.document.getElementById(id); let target = frame.document.getElementById(parentId);
if (target) { if (target) {
target.remove(); parent = target.contentWindow.document.body;
break; break;
} }
frames = frames.concat(Array.from(frame.frames)); frames = frames.concat(Array.from(frame.frames));
} }
}); } else {
parent = content.document.body;
}
let frame = content.document.createElement("iframe");
frame.id = id || "";
frame.url = "about:blank";
parent.appendChild(frame);
return frame.contentWindow.docShell.browsingContext.id;
});
}
async function removeFrame(browser, id) {
return ContentTask.spawn(browser, id, async function(id) {
let frames = [content.window];
while (frames.length) {
let frame = frames.pop();
let target = frame.document.getElementById(id);
if (target) {
target.remove();
break;
}
frames = frames.concat(Array.from(frame.frames));
}
});
} }
function getBrowsingContextById(id) { function getBrowsingContextById(id) {
@ -82,57 +76,76 @@ function getBrowsingContextById(id) {
} }
add_task(async function() { add_task(async function() {
await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function(
async function(browser) { browser
let topId = await getBrowsingContextId(browser, ""); ) {
let topContext = getBrowsingContextById(topId); let topId = await getBrowsingContextId(browser, "");
isnot(topContext, null); let topContext = getBrowsingContextById(topId);
is(topContext.parent, null); isnot(topContext, null);
is(topId, browser.browsingContext.id, "<browser> has the correct browsingContext"); is(topContext.parent, null);
is(
topId,
browser.browsingContext.id,
"<browser> has the correct browsingContext"
);
let id0 = await addFrame(browser, "frame0"); let id0 = await addFrame(browser, "frame0");
let browsingContext0 = getBrowsingContextById(id0); let browsingContext0 = getBrowsingContextById(id0);
isnot(browsingContext0, null); isnot(browsingContext0, null);
is(browsingContext0.parent, topContext); is(browsingContext0.parent, topContext);
let id1 = await addFrame(browser, "frame1", "frame0"); let id1 = await addFrame(browser, "frame1", "frame0");
let browsingContext1 = getBrowsingContextById(id1); let browsingContext1 = getBrowsingContextById(id1);
isnot(browsingContext1, null); isnot(browsingContext1, null);
is(browsingContext1.parent, browsingContext0); is(browsingContext1.parent, browsingContext0);
let id2 = await addFrame(browser, "frame2", "frame1"); let id2 = await addFrame(browser, "frame2", "frame1");
let browsingContext2 = getBrowsingContextById(id2); let browsingContext2 = getBrowsingContextById(id2);
isnot(browsingContext2, null); isnot(browsingContext2, null);
is(browsingContext2.parent, browsingContext1); is(browsingContext2.parent, browsingContext1);
await removeFrame(browser, "frame2"); await removeFrame(browser, "frame2");
is(browsingContext1.getChildren().indexOf(browsingContext2), -1); is(browsingContext1.getChildren().indexOf(browsingContext2), -1);
// TODO(farre): Handle browsingContext removal [see Bug 1486719]. // TODO(farre): Handle browsingContext removal [see Bug 1486719].
todo_isnot(browsingContext2.parent, browsingContext1); todo_isnot(browsingContext2.parent, browsingContext1);
}); });
}); });
add_task(async function() { add_task(async function() {
await BrowserTestUtils.withNewTab({ gBrowser, url: getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com") + "dummy_page.html" }, await BrowserTestUtils.withNewTab(
{
gBrowser,
url:
getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
) + "dummy_page.html",
},
async function(browser) { async function(browser) {
let path = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com"); let path = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
await ContentTask.spawn(browser, path, async function(path) { await ContentTask.spawn(browser, path, async function(path) {
function waitForMessage(command) { function waitForMessage(command) {
let r; let r;
let p = new Promise(resolve => { let p = new Promise(resolve => {
content.window.addEventListener("message", e => resolve({result: r, event: e}), content.window.addEventListener(
{once: true}); "message",
e => resolve({ result: r, event: e }),
{ once: true }
);
}); });
r = command(); r = command();
return p; return p;
} }
// Open a new window and wait for the message. // Open a new window and wait for the message.
let { result: win, event: e1 } = let { result: win, event: e1 } = await waitForMessage(_ =>
await waitForMessage( content.window.open(path + "onpageshow_message.html")
_ => content.window.open(path + "onpageshow_message.html")); );
is(e1.data, "pageshow"); is(e1.data, "pageshow");
@ -152,7 +165,8 @@ add_task(async function() {
// Navigate the window and wait for the message. // Navigate the window and wait for the message.
let { event: e2 } = await waitForMessage( let { event: e2 } = await waitForMessage(
_ => win.location = path + "onload_message.html"); _ => (win.location = path + "onload_message.html")
);
is(e2.data, "load"); is(e2.data, "load");
is(win.frames.length, 0, "Here there shouldn't be an iframe"); is(win.frames.length, 0, "Here there shouldn't be an iframe");
@ -165,15 +179,29 @@ add_task(async function() {
is(win.frames.length, 1, "And again there should be an iframe"); is(win.frames.length, 1, "And again there should be an iframe");
is(winDocShell, win.frames[0].docShell, "BF cache cached docshell"); is(winDocShell, win.frames[0].docShell, "BF cache cached docshell");
is(frameBC, win.frames[0].docShell.browsingContext, "BF cache cached BC"); is(
is(frameBC.id, win.frames[0].docShell.browsingContext.id, frameBC,
"BF cached BC's have same id"); win.frames[0].docShell.browsingContext,
is(win.docShell.browsingContext.getChildren()[0], frameBC, "BF cache cached BC"
"BF cached BC's should still be a child of its parent"); );
is(win.docShell.browsingContext, frameBC.parent, is(
"BF cached BC's should still be a connected to its parent"); frameBC.id,
win.frames[0].docShell.browsingContext.id,
"BF cached BC's have same id"
);
is(
win.docShell.browsingContext.getChildren()[0],
frameBC,
"BF cached BC's should still be a child of its parent"
);
is(
win.docShell.browsingContext,
frameBC.parent,
"BF cached BC's should still be a connected to its parent"
);
win.close(); win.close();
}); });
}); }
);
}); });

View file

@ -5,114 +5,144 @@
add_task(async function() { add_task(async function() {
await BrowserTestUtils.withNewTab( await BrowserTestUtils.withNewTab(
{gBrowser, url: "about:blank"}, async function(browser) { { gBrowser, url: "about:blank" },
const BASE1 = getRootDirectory(gTestPath) async function(browser) {
.replace("chrome://mochitests/content", "http://example.com"); const BASE1 = getRootDirectory(gTestPath).replace(
const BASE2 = getRootDirectory(gTestPath) "chrome://mochitests/content",
.replace("chrome://mochitests/content", "http://test1.example.com"); "http://example.com"
);
const BASE2 = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://test1.example.com"
);
const URL = BASE1 + "onload_message.html"; const URL = BASE1 + "onload_message.html";
let sixth = BrowserTestUtils.waitForNewTab(gBrowser, URL + "#sixth", true, true); let sixth = BrowserTestUtils.waitForNewTab(
let seventh = BrowserTestUtils.waitForNewTab(gBrowser, URL + "#seventh", true, true); gBrowser,
await ContentTask.spawn(browser, {base1: BASE1, base2: BASE2}, URL + "#sixth",
async function({base1, base2}) { true,
let top = content.window; true
top.name = "top"; );
top.location.href += "#top"; let seventh = BrowserTestUtils.waitForNewTab(
gBrowser,
URL + "#seventh",
true,
true
);
await ContentTask.spawn(
browser,
{ base1: BASE1, base2: BASE2 },
async function({ base1, base2 }) {
let top = content.window;
top.name = "top";
top.location.href += "#top";
let contexts = { let contexts = {
top: top.location.href, top: top.location.href,
first: base1 + "dummy_page.html#first", first: base1 + "dummy_page.html#first",
third: base2 + "dummy_page.html#third", third: base2 + "dummy_page.html#third",
second: base1 + "dummy_page.html#second", second: base1 + "dummy_page.html#second",
fourth: base2 + "dummy_page.html#fourth", fourth: base2 + "dummy_page.html#fourth",
fifth: base1 + "dummy_page.html#fifth", fifth: base1 + "dummy_page.html#fifth",
sixth: base1 + "onload_message.html#sixth", sixth: base1 + "onload_message.html#sixth",
seventh: base1 + "onload_message.html#seventh", seventh: base1 + "onload_message.html#seventh",
}; };
function addFrame(target, name) { function addFrame(target, name) {
let doc = (target.contentWindow || target).document; let doc = (target.contentWindow || target).document;
let frame = doc.createElement("iframe"); let frame = doc.createElement("iframe");
let p = new Promise(resolve => (frame.onload = () => resolve(frame))); let p = new Promise(
doc.body.appendChild(frame); resolve => (frame.onload = () => resolve(frame))
frame.name = name; );
frame.src = contexts[name]; doc.body.appendChild(frame);
return p; frame.name = name;
} frame.src = contexts[name];
return p;
function addWindow(target, name, {options, resolve}) {
var win = target.contentWindow.open(contexts[name], name, options);
if (resolve) {
return new Promise(
resolve => target.contentWindow.addEventListener(
"message", () => resolve(win)));
} }
return Promise.resolve({name});
}
// We're going to create a tree that looks like the function addWindow(target, name, { options, resolve }) {
// following. var win = target.contentWindow.open(contexts[name], name, options);
//
// top sixth seventh
// / \
// / \ /
// first second
// / \ /
// / \
// third fourth - - -
// /
// /
// fifth
//
// The idea is to have one top level non-auxiliary browsing
// context, five nested, one top level auxiliary with an
// opener, and one top level without an opener. Given that
// set of related and one unrelated browsing contexts we
// wish to confirm that targeting is able to find
// appropriate browsing contexts.
if (resolve) {
return new Promise(resolve =>
target.contentWindow.addEventListener("message", () =>
resolve(win)
)
);
}
return Promise.resolve({ name });
}
function bc(frame) { // We're going to create a tree that looks like the
return (frame.contentWindow || frame).docShell.browsingContext; // following.
} //
// top sixth seventh
// / \
// / \ /
// first second
// / \ /
// / \
// third fourth - - -
// /
// /
// fifth
//
// The idea is to have one top level non-auxiliary browsing
// context, five nested, one top level auxiliary with an
// opener, and one top level without an opener. Given that
// set of related and one unrelated browsing contexts we
// wish to confirm that targeting is able to find
// appropriate browsing contexts.
function reachable(start, targets) { function bc(frame) {
for (let target of targets) { return (frame.contentWindow || frame).docShell.browsingContext;
is(bc(start).findWithName(target.name), bc(target), }
[bc(start).name, "can reach", target.name].join(" "));
function reachable(start, targets) {
for (let target of targets) {
is(
bc(start).findWithName(target.name),
bc(target),
[bc(start).name, "can reach", target.name].join(" ")
);
}
}
function unreachable(start, target) {
is(
bc(start).findWithName(target.name),
null,
[bc(start).name, "can't reach", target.name].join(" ")
);
}
let first = await addFrame(top, "first");
info("first");
let second = await addFrame(top, "second");
info("second");
let third = await addFrame(first, "third");
info("third");
let fourth = await addFrame(first, "fourth");
info("fourth");
let fifth = await addFrame(fourth, "fifth");
info("fifth");
let sixth = await addWindow(fourth, "sixth", { resolve: true });
info("sixth");
let seventh = await addWindow(fourth, "seventh", {
options: ["noopener"],
});
info("seventh");
let frames = [top, first, second, third, fourth, fifth, sixth];
for (let start of frames) {
reachable(start, frames);
unreachable(start, seventh);
} }
} }
);
function unreachable(start, target) {
is(bc(start).findWithName(target.name), null,
[bc(start).name, "can't reach", target.name].join(" "));
}
let first = await addFrame(top, "first");
info("first");
let second = await addFrame(top, "second");
info("second");
let third = await addFrame(first, "third");
info("third");
let fourth = await addFrame(first, "fourth");
info("fourth");
let fifth = await addFrame(fourth, "fifth");
info("fifth");
let sixth = await addWindow(fourth, "sixth", { resolve: true });
info("sixth");
let seventh = await addWindow(fourth, "seventh", { options: ["noopener"] });
info("seventh");
let frames = [top, first, second, third, fourth, fifth, sixth];
for (let start of frames) {
reachable(start, frames);
unreachable(start, seventh);
}
});
for (let tab of await Promise.all([sixth, seventh])) { for (let tab of await Promise.all([sixth, seventh])) {
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);
} }
}); }
);
}); });

View file

@ -5,132 +5,169 @@
add_task(async function() { add_task(async function() {
await BrowserTestUtils.withNewTab( await BrowserTestUtils.withNewTab(
{gBrowser, url: "about:blank"}, async function(browser) { { gBrowser, url: "about:blank" },
const BASE1 = getRootDirectory(gTestPath) async function(browser) {
.replace("chrome://mochitests/content", "http://example.com"); const BASE1 = getRootDirectory(gTestPath).replace(
const BASE2 = getRootDirectory(gTestPath) "chrome://mochitests/content",
.replace("chrome://mochitests/content", "http://test1.example.com"); "http://example.com"
);
const BASE2 = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://test1.example.com"
);
const URL = BASE1 + "onload_message.html"; const URL = BASE1 + "onload_message.html";
let sixth = BrowserTestUtils.waitForNewTab(gBrowser, URL + "#sixth", true, true); let sixth = BrowserTestUtils.waitForNewTab(
await ContentTask.spawn(browser, {base1: BASE1, base2: BASE2}, gBrowser,
async function({base1, base2}) { URL + "#sixth",
let top = content.window; true,
top.name = "top"; true
top.location.href += "#top"; );
await ContentTask.spawn(
browser,
{ base1: BASE1, base2: BASE2 },
async function({ base1, base2 }) {
let top = content.window;
top.name = "top";
top.location.href += "#top";
let contexts = { let contexts = {
top: top.location.href, top: top.location.href,
first: base1 + "dummy_page.html#first", first: base1 + "dummy_page.html#first",
third: base2 + "dummy_page.html#third", third: base2 + "dummy_page.html#third",
second: base1 + "dummy_page.html#second", second: base1 + "dummy_page.html#second",
fourth: base2 + "dummy_page.html#fourth", fourth: base2 + "dummy_page.html#fourth",
fifth: base1 + "dummy_page.html#fifth", fifth: base1 + "dummy_page.html#fifth",
sixth: base1 + "onload_message.html#sixth", sixth: base1 + "onload_message.html#sixth",
}; };
function addFrame(target, name) { function addFrame(target, name) {
let doc = (target.contentWindow || target).document; let doc = (target.contentWindow || target).document;
let frame = doc.createElement("iframe"); let frame = doc.createElement("iframe");
let p = new Promise(resolve => (frame.onload = () => resolve(frame))); let p = new Promise(
doc.body.appendChild(frame); resolve => (frame.onload = () => resolve(frame))
frame.name = name; );
frame.src = contexts[name]; doc.body.appendChild(frame);
return p; frame.name = name;
} frame.src = contexts[name];
return p;
}
function addWindow(target, name) { function addWindow(target, name) {
var win = target.contentWindow.open(contexts[name], name); var win = target.contentWindow.open(contexts[name], name);
return new Promise( return new Promise(resolve =>
resolve => target.contentWindow.addEventListener( target.contentWindow.addEventListener("message", () =>
"message", () => resolve(win))); resolve(win)
} )
);
}
// Generate all lists of length length with every combination of // Generate all lists of length length with every combination of
// values in input // values in input
function* generate(input, length) { function* generate(input, length) {
let list = new Array(length); let list = new Array(length);
function* values(pos) { function* values(pos) {
if (pos >= list.length) { if (pos >= list.length) {
yield list; yield list;
} else { } else {
for (let v of input) { for (let v of input) {
list[pos] = v; list[pos] = v;
yield* values(pos + 1); yield* values(pos + 1);
}
} }
} }
} yield* values(0);
yield* values(0);
}
// We're going to create a tree that looks like the
// follwing.
//
// top sixth
// / \
// / \ /
// first second
// / \ /
// / \
// third fourth - - -
// /
// /
// fifth
//
// The idea is to have one top level non-auxiliary browsing
// context, five nested, one top level auxiliary with an
// opener. Given that set of related browsing contexts we
// wish to confirm that targeting is semantically equivalent
// with how nsIDocShellTreeItem.findItemWithName works. The
// trick to ensure that is to give all frames the same name!
// and ensure that the find algorithms return the same nodes
// in the same order.
function bc(frame) {
return (frame.contentWindow || frame).docShell.browsingContext;
}
let first = await addFrame(top, "first");
let second = await addFrame(top, "second");
let third = await addFrame(first, "third");
let fourth = await addFrame(first, "fourth");
let fifth = await addFrame(fourth, "fifth");
let sixth = await addWindow(fourth, "sixth");
let frames = [top, first, second, third, fourth, fifth, sixth];
let browsingContexts = frames.map(bc);
let docShells = browsingContexts.map(context => context.docShell);
ok(top.docShell instanceof Ci.nsIDocShellTreeItem,
"When we remove nsIDocShellTreeItem this test should be removed");
// For every browsing context we generate all possible
// combinations of names for these browsing contexts using
// "dummy" and "target" as possible name.
for (let names of generate(["dummy", "target"], docShells.length)) {
for (let i = names.length - 1; i >= 0; --i) {
docShells[i].name = names[i];
} }
for (let i = 0; i < docShells.length; ++i) { // We're going to create a tree that looks like the
let docShell = docShells[i].findItemWithName("target", null, null, false); // follwing.
let browsingContext = browsingContexts[i].findWithName("target"); //
is(docShell ? docShell.browsingContext : null, browsingContext, // top sixth
"findItemWithName should find same browsing context as findWithName"); // / \
} // / \ /
} // first second
// / \ /
// / \
// third fourth - - -
// /
// /
// fifth
//
// The idea is to have one top level non-auxiliary browsing
// context, five nested, one top level auxiliary with an
// opener. Given that set of related browsing contexts we
// wish to confirm that targeting is semantically equivalent
// with how nsIDocShellTreeItem.findItemWithName works. The
// trick to ensure that is to give all frames the same name!
// and ensure that the find algorithms return the same nodes
// in the same order.
for (let target of ["_self", "_top", "_parent", "_blank"]) { function bc(frame) {
for (let i = 0; i < docShells.length; ++i) { return (frame.contentWindow || frame).docShell.browsingContext;
let docShell = docShells[i].findItemWithName(target, null, null, false); }
let browsingContext = browsingContexts[i].findWithName(target);
is(docShell ? docShell.browsingContext : null, browsingContext, let first = await addFrame(top, "first");
"findItemWithName should find same browsing context as findWithName for " + target); let second = await addFrame(top, "second");
let third = await addFrame(first, "third");
let fourth = await addFrame(first, "fourth");
let fifth = await addFrame(fourth, "fifth");
let sixth = await addWindow(fourth, "sixth");
let frames = [top, first, second, third, fourth, fifth, sixth];
let browsingContexts = frames.map(bc);
let docShells = browsingContexts.map(context => context.docShell);
ok(
top.docShell instanceof Ci.nsIDocShellTreeItem,
"When we remove nsIDocShellTreeItem this test should be removed"
);
// For every browsing context we generate all possible
// combinations of names for these browsing contexts using
// "dummy" and "target" as possible name.
for (let names of generate(["dummy", "target"], docShells.length)) {
for (let i = names.length - 1; i >= 0; --i) {
docShells[i].name = names[i];
}
for (let i = 0; i < docShells.length; ++i) {
let docShell = docShells[i].findItemWithName(
"target",
null,
null,
false
);
let browsingContext = browsingContexts[i].findWithName("target");
is(
docShell ? docShell.browsingContext : null,
browsingContext,
"findItemWithName should find same browsing context as findWithName"
);
}
}
for (let target of ["_self", "_top", "_parent", "_blank"]) {
for (let i = 0; i < docShells.length; ++i) {
let docShell = docShells[i].findItemWithName(
target,
null,
null,
false
);
let browsingContext = browsingContexts[i].findWithName(target);
is(
docShell ? docShell.browsingContext : null,
browsingContext,
"findItemWithName should find same browsing context as findWithName for " +
target
);
}
} }
} }
}); );
BrowserTestUtils.removeTab(await sixth); BrowserTestUtils.removeTab(await sixth);
}); }
);
}); });

View file

@ -12,8 +12,9 @@ function observeOnce(topic) {
} }
add_task(async function setPrefs() { add_task(async function setPrefs() {
await SpecialPowers.pushPrefEnv({"set": [["fission.oopif.attribute", true], await SpecialPowers.pushPrefEnv({
["dom.ipc.processCount", 10000]]}); set: [["fission.oopif.attribute", true], ["dom.ipc.processCount", 10000]],
});
}); });
add_task(async function runTest() { add_task(async function runTest() {
@ -25,13 +26,21 @@ add_task(async function runTest() {
is(chromeBC.parent, null, "chrome has no parent"); is(chromeBC.parent, null, "chrome has no parent");
// Open a new tab, and check that basic frames work out. // Open a new tab, and check that basic frames work out.
let tab = await BrowserTestUtils.openNewForegroundTab({gBrowser}); let tab = await BrowserTestUtils.openNewForegroundTab({ gBrowser });
info(`root, parent`); info(`root, parent`);
let rootBC = tab.linkedBrowser.browsingContext; let rootBC = tab.linkedBrowser.browsingContext;
ok(rootBC.currentWindowGlobal, "[parent] root has a window global"); ok(rootBC.currentWindowGlobal, "[parent] root has a window global");
is(rootBC.embedderWindowGlobal, chromeBC.currentWindowGlobal, "[parent] root has chrome as embedder global"); is(
is(rootBC.embedderElement, tab.linkedBrowser, "[parent] root has browser as embedder element"); rootBC.embedderWindowGlobal,
chromeBC.currentWindowGlobal,
"[parent] root has chrome as embedder global"
);
is(
rootBC.embedderElement,
tab.linkedBrowser,
"[parent] root has browser as embedder element"
);
is(rootBC.parent, null, "[parent] root has no parent"); is(rootBC.parent, null, "[parent] root has no parent");
// Test with an in-process frame // Test with an in-process frame
@ -55,7 +64,11 @@ add_task(async function runTest() {
info(`frame, parent`); info(`frame, parent`);
let frameBC = BrowsingContext.get(frameId); let frameBC = BrowsingContext.get(frameId);
ok(frameBC.currentWindowGlobal, "[parent] frame has a window global"); ok(frameBC.currentWindowGlobal, "[parent] frame has a window global");
is(frameBC.embedderWindowGlobal, rootBC.currentWindowGlobal, "[parent] frame has root as embedder global"); is(
frameBC.embedderWindowGlobal,
rootBC.currentWindowGlobal,
"[parent] frame has root as embedder global"
);
is(frameBC.embedderElement, null, "[parent] frame has no embedder element"); is(frameBC.embedderElement, null, "[parent] frame has no embedder element");
is(frameBC.parent, rootBC, "[parent] frame has root as parent"); is(frameBC.parent, rootBC, "[parent] frame has root as parent");
@ -86,20 +99,32 @@ add_task(async function runTest() {
info(`oop frame, child`); info(`oop frame, child`);
let oopBC = oop.frameLoader.browsingContext; let oopBC = oop.frameLoader.browsingContext;
is(oopBC.embedderElement, oop, "[child] oop frame embedded within iframe"); is(oopBC.embedderElement, oop, "[child] oop frame embedded within iframe");
is(oopBC.parent, content.docShell.browsingContext, "[child] frame has root as parent"); is(
oopBC.parent,
content.docShell.browsingContext,
"[child] frame has root as parent"
);
return oopBC.id; return oopBC.id;
}); });
info(`oop frame, parent`); info(`oop frame, parent`);
let oopBC = BrowsingContext.get(oopID); let oopBC = BrowsingContext.get(oopID);
is(oopBC.embedderWindowGlobal, rootBC.currentWindowGlobal, "[parent] oop frame has root as embedder global"); is(
oopBC.embedderWindowGlobal,
rootBC.currentWindowGlobal,
"[parent] oop frame has root as embedder global"
);
is(oopBC.embedderElement, null, "[parent] oop frame has no embedder element"); is(oopBC.embedderElement, null, "[parent] oop frame has no embedder element");
is(oopBC.parent, rootBC, "[parent] oop frame has root as parent"); is(oopBC.parent, rootBC, "[parent] oop frame has root as parent");
info(`waiting for oop window global`); info(`waiting for oop window global`);
let oopWindowGlobal = await oopWindowGlobalPromise; let oopWindowGlobal = await oopWindowGlobalPromise;
is(oopBC.currentWindowGlobal, oopWindowGlobal, "[parent] oop frame has a window global"); is(
oopBC.currentWindowGlobal,
oopWindowGlobal,
"[parent] oop frame has a window global"
);
// Open a new window, and adopt |tab| into it. // Open a new window, and adopt |tab| into it.
@ -108,7 +133,11 @@ add_task(async function runTest() {
info(`new chrome, parent`); info(`new chrome, parent`);
let newChromeBC = newWindow.docShell.browsingContext; let newChromeBC = newWindow.docShell.browsingContext;
ok(newChromeBC.currentWindowGlobal, "Should have a current WindowGlobal"); ok(newChromeBC.currentWindowGlobal, "Should have a current WindowGlobal");
is(newChromeBC.embedderWindowGlobal, null, "new chrome has no embedder global"); is(
newChromeBC.embedderWindowGlobal,
null,
"new chrome has no embedder global"
);
is(newChromeBC.embedderElement, null, "new chrome has no embedder element"); is(newChromeBC.embedderElement, null, "new chrome has no embedder element");
is(newChromeBC.parent, null, "new chrome has no parent"); is(newChromeBC.parent, null, "new chrome has no parent");
@ -117,9 +146,21 @@ add_task(async function runTest() {
info(`adopting tab`); info(`adopting tab`);
let newTab = newWindow.gBrowser.adoptTab(tab); let newTab = newWindow.gBrowser.adoptTab(tab);
is(newTab.linkedBrowser.browsingContext, rootBC, "[parent] root browsing context survived"); is(
is(rootBC.embedderWindowGlobal, newChromeBC.currentWindowGlobal, "[parent] embedder window global updated"); newTab.linkedBrowser.browsingContext,
is(rootBC.embedderElement, newTab.linkedBrowser, "[parent] embedder element updated"); rootBC,
"[parent] root browsing context survived"
);
is(
rootBC.embedderWindowGlobal,
newChromeBC.currentWindowGlobal,
"[parent] embedder window global updated"
);
is(
rootBC.embedderElement,
newTab.linkedBrowser,
"[parent] embedder element updated"
);
is(rootBC.parent, null, "[parent] root has no parent"); is(rootBC.parent, null, "[parent] root has no parent");
info(`closing window`); info(`closing window`);

View file

@ -26,6 +26,9 @@ add_task(async function() {
gBrowser.removeTab(tab); gBrowser.removeTab(tab);
gBrowser.removeTabsProgressListener(listener); gBrowser.removeTabsProgressListener(listener);
is(numLocationChanges, 1, is(
"pushState with a different URI should cause a LocationChange event."); numLocationChanges,
1,
"pushState with a different URI should cause a LocationChange event."
);
}); });

View file

@ -5,7 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
add_task(async function runTests() { add_task(async function runTests() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:about"); let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:about"
);
registerCleanupFunction(function() { registerCleanupFunction(function() {
gBrowser.removeTab(tab); gBrowser.removeTab(tab);
@ -21,10 +24,16 @@ add_task(async function runTests() {
// Using a dummy onunload listener to disable the bfcache as that can prevent // Using a dummy onunload listener to disable the bfcache as that can prevent
// the test browser load detection mechanism from working. // the test browser load detection mechanism from working.
loaded = BrowserTestUtils.browserLoaded(browser); loaded = BrowserTestUtils.browserLoaded(browser);
BrowserTestUtils.loadURI(browser, "data:text/html,<body%20onunload=''><iframe></iframe></body>"); BrowserTestUtils.loadURI(
browser,
"data:text/html,<body%20onunload=''><iframe></iframe></body>"
);
href = await loaded; href = await loaded;
is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>", is(
"Check data URL loaded"); href,
"data:text/html,<body%20onunload=''><iframe></iframe></body>",
"Check data URL loaded"
);
loaded = BrowserTestUtils.browserLoaded(browser); loaded = BrowserTestUtils.browserLoaded(browser);
browser.goBack(); browser.goBack();
@ -34,6 +43,9 @@ add_task(async function runTests() {
loaded = BrowserTestUtils.browserLoaded(browser); loaded = BrowserTestUtils.browserLoaded(browser);
browser.goForward(); browser.goForward();
href = await loaded; href = await loaded;
is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>", is(
"Check we've gone forward to data URL"); href,
"data:text/html,<body%20onunload=''><iframe></iframe></body>",
"Check we've gone forward to data URL"
);
}); });

View file

@ -1,14 +1,19 @@
const HTML_URL = "http://mochi.test:8888/browser/docshell/test/browser/file_bug1328501.html"; const HTML_URL =
const FRAME_URL = "http://mochi.test:8888/browser/docshell/test/browser/file_bug1328501_frame.html"; "http://mochi.test:8888/browser/docshell/test/browser/file_bug1328501.html";
const FRAME_SCRIPT_URL = "chrome://mochitests/content/browser/docshell/test/browser/file_bug1328501_framescript.js"; const FRAME_URL =
"http://mochi.test:8888/browser/docshell/test/browser/file_bug1328501_frame.html";
const FRAME_SCRIPT_URL =
"chrome://mochitests/content/browser/docshell/test/browser/file_bug1328501_framescript.js";
add_task(async function testMultiFrameRestore() { add_task(async function testMultiFrameRestore() {
await BrowserTestUtils.withNewTab({gBrowser, url: HTML_URL}, async function(browser) { await BrowserTestUtils.withNewTab({ gBrowser, url: HTML_URL }, async function(
browser
) {
// Navigate 2 subframes and load about:blank. // Navigate 2 subframes and load about:blank.
let browserLoaded = BrowserTestUtils.browserLoaded(browser); let browserLoaded = BrowserTestUtils.browserLoaded(browser);
await ContentTask.spawn(browser, FRAME_URL, async function(FRAME_URL) { await ContentTask.spawn(browser, FRAME_URL, async function(FRAME_URL) {
function frameLoaded(frame) { function frameLoaded(frame) {
frame.contentWindow.location = FRAME_URL; frame.contentWindow.location = FRAME_URL;
return new Promise(r => frame.onload = r); return new Promise(r => (frame.onload = r));
} }
let frame1 = content.document.querySelector("#testFrame1"); let frame1 = content.document.querySelector("#testFrame1");
let frame2 = content.document.querySelector("#testFrame2"); let frame2 = content.document.querySelector("#testFrame2");
@ -25,15 +30,26 @@ add_task(async function testMultiFrameRestore() {
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false); browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
// The frame script also forwards frames-loaded. // The frame script also forwards frames-loaded.
let framesLoaded = BrowserTestUtils.waitForMessage(browser.messageManager, "test:frames-loaded"); let framesLoaded = BrowserTestUtils.waitForMessage(
browser.messageManager,
"test:frames-loaded"
);
browser.goBack(); browser.goBack();
await framesLoaded; await framesLoaded;
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(r => setTimeout(r, 1000)); await new Promise(r => setTimeout(r, 1000));
await ContentTask.spawn(browser, FRAME_URL, (FRAME_URL) => { await ContentTask.spawn(browser, FRAME_URL, FRAME_URL => {
is(content.document.querySelector("#testFrame1").contentWindow.location.href, FRAME_URL); is(
is(content.document.querySelector("#testFrame2").contentWindow.location.href, FRAME_URL); content.document.querySelector("#testFrame1").contentWindow.location
.href,
FRAME_URL
);
is(
content.document.querySelector("#testFrame2").contentWindow.location
.href,
FRAME_URL
);
}); });
}); });
}); });

View file

@ -11,7 +11,7 @@ add_task(async function testValidCache() {
}); });
await BrowserTestUtils.withNewTab( await BrowserTestUtils.withNewTab(
{gBrowser, url: "data:text/html;charset=utf-8,page1"}, { gBrowser, url: "data:text/html;charset=utf-8,page1" },
async function(browser) { async function(browser) {
// Make a simple modification for bfcache testing. // Make a simple modification for bfcache testing.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
@ -23,13 +23,17 @@ add_task(async function testValidCache() {
await BrowserTestUtils.browserLoaded(browser); await BrowserTestUtils.browserLoaded(browser);
// Go back and verify text content. // Go back and verify text content.
let awaitPageShow = BrowserTestUtils.waitForContentEvent(browser, "pageshow"); let awaitPageShow = BrowserTestUtils.waitForContentEvent(
browser,
"pageshow"
);
browser.goBack(); browser.goBack();
await awaitPageShow; await awaitPageShow;
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
is(content.document.body.textContent, "modified"); is(content.document.body.textContent, "modified");
}); });
}); }
);
}); });
// With bfcache expired. // With bfcache expired.
@ -40,7 +44,7 @@ add_task(async function testExpiredCache() {
}); });
await BrowserTestUtils.withNewTab( await BrowserTestUtils.withNewTab(
{gBrowser, url: "data:text/html;charset=utf-8,page1"}, { gBrowser, url: "data:text/html;charset=utf-8,page1" },
async function(browser) { async function(browser) {
// Make a simple modification for bfcache testing. // Make a simple modification for bfcache testing.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
@ -59,11 +63,15 @@ add_task(async function testExpiredCache() {
}); });
// Go back and verify text content. // Go back and verify text content.
let awaitPageShow = BrowserTestUtils.waitForContentEvent(browser, "pageshow"); let awaitPageShow = BrowserTestUtils.waitForContentEvent(
browser,
"pageshow"
);
browser.goBack(); browser.goBack();
await awaitPageShow; await awaitPageShow;
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
is(content.document.body.textContent, "page1"); is(content.document.body.textContent, "page1");
}); });
}); }
);
}); });

View file

@ -1,21 +1,28 @@
const TEXT = { const TEXT = {
/* The test text decoded correctly as Shift_JIS */ /* The test text decoded correctly as Shift_JIS */
rightText: "\u30E6\u30CB\u30B3\u30FC\u30C9\u306F\u3001\u3059\u3079\u3066\u306E\u6587\u5B57\u306B\u56FA\u6709\u306E\u756A\u53F7\u3092\u4ED8\u4E0E\u3057\u307E\u3059", rightText:
"\u30E6\u30CB\u30B3\u30FC\u30C9\u306F\u3001\u3059\u3079\u3066\u306E\u6587\u5B57\u306B\u56FA\u6709\u306E\u756A\u53F7\u3092\u4ED8\u4E0E\u3057\u307E\u3059",
enteredText1: "The quick brown fox jumps over the lazy dog", enteredText1: "The quick brown fox jumps over the lazy dog",
enteredText2: "\u03BE\u03B5\u03C3\u03BA\u03B5\u03C0\u03AC\u03B6\u03C9\u0020\u03C4\u1F74\u03BD\u0020\u03C8\u03C5\u03C7\u03BF\u03C6\u03B8\u03CC\u03C1\u03B1\u0020\u03B2\u03B4\u03B5\u03BB\u03C5\u03B3\u03BC\u03AF\u03B1", enteredText2:
"\u03BE\u03B5\u03C3\u03BA\u03B5\u03C0\u03AC\u03B6\u03C9\u0020\u03C4\u1F74\u03BD\u0020\u03C8\u03C5\u03C7\u03BF\u03C6\u03B8\u03CC\u03C1\u03B1\u0020\u03B2\u03B4\u03B5\u03BB\u03C5\u03B3\u03BC\u03AF\u03B1",
}; };
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, rootDir + "test-form_sjis.html"); gBrowser.selectedTab = BrowserTestUtils.addTab(
gBrowser,
rootDir + "test-form_sjis.html"
);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterOpen); BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterOpen);
} }
function afterOpen() { function afterOpen() {
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterChangeCharset); BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(
afterChangeCharset
);
ContentTask.spawn(gBrowser.selectedBrowser, TEXT, function(TEXT) { ContentTask.spawn(gBrowser.selectedBrowser, TEXT, function(TEXT) {
content.document.getElementById("testtextarea").value = TEXT.enteredText1; content.document.getElementById("testtextarea").value = TEXT.enteredText1;
@ -28,12 +35,21 @@ function afterOpen() {
function afterChangeCharset() { function afterChangeCharset() {
ContentTask.spawn(gBrowser.selectedBrowser, TEXT, function(TEXT) { ContentTask.spawn(gBrowser.selectedBrowser, TEXT, function(TEXT) {
is(content.document.getElementById("testpar").innerHTML, TEXT.rightText, is(
"encoding successfully changed"); content.document.getElementById("testpar").innerHTML,
is(content.document.getElementById("testtextarea").value, TEXT.enteredText1, TEXT.rightText,
"text preserved in <textarea>"); "encoding successfully changed"
is(content.document.getElementById("testinput").value, TEXT.enteredText2, );
"text preserved in <input>"); is(
content.document.getElementById("testtextarea").value,
TEXT.enteredText1,
"text preserved in <textarea>"
);
is(
content.document.getElementById("testinput").value,
TEXT.enteredText2,
"text preserved in <input>"
);
}).then(() => { }).then(() => {
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View file

@ -1,15 +1,17 @@
/* Any copyright is dedicated to the Public Domain. /* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */ http://creativecommons.org/publicdomain/zero/1.0/ */
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com"); const TEST_PATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
add_task(async function test() { add_task(async function test() {
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const XUL_NS =
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
await SpecialPowers.pushPrefEnv({ await SpecialPowers.pushPrefEnv({
"set": [ set: [["dom.require_user_interaction_for_beforeunload", false]],
["dom.require_user_interaction_for_beforeunload", false],
],
}); });
let url = TEST_PATH + "file_bug1415918_beforeunload.html"; let url = TEST_PATH + "file_bug1415918_beforeunload.html";
@ -21,7 +23,11 @@ add_task(async function test() {
let observer = new MutationObserver(function(mutations) { let observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) { mutations.forEach(function(mutation) {
if (buttonId && mutation.type == "attributes" && browser.hasAttribute("tabmodalPromptShowing")) { if (
buttonId &&
mutation.type == "attributes" &&
browser.hasAttribute("tabmodalPromptShowing")
) {
let prompt = stack.getElementsByTagNameNS(XUL_NS, "tabmodalprompt")[0]; let prompt = stack.getElementsByTagNameNS(XUL_NS, "tabmodalprompt")[0];
prompt.querySelector(`.tabmodalprompt-${buttonId}`).click(); prompt.querySelector(`.tabmodalprompt-${buttonId}`).click();
promptShown = true; promptShown = true;
@ -42,11 +48,17 @@ add_task(async function test() {
// Check that all beforeunload handlers fired and reset attributes. // Check that all beforeunload handlers fired and reset attributes.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
content.window.document.body.removeAttribute("fired"); content.window.document.body.removeAttribute("fired");
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should fire"); ok(
frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should fire"
);
frame.document.body.removeAttribute("fired"); frame.document.body.removeAttribute("fired");
} }
}); });
@ -60,40 +72,64 @@ add_task(async function test() {
// Check that only the parent beforeunload handler fired, and reset attribute. // Check that only the parent beforeunload handler fired, and reset attribute.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
content.window.document.body.removeAttribute("fired"); content.window.document.body.removeAttribute("fired");
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(!frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should not fire"); ok(
!frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should not fire"
);
} }
}); });
// Prompt is not shown, don't permit unload. // Prompt is not shown, don't permit unload.
promptShown = false; promptShown = false;
ok(!browser.permitUnload(browser.dontPromptAndDontUnload).permitUnload, "permit unload should be false"); ok(
!browser.permitUnload(browser.dontPromptAndDontUnload).permitUnload,
"permit unload should be false"
);
ok(!promptShown, "prompt should not have been displayed"); ok(!promptShown, "prompt should not have been displayed");
// Check that only the parent beforeunload handler fired, and reset attribute. // Check that only the parent beforeunload handler fired, and reset attribute.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
content.window.document.body.removeAttribute("fired"); content.window.document.body.removeAttribute("fired");
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(!frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should not fire"); ok(
!frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should not fire"
);
} }
}); });
// Prompt is not shown, permit unload. // Prompt is not shown, permit unload.
promptShown = false; promptShown = false;
ok(browser.permitUnload(browser.dontPromptAndUnload).permitUnload, "permit unload should be true"); ok(
browser.permitUnload(browser.dontPromptAndUnload).permitUnload,
"permit unload should be true"
);
ok(!promptShown, "prompt should not have been displayed"); ok(!promptShown, "prompt should not have been displayed");
// Check that all beforeunload handlers fired. // Check that all beforeunload handlers fired.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should fire"); ok(
frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should fire"
);
} }
}); });
@ -114,40 +150,64 @@ add_task(async function test() {
// Check that all beforeunload handlers fired and reset attributes. // Check that all beforeunload handlers fired and reset attributes.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
content.window.document.body.removeAttribute("fired"); content.window.document.body.removeAttribute("fired");
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should fire"); ok(
frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should fire"
);
frame.document.body.removeAttribute("fired"); frame.document.body.removeAttribute("fired");
} }
}); });
promptShown = false; promptShown = false;
ok(browser.permitUnload(browser.dontPromptAndDontUnload).permitUnload, "permit unload should be true"); ok(
browser.permitUnload(browser.dontPromptAndDontUnload).permitUnload,
"permit unload should be true"
);
ok(!promptShown, "prompt should not have been displayed"); ok(!promptShown, "prompt should not have been displayed");
// Check that all beforeunload handlers fired and reset attributes. // Check that all beforeunload handlers fired and reset attributes.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
content.window.document.body.removeAttribute("fired"); content.window.document.body.removeAttribute("fired");
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should fire"); ok(
frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should fire"
);
frame.document.body.removeAttribute("fired"); frame.document.body.removeAttribute("fired");
} }
}); });
promptShown = false; promptShown = false;
ok(browser.permitUnload(browser.dontPromptAndUnload).permitUnload, "permit unload should be true"); ok(
browser.permitUnload(browser.dontPromptAndUnload).permitUnload,
"permit unload should be true"
);
ok(!promptShown, "prompt should not have been displayed"); ok(!promptShown, "prompt should not have been displayed");
// Check that all beforeunload handlers fired. // Check that all beforeunload handlers fired.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should fire"); ok(
frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should fire"
);
} }
}); });
@ -168,11 +228,17 @@ add_task(async function test() {
// Check that all beforeunload handlers fired and reset attributes. // Check that all beforeunload handlers fired and reset attributes.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
content.window.document.body.removeAttribute("fired"); content.window.document.body.removeAttribute("fired");
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should fire"); ok(
frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should fire"
);
frame.document.body.removeAttribute("fired"); frame.document.body.removeAttribute("fired");
} }
}); });
@ -187,7 +253,10 @@ add_task(async function test() {
// Check that the parent beforeunload handler fired, and only one child beforeunload // Check that the parent beforeunload handler fired, and only one child beforeunload
// handler fired. Reset attributes. // handler fired. Reset attributes.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
content.window.document.body.removeAttribute("fired"); content.window.document.body.removeAttribute("fired");
let count = 0; let count = 0;
@ -202,13 +271,19 @@ add_task(async function test() {
// Prompt is not shown, don't permit unload. // Prompt is not shown, don't permit unload.
promptShown = false; promptShown = false;
ok(!browser.permitUnload(browser.dontPromptAndDontUnload).permitUnload, "permit unload should be false"); ok(
!browser.permitUnload(browser.dontPromptAndDontUnload).permitUnload,
"permit unload should be false"
);
ok(!promptShown, "prompt should not have been displayed"); ok(!promptShown, "prompt should not have been displayed");
// Check that the parent beforeunload handler fired, and only one child beforeunload // Check that the parent beforeunload handler fired, and only one child beforeunload
// handler fired. Reset attributes. // handler fired. Reset attributes.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
content.window.document.body.removeAttribute("fired"); content.window.document.body.removeAttribute("fired");
let count = 0; let count = 0;
@ -223,15 +298,24 @@ add_task(async function test() {
// Prompt is not shown, permit unload. // Prompt is not shown, permit unload.
promptShown = false; promptShown = false;
ok(browser.permitUnload(browser.dontPromptAndUnload).permitUnload, "permit unload should be true"); ok(
browser.permitUnload(browser.dontPromptAndUnload).permitUnload,
"permit unload should be true"
);
ok(!promptShown, "prompt should not have been displayed"); ok(!promptShown, "prompt should not have been displayed");
// Check that all beforeunload handlers fired. // Check that all beforeunload handlers fired.
await ContentTask.spawn(browser, null, () => { await ContentTask.spawn(browser, null, () => {
ok(content.window.document.body.hasAttribute("fired"), "parent document beforeunload handler should fire"); ok(
content.window.document.body.hasAttribute("fired"),
"parent document beforeunload handler should fire"
);
for (let frame of Array.from(content.window.frames)) { for (let frame of Array.from(content.window.frames)) {
ok(frame.document.body.hasAttribute("fired"), "frame document beforeunload handler should fire"); ok(
frame.document.body.hasAttribute("fired"),
"frame document beforeunload handler should fire"
);
} }
}); });
@ -239,4 +323,3 @@ add_task(async function test() {
buttonId = "button0"; buttonId = "button0";
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);
}); });

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug1543077-1.html", afterOpen, "Japanese", afterChangeCharset); runCharsetTest(
rootDir + "file_bug1543077-1.html",
afterOpen,
"Japanese",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u00A4"), 131, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u00A4"),
131,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u00A4"), 87, "Child doc should be windows-1252 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u00A4"),
87,
"Child doc should be windows-1252 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u3042"), 131, "Parent doc should decode as EUC-JP subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u3042"), 87, "Child doc should decode as EUC-JP subsequently"); content.document.documentElement.textContent.indexOf("\u3042"),
131,
"Parent doc should decode as EUC-JP subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u3042"),
87,
"Child doc should decode as EUC-JP subsequently"
);
is(content.document.characterSet, "EUC-JP", "Parent doc should report EUC-JP subsequently"); is(
is(content.frames[0].document.characterSet, "EUC-JP", "Child doc should report EUC-JP subsequently"); content.document.characterSet,
"EUC-JP",
"Parent doc should report EUC-JP subsequently"
);
is(
content.frames[0].document.characterSet,
"EUC-JP",
"Child doc should report EUC-JP subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug1543077-2.html", afterOpen, "Japanese", afterChangeCharset); runCharsetTest(
rootDir + "file_bug1543077-2.html",
afterOpen,
"Japanese",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u201A"), 134, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u201A"),
134,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u201A"), 90, "Child doc should be windows-1252 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u201A"),
90,
"Child doc should be windows-1252 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u3042"), 134, "Parent doc should decode as Shift_JIS subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u3042"), 90, "Child doc should decode as Shift_JIS subsequently"); content.document.documentElement.textContent.indexOf("\u3042"),
134,
"Parent doc should decode as Shift_JIS subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u3042"),
90,
"Child doc should decode as Shift_JIS subsequently"
);
is(content.document.characterSet, "Shift_JIS", "Parent doc should report Shift_JIS subsequently"); is(
is(content.frames[0].document.characterSet, "Shift_JIS", "Child doc should report Shift_JIS subsequently"); content.document.characterSet,
"Shift_JIS",
"Parent doc should report Shift_JIS subsequently"
);
is(
content.frames[0].document.characterSet,
"Shift_JIS",
"Child doc should report Shift_JIS subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug1543077-3.html", afterOpen, "Japanese", afterChangeCharset); runCharsetTest(
rootDir + "file_bug1543077-3.html",
afterOpen,
"Japanese",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u001B"), 136, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u001B"),
136,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u001B"), 92, "Child doc should be windows-1252 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u001B"),
92,
"Child doc should be windows-1252 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u3042"), 136, "Parent doc should decode as ISO-2022-JP subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u3042"), 92, "Child doc should decode as ISO-2022-JP subsequently"); content.document.documentElement.textContent.indexOf("\u3042"),
136,
"Parent doc should decode as ISO-2022-JP subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u3042"),
92,
"Child doc should decode as ISO-2022-JP subsequently"
);
is(content.document.characterSet, "ISO-2022-JP", "Parent doc should report ISO-2022-JP subsequently"); is(
is(content.frames[0].document.characterSet, "ISO-2022-JP", "Child doc should report ISO-2022-JP subsequently"); content.document.characterSet,
"ISO-2022-JP",
"Parent doc should report ISO-2022-JP subsequently"
);
is(
content.frames[0].document.characterSet,
"ISO-2022-JP",
"Child doc should report ISO-2022-JP subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug1543077-4.html", afterOpen, "Japanese", afterChangeCharset); runCharsetTest(
rootDir + "file_bug1543077-4.html",
afterOpen,
"Japanese",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u00A4"), 131, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u00A4"),
131,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u201A"), 90, "Child doc should be windows-1252 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u201A"),
90,
"Child doc should be windows-1252 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u3042"), 131, "Parent doc should decode as EUC-JP subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u3042"), 90, "Child doc should decode as Shift_JIS subsequently"); content.document.documentElement.textContent.indexOf("\u3042"),
131,
"Parent doc should decode as EUC-JP subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u3042"),
90,
"Child doc should decode as Shift_JIS subsequently"
);
is(content.document.characterSet, "EUC-JP", "Parent doc should report EUC-JP subsequently"); is(
is(content.frames[0].document.characterSet, "Shift_JIS", "Child doc should report Shift_JIS subsequently"); content.document.characterSet,
"EUC-JP",
"Parent doc should report EUC-JP subsequently"
);
is(
content.frames[0].document.characterSet,
"Shift_JIS",
"Child doc should report Shift_JIS subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-1.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-1.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 129, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
129,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 85, "Child doc should be windows-1252 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
85,
"Child doc should be windows-1252 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 129, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u0402"), 85, "Child doc should decode as windows-1251 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
129,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u0402"),
85,
"Child doc should decode as windows-1251 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"windows-1251",
"Child doc should report windows-1251 subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-10.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-10.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 151, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
151,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 71, "Child doc should be utf-8 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
71,
"Child doc should be utf-8 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 151, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 71, "Child doc should decode as utf-8 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
151,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
71,
"Child doc should decode as utf-8 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"UTF-8",
"Child doc should report UTF-8 subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-11.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-11.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 193, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
193,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 107, "Child doc should be utf-8 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
107,
"Child doc should be utf-8 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 193, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 107, "Child doc should decode as utf-8 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
193,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
107,
"Child doc should decode as utf-8 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"UTF-8",
"Child doc should report UTF-8 subsequently"
);
} }

View file

@ -1,18 +1,51 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-2.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-2.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 129, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
129,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u00E2\u201A\u00AC"), 78, "Child doc should be windows-1252 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf(
"\u00E2\u201A\u00AC"
),
78,
"Child doc should be windows-1252 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 129, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u0432\u201A\u00AC"), 78, "Child doc should decode as windows-1251 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
129,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf(
"\u0432\u201A\u00AC"
),
78,
"Child doc should decode as windows-1251 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"windows-1251",
"Child doc should report windows-1251 subsequently"
);
} }

View file

@ -1,18 +1,49 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-3.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-3.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 118, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
118,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 73, "Child doc should be utf-8 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
73,
"Child doc should be utf-8 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 118, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u0432\u201A\u00AC"), 73, "Child doc should decode as windows-1251 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
118,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf(
"\u0432\u201A\u00AC"
),
73,
"Child doc should decode as windows-1251 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"windows-1251",
"Child doc should report windows-1251 subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-4.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-4.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 132, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
132,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 79, "Child doc should be utf-8 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
79,
"Child doc should be utf-8 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 132, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 79, "Child doc should decode as utf-8 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
132,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
79,
"Child doc should decode as utf-8 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"UTF-8",
"Child doc should report UTF-8 subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-5.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-5.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 146, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
146,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 87, "Child doc should be utf-16 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
87,
"Child doc should be utf-16 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 146, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 87, "Child doc should decode as utf-16 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
146,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
87,
"Child doc should decode as utf-16 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "UTF-16LE", "Child doc should report UTF-16LE subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"UTF-16LE",
"Child doc should report UTF-16LE subsequently"
);
} }

View file

@ -1,18 +1,47 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-6.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-6.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 190, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
190,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 109, "Child doc should be utf-16 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
109,
"Child doc should be utf-16 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 190, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 109, "Child doc should decode as utf-16 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
190,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
109,
"Child doc should decode as utf-16 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "UTF-16BE", "Child doc should report UTF-16 subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"UTF-16BE",
"Child doc should report UTF-16 subsequently"
);
} }

View file

@ -1,18 +1,49 @@
function test() { function test() {
var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/"; var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
runCharsetTest(rootDir + "file_bug234628-7.html", afterOpen, "windows-1251", afterChangeCharset); runCharsetTest(
rootDir + "file_bug234628-7.html",
afterOpen,
"windows-1251",
afterChangeCharset
);
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 188, "Parent doc should be windows-1252 initially"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
188,
"Parent doc should be windows-1252 initially"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 107, "Child doc should be utf-8 initially"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
107,
"Child doc should be utf-8 initially"
);
} }
function afterChangeCharset() { function afterChangeCharset() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 188, "Parent doc should decode as windows-1251 subsequently"); is(
is(content.frames[0].document.documentElement.textContent.indexOf("\u0432\u201A\u00AC"), 107, "Child doc should decode as windows-1251 subsequently"); content.document.documentElement.textContent.indexOf("\u0402"),
188,
"Parent doc should decode as windows-1251 subsequently"
);
is(
content.frames[0].document.documentElement.textContent.indexOf(
"\u0432\u201A\u00AC"
),
107,
"Child doc should decode as windows-1251 subsequently"
);
is(content.document.characterSet, "windows-1251", "Parent doc should report windows-1251 subsequently"); is(
is(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently"); content.document.characterSet,
"windows-1251",
"Parent doc should report windows-1251 subsequently"
);
is(
content.frames[0].document.characterSet,
"windows-1251",
"Child doc should report windows-1251 subsequently"
);
} }

View file

@ -4,8 +4,15 @@ function test() {
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u0402"), 156, "Parent doc should be windows-1251"); is(
content.document.documentElement.textContent.indexOf("\u0402"),
156,
"Parent doc should be windows-1251"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u0402"), 99, "Child doc should be windows-1251"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u0402"),
99,
"Child doc should be windows-1251"
);
} }

View file

@ -4,8 +4,15 @@ function test() {
} }
function afterOpen() { function afterOpen() {
is(content.document.documentElement.textContent.indexOf("\u20AC"), 145, "Parent doc should be UTF-16"); is(
content.document.documentElement.textContent.indexOf("\u20AC"),
145,
"Parent doc should be UTF-16"
);
is(content.frames[0].document.documentElement.textContent.indexOf("\u20AC"), 96, "Child doc should be windows-1252"); is(
content.frames[0].document.documentElement.textContent.indexOf("\u20AC"),
96,
"Child doc should be windows-1252"
);
} }

View file

@ -4,11 +4,22 @@ add_task(async function test() {
function checkContentProcess(newBrowser, uri) { function checkContentProcess(newBrowser, uri) {
return ContentTask.spawn(newBrowser, uri, async function(uri) { return ContentTask.spawn(newBrowser, uri, async function(uri) {
var prin = content.document.nodePrincipal; var prin = content.document.nodePrincipal;
Assert.notEqual(prin, null, "Loaded principal must not be null when adding " + uri); Assert.notEqual(
Assert.notEqual(prin, undefined, "Loaded principal must not be undefined when loading " + uri); prin,
null,
"Loaded principal must not be null when adding " + uri
);
Assert.notEqual(
prin,
undefined,
"Loaded principal must not be undefined when loading " + uri
);
Assert.equal(prin.isSystemPrincipal, false, Assert.equal(
"Loaded principal must not be system when loading " + uri); prin.isSystemPrincipal,
false,
"Loaded principal must not be system when loading " + uri
);
}); });
} }
@ -18,11 +29,21 @@ add_task(async function test() {
await BrowserTestUtils.loadURI(newBrowser, uri); await BrowserTestUtils.loadURI(newBrowser, uri);
var prin = newBrowser.contentPrincipal; var prin = newBrowser.contentPrincipal;
isnot(prin, null, "Forced principal must not be null when loading " + uri); isnot(
isnot(prin, undefined, prin,
"Forced principal must not be undefined when loading " + uri); null,
is(prin.isSystemPrincipal, false, "Forced principal must not be null when loading " + uri
"Forced principal must not be system when loading " + uri); );
isnot(
prin,
undefined,
"Forced principal must not be undefined when loading " + uri
);
is(
prin.isSystemPrincipal,
false,
"Forced principal must not be system when loading " + uri
);
// Belt-and-suspenders e10s check: make sure that the same checks hold // Belt-and-suspenders e10s check: make sure that the same checks hold
// true in the content process. // true in the content process.
@ -32,9 +53,16 @@ add_task(async function test() {
prin = newBrowser.contentPrincipal; prin = newBrowser.contentPrincipal;
isnot(prin, null, "Loaded principal must not be null when adding " + uri); isnot(prin, null, "Loaded principal must not be null when adding " + uri);
isnot(prin, undefined, "Loaded principal must not be undefined when loading " + uri); isnot(
is(prin.isSystemPrincipal, false, prin,
"Loaded principal must not be system when loading " + uri); undefined,
"Loaded principal must not be undefined when loading " + uri
);
is(
prin.isSystemPrincipal,
false,
"Loaded principal must not be system when loading " + uri
);
// Belt-and-suspenders e10s check: make sure that the same checks hold // Belt-and-suspenders e10s check: make sure that the same checks hold
// true in the content process. // true in the content process.
@ -42,4 +70,3 @@ add_task(async function test() {
}); });
} }
}); });

View file

@ -1,13 +1,22 @@
add_task(async function test() { add_task(async function test() {
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, async function(newBrowser) { await BrowserTestUtils.withNewTab(
await ContentTask.spawn(newBrowser, null, async function() { { gBrowser, url: "about:blank" },
var prin = content.document.nodePrincipal; async function(newBrowser) {
Assert.notEqual(prin, null, "Loaded principal must not be null"); await ContentTask.spawn(newBrowser, null, async function() {
Assert.notEqual(prin, undefined, "Loaded principal must not be undefined"); var prin = content.document.nodePrincipal;
Assert.notEqual(prin, null, "Loaded principal must not be null");
Assert.notEqual(
prin,
undefined,
"Loaded principal must not be undefined"
);
Assert.equal(prin.isSystemPrincipal, false, Assert.equal(
"Loaded principal must not be system"); prin.isSystemPrincipal,
}); false,
}); "Loaded principal must not be system"
);
});
}
);
}); });

View file

@ -16,9 +16,16 @@ function test() {
} }
var prin = w.document.nodePrincipal; var prin = w.document.nodePrincipal;
isnot(prin, null, "Loaded principal must not be null when adding " + uri); isnot(prin, null, "Loaded principal must not be null when adding " + uri);
isnot(prin, undefined, "Loaded principal must not be undefined when loading " + uri); isnot(
is(prin.isSystemPrincipal, false, prin,
"Loaded principal must not be system when loading " + uri); undefined,
"Loaded principal must not be undefined when loading " + uri
);
is(
prin.isSystemPrincipal,
false,
"Loaded principal must not be system when loading " + uri
);
w.close(); w.close();
if (iteration == uris.length) { if (iteration == uris.length) {
@ -37,10 +44,16 @@ function test() {
uri = undefined; uri = undefined;
} }
isnot(prin, null, "Forced principal must not be null when loading " + uri); isnot(prin, null, "Forced principal must not be null when loading " + uri);
isnot(prin, undefined, isnot(
"Forced principal must not be undefined when loading " + uri); prin,
is(prin.isSystemPrincipal, false, undefined,
"Forced principal must not be system when loading " + uri); "Forced principal must not be undefined when loading " + uri
);
is(
prin.isSystemPrincipal,
false,
"Forced principal must not be system when loading " + uri
);
if (uri == undefined) { if (uri == undefined) {
// No actual load here, so just move along. // No actual load here, so just move along.
w.close(); w.close();

View file

@ -3,109 +3,123 @@
*/ */
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
var pageurl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug420605.html"; var pageurl =
var fragmenturl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug420605.html#firefox"; "http://mochi.test:8888/browser/docshell/test/browser/file_bug420605.html";
var fragmenturl =
"http://mochi.test:8888/browser/docshell/test/browser/file_bug420605.html#firefox";
var historyService = Cc["@mozilla.org/browser/nav-history-service;1"] var historyService = Cc[
.getService(Ci.nsINavHistoryService); "@mozilla.org/browser/nav-history-service;1"
].getService(Ci.nsINavHistoryService);
/* Queries nsINavHistoryService and returns a single history entry /* Queries nsINavHistoryService and returns a single history entry
* for a given URI */ * for a given URI */
function getNavHistoryEntry(aURI) { function getNavHistoryEntry(aURI) {
var options = historyService.getNewQueryOptions(); var options = historyService.getNewQueryOptions();
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY; options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
options.maxResults = 1; options.maxResults = 1;
var query = historyService.getNewQuery(); var query = historyService.getNewQuery();
query.uri = aURI; query.uri = aURI;
var result = historyService.executeQuery(query, options); var result = historyService.executeQuery(query, options);
result.root.containerOpen = true; result.root.containerOpen = true;
if (!result.root.childCount) { if (!result.root.childCount) {
return null; return null;
}
return result.root.getChild(0);
} }
return result.root.getChild(0);
}
// We'll save the favicon URL of the orignal page here and check that the // We'll save the favicon URL of the orignal page here and check that the
// page with a hash has the same favicon. // page with a hash has the same favicon.
var originalFavicon; var originalFavicon;
// Control flow in this test is a bit complicated. // Control flow in this test is a bit complicated.
// //
// When the page loads, onPageLoad (the DOMContentLoaded handler) and // When the page loads, onPageLoad (the DOMContentLoaded handler) and
// historyObserver::onPageChanged are both called, in some order. Once // historyObserver::onPageChanged are both called, in some order. Once
// they've both run, we click a fragment link in the content page // they've both run, we click a fragment link in the content page
// (clickLinkIfReady), which should trigger another onPageChanged event, // (clickLinkIfReady), which should trigger another onPageChanged event,
// this time for the fragment's URL. // this time for the fragment's URL.
var _clickLinkTimes = 0; var _clickLinkTimes = 0;
function clickLinkIfReady() { function clickLinkIfReady() {
_clickLinkTimes++; _clickLinkTimes++;
if (_clickLinkTimes == 2) { if (_clickLinkTimes == 2) {
BrowserTestUtils.synthesizeMouseAtCenter("#firefox-link", {}, BrowserTestUtils.synthesizeMouseAtCenter(
gBrowser.selectedBrowser); "#firefox-link",
{},
gBrowser.selectedBrowser
);
}
}
/* Global history observer that triggers for the two test URLs above. */
var historyObserver = {
onBeginUpdateBatch() {},
onEndUpdateBatch() {},
onTitleChanged(aURI, aPageTitle) {},
onDeleteURI(aURI) {},
onClearHistory() {},
onPageChanged(aURI, aWhat, aValue) {
if (aWhat != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) {
return;
} }
} aURI = aURI.spec;
switch (aURI) {
case pageurl:
ok(aValue, "Favicon value is not null for page without fragment.");
originalFavicon = aValue;
/* Global history observer that triggers for the two test URLs above. */ // Now that the favicon has loaded, click on fragment link.
var historyObserver = { // This should trigger the |case fragmenturl| below.
onBeginUpdateBatch() {}, clickLinkIfReady();
onEndUpdateBatch() {},
onTitleChanged(aURI, aPageTitle) {},
onDeleteURI(aURI) {},
onClearHistory() {},
onPageChanged(aURI, aWhat, aValue) {
if (aWhat != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) {
return;
}
aURI = aURI.spec;
switch (aURI) {
case pageurl:
ok(aValue, "Favicon value is not null for page without fragment.");
originalFavicon = aValue;
// Now that the favicon has loaded, click on fragment link. return;
// This should trigger the |case fragmenturl| below. case fragmenturl:
clickLinkIfReady(); // If the fragment URL's favicon isn't set, this branch won't
// be called and the test will time out.
return; is(
case fragmenturl: aValue,
// If the fragment URL's favicon isn't set, this branch won't originalFavicon,
// be called and the test will time out. "New favicon should be same as original favicon."
);
is(aValue, originalFavicon, "New favicon should be same as original favicon."); // Let's explicitly check that we can get the favicon
// from nsINavHistoryService now.
let info = getNavHistoryEntry(makeURI(aURI));
ok(info, "There must be a history entry for the fragment.");
ok(info.icon, "The history entry must have an associated favicon.");
historyService.removeObserver(historyObserver, false);
gBrowser.removeCurrentTab();
finish();
}
},
onPageExpired(aURI, aVisitTime, aWholeEntry) {},
QueryInterface: ChromeUtils.generateQI(["nsINavHistoryObserver"]),
};
historyService.addObserver(historyObserver);
// Let's explicitly check that we can get the favicon function onPageLoad() {
// from nsINavHistoryService now. clickLinkIfReady();
let info = getNavHistoryEntry(makeURI(aURI)); }
ok(info, "There must be a history entry for the fragment.");
ok(info.icon, "The history entry must have an associated favicon.");
historyService.removeObserver(historyObserver, false);
gBrowser.removeCurrentTab();
finish();
}
},
onPageExpired(aURI, aVisitTime, aWholeEntry) {},
QueryInterface: ChromeUtils.generateQI(["nsINavHistoryObserver"]),
};
historyService.addObserver(historyObserver);
function onPageLoad() { // Make sure neither of the test pages haven't been loaded before.
clickLinkIfReady(); var info = getNavHistoryEntry(makeURI(pageurl));
} ok(!info, "The test page must not have been visited already.");
info = getNavHistoryEntry(makeURI(fragmenturl));
ok(!info, "The fragment test page must not have been visited already.");
// Make sure neither of the test pages haven't been loaded before. // Now open the test page in a new tab.
var info = getNavHistoryEntry(makeURI(pageurl)); gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
ok(!info, "The test page must not have been visited already."); BrowserTestUtils.waitForContentEvent(
info = getNavHistoryEntry(makeURI(fragmenturl)); gBrowser.selectedBrowser,
ok(!info, "The fragment test page must not have been visited already."); "DOMContentLoaded",
true
// Now open the test page in a new tab. ).then(onPageLoad);
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); BrowserTestUtils.loadURI(gBrowser.selectedBrowser, pageurl);
BrowserTestUtils.waitForContentEvent(gBrowser.selectedBrowser, "DOMContentLoaded", true).then(onPageLoad);
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, pageurl);
} }

View file

@ -9,7 +9,9 @@ add_task(async function runTests() {
// Check if all history listeners are always notified. // Check if all history listeners are always notified.
info("# part 1"); info("# part 1");
await whenPageShown(browser, () => BrowserTestUtils.loadURI(browser, "http://www.example.com/")); await whenPageShown(browser, () =>
BrowserTestUtils.loadURI(browser, "http://www.example.com/")
);
await checkListeners("newentry", "shistory has a new entry"); await checkListeners("newentry", "shistory has a new entry");
ok(browser.canGoBack, "we can go back"); ok(browser.canGoBack, "we can go back");
@ -28,7 +30,7 @@ add_task(async function runTests() {
// Check nsISHistory.notifyOnHistoryReload // Check nsISHistory.notifyOnHistoryReload
info("# part 2"); info("# part 2");
ok((await notifyReload()), "reloading has not been canceled"); ok(await notifyReload(), "reloading has not been canceled");
await checkListeners("reload", "saw the reload notification"); await checkListeners("reload", "saw the reload notification");
// Let the first listener cancel the reload action. // Let the first listener cancel the reload action.
@ -66,7 +68,7 @@ function listenOnce(message, arg = {}) {
} }
function checkListeners(aLast, aMessage) { function checkListeners(aLast, aMessage) {
return listenOnce("bug422543:getListenerStatus").then((listenerStatuses) => { return listenOnce("bug422543:getListenerStatus").then(listenerStatuses => {
is(listenerStatuses[0], aLast, aMessage); is(listenerStatuses[0], aLast, aMessage);
is(listenerStatuses[1], aLast, aMessage); is(listenerStatuses[1], aLast, aMessage);
}); });
@ -87,27 +89,34 @@ function setListenerRetval(num, val) {
} }
function setup() { function setup() {
return BrowserTestUtils.openNewForegroundTab(gBrowser, return BrowserTestUtils.openNewForegroundTab(
"http://mochi.test:8888") gBrowser,
.then(function(tab) { "http://mochi.test:8888"
).then(function(tab) {
let browser = tab.linkedBrowser; let browser = tab.linkedBrowser;
registerCleanupFunction(async function() { registerCleanupFunction(async function() {
await listenOnce("bug422543:cleanup"); await listenOnce("bug422543:cleanup");
gBrowser.removeTab(tab); gBrowser.removeTab(tab);
}); });
browser.messageManager browser.messageManager.loadFrameScript(
.loadFrameScript(getRootDirectory(gTestPath) + "file_bug422543_script.js", false); getRootDirectory(gTestPath) + "file_bug422543_script.js",
false
);
}); });
} }
function whenPageShown(aBrowser, aNavigation) { function whenPageShown(aBrowser, aNavigation) {
let listener = ContentTask.spawn(aBrowser, null, function() { let listener = ContentTask.spawn(aBrowser, null, function() {
return new Promise(resolve => { return new Promise(resolve => {
addEventListener("pageshow", function onLoad() { addEventListener(
removeEventListener("pageshow", onLoad, true); "pageshow",
resolve(); function onLoad() {
}, true); removeEventListener("pageshow", onLoad, true);
resolve();
},
true
);
}); });
}); });

View file

@ -3,7 +3,9 @@ var newBrowser;
function task() { function task() {
let resolve; let resolve;
let promise = new Promise(r => { resolve = r; }); let promise = new Promise(r => {
resolve = r;
});
addEventListener("DOMContentLoaded", checkPage, false); addEventListener("DOMContentLoaded", checkPage, false);
@ -13,11 +15,16 @@ function task() {
} }
removeEventListener("DOMContentLoaded", checkPage, false); removeEventListener("DOMContentLoaded", checkPage, false);
is(content.document.getElementById("test_span"), null, "Error message should not be parsed as HTML, and hence shouldn't include the 'test_span' element."); is(
content.document.getElementById("test_span"),
null,
"Error message should not be parsed as HTML, and hence shouldn't include the 'test_span' element."
);
resolve(); resolve();
} }
var chromeURL = "about:neterror?e=nssBadCert&u=https%3A//test.kuix.de/&c=UTF-8&d=This%20sentence%20should%20not%20be%20parsed%20to%20include%20a%20%3Cspan%20id=%22test_span%22%3Enamed%3C/span%3E%20span%20tag.%0A%0AThe%20certificate%20is%20only%20valid%20for%20%3Ca%20id=%22cert_domain_link%22%20title=%22kuix.de%22%3Ekuix.de%3C/a%3E%0A%0A(Error%20code%3A%20ssl_error_bad_cert_domain)"; var chromeURL =
"about:neterror?e=nssBadCert&u=https%3A//test.kuix.de/&c=UTF-8&d=This%20sentence%20should%20not%20be%20parsed%20to%20include%20a%20%3Cspan%20id=%22test_span%22%3Enamed%3C/span%3E%20span%20tag.%0A%0AThe%20certificate%20is%20only%20valid%20for%20%3Ca%20id=%22cert_domain_link%22%20title=%22kuix.de%22%3Ekuix.de%3C/a%3E%0A%0A(Error%20code%3A%20ssl_error_bad_cert_domain)";
content.location = chromeURL; content.location = chromeURL;
return promise; return promise;

View file

@ -3,77 +3,83 @@
*/ */
add_task(async function() { add_task(async function() {
var pagetitle = "Page Title for Bug 503832"; var pagetitle = "Page Title for Bug 503832";
var pageurl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug503832.html"; var pageurl =
var fragmenturl = "http://mochi.test:8888/browser/docshell/test/browser/file_bug503832.html#firefox"; "http://mochi.test:8888/browser/docshell/test/browser/file_bug503832.html";
var fragmenturl =
"http://mochi.test:8888/browser/docshell/test/browser/file_bug503832.html#firefox";
var historyService = Cc["@mozilla.org/browser/nav-history-service;1"] var historyService = Cc[
.getService(Ci.nsINavHistoryService); "@mozilla.org/browser/nav-history-service;1"
].getService(Ci.nsINavHistoryService);
let fragmentPromise = new Promise(resolve => { let fragmentPromise = new Promise(resolve => {
/* Global history observer that triggers for the two test URLs above. */ /* Global history observer that triggers for the two test URLs above. */
var historyObserver = { var historyObserver = {
onBeginUpdateBatch() {}, onBeginUpdateBatch() {},
onEndUpdateBatch() {}, onEndUpdateBatch() {},
onTitleChanged(aURI, aPageTitle) { onTitleChanged(aURI, aPageTitle) {
aURI = aURI.spec; aURI = aURI.spec;
switch (aURI) { switch (aURI) {
case pageurl: case pageurl:
is(aPageTitle, pagetitle, "Correct page title for " + aURI); is(aPageTitle, pagetitle, "Correct page title for " + aURI);
return; return;
case fragmenturl: case fragmenturl:
is(aPageTitle, pagetitle, "Correct page title for " + aURI); is(aPageTitle, pagetitle, "Correct page title for " + aURI);
// If titles for fragment URLs aren't set, this code // If titles for fragment URLs aren't set, this code
// branch won't be called and the test will timeout, // branch won't be called and the test will timeout,
// resulting in a failure // resulting in a failure
historyService.removeObserver(historyObserver, false); historyService.removeObserver(historyObserver, false);
resolve(); resolve();
}
},
onDeleteURI(aURI) {},
onClearHistory() {},
onPageChanged(aURI, aWhat, aValue) {},
onDeleteVisits() {},
QueryInterface: ChromeUtils.generateQI(["nsINavHistoryObserver"]),
};
historyService.addObserver(historyObserver);
});
/* Queries nsINavHistoryService and returns a single history entry
* for a given URI */
function getNavHistoryEntry(aURI) {
var options = historyService.getNewQueryOptions();
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
options.maxResults = 1;
var query = historyService.getNewQuery();
query.uri = aURI;
var result = historyService.executeQuery(query, options);
result.root.containerOpen = true;
if (!result.root.childCount) {
return null;
} }
var node = result.root.getChild(0); },
result.root.containerOpen = false; onDeleteURI(aURI) {},
return node; onClearHistory() {},
onPageChanged(aURI, aWhat, aValue) {},
onDeleteVisits() {},
QueryInterface: ChromeUtils.generateQI(["nsINavHistoryObserver"]),
};
historyService.addObserver(historyObserver);
});
/* Queries nsINavHistoryService and returns a single history entry
* for a given URI */
function getNavHistoryEntry(aURI) {
var options = historyService.getNewQueryOptions();
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
options.maxResults = 1;
var query = historyService.getNewQuery();
query.uri = aURI;
var result = historyService.executeQuery(query, options);
result.root.containerOpen = true;
if (!result.root.childCount) {
return null;
} }
var node = result.root.getChild(0);
result.root.containerOpen = false;
return node;
}
// Make sure neither of the test pages haven't been loaded before. // Make sure neither of the test pages haven't been loaded before.
var info = getNavHistoryEntry(makeURI(pageurl)); var info = getNavHistoryEntry(makeURI(pageurl));
ok(!info, "The test page must not have been visited already."); ok(!info, "The test page must not have been visited already.");
info = getNavHistoryEntry(makeURI(fragmenturl)); info = getNavHistoryEntry(makeURI(fragmenturl));
ok(!info, "The fragment test page must not have been visited already."); ok(!info, "The fragment test page must not have been visited already.");
// Now open the test page in a new tab // Now open the test page in a new tab
await BrowserTestUtils.openNewForegroundTab(gBrowser, pageurl); await BrowserTestUtils.openNewForegroundTab(gBrowser, pageurl);
// Now that the page is loaded, click on fragment link // Now that the page is loaded, click on fragment link
await BrowserTestUtils.synthesizeMouseAtCenter("#firefox-link", {}, await BrowserTestUtils.synthesizeMouseAtCenter(
gBrowser.selectedBrowser); "#firefox-link",
await fragmentPromise; {},
gBrowser.selectedBrowser
);
await fragmentPromise;
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
}); });

View file

@ -1,26 +1,32 @@
add_task(async function test() { add_task(async function test() {
await BrowserTestUtils.withNewTab({ gBrowser, url: "http://example.com" }, async function(browser) { await BrowserTestUtils.withNewTab(
let numLocationChanges = 0; { gBrowser, url: "http://example.com" },
async function(browser) {
let numLocationChanges = 0;
let listener = { let listener = {
onLocationChange(browser, webProgress, request, uri, flags) { onLocationChange(browser, webProgress, request, uri, flags) {
info("location change: " + (uri && uri.spec)); info("location change: " + (uri && uri.spec));
numLocationChanges++; numLocationChanges++;
}, },
}; };
gBrowser.addTabsProgressListener(listener); gBrowser.addTabsProgressListener(listener);
await ContentTask.spawn(browser, null, function() { await ContentTask.spawn(browser, null, function() {
// pushState to a new URL (http://example.com/foo"). This should trigger // pushState to a new URL (http://example.com/foo"). This should trigger
// exactly one LocationChange event. // exactly one LocationChange event.
content.history.pushState(null, null, "foo"); content.history.pushState(null, null, "foo");
}); });
await Promise.resolve(); await Promise.resolve();
gBrowser.removeTabsProgressListener(listener); gBrowser.removeTabsProgressListener(listener);
is(numLocationChanges, 1, is(
"pushState should cause exactly one LocationChange event."); numLocationChanges,
}); 1,
"pushState should cause exactly one LocationChange event."
);
}
);
}); });

View file

@ -11,7 +11,7 @@
function test() { function test() {
const testDir = "http://mochi.test:8888/browser/docshell/test/browser/"; const testDir = "http://mochi.test:8888/browser/docshell/test/browser/";
const origURL = testDir + "file_bug655270.html"; const origURL = testDir + "file_bug655270.html";
const newURL = origURL + "?new_page"; const newURL = origURL + "?new_page";
const faviconURL = testDir + "favicon_bug655270.ico"; const faviconURL = testDir + "favicon_bug655270.ico";
@ -26,8 +26,9 @@ function test() {
let observer = { let observer = {
onPageChanged(aURI, aWhat, aValue) { onPageChanged(aURI, aWhat, aValue) {
if (aWhat != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) if (aWhat != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) {
return; return;
}
if (aURI.spec == origURL) { if (aURI.spec == origURL) {
is(aValue, faviconURL, "FaviconURL for original URI"); is(aValue, faviconURL, "FaviconURL for original URI");
@ -46,12 +47,12 @@ function test() {
} }
}, },
onBeginUpdateBatch() { }, onBeginUpdateBatch() {},
onEndUpdateBatch() { }, onEndUpdateBatch() {},
onTitleChanged() { }, onTitleChanged() {},
onDeleteURI() { }, onDeleteURI() {},
onClearHistory() { }, onClearHistory() {},
onDeleteVisits() { }, onDeleteVisits() {},
QueryInterface: ChromeUtils.generateQI([Ci.nsINavHistoryObserver]), QueryInterface: ChromeUtils.generateQI([Ci.nsINavHistoryObserver]),
}; };

View file

@ -11,7 +11,8 @@
add_task(async function test() { add_task(async function test() {
waitForExplicitFinish(); waitForExplicitFinish();
await BrowserTestUtils.withNewTab({ gBrowser, url: "http://example.com" }, await BrowserTestUtils.withNewTab(
{ gBrowser, url: "http://example.com" },
async function(browser) { async function(browser) {
await ContentTask.spawn(browser, null, async function() { await ContentTask.spawn(browser, null, async function() {
let cw = content; let cw = content;
@ -19,12 +20,15 @@ add_task(async function test() {
ok(oldTitle, "Content window should initially have a title."); ok(oldTitle, "Content window should initially have a title.");
cw.history.pushState("", "", "new_page"); cw.history.pushState("", "", "new_page");
let shistory = cw.docShell let shistory = cw.docShell.QueryInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIWebNavigation) .sessionHistory;
.sessionHistory;
is(shistory.legacySHistory.getEntryAtIndex(shistory.index).title, is(
oldTitle, "SHEntry title after pushstate."); shistory.legacySHistory.getEntryAtIndex(shistory.index).title,
oldTitle,
"SHEntry title after pushstate."
);
}); });
}); }
);
}); });

View file

@ -8,58 +8,75 @@
* entries, history.index can end up out of range (>= history.count). * entries, history.index can end up out of range (>= history.count).
*/ */
const URL = "http://mochi.test:8888/browser/docshell/test/browser/file_bug670318.html"; const URL =
"http://mochi.test:8888/browser/docshell/test/browser/file_bug670318.html";
add_task(async function test() { add_task(async function test() {
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, await BrowserTestUtils.withNewTab(
async function(browser) { { gBrowser, url: "about:blank" },
await ContentTask.spawn(browser, URL, async function(URL) { async function(browser) {
let history = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory; await ContentTask.spawn(browser, URL, async function(URL) {
let count = 0; let history = docShell.QueryInterface(Ci.nsIWebNavigation)
.sessionHistory;
let count = 0;
let testDone = {}; let testDone = {};
testDone.promise = new Promise(resolve => { testDone.resolve = resolve; }); testDone.promise = new Promise(resolve => {
testDone.resolve = resolve;
});
let listener = { let listener = {
OnHistoryNewEntry(aNewURI) { OnHistoryNewEntry(aNewURI) {
if (aNewURI.spec == URL && 5 == ++count) { if (aNewURI.spec == URL && 5 == ++count) {
addEventListener("load", function onLoad() { addEventListener(
removeEventListener("load", onLoad, true); "load",
function onLoad() {
removeEventListener("load", onLoad, true);
Assert.ok(history.index < history.count, "history.index is valid"); Assert.ok(
testDone.resolve(); history.index < history.count,
}, true); "history.index is valid"
);
testDone.resolve();
},
true
);
history.legacySHistory.removeSHistoryListener(listener); history.legacySHistory.removeSHistoryListener(listener);
delete content._testListener; delete content._testListener;
content.setTimeout(() => { content.location.reload(); }, 0); content.setTimeout(() => {
} content.location.reload();
}, }, 0);
}
},
OnHistoryReload: () => true, OnHistoryReload: () => true,
OnHistoryGotoIndex: () => {}, OnHistoryGotoIndex: () => {},
OnHistoryPurge: () => {}, OnHistoryPurge: () => {},
OnHistoryReplaceEntry: () => { OnHistoryReplaceEntry: () => {
// The initial load of about:blank causes a transient entry to be // The initial load of about:blank causes a transient entry to be
// created, so our first navigation to a real page is a replace // created, so our first navigation to a real page is a replace
// instead of a new entry. // instead of a new entry.
++count; ++count;
}, },
QueryInterface: ChromeUtils.generateQI([Ci.nsISHistoryListener, QueryInterface: ChromeUtils.generateQI([
Ci.nsISupportsWeakReference]), Ci.nsISHistoryListener,
}; Ci.nsISupportsWeakReference,
]),
};
history.legacySHistory.addSHistoryListener(listener); history.legacySHistory.addSHistoryListener(listener);
// Since listener implements nsISupportsWeakReference, we are // Since listener implements nsISupportsWeakReference, we are
// responsible for keeping it alive so that the GC doesn't clear // responsible for keeping it alive so that the GC doesn't clear
// it before the test completes. We do this by anchoring the listener // it before the test completes. We do this by anchoring the listener
// to the content global window, and clearing it just before the test // to the content global window, and clearing it just before the test
// completes. // completes.
content._testListener = listener; content._testListener = listener;
content.location = URL; content.location = URL;
await testDone.promise; await testDone.promise;
}); });
}); }
);
}); });

View file

@ -5,42 +5,52 @@
// before the load and then sets its location during the load. This should // before the load and then sets its location during the load. This should
// create just one SHEntry. // create just one SHEntry.
var doc = "data:text/html,<html><body onload='load()'>" + var doc =
"<script>" + "data:text/html,<html><body onload='load()'>" +
" var iframe = document.createElement('iframe');" + "<script>" +
" iframe.id = 'iframe';" + " var iframe = document.createElement('iframe');" +
" document.documentElement.appendChild(iframe);" + " iframe.id = 'iframe';" +
" function load() {" + " document.documentElement.appendChild(iframe);" +
" iframe.src = 'data:text/html,Hello!';" + " function load() {" +
" }" + " iframe.src = 'data:text/html,Hello!';" +
"</script>" + " }" +
"</body></html>"; "</script>" +
"</body></html>";
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
let taskFinished; let taskFinished;
let tab = BrowserTestUtils.addTab(gBrowser, doc, {}, (tab) => { let tab = BrowserTestUtils.addTab(gBrowser, doc, {}, tab => {
taskFinished = ContentTask.spawn(tab.linkedBrowser, null, () => { taskFinished = ContentTask.spawn(tab.linkedBrowser, null, () => {
return new Promise(resolve => { return new Promise(resolve => {
addEventListener("load", function() { addEventListener(
// The main page has loaded. Now wait for the iframe to load. "load",
let iframe = content.document.getElementById("iframe"); function() {
iframe.addEventListener("load", function listener(aEvent) { // The main page has loaded. Now wait for the iframe to load.
// Wait for the iframe to load the new document, not about:blank. let iframe = content.document.getElementById("iframe");
if (!iframe.src) iframe.addEventListener(
return; "load",
function listener(aEvent) {
// Wait for the iframe to load the new document, not about:blank.
if (!iframe.src) {
return;
}
iframe.removeEventListener("load", listener, true); iframe.removeEventListener("load", listener, true);
let shistory = content.docShell let shistory = content.docShell.QueryInterface(
.QueryInterface(Ci.nsIWebNavigation) Ci.nsIWebNavigation
.sessionHistory; ).sessionHistory;
Assert.equal(shistory.count, 1, "shistory count should be 1."); Assert.equal(shistory.count, 1, "shistory count should be 1.");
resolve(); resolve();
}, true); },
}, true); true
);
},
true
);
}); });
}); });
}); });

View file

@ -3,20 +3,32 @@ var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, rootDir + "file_bug852909.png"); gBrowser.selectedTab = BrowserTestUtils.addTab(
gBrowser,
rootDir + "file_bug852909.png"
);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(image); BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(image);
} }
function image(event) { function image(event) {
ok(!gBrowser.selectedTab.mayEnableCharacterEncodingMenu, "Docshell should say the menu should be disabled for images."); ok(
!gBrowser.selectedTab.mayEnableCharacterEncodingMenu,
"Docshell should say the menu should be disabled for images."
);
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, rootDir + "file_bug852909.pdf"); gBrowser.selectedTab = BrowserTestUtils.addTab(
gBrowser,
rootDir + "file_bug852909.pdf"
);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(pdf); BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(pdf);
} }
function pdf(event) { function pdf(event) {
ok(!gBrowser.selectedTab.mayEnableCharacterEncodingMenu, "Docshell should say the menu should be disabled for PDF.js."); ok(
!gBrowser.selectedTab.mayEnableCharacterEncodingMenu,
"Docshell should say the menu should be disabled for PDF.js."
);
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();
finish(); finish();

View file

@ -4,21 +4,33 @@
function testContent(text) { function testContent(text) {
return ContentTask.spawn(gBrowser.selectedBrowser, text, text => { return ContentTask.spawn(gBrowser.selectedBrowser, text, text => {
Assert.equal(content.document.getElementById("testpar").innerHTML, text, Assert.equal(
"<p> contains expected text"); content.document.getElementById("testpar").innerHTML,
Assert.equal(content.document.getElementById("testtextarea").innerHTML, text, text,
"<textarea> contains expected text"); "<p> contains expected text"
Assert.equal(content.document.getElementById("testinput").value, text, );
"<input> contains expected text"); Assert.equal(
content.document.getElementById("testtextarea").innerHTML,
text,
"<textarea> contains expected text"
);
Assert.equal(
content.document.getElementById("testinput").value,
text,
"<input> contains expected text"
);
}); });
} }
function afterOpen() { function afterOpen() {
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterChangeCharset); BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(
afterChangeCharset
);
/* The test text decoded incorrectly as Windows-1251. This is the "right" wrong /* The test text decoded incorrectly as Windows-1251. This is the "right" wrong
text; anything else is unexpected. */ text; anything else is unexpected. */
const wrongText = "\u0453\u2020\u0453\u006A\u0453\u0052\u0403\u005B\u0453\u0068\u201A\u041D\u0403\u0041\u201A\u00B7\u201A\u0427\u201A\u0414\u201A\u041C\u2022\u00B6\u040B\u0459\u201A\u0419\u040A\u0415\u2014\u004C\u201A\u041C\u201D\u0424\u040C\u2020\u201A\u0440\u2022\u0074\u2014\u005E\u201A\u00B5\u201A\u042C\u201A\u00B7"; const wrongText =
"\u0453\u2020\u0453\u006A\u0453\u0052\u0403\u005B\u0453\u0068\u201A\u041D\u0403\u0041\u201A\u00B7\u201A\u0427\u201A\u0414\u201A\u041C\u2022\u00B6\u040B\u0459\u201A\u0419\u040A\u0415\u2014\u004C\u201A\u041C\u201D\u0424\u040C\u2020\u201A\u0440\u2022\u0074\u2014\u005E\u201A\u00B5\u201A\u042C\u201A\u00B7";
/* Test that the content on load is the expected wrong decoding */ /* Test that the content on load is the expected wrong decoding */
testContent(wrongText).then(() => { testContent(wrongText).then(() => {
@ -28,7 +40,8 @@ function afterOpen() {
function afterChangeCharset() { function afterChangeCharset() {
/* The test text decoded correctly as Shift_JIS */ /* The test text decoded correctly as Shift_JIS */
const rightText = "\u30E6\u30CB\u30B3\u30FC\u30C9\u306F\u3001\u3059\u3079\u3066\u306E\u6587\u5B57\u306B\u56FA\u6709\u306E\u756A\u53F7\u3092\u4ED8\u4E0E\u3057\u307E\u3059"; const rightText =
"\u30E6\u30CB\u30B3\u30FC\u30C9\u306F\u3001\u3059\u3079\u3066\u306E\u6587\u5B57\u306B\u56FA\u6709\u306E\u756A\u53F7\u3092\u4ED8\u4E0E\u3057\u307E\u3059";
/* test that the content is decoded correctly */ /* test that the content is decoded correctly */
testContent(rightText).then(() => { testContent(rightText).then(() => {
@ -44,11 +57,14 @@ function test() {
// are always UTF-8 (bug 617339) and we are testing decoding from other // are always UTF-8 (bug 617339) and we are testing decoding from other
// charsets. // charsets.
var jar = getJar(getRootDirectory(gTestPath)); var jar = getJar(getRootDirectory(gTestPath));
var dir = jar ? var dir = jar
extractJarToTmp(jar) : ? extractJarToTmp(jar)
getChromeDir(getResolvedURI(gTestPath)); : getChromeDir(getResolvedURI(gTestPath));
var rootDir = Services.io.newFileURI(dir).spec; var rootDir = Services.io.newFileURI(dir).spec;
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, rootDir + "test-form_sjis.html"); gBrowser.selectedTab = BrowserTestUtils.addTab(
gBrowser,
rootDir + "test-form_sjis.html"
);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterOpen); BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterOpen);
} }

View file

@ -21,8 +21,10 @@ add_task(async function test_click_link_within_view_source() {
await BrowserTestUtils.withNewTab(TEST_FILE_URI, async function(aBrowser) { await BrowserTestUtils.withNewTab(TEST_FILE_URI, async function(aBrowser) {
let tabSpec = gBrowser.selectedBrowser.currentURI.spec; let tabSpec = gBrowser.selectedBrowser.currentURI.spec;
info("loading: " + tabSpec); info("loading: " + tabSpec);
ok(tabSpec.startsWith("file://") && tabSpec.endsWith(TEST_FILE), ok(
"sanity check to make sure html loaded"); tabSpec.startsWith("file://") && tabSpec.endsWith(TEST_FILE),
"sanity check to make sure html loaded"
);
info("click view-source of html"); info("click view-source of html");
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser); let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
@ -31,19 +33,33 @@ add_task(async function test_click_link_within_view_source() {
let tab = await tabPromise; let tab = await tabPromise;
tabSpec = gBrowser.selectedBrowser.currentURI.spec; tabSpec = gBrowser.selectedBrowser.currentURI.spec;
info("loading: " + tabSpec); info("loading: " + tabSpec);
ok(tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(TEST_FILE), ok(
"loading view-source of html succeeded"); tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(TEST_FILE),
"loading view-source of html succeeded"
);
info("click testlink within view-source page"); info("click testlink within view-source page");
let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url => url.endsWith("dummy_page.html")); let loadPromise = BrowserTestUtils.browserLoaded(
tab.linkedBrowser,
false,
url => url.endsWith("dummy_page.html")
);
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() { await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
if (content.document.readyState != "complete") { if (content.document.readyState != "complete") {
await ContentTaskUtils.waitForEvent(content.document, "readystatechange", false, () => await ContentTaskUtils.waitForEvent(
content.document.readyState == "complete"); content.document,
"readystatechange",
false,
() => content.document.readyState == "complete"
);
} }
// document.getElementById() does not work on a view-source page, hence we use document.links // document.getElementById() does not work on a view-source page, hence we use document.links
let linksOnPage = content.document.links; let linksOnPage = content.document.links;
is(linksOnPage.length, 1, "sanity check: make sure only one link is present on page"); is(
linksOnPage.length,
1,
"sanity check: make sure only one link is present on page"
);
let myLink = content.document.links[0]; let myLink = content.document.links[0];
myLink.click(); myLink.click();
}); });
@ -52,8 +68,10 @@ add_task(async function test_click_link_within_view_source() {
tabSpec = gBrowser.selectedBrowser.currentURI.spec; tabSpec = gBrowser.selectedBrowser.currentURI.spec;
info("loading: " + tabSpec); info("loading: " + tabSpec);
ok(tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(DUMMY_FILE), ok(
"loading view-source of html succeeded"); tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(DUMMY_FILE),
"loading view-source of html succeeded"
);
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);
}); });

View file

@ -3,9 +3,13 @@
"use strict"; "use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com"); const TEST_PATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
const TEST_URI = TEST_PATH + "file_cross_process_csp_inheritance.html"; const TEST_URI = TEST_PATH + "file_cross_process_csp_inheritance.html";
const DATA_URI = "data:text/html,<html>test-same-diff-process-csp-inhertiance</html>"; const DATA_URI =
"data:text/html,<html>test-same-diff-process-csp-inhertiance</html>";
function getCurrentPID(aBrowser) { function getCurrentPID(aBrowser) {
return ContentTask.spawn(aBrowser, null, () => { return ContentTask.spawn(aBrowser, null, () => {
@ -21,26 +25,38 @@ function getCurrentURI(aBrowser) {
} }
function verifyResult(aTestName, aBrowser, aDataURI, aPID, aSamePID) { function verifyResult(aTestName, aBrowser, aDataURI, aPID, aSamePID) {
return ContentTask.spawn(aBrowser, {aTestName, aDataURI, aPID, aSamePID}, async function({aTestName, aDataURI, aPID, aSamePID}) { return ContentTask.spawn(
// sanity, to make sure the correct URI was loaded aBrowser,
let channel = content.docShell.currentDocumentChannel; { aTestName, aDataURI, aPID, aSamePID },
is(channel.URI.asciiSpec, aDataURI, aTestName + ": correct data uri loaded"); async function({ aTestName, aDataURI, aPID, aSamePID }) {
// sanity, to make sure the correct URI was loaded
let channel = content.docShell.currentDocumentChannel;
is(
channel.URI.asciiSpec,
aDataURI,
aTestName + ": correct data uri loaded"
);
// check that the process ID is the same/different when opening the new tab // check that the process ID is the same/different when opening the new tab
let pid = Services.appinfo.processID; let pid = Services.appinfo.processID;
if (aSamePID) { if (aSamePID) {
is(pid, aPID, aTestName + ": process ID needs to be identical"); is(pid, aPID, aTestName + ": process ID needs to be identical");
} else { } else {
isnot(pid, aPID, aTestName + ": process ID needs to be different"); isnot(pid, aPID, aTestName + ": process ID needs to be different");
}
// finally, evaluate that the CSP was set.
let cspOBJ = JSON.parse(content.document.cspJSON);
let policies = cspOBJ["csp-policies"];
is(policies.length, 1, "should be one policy");
let policy = policies[0];
is(
policy["script-src"],
"'none'",
aTestName + ": script-src directive matches"
);
} }
);
// finally, evaluate that the CSP was set.
let cspOBJ = JSON.parse(content.document.cspJSON);
let policies = cspOBJ["csp-policies"];
is(policies.length, 1, "should be one policy");
let policy = policies[0];
is(policy["script-src"], "'none'", aTestName + ": script-src directive matches");
});
} }
async function simulateCspInheritanceForNewTab(aTestName, aSamePID) { async function simulateCspInheritanceForNewTab(aTestName, aSamePID) {
@ -52,11 +68,20 @@ async function simulateCspInheritanceForNewTab(aTestName, aSamePID) {
let pid = await getCurrentPID(gBrowser.selectedBrowser); let pid = await getCurrentPID(gBrowser.selectedBrowser);
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI); let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
// simulate click // simulate click
BrowserTestUtils.synthesizeMouseAtCenter("#testLink", {}, BrowserTestUtils.synthesizeMouseAtCenter(
gBrowser.selectedBrowser); "#testLink",
{},
gBrowser.selectedBrowser
);
let tab = await loadPromise; let tab = await loadPromise;
gBrowser.selectTabAtIndex(2); gBrowser.selectTabAtIndex(2);
await verifyResult(aTestName, gBrowser.selectedBrowser, DATA_URI, pid, aSamePID); await verifyResult(
aTestName,
gBrowser.selectedBrowser,
DATA_URI,
pid,
aSamePID
);
await BrowserTestUtils.removeTab(tab); await BrowserTestUtils.removeTab(tab);
}); });
} }
@ -64,13 +89,17 @@ async function simulateCspInheritanceForNewTab(aTestName, aSamePID) {
add_task(async function test_csp_inheritance_diff_process() { add_task(async function test_csp_inheritance_diff_process() {
// forcing the new data: URI load to happen in a *new* process by flipping the pref // forcing the new data: URI load to happen in a *new* process by flipping the pref
// to force <a rel="noopener" ...> to be loaded in a new process. // to force <a rel="noopener" ...> to be loaded in a new process.
await SpecialPowers.pushPrefEnv({"set": [["dom.noopener.newprocess.enabled", true]]}); await SpecialPowers.pushPrefEnv({
set: [["dom.noopener.newprocess.enabled", true]],
});
await simulateCspInheritanceForNewTab("diff-process-inheritance", false); await simulateCspInheritanceForNewTab("diff-process-inheritance", false);
}); });
add_task(async function test_csp_inheritance_same_process() { add_task(async function test_csp_inheritance_same_process() {
// forcing the new data: URI load to happen in a *same* process by resetting the pref // forcing the new data: URI load to happen in a *same* process by resetting the pref
// and loaded <a rel="noopener" ...> in the *same* process. // and loaded <a rel="noopener" ...> in the *same* process.
await SpecialPowers.pushPrefEnv({"set": [["dom.noopener.newprocess.enabled", false]]}); await SpecialPowers.pushPrefEnv({
set: [["dom.noopener.newprocess.enabled", false]],
});
await simulateCspInheritanceForNewTab("same-process-inheritance", true); await simulateCspInheritanceForNewTab("same-process-inheritance", true);
}); });

View file

@ -1,11 +1,18 @@
"use strict"; "use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com"); const TEST_PATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
const TEST_URI = TEST_PATH + "file_csp_uir.html"; // important to be http: to test upgrade-insecure-requests const TEST_URI = TEST_PATH + "file_csp_uir.html"; // important to be http: to test upgrade-insecure-requests
const RESULT_URI = TEST_PATH.replace("http://", "https://") + "file_csp_uir_dummy.html"; const RESULT_URI =
TEST_PATH.replace("http://", "https://") + "file_csp_uir_dummy.html";
function verifyCSP(aTestName, aBrowser, aResultURI) { function verifyCSP(aTestName, aBrowser, aResultURI) {
return ContentTask.spawn(aBrowser, {aTestName, aResultURI}, async function({aTestName, aResultURI}) { return ContentTask.spawn(aBrowser, { aTestName, aResultURI }, async function({
aTestName,
aResultURI,
}) {
let channel = content.docShell.currentDocumentChannel; let channel = content.docShell.currentDocumentChannel;
is(channel.URI.asciiSpec, aResultURI, "testing CSP for " + aTestName); is(channel.URI.asciiSpec, aResultURI, "testing CSP for " + aTestName);
}); });
@ -13,10 +20,17 @@ function verifyCSP(aTestName, aBrowser, aResultURI) {
add_task(async function test_csp_inheritance_regular_click() { add_task(async function test_csp_inheritance_regular_click() {
await BrowserTestUtils.withNewTab(TEST_URI, async function(browser) { await BrowserTestUtils.withNewTab(TEST_URI, async function(browser) {
let loadPromise = BrowserTestUtils.browserLoaded(browser, false, RESULT_URI); let loadPromise = BrowserTestUtils.browserLoaded(
browser,
false,
RESULT_URI
);
// set the data href + simulate click // set the data href + simulate click
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", {}, BrowserTestUtils.synthesizeMouseAtCenter(
gBrowser.selectedBrowser); "#testlink",
{},
gBrowser.selectedBrowser
);
await loadPromise; await loadPromise;
await verifyCSP("click()", gBrowser.selectedBrowser, RESULT_URI); await verifyCSP("click()", gBrowser.selectedBrowser, RESULT_URI);
}); });
@ -26,9 +40,11 @@ add_task(async function test_csp_inheritance_ctrl_click() {
await BrowserTestUtils.withNewTab(TEST_URI, async function(browser) { await BrowserTestUtils.withNewTab(TEST_URI, async function(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, RESULT_URI); let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, RESULT_URI);
// set the data href + simulate ctrl+click // set the data href + simulate ctrl+click
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", BrowserTestUtils.synthesizeMouseAtCenter(
{ ctrlKey: true, metaKey: true }, "#testlink",
gBrowser.selectedBrowser); { ctrlKey: true, metaKey: true },
gBrowser.selectedBrowser
);
let tab = await loadPromise; let tab = await loadPromise;
gBrowser.selectTabAtIndex(2); gBrowser.selectTabAtIndex(2);
await verifyCSP("ctrl-click()", gBrowser.selectedBrowser, RESULT_URI); await verifyCSP("ctrl-click()", gBrowser.selectedBrowser, RESULT_URI);
@ -36,23 +52,31 @@ add_task(async function test_csp_inheritance_ctrl_click() {
}); });
}); });
add_task(async function test_csp_inheritance_right_click_open_link_in_new_tab() { add_task(
await BrowserTestUtils.withNewTab(TEST_URI, async function(browser) { async function test_csp_inheritance_right_click_open_link_in_new_tab() {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, RESULT_URI); await BrowserTestUtils.withNewTab(TEST_URI, async function(browser) {
// set the data href + simulate right-click open link in tab let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, RESULT_URI);
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => { // set the data href + simulate right-click open link in tab
// These are operations that must be executed synchronously with the event. BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
document.getElementById("context-openlinkintab").doCommand(); // These are operations that must be executed synchronously with the event.
event.target.hidePopup(); document.getElementById("context-openlinkintab").doCommand();
return true; event.target.hidePopup();
}); return true;
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", });
{ type: "contextmenu", button: 2 }, BrowserTestUtils.synthesizeMouseAtCenter(
gBrowser.selectedBrowser); "#testlink",
{ type: "contextmenu", button: 2 },
gBrowser.selectedBrowser
);
let tab = await loadPromise; let tab = await loadPromise;
gBrowser.selectTabAtIndex(2); gBrowser.selectTabAtIndex(2);
await verifyCSP("right-click-open-in-new-tab()", gBrowser.selectedBrowser, RESULT_URI); await verifyCSP(
await BrowserTestUtils.removeTab(tab); "right-click-open-in-new-tab()",
}); gBrowser.selectedBrowser,
}); RESULT_URI
);
await BrowserTestUtils.removeTab(tab);
});
}
);

View file

@ -17,12 +17,18 @@ add_task(async function test_dataURI_unique_opaque_origin() {
BrowserTestUtils.loadURI(browser, "data:text/html,hi"); BrowserTestUtils.loadURI(browser, "data:text/html,hi");
await BrowserTestUtils.browserLoaded(browser); await BrowserTestUtils.browserLoaded(browser);
await ContentTask.spawn(browser, { principal: pagePrincipal }, async function(args) { await ContentTask.spawn(browser, { principal: pagePrincipal }, async function(
args
) {
info("data URI principal: " + content.document.nodePrincipal.origin); info("data URI principal: " + content.document.nodePrincipal.origin);
Assert.ok(content.document.nodePrincipal.isNullPrincipal, Assert.ok(
"data: URI should have NullPrincipal."); content.document.nodePrincipal.isNullPrincipal,
Assert.ok(!content.document.nodePrincipal.equals(args.principal), "data: URI should have NullPrincipal."
"data: URI should have unique opaque origin."); );
Assert.ok(
!content.document.nodePrincipal.equals(args.principal),
"data: URI should have unique opaque origin."
);
}); });
gBrowser.removeTab(tab); gBrowser.removeTab(tab);

View file

@ -1,6 +1,9 @@
"use strict"; "use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com"); const TEST_PATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
const HTML_URI = TEST_PATH + "file_data_load_inherit_csp.html"; const HTML_URI = TEST_PATH + "file_data_load_inherit_csp.html";
const DATA_URI = "data:text/html;html,<html><body>foo</body></html>"; const DATA_URI = "data:text/html;html,<html><body>foo</body></html>";
@ -12,7 +15,10 @@ function setDataHrefOnLink(aBrowser, aDataURI) {
} }
function verifyCSP(aTestName, aBrowser, aDataURI) { function verifyCSP(aTestName, aBrowser, aDataURI) {
return ContentTask.spawn(aBrowser, {aTestName, aDataURI}, async function({aTestName, aDataURI}) { return ContentTask.spawn(aBrowser, { aTestName, aDataURI }, async function({
aTestName,
aDataURI,
}) {
let channel = content.docShell.currentDocumentChannel; let channel = content.docShell.currentDocumentChannel;
is(channel.URI.spec, aDataURI, "testing CSP for " + aTestName); is(channel.URI.spec, aDataURI, "testing CSP for " + aTestName);
let cspJSON = content.document.cspJSON; let cspJSON = content.document.cspJSON;
@ -27,7 +33,7 @@ function verifyCSP(aTestName, aBrowser, aDataURI) {
add_task(async function setup() { add_task(async function setup() {
// allow top level data: URI navigations, otherwise clicking data: link fails // allow top level data: URI navigations, otherwise clicking data: link fails
await SpecialPowers.pushPrefEnv({ await SpecialPowers.pushPrefEnv({
"set": [["security.data_uri.block_toplevel_data_uri_navigations", false]], set: [["security.data_uri.block_toplevel_data_uri_navigations", false]],
}); });
}); });
@ -36,8 +42,11 @@ add_task(async function test_data_csp_inheritance_regular_click() {
let loadPromise = BrowserTestUtils.browserLoaded(browser, false, DATA_URI); let loadPromise = BrowserTestUtils.browserLoaded(browser, false, DATA_URI);
// set the data href + simulate click // set the data href + simulate click
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI); await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", {}, BrowserTestUtils.synthesizeMouseAtCenter(
gBrowser.selectedBrowser); "#testlink",
{},
gBrowser.selectedBrowser
);
await loadPromise; await loadPromise;
await verifyCSP("click()", gBrowser.selectedBrowser, DATA_URI); await verifyCSP("click()", gBrowser.selectedBrowser, DATA_URI);
}); });
@ -48,9 +57,11 @@ add_task(async function test_data_csp_inheritance_ctrl_click() {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI); let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
// set the data href + simulate ctrl+click // set the data href + simulate ctrl+click
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI); await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", BrowserTestUtils.synthesizeMouseAtCenter(
{ ctrlKey: true, metaKey: true }, "#testlink",
gBrowser.selectedBrowser); { ctrlKey: true, metaKey: true },
gBrowser.selectedBrowser
);
let tab = await loadPromise; let tab = await loadPromise;
gBrowser.selectTabAtIndex(2); gBrowser.selectTabAtIndex(2);
await verifyCSP("ctrl-click()", gBrowser.selectedBrowser, DATA_URI); await verifyCSP("ctrl-click()", gBrowser.selectedBrowser, DATA_URI);
@ -58,24 +69,32 @@ add_task(async function test_data_csp_inheritance_ctrl_click() {
}); });
}); });
add_task(async function test_data_csp_inheritance_right_click_open_link_in_new_tab() { add_task(
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) { async function test_data_csp_inheritance_right_click_open_link_in_new_tab() {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI); await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
// set the data href + simulate right-click open link in tab let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI); // set the data href + simulate right-click open link in tab
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => { await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
// These are operations that must be executed synchronously with the event. BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
document.getElementById("context-openlinkintab").doCommand(); // These are operations that must be executed synchronously with the event.
event.target.hidePopup(); document.getElementById("context-openlinkintab").doCommand();
return true; event.target.hidePopup();
}); return true;
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", });
{ type: "contextmenu", button: 2 }, BrowserTestUtils.synthesizeMouseAtCenter(
gBrowser.selectedBrowser); "#testlink",
{ type: "contextmenu", button: 2 },
gBrowser.selectedBrowser
);
let tab = await loadPromise; let tab = await loadPromise;
gBrowser.selectTabAtIndex(2); gBrowser.selectTabAtIndex(2);
await verifyCSP("right-click-open-in-new-tab()", gBrowser.selectedBrowser, DATA_URI); await verifyCSP(
await BrowserTestUtils.removeTab(tab); "right-click-open-in-new-tab()",
}); gBrowser.selectedBrowser,
}); DATA_URI
);
await BrowserTestUtils.removeTab(tab);
});
}
);

View file

@ -1,49 +1,87 @@
"use strict"; "use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com"); const TEST_PATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
const HTML_URI = TEST_PATH + "dummy_page.html"; const HTML_URI = TEST_PATH + "dummy_page.html";
const VIEW_SRC_URI = "view-source:" + HTML_URI; const VIEW_SRC_URI = "view-source:" + HTML_URI;
add_task(async function() { add_task(async function() {
info("load baseline html in new tab"); info("load baseline html in new tab");
await BrowserTestUtils.withNewTab(HTML_URI, async function(aBrowser) { await BrowserTestUtils.withNewTab(HTML_URI, async function(aBrowser) {
is(gBrowser.selectedBrowser.currentURI.spec, HTML_URI, is(
"sanity check to make sure html loaded"); gBrowser.selectedBrowser.currentURI.spec,
HTML_URI,
"sanity check to make sure html loaded"
);
info("right-click -> view-source of html"); info("right-click -> view-source of html");
let vSrcCtxtMenu = document.getElementById("contentAreaContextMenu"); let vSrcCtxtMenu = document.getElementById("contentAreaContextMenu");
let popupPromise = BrowserTestUtils.waitForEvent(vSrcCtxtMenu, "popupshown"); let popupPromise = BrowserTestUtils.waitForEvent(
BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, aBrowser); vSrcCtxtMenu,
"popupshown"
);
BrowserTestUtils.synthesizeMouseAtCenter(
"body",
{ type: "contextmenu", button: 2 },
aBrowser
);
await popupPromise; await popupPromise;
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, VIEW_SRC_URI); let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, VIEW_SRC_URI);
let vSrcItem = vSrcCtxtMenu.getElementsByAttribute("id", "context-viewsource")[0]; let vSrcItem = vSrcCtxtMenu.getElementsByAttribute(
"id",
"context-viewsource"
)[0];
vSrcItem.click(); vSrcItem.click();
vSrcCtxtMenu.hidePopup(); vSrcCtxtMenu.hidePopup();
let tab = await tabPromise; let tab = await tabPromise;
is(gBrowser.selectedBrowser.currentURI.spec, VIEW_SRC_URI, is(
"loading view-source of html succeeded"); gBrowser.selectedBrowser.currentURI.spec,
VIEW_SRC_URI,
"loading view-source of html succeeded"
);
info("load html file again before going .back()"); info("load html file again before going .back()");
let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, HTML_URI); let loadPromise = BrowserTestUtils.browserLoaded(
tab.linkedBrowser,
false,
HTML_URI
);
await ContentTask.spawn(tab.linkedBrowser, HTML_URI, HTML_URI => { await ContentTask.spawn(tab.linkedBrowser, HTML_URI, HTML_URI => {
content.document.location = HTML_URI; content.document.location = HTML_URI;
}); });
await loadPromise; await loadPromise;
is(gBrowser.selectedBrowser.currentURI.spec, HTML_URI, is(
"loading html another time succeeded"); gBrowser.selectedBrowser.currentURI.spec,
HTML_URI,
"loading html another time succeeded"
);
info("click .back() to view-source of html again and make sure the history entry has a triggeringPrincipal"); info(
"click .back() to view-source of html again and make sure the history entry has a triggeringPrincipal"
);
let backCtxtMenu = document.getElementById("contentAreaContextMenu"); let backCtxtMenu = document.getElementById("contentAreaContextMenu");
popupPromise = BrowserTestUtils.waitForEvent(backCtxtMenu, "popupshown"); popupPromise = BrowserTestUtils.waitForEvent(backCtxtMenu, "popupshown");
BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, aBrowser); BrowserTestUtils.synthesizeMouseAtCenter(
"body",
{ type: "contextmenu", button: 2 },
aBrowser
);
await popupPromise; await popupPromise;
loadPromise = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow"); loadPromise = BrowserTestUtils.waitForContentEvent(
tab.linkedBrowser,
"pageshow"
);
let backItem = backCtxtMenu.getElementsByAttribute("id", "context-back")[0]; let backItem = backCtxtMenu.getElementsByAttribute("id", "context-back")[0];
backItem.click(); backItem.click();
backCtxtMenu.hidePopup(); backCtxtMenu.hidePopup();
await loadPromise; await loadPromise;
is(gBrowser.selectedBrowser.currentURI.spec, VIEW_SRC_URI, is(
"clicking .back() to view-source of html succeeded"); gBrowser.selectedBrowser.currentURI.spec,
VIEW_SRC_URI,
"clicking .back() to view-source of html succeeded"
);
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);
}); });

View file

@ -8,17 +8,22 @@ function test() {
Services.prefs.setBoolPref("security.data_uri.unique_opaque_origin", false); Services.prefs.setBoolPref("security.data_uri.unique_opaque_origin", false);
// data: URIs will only open at the top level when the pref is false // data: URIs will only open at the top level when the pref is false
// or the use of system principal but we can't use that to test here. // or the use of system principal but we can't use that to test here.
Services.prefs.setBoolPref("security.data_uri.block_toplevel_data_uri_navigations", false); Services.prefs.setBoolPref(
"security.data_uri.block_toplevel_data_uri_navigations",
false
);
registerCleanupFunction(function() { registerCleanupFunction(function() {
Services.prefs.clearUserPref("security.data_uri.unique_opaque_origin"); Services.prefs.clearUserPref("security.data_uri.unique_opaque_origin");
Services.prefs.clearUserPref("security.data_uri.block_toplevel_data_uri_navigations"); Services.prefs.clearUserPref(
"security.data_uri.block_toplevel_data_uri_navigations"
);
}); });
executeSoon(startTest); executeSoon(startTest);
} }
function startTest() { function startTest() {
let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser));
let browser = gBrowser.getBrowserForTab(tab); let browser = gBrowser.getBrowserForTab(tab);
@ -33,25 +38,39 @@ function startTest() {
function testURL(url, func) { function testURL(url, func) {
let secMan = Services.scriptSecurityManager; let secMan = Services.scriptSecurityManager;
let ios = Services.io; let ios = Services.io;
let artificialPrincipal = secMan.createCodebasePrincipal(ios.newURI("http://example.com/"), {}); let artificialPrincipal = secMan.createCodebasePrincipal(
ios.newURI("http://example.com/"),
{}
);
loadURL("http://example.com/", 0, artificialPrincipal, function() { loadURL("http://example.com/", 0, artificialPrincipal, function() {
let pagePrincipal = browser.contentPrincipal; let pagePrincipal = browser.contentPrincipal;
ok(pagePrincipal, "got principal for http:// page"); ok(pagePrincipal, "got principal for http:// page");
// Now load the URL normally // Now load the URL normally
loadURL(url, 0, artificialPrincipal, function() { loadURL(url, 0, artificialPrincipal, function() {
ok(browser.contentPrincipal.equals(pagePrincipal), url + " should inherit principal"); ok(
browser.contentPrincipal.equals(pagePrincipal),
url + " should inherit principal"
);
// Now load the URL and disallow inheriting the principal // Now load the URL and disallow inheriting the principal
let webNav = Ci.nsIWebNavigation; let webNav = Ci.nsIWebNavigation;
loadURL(url, webNav.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL, artificialPrincipal, function() { loadURL(
let newPrincipal = browser.contentPrincipal; url,
ok(newPrincipal, "got inner principal"); webNav.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL,
ok(!newPrincipal.equals(pagePrincipal), artificialPrincipal,
url + " should not inherit principal when loaded with DISALLOW_INHERIT_OWNER"); function() {
let newPrincipal = browser.contentPrincipal;
ok(newPrincipal, "got inner principal");
ok(
!newPrincipal.equals(pagePrincipal),
url +
" should not inherit principal when loaded with DISALLOW_INHERIT_OWNER"
);
func(); func();
}); }
);
}); });
}); });
} }

View file

@ -6,30 +6,38 @@ const gPostData = "postdata=true";
function test() { function test() {
waitForExplicitFinish(); waitForExplicitFinish();
let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser));
registerCleanupFunction(function() { registerCleanupFunction(function() {
gBrowser.removeTab(tab); gBrowser.removeTab(tab);
}); });
var dataStream = Cc["@mozilla.org/io/string-input-stream;1"]. var dataStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
createInstance(Ci.nsIStringInputStream); Ci.nsIStringInputStream
);
dataStream.data = gPostData; dataStream.data = gPostData;
var postStream = Cc["@mozilla.org/network/mime-input-stream;1"]. var postStream = Cc[
createInstance(Ci.nsIMIMEInputStream); "@mozilla.org/network/mime-input-stream;1"
].createInstance(Ci.nsIMIMEInputStream);
postStream.addHeader("Content-Type", "application/x-www-form-urlencoded"); postStream.addHeader("Content-Type", "application/x-www-form-urlencoded");
postStream.setData(dataStream); postStream.setData(dataStream);
var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"] var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].getService(
.getService(Ci.nsIPrincipal); Ci.nsIPrincipal
);
tab.linkedBrowser.loadURI("http://mochi.test:8888/browser/docshell/test/browser/print_postdata.sjs", { tab.linkedBrowser.loadURI(
triggeringPrincipal: systemPrincipal, "http://mochi.test:8888/browser/docshell/test/browser/print_postdata.sjs",
postData: postStream, {
}); triggeringPrincipal: systemPrincipal,
postData: postStream,
}
);
BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => { BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
ContentTask.spawn(tab.linkedBrowser, gPostData, function(postData) { ContentTask.spawn(tab.linkedBrowser, gPostData, function(postData) {
var bodyText = content.document.body.textContent; var bodyText = content.document.body.textContent;
is(bodyText, postData, "post data was submitted correctly"); is(bodyText, postData, "post data was submitted correctly");
}).then(() => { finish(); }); }).then(() => {
finish();
});
}); });
} }

View file

@ -1,15 +1,23 @@
add_task(async function test_multiple_pushState() { add_task(async function test_multiple_pushState() {
await BrowserTestUtils.withNewTab({ await BrowserTestUtils.withNewTab(
gBrowser, {
url: "http://example.org/browser/docshell/test/browser/file_multiple_pushState.html", gBrowser,
}, async function(browser) { url:
const kExpected = "http://example.org/bar/ABC/DEF?key=baz"; "http://example.org/browser/docshell/test/browser/file_multiple_pushState.html",
},
async function(browser) {
const kExpected = "http://example.org/bar/ABC/DEF?key=baz";
let contentLocation = await ContentTask.spawn(browser, null, async function() { let contentLocation = await ContentTask.spawn(
return content.document.location.href; browser,
}); null,
async function() {
return content.document.location.href;
}
);
is(contentLocation, kExpected); is(contentLocation, kExpected);
is(browser.documentURI.spec, kExpected); is(browser.documentURI.spec, kExpected);
}); }
);
}); });

View file

@ -1,14 +1,19 @@
function contentTask() { function contentTask() {
let finish; let finish;
let promise = new Promise(resolve => { finish = resolve; }); let promise = new Promise(resolve => {
finish = resolve;
});
let contentWindow; let contentWindow;
let originalLocation; let originalLocation;
let currentTest = -1; let currentTest = -1;
let stayingOnPage = true; let stayingOnPage = true;
const TEST_PAGE = "http://mochi.test:8888/browser/docshell/test/browser/file_bug1046022.html"; const TEST_PAGE =
const TARGETED_PAGE = "data:text/html," + encodeURIComponent("<body>Shouldn't be seeing this</body>"); "http://mochi.test:8888/browser/docshell/test/browser/file_bug1046022.html";
const TARGETED_PAGE =
"data:text/html," +
encodeURIComponent("<body>Shouldn't be seeing this</body>");
let loadExpected = TEST_PAGE; let loadExpected = TEST_PAGE;
var testsLength; var testsLength;
@ -16,13 +21,18 @@ function contentTask() {
function onTabLoaded(event) { function onTabLoaded(event) {
info("A document loaded in a tab!"); info("A document loaded in a tab!");
let loadedPage = event.target.location.href; let loadedPage = event.target.location.href;
if (loadedPage == "about:blank" || if (
event.originalTarget != content.document) { loadedPage == "about:blank" ||
event.originalTarget != content.document
) {
return; return;
} }
if (!loadExpected) { if (!loadExpected) {
ok(false, "Expected no page loads, but loaded " + loadedPage + " instead!"); ok(
false,
"Expected no page loads, but loaded " + loadedPage + " instead!"
);
return; return;
} }
@ -40,8 +50,15 @@ function contentTask() {
} }
function onAfterTargetedPageLoad() { function onAfterTargetedPageLoad() {
ok(!stayingOnPage, "We should only fire if we're expecting to let the onbeforeunload dialog proceed to the new location"); ok(
is(content.location.href, TARGETED_PAGE, "Should have loaded the expected new page"); !stayingOnPage,
"We should only fire if we're expecting to let the onbeforeunload dialog proceed to the new location"
);
is(
content.location.href,
TARGETED_PAGE,
"Should have loaded the expected new page"
);
runNextTest(); runNextTest();
} }
@ -49,10 +66,17 @@ function contentTask() {
function onTabModalDialogLoaded() { function onTabModalDialogLoaded() {
info(content.location.href); info(content.location.href);
is(content, contentWindow, "Window should be the same still."); is(content, contentWindow, "Window should be the same still.");
is(content.location.href, originalLocation, "Page should not have changed."); is(
content.location.href,
originalLocation,
"Page should not have changed."
);
is(content.mySuperSpecialMark, 42, "Page should not have refreshed."); is(content.mySuperSpecialMark, 42, "Page should not have refreshed.");
ok(!content.dialogWasInvoked, "Dialog should only be invoked once per test."); ok(
!content.dialogWasInvoked,
"Dialog should only be invoked once per test."
);
content.dialogWasInvoked = true; content.dialogWasInvoked = true;
addMessageListener("test-beforeunload:dialog-gone", function listener(msg) { addMessageListener("test-beforeunload:dialog-gone", function listener(msg) {
@ -93,7 +117,6 @@ function contentTask() {
currentTest = 0; currentTest = 0;
} }
if (!stayingOnPage) { if (!stayingOnPage) {
// Right now we're on the data: page. Null contentWindow out to // Right now we're on the data: page. Null contentWindow out to
// avoid CPOW errors when contentWindow is no longer the correct // avoid CPOW errors when contentWindow is no longer the correct
@ -115,8 +138,12 @@ function contentTask() {
contentWindow.dialogWasInvoked = false; contentWindow.dialogWasInvoked = false;
originalLocation = contentWindow.location.href; originalLocation = contentWindow.location.href;
// And run this test: // And run this test:
info("Running test with onbeforeunload " + contentWindow.wrappedJSObject.testFns[currentTest].toSource()); info(
contentWindow.onbeforeunload = contentWindow.wrappedJSObject.testFns[currentTest]; "Running test with onbeforeunload " +
contentWindow.wrappedJSObject.testFns[currentTest].toSource()
);
contentWindow.onbeforeunload =
contentWindow.wrappedJSObject.testFns[currentTest];
sendAsyncMessage("test-beforeunload:reset"); sendAsyncMessage("test-beforeunload:reset");
content.location = TARGETED_PAGE; content.location = TARGETED_PAGE;
} }
@ -138,15 +165,18 @@ function contentTask() {
}); });
} }
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]}); SpecialPowers.pushPrefEnv({
set: [["dom.require_user_interaction_for_beforeunload", false]],
});
var testTab; var testTab;
var loadStarted = false; var loadStarted = false;
var tabStateListener = { var tabStateListener = {
onStateChange(webprogress, request, stateFlags, status) { onStateChange(webprogress, request, stateFlags, status) {
let startDocumentFlags = Ci.nsIWebProgressListener.STATE_START | let startDocumentFlags =
Ci.nsIWebProgressListener.STATE_IS_DOCUMENT; Ci.nsIWebProgressListener.STATE_START |
Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
if ((stateFlags & startDocumentFlags) == startDocumentFlags) { if ((stateFlags & startDocumentFlags) == startDocumentFlags) {
loadStarted = true; loadStarted = true;
} }
@ -183,14 +213,18 @@ function onTabModalDialogLoaded(node) {
}); });
} }
}); });
observer.observe(node.parentNode, {childList: true}); observer.observe(node.parentNode, { childList: true });
BrowserTestUtils.waitForMessage(mm, "test-beforeunload:dialog-response").then((stayingOnPage) => { BrowserTestUtils.waitForMessage(mm, "test-beforeunload:dialog-response").then(
let button = node.querySelector(stayingOnPage ? ".tabmodalprompt-button1" : ".tabmodalprompt-button0"); stayingOnPage => {
// ... and then actually make the dialog go away let button = node.querySelector(
info("Clicking button: " + button.label); stayingOnPage ? ".tabmodalprompt-button1" : ".tabmodalprompt-button0"
EventUtils.synthesizeMouseAtCenter(button, {}); );
}); // ... and then actually make the dialog go away
info("Clicking button: " + button.label);
EventUtils.synthesizeMouseAtCenter(button, {});
}
);
} }
// Listen for the dialog being created // Listen for the dialog being created
@ -202,9 +236,12 @@ function test() {
testTab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser); testTab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
testTab.linkedBrowser.messageManager.addMessageListener("test-beforeunload:reset", () => { testTab.linkedBrowser.messageManager.addMessageListener(
loadStarted = false; "test-beforeunload:reset",
}); () => {
loadStarted = false;
}
);
ContentTask.spawn(testTab.linkedBrowser, null, contentTask).then(finish); ContentTask.spawn(testTab.linkedBrowser, null, contentTask).then(finish);
} }
@ -214,4 +251,3 @@ registerCleanupFunction(function() {
gBrowser.removeProgressListener(tabStateListener); gBrowser.removeProgressListener(tabStateListener);
gBrowser.removeTab(testTab); gBrowser.removeTab(testTab);
}); });

View file

@ -4,14 +4,22 @@
add_task(async function() { add_task(async function() {
const kSearchEngineID = "test_urifixup_search_engine"; const kSearchEngineID = "test_urifixup_search_engine";
const kSearchEngineURL = "http://localhost/?search={searchTerms}"; const kSearchEngineURL = "http://localhost/?search={searchTerms}";
await Services.search.addEngineWithDetails(kSearchEngineID, await Services.search.addEngineWithDetails(kSearchEngineID, {
{method: "get", template: kSearchEngineURL}); method: "get",
template: kSearchEngineURL,
});
let oldDefaultEngine = await Services.search.getDefault(); let oldDefaultEngine = await Services.search.getDefault();
await Services.search.setDefault(Services.search.getEngineByName(kSearchEngineID)); await Services.search.setDefault(
Services.search.getEngineByName(kSearchEngineID)
);
let selectedName = (await Services.search.getDefault()).name; let selectedName = (await Services.search.getDefault()).name;
Assert.equal(selectedName, kSearchEngineID, "Check fake search engine is selected"); Assert.equal(
selectedName,
kSearchEngineID,
"Check fake search engine is selected"
);
registerCleanupFunction(async function() { registerCleanupFunction(async function() {
if (oldDefaultEngine) { if (oldDefaultEngine) {
@ -34,7 +42,11 @@ add_task(async function() {
let engine = Services.search.defaultEngine; let engine = Services.search.defaultEngine;
Assert.ok(engine, "Have default search engine."); Assert.ok(engine, "Have default search engine.");
Assert.equal(engine, subject, "Notification subject is engine."); Assert.equal(engine, subject, "Notification subject is engine.");
Assert.equal(data, "firefox health report", "Notification data is search term."); Assert.equal(
data,
"firefox health report",
"Notification data is search term."
);
gBrowser.removeTab(tab); gBrowser.removeTab(tab);
}); });

View file

@ -6,7 +6,9 @@
add_task(async function() { add_task(async function() {
const URI = "data:text/html;charset=utf-8,<iframe id='test-iframe'></iframe>"; const URI = "data:text/html;charset=utf-8,<iframe id='test-iframe'></iframe>";
await BrowserTestUtils.withNewTab({ gBrowser, url: URI }, async function(browser) { await BrowserTestUtils.withNewTab({ gBrowser, url: URI }, async function(
browser
) {
await ContentTask.spawn(browser, null, test_body); await ContentTask.spawn(browser, null, test_body);
}); });
}); });
@ -14,30 +16,45 @@ add_task(async function() {
async function test_body() { async function test_body() {
let docshell = docShell; let docshell = docShell;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_NONE, is(
"touchEventsOverride flag should be initially set to NONE"); docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_NONE,
"touchEventsOverride flag should be initially set to NONE"
);
docshell.touchEventsOverride = Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED; docshell.touchEventsOverride = Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED, is(
"touchEventsOverride flag should be changed to DISABLED"); docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"touchEventsOverride flag should be changed to DISABLED"
);
let frameWin = content.document.querySelector("#test-iframe").contentWindow; let frameWin = content.document.querySelector("#test-iframe").contentWindow;
docshell = frameWin.docShell; docshell = frameWin.docShell;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED, is(
"touchEventsOverride flag should be passed on to frames."); docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"touchEventsOverride flag should be passed on to frames."
);
let newFrame = content.document.createElement("iframe"); let newFrame = content.document.createElement("iframe");
content.document.body.appendChild(newFrame); content.document.body.appendChild(newFrame);
let newFrameWin = newFrame.contentWindow; let newFrameWin = newFrame.contentWindow;
docshell = newFrameWin.docShell; docshell = newFrameWin.docShell;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED, is(
"Newly created frames should use the new touchEventsOverride flag"); docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"Newly created frames should use the new touchEventsOverride flag"
);
newFrameWin.location.reload(); newFrameWin.location.reload();
await ContentTaskUtils.waitForEvent(newFrameWin, "load"); await ContentTaskUtils.waitForEvent(newFrameWin, "load");
docshell = newFrameWin.docShell; docshell = newFrameWin.docShell;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED, is(
"New touchEventsOverride flag should persist across reloads"); docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"New touchEventsOverride flag should persist across reloads"
);
} }

View file

@ -8,25 +8,38 @@
const URL = "data:text/html;charset=utf-8,Test page"; const URL = "data:text/html;charset=utf-8,Test page";
add_task(async function() { add_task(async function() {
await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function(
async function(browser) { browser
await ContentTask.spawn(browser, null, function() { ) {
ok("recordProfileTimelineMarkers" in docShell, await ContentTask.spawn(browser, null, function() {
"The recordProfileTimelineMarkers attribute exists"); ok(
ok("popProfileTimelineMarkers" in docShell, "recordProfileTimelineMarkers" in docShell,
"The popProfileTimelineMarkers function exists"); "The recordProfileTimelineMarkers attribute exists"
ok(docShell.recordProfileTimelineMarkers === false, );
"recordProfileTimelineMarkers is false by default"); ok(
ok(docShell.popProfileTimelineMarkers().length === 0, "popProfileTimelineMarkers" in docShell,
"There are no markers by default"); "The popProfileTimelineMarkers function exists"
);
ok(
docShell.recordProfileTimelineMarkers === false,
"recordProfileTimelineMarkers is false by default"
);
ok(
docShell.popProfileTimelineMarkers().length === 0,
"There are no markers by default"
);
docShell.recordProfileTimelineMarkers = true; docShell.recordProfileTimelineMarkers = true;
ok(docShell.recordProfileTimelineMarkers === true, ok(
"recordProfileTimelineMarkers can be set to true"); docShell.recordProfileTimelineMarkers === true,
"recordProfileTimelineMarkers can be set to true"
);
docShell.recordProfileTimelineMarkers = false; docShell.recordProfileTimelineMarkers = false;
ok(docShell.recordProfileTimelineMarkers === false, ok(
"recordProfileTimelineMarkers can be set to false"); docShell.recordProfileTimelineMarkers === false,
}); "recordProfileTimelineMarkers can be set to false"
);
}); });
});
}); });

View file

@ -3,13 +3,14 @@
"use strict"; "use strict";
var TEST_URL = "<!DOCTYPE html><style>" + var TEST_URL =
"body {margin:0; padding: 0;} " + "<!DOCTYPE html><style>" +
"div {width:100px;height:100px;background:red;} " + "body {margin:0; padding: 0;} " +
".resize-change-color {width:50px;height:50px;background:blue;} " + "div {width:100px;height:100px;background:red;} " +
".change-color {width:50px;height:50px;background:yellow;} " + ".resize-change-color {width:50px;height:50px;background:blue;} " +
".add-class {}" + ".change-color {width:50px;height:50px;background:yellow;} " +
"</style><div></div>"; ".add-class {}" +
"</style><div></div>";
TEST_URL = "data:text/html;charset=utf8," + encodeURIComponent(TEST_URL); TEST_URL = "data:text/html;charset=utf8," + encodeURIComponent(TEST_URL);
var test = makeTimelineTest("browser_timelineMarkers-frame-02.js", TEST_URL); var test = makeTimelineTest("browser_timelineMarkers-frame-02.js", TEST_URL);

View file

@ -3,6 +3,7 @@
"use strict"; "use strict";
const URL = "http://mochi.test:8888/browser/docshell/test/browser/timelineMarkers-04.html"; const URL =
"http://mochi.test:8888/browser/docshell/test/browser/timelineMarkers-04.html";
var test = makeTimelineTest("browser_timelineMarkers-frame-04.js", URL); var test = makeTimelineTest("browser_timelineMarkers-frame-04.js", URL);

View file

@ -3,13 +3,14 @@
"use strict"; "use strict";
var TEST_URL = "<!DOCTYPE html><style>" + var TEST_URL =
"body {margin:0; padding: 0;} " + "<!DOCTYPE html><style>" +
"div {width:100px;height:100px;background:red;} " + "body {margin:0; padding: 0;} " +
".resize-change-color {width:50px;height:50px;background:blue;} " + "div {width:100px;height:100px;background:red;} " +
".change-color {width:50px;height:50px;background:yellow;} " + ".resize-change-color {width:50px;height:50px;background:blue;} " +
".add-class {}" + ".change-color {width:50px;height:50px;background:yellow;} " +
"</style><div></div>"; ".add-class {}" +
"</style><div></div>";
TEST_URL = "data:text/html;charset=utf8," + encodeURIComponent(TEST_URL); TEST_URL = "data:text/html;charset=utf8," + encodeURIComponent(TEST_URL);
var test = makeTimelineTest("browser_timelineMarkers-frame-05.js", TEST_URL); var test = makeTimelineTest("browser_timelineMarkers-frame-05.js", TEST_URL);

View file

@ -10,8 +10,9 @@
// restyles, reflows and paints occur // restyles, reflows and paints occur
function rectangleContains(rect, x, y, width, height) { function rectangleContains(rect, x, y, width, height) {
return rect.x <= x && rect.y <= y && rect.width >= width && return (
rect.height >= height; rect.x <= x && rect.y <= y && rect.width >= width && rect.height >= height
);
} }
function sanitizeMarkers(list) { function sanitizeMarkers(list) {
@ -20,117 +21,145 @@ function sanitizeMarkers(list) {
return list.filter(e => e.name != "Worker" && e.name != "MinorGC"); return list.filter(e => e.name != "Worker" && e.name != "MinorGC");
} }
var TESTS = [{ var TESTS = [
desc: "Changing the width of the test element", {
searchFor: "Paint", desc: "Changing the width of the test element",
setup(docShell) { searchFor: "Paint",
let div = content.document.querySelector("div"); setup(docShell) {
div.setAttribute("class", "resize-change-color"); let div = content.document.querySelector("div");
div.setAttribute("class", "resize-change-color");
},
check(markers) {
markers = sanitizeMarkers(markers);
ok(markers.length > 0, "markers were returned");
console.log(markers);
info(JSON.stringify(markers.filter(m => m.name == "Paint")));
ok(markers.some(m => m.name == "Reflow"), "markers includes Reflow");
ok(markers.some(m => m.name == "Paint"), "markers includes Paint");
for (let marker of markers.filter(m => m.name == "Paint")) {
// This change should generate at least one rectangle.
ok(marker.rectangles.length >= 1, "marker has one rectangle");
// One of the rectangles should contain the div.
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 100, 100)));
}
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
},
}, },
check(markers) { {
markers = sanitizeMarkers(markers); desc: "Changing the test element's background color",
ok(markers.length > 0, "markers were returned"); searchFor: "Paint",
console.log(markers); setup(docShell) {
info(JSON.stringify(markers.filter(m => m.name == "Paint"))); let div = content.document.querySelector("div");
ok(markers.some(m => m.name == "Reflow"), "markers includes Reflow"); div.setAttribute("class", "change-color");
ok(markers.some(m => m.name == "Paint"), "markers includes Paint"); },
for (let marker of markers.filter(m => m.name == "Paint")) { check(markers) {
// This change should generate at least one rectangle. markers = sanitizeMarkers(markers);
ok(marker.rectangles.length >= 1, "marker has one rectangle"); ok(markers.length > 0, "markers were returned");
// One of the rectangles should contain the div. ok(
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 100, 100))); !markers.some(m => m.name == "Reflow"),
} "markers doesn't include Reflow"
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle"); );
ok(markers.some(m => m.name == "Paint"), "markers includes Paint");
for (let marker of markers.filter(m => m.name == "Paint")) {
// This change should generate at least one rectangle.
ok(marker.rectangles.length >= 1, "marker has one rectangle");
// One of the rectangles should contain the div.
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 50, 50)));
}
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
},
}, },
}, { {
desc: "Changing the test element's background color", desc: "Changing the test element's classname",
searchFor: "Paint", searchFor: "Paint",
setup(docShell) { setup(docShell) {
let div = content.document.querySelector("div"); let div = content.document.querySelector("div");
div.setAttribute("class", "change-color"); div.setAttribute("class", "change-color add-class");
},
check(markers) {
markers = sanitizeMarkers(markers);
ok(markers.length > 0, "markers were returned");
ok(
!markers.some(m => m.name == "Reflow"),
"markers doesn't include Reflow"
);
ok(
!markers.some(m => m.name == "Paint"),
"markers doesn't include Paint"
);
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
},
}, },
check(markers) { {
markers = sanitizeMarkers(markers); desc: "sync console.time/timeEnd",
ok(markers.length > 0, "markers were returned"); searchFor: "ConsoleTime",
ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow"); setup(docShell) {
ok(markers.some(m => m.name == "Paint"), "markers includes Paint"); content.console.time("FOOBAR");
for (let marker of markers.filter(m => m.name == "Paint")) { content.console.timeEnd("FOOBAR");
// This change should generate at least one rectangle. let markers = docShell.popProfileTimelineMarkers();
ok(marker.rectangles.length >= 1, "marker has one rectangle"); is(markers.length, 1, "Got one marker");
// One of the rectangles should contain the div. is(markers[0].name, "ConsoleTime", "Got ConsoleTime marker");
ok(marker.rectangles.some(r => rectangleContains(r, 0, 0, 50, 50))); is(markers[0].causeName, "FOOBAR", "Got ConsoleTime FOOBAR detail");
} content.console.time("FOO");
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
},
}, {
desc: "Changing the test element's classname",
searchFor: "Paint",
setup(docShell) {
let div = content.document.querySelector("div");
div.setAttribute("class", "change-color add-class");
},
check(markers) {
markers = sanitizeMarkers(markers);
ok(markers.length > 0, "markers were returned");
ok(!markers.some(m => m.name == "Reflow"), "markers doesn't include Reflow");
ok(!markers.some(m => m.name == "Paint"), "markers doesn't include Paint");
ok(markers.some(m => m.name == "Styles"), "markers includes Restyle");
},
}, {
desc: "sync console.time/timeEnd",
searchFor: "ConsoleTime",
setup(docShell) {
content.console.time("FOOBAR");
content.console.timeEnd("FOOBAR");
let markers = docShell.popProfileTimelineMarkers();
is(markers.length, 1, "Got one marker");
is(markers[0].name, "ConsoleTime", "Got ConsoleTime marker");
is(markers[0].causeName, "FOOBAR", "Got ConsoleTime FOOBAR detail");
content.console.time("FOO");
content.setTimeout(() => {
content.console.time("BAR");
content.setTimeout(() => { content.setTimeout(() => {
content.console.timeEnd("FOO"); content.console.time("BAR");
content.console.timeEnd("BAR"); content.setTimeout(() => {
content.console.timeEnd("FOO");
content.console.timeEnd("BAR");
}, 100);
}, 100); }, 100);
}, 100); },
check(markers) {
markers = sanitizeMarkers(markers);
is(markers.length, 2, "Got 2 markers");
is(markers[0].name, "ConsoleTime", "Got first ConsoleTime marker");
is(markers[0].causeName, "FOO", "Got ConsoleTime FOO detail");
is(markers[1].name, "ConsoleTime", "Got second ConsoleTime marker");
is(markers[1].causeName, "BAR", "Got ConsoleTime BAR detail");
},
}, },
check(markers) { {
markers = sanitizeMarkers(markers); desc: "Timestamps created by console.timeStamp()",
is(markers.length, 2, "Got 2 markers"); searchFor: "Timestamp",
is(markers[0].name, "ConsoleTime", "Got first ConsoleTime marker"); setup(docShell) {
is(markers[0].causeName, "FOO", "Got ConsoleTime FOO detail"); content.console.timeStamp("rock");
is(markers[1].name, "ConsoleTime", "Got second ConsoleTime marker"); let markers = docShell.popProfileTimelineMarkers();
is(markers[1].causeName, "BAR", "Got ConsoleTime BAR detail"); is(markers.length, 1, "Got one marker");
is(markers[0].name, "TimeStamp", "Got Timestamp marker");
is(markers[0].causeName, "rock", "Got Timestamp label value");
content.console.timeStamp("paper");
content.console.timeStamp("scissors");
content.console.timeStamp();
content.console.timeStamp(undefined);
},
check(markers) {
markers = sanitizeMarkers(markers);
is(markers.length, 4, "Got 4 markers");
is(markers[0].name, "TimeStamp", "Got Timestamp marker");
is(markers[0].causeName, "paper", "Got Timestamp label value");
is(markers[1].name, "TimeStamp", "Got Timestamp marker");
is(markers[1].causeName, "scissors", "Got Timestamp label value");
is(
markers[2].name,
"TimeStamp",
"Got empty Timestamp marker when no argument given"
);
is(markers[2].causeName, void 0, "Got empty Timestamp label value");
is(
markers[3].name,
"TimeStamp",
"Got empty Timestamp marker when argument is undefined"
);
is(markers[3].causeName, void 0, "Got empty Timestamp label value");
markers.forEach(m =>
is(
m.end,
m.start,
"All Timestamp markers should have identical start/end times"
)
);
},
}, },
}, { ];
desc: "Timestamps created by console.timeStamp()",
searchFor: "Timestamp",
setup(docShell) {
content.console.timeStamp("rock");
let markers = docShell.popProfileTimelineMarkers();
is(markers.length, 1, "Got one marker");
is(markers[0].name, "TimeStamp", "Got Timestamp marker");
is(markers[0].causeName, "rock", "Got Timestamp label value");
content.console.timeStamp("paper");
content.console.timeStamp("scissors");
content.console.timeStamp();
content.console.timeStamp(undefined);
},
check(markers) {
markers = sanitizeMarkers(markers);
is(markers.length, 4, "Got 4 markers");
is(markers[0].name, "TimeStamp", "Got Timestamp marker");
is(markers[0].causeName, "paper", "Got Timestamp label value");
is(markers[1].name, "TimeStamp", "Got Timestamp marker");
is(markers[1].causeName, "scissors", "Got Timestamp label value");
is(markers[2].name, "TimeStamp", "Got empty Timestamp marker when no argument given");
is(markers[2].causeName, void 0, "Got empty Timestamp label value");
is(markers[3].name, "TimeStamp", "Got empty Timestamp marker when argument is undefined");
is(markers[3].causeName, void 0, "Got empty Timestamp label value");
markers.forEach(m => is(m.end, m.start,
"All Timestamp markers should have identical start/end times"));
},
}];
timelineContentTest(TESTS); timelineContentTest(TESTS);

View file

@ -9,85 +9,98 @@
// Test that the docShell profile timeline API returns the right // Test that the docShell profile timeline API returns the right
// markers for DOM events. // markers for DOM events.
var TESTS = [{ var TESTS = [
desc: "Event dispatch with single handler", {
searchFor: "DOMEvent", desc: "Event dispatch with single handler",
setup(docShell) { searchFor: "DOMEvent",
content.document.body.addEventListener("dog", setup(docShell) {
function(e) { console.log("hi"); }, content.document.body.addEventListener(
true); "dog",
content.document.body.dispatchEvent(new content.Event("dog")); function(e) {
console.log("hi");
},
true
);
content.document.body.dispatchEvent(new content.Event("dog"));
},
check(markers) {
markers = markers.filter(m => m.name == "DOMEvent");
is(markers.length, 1, "Got 1 marker");
is(markers[0].type, "dog", "Got dog event name");
is(markers[0].eventPhase, 2, "Got phase 2");
},
}, },
check(markers) { {
markers = markers.filter(m => m.name == "DOMEvent"); desc: "Event dispatch with a second handler",
is(markers.length, 1, "Got 1 marker"); searchFor(markers) {
is(markers[0].type, "dog", "Got dog event name"); return markers.filter(m => m.name == "DOMEvent").length >= 2;
is(markers[0].eventPhase, 2, "Got phase 2"); },
setup(docShell) {
content.document.body.addEventListener("dog", function(e) {
console.log("hi");
});
content.document.body.dispatchEvent(new content.Event("dog"));
},
check(markers) {
markers = markers.filter(m => m.name == "DOMEvent");
is(markers.length, 2, "Got 2 markers");
},
}, },
}, { {
desc: "Event dispatch with a second handler", desc: "Event targeted at child",
searchFor(markers) { searchFor(markers) {
return markers.filter(m => m.name == "DOMEvent").length >= 2; return markers.filter(m => m.name == "DOMEvent").length >= 2;
},
setup(docShell) {
let child = content.document.body.firstElementChild;
child.addEventListener("dog", function(e) {});
child.dispatchEvent(new content.Event("dog"));
},
check(markers) {
markers = markers.filter(m => m.name == "DOMEvent");
is(markers.length, 2, "Got 2 markers");
is(markers[0].eventPhase, 1, "Got phase 1 marker");
is(markers[1].eventPhase, 2, "Got phase 2 marker");
},
}, },
setup(docShell) { {
content.document.body.addEventListener("dog", desc: "Event dispatch on a new document",
function(e) { console.log("hi"); }); searchFor(markers) {
content.document.body.dispatchEvent(new content.Event("dog")); return markers.filter(m => m.name == "DOMEvent").length >= 2;
}, },
check(markers) { setup(docShell) {
markers = markers.filter(m => m.name == "DOMEvent"); let doc = content.document.implementation.createHTMLDocument("doc");
is(markers.length, 2, "Got 2 markers"); let p = doc.createElement("p");
}, p.innerHTML = "inside";
}, { doc.body.appendChild(p);
desc: "Event targeted at child",
searchFor(markers) {
return markers.filter(m => m.name == "DOMEvent").length >= 2;
},
setup(docShell) {
let child = content.document.body.firstElementChild;
child.addEventListener("dog", function(e) { });
child.dispatchEvent(new content.Event("dog"));
},
check(markers) {
markers = markers.filter(m => m.name == "DOMEvent");
is(markers.length, 2, "Got 2 markers");
is(markers[0].eventPhase, 1, "Got phase 1 marker");
is(markers[1].eventPhase, 2, "Got phase 2 marker");
},
}, {
desc: "Event dispatch on a new document",
searchFor(markers) {
return markers.filter(m => m.name == "DOMEvent").length >= 2;
},
setup(docShell) {
let doc = content.document.implementation.createHTMLDocument("doc");
let p = doc.createElement("p");
p.innerHTML = "inside";
doc.body.appendChild(p);
p.addEventListener("zebra", function(e) { console.log("hi"); }); p.addEventListener("zebra", function(e) {
p.dispatchEvent(new content.Event("zebra")); console.log("hi");
});
p.dispatchEvent(new content.Event("zebra"));
},
check(markers) {
markers = markers.filter(m => m.name == "DOMEvent");
is(markers.length, 1, "Got 1 marker");
},
}, },
check(markers) { {
markers = markers.filter(m => m.name == "DOMEvent"); desc: "Event dispatch on window",
is(markers.length, 1, "Got 1 marker"); searchFor(markers) {
}, return markers.filter(m => m.name == "DOMEvent").length >= 2;
}, { },
desc: "Event dispatch on window", setup(docShell) {
searchFor(markers) { content.window.addEventListener("aardvark", function(e) {
return markers.filter(m => m.name == "DOMEvent").length >= 2; console.log("I like ants!");
}, });
setup(docShell) {
content.window.addEventListener("aardvark", function(e) {
console.log("I like ants!");
});
content.window.dispatchEvent(new content.Event("aardvark")); content.window.dispatchEvent(new content.Event("aardvark"));
},
check(markers) {
markers = markers.filter(m => m.name == "DOMEvent");
is(markers.length, 1, "Got 1 marker");
},
}, },
check(markers) { ];
markers = markers.filter(m => m.name == "DOMEvent");
is(markers.length, 1, "Got 1 marker");
},
}];
timelineContentTest(TESTS); timelineContentTest(TESTS);

View file

@ -9,83 +9,111 @@
// Test that the docShell profile timeline API returns the right // Test that the docShell profile timeline API returns the right
// markers for XMLHttpRequest events. // markers for XMLHttpRequest events.
var TESTS = [{ var TESTS = [
desc: "Event dispatch from XMLHttpRequest", {
searchFor(markers) { desc: "Event dispatch from XMLHttpRequest",
return markers.filter(m => m.name == "DOMEvent").length >= 5; searchFor(markers) {
}, return markers.filter(m => m.name == "DOMEvent").length >= 5;
setup(docShell) { },
content.dispatchEvent(new content.Event("dog")); setup(docShell) {
}, content.dispatchEvent(new content.Event("dog"));
check(markers) { },
let domMarkers = markers.filter(m => m.name == "DOMEvent"); check(markers) {
// One subtlety here is that we have five events: the event we let domMarkers = markers.filter(m => m.name == "DOMEvent");
// inject in "setup", plus the four state transition events. The // One subtlety here is that we have five events: the event we
// first state transition is reported synchronously and so should // inject in "setup", plus the four state transition events. The
// show up as a nested marker. // first state transition is reported synchronously and so should
is(domMarkers.length, 5, "Got 5 markers"); // show up as a nested marker.
is(domMarkers.length, 5, "Got 5 markers");
// We should see some Javascript markers, and they should have a // We should see some Javascript markers, and they should have a
// cause. // cause.
let jsMarkers = markers.filter(m => m.name == "Javascript" && m.causeName); let jsMarkers = markers.filter(
ok(jsMarkers.length > 0, "Got some Javascript markers"); m => m.name == "Javascript" && m.causeName
is(jsMarkers[0].stack.functionDisplayName, "do_xhr", );
"Javascript marker has entry point name"); ok(jsMarkers.length > 0, "Got some Javascript markers");
is(
jsMarkers[0].stack.functionDisplayName,
"do_xhr",
"Javascript marker has entry point name"
);
},
}, },
}]; ];
if (Services.prefs.getBoolPref("javascript.options.asyncstack")) { if (Services.prefs.getBoolPref("javascript.options.asyncstack")) {
TESTS.push({ TESTS.push(
desc: "Async stack trace on Javascript marker", {
searchFor: (markers) => { desc: "Async stack trace on Javascript marker",
return markers.some(m => (m.name == "Javascript" && searchFor: markers => {
m.causeName == "promise callback")); return markers.some(
}, m => m.name == "Javascript" && m.causeName == "promise callback"
setup(docShell) { );
content.dispatchEvent(new content.Event("promisetest")); },
}, setup(docShell) {
check(markers) { content.dispatchEvent(new content.Event("promisetest"));
markers = markers.filter(m => (m.name == "Javascript" && },
m.causeName == "promise callback")); check(markers) {
ok(markers.length > 0, "Found a Javascript marker"); markers = markers.filter(
m => m.name == "Javascript" && m.causeName == "promise callback"
);
ok(markers.length > 0, "Found a Javascript marker");
let frame = markers[0].stack; let frame = markers[0].stack;
ok(frame.asyncParent !== null, "Parent frame has async parent"); ok(frame.asyncParent !== null, "Parent frame has async parent");
is(frame.asyncParent.asyncCause, "promise callback", is(
"Async parent has correct cause"); frame.asyncParent.asyncCause,
let asyncFrame = frame.asyncParent; "promise callback",
// Skip over self-hosted parts of our Promise implementation. "Async parent has correct cause"
while (asyncFrame.source === "self-hosted") );
asyncFrame = asyncFrame.parent; let asyncFrame = frame.asyncParent;
is(asyncFrame.functionDisplayName, "do_promise", // Skip over self-hosted parts of our Promise implementation.
"Async parent has correct function name"); while (asyncFrame.source === "self-hosted") {
asyncFrame = asyncFrame.parent;
}
is(
asyncFrame.functionDisplayName,
"do_promise",
"Async parent has correct function name"
);
},
}, },
}, { {
desc: "Async stack trace on Javascript marker with script", desc: "Async stack trace on Javascript marker with script",
searchFor: (markers) => { searchFor: markers => {
return markers.some(m => (m.name == "Javascript" && return markers.some(
m.causeName == "promise callback")); m => m.name == "Javascript" && m.causeName == "promise callback"
}, );
setup(docShell) { },
content.dispatchEvent(new content.Event("promisescript")); setup(docShell) {
}, content.dispatchEvent(new content.Event("promisescript"));
check(markers) { },
markers = markers.filter(m => (m.name == "Javascript" && check(markers) {
m.causeName == "promise callback")); markers = markers.filter(
ok(markers.length > 0, "Found a Javascript marker"); m => m.name == "Javascript" && m.causeName == "promise callback"
);
ok(markers.length > 0, "Found a Javascript marker");
let frame = markers[0].stack; let frame = markers[0].stack;
ok(frame.asyncParent !== null, "Parent frame has async parent"); ok(frame.asyncParent !== null, "Parent frame has async parent");
is(frame.asyncParent.asyncCause, "promise callback", is(
"Async parent has correct cause"); frame.asyncParent.asyncCause,
let asyncFrame = frame.asyncParent; "promise callback",
// Skip over self-hosted parts of our Promise implementation. "Async parent has correct cause"
while (asyncFrame.source === "self-hosted") );
asyncFrame = asyncFrame.parent; let asyncFrame = frame.asyncParent;
is(asyncFrame.functionDisplayName, "do_promise_script", // Skip over self-hosted parts of our Promise implementation.
"Async parent has correct function name"); while (asyncFrame.source === "self-hosted") {
}, asyncFrame = asyncFrame.parent;
}); }
is(
asyncFrame.functionDisplayName,
"do_promise_script",
"Async parent has correct function name"
);
},
}
);
} }
timelineContentTest(TESTS); timelineContentTest(TESTS);

View file

@ -39,49 +39,63 @@ function resolvePromise(resolver) {
resolver(23); resolver(23);
} }
var TESTS = [{ var TESTS = [
desc: "Stack trace on sync reflow", {
searchFor: "Reflow", desc: "Stack trace on sync reflow",
setup(docShell) { searchFor: "Reflow",
let div = content.document.querySelector("div"); setup(docShell) {
forceSyncReflow(div); let div = content.document.querySelector("div");
forceSyncReflow(div);
},
check(markers) {
markers = markers.filter(m => m.name == "Reflow");
ok(markers.length > 0, "Reflow marker includes stack");
ok(markers[0].stack.functionDisplayName == "forceSyncReflow");
},
}, },
check(markers) { {
markers = markers.filter(m => m.name == "Reflow"); desc: "Stack trace on DOM event",
ok(markers.length > 0, "Reflow marker includes stack"); searchFor: "DOMEvent",
ok(markers[0].stack.functionDisplayName == "forceSyncReflow"); setup(docShell) {
content.document.body.addEventListener(
"dog",
function(e) {
console.log("hi");
},
true
);
testSendingEvent();
},
check(markers) {
markers = markers.filter(m => m.name == "DOMEvent");
ok(markers.length > 0, "DOMEvent marker includes stack");
ok(
markers[0].stack.functionDisplayName == "testSendingEvent",
"testSendingEvent is on the stack"
);
},
}, },
}, { {
desc: "Stack trace on DOM event", desc: "Stack trace on console event",
searchFor: "DOMEvent", searchFor: "ConsoleTime",
setup(docShell) { setup(docShell) {
content.document.body.addEventListener("dog", testConsoleTime();
function(e) { console.log("hi"); }, testConsoleTimeEnd();
true); },
testSendingEvent(); check(markers) {
markers = markers.filter(m => m.name == "ConsoleTime");
ok(markers.length > 0, "ConsoleTime marker includes stack");
ok(
markers[0].stack.functionDisplayName == "testConsoleTime",
"testConsoleTime is on the stack"
);
ok(
markers[0].endStack.functionDisplayName == "testConsoleTimeEnd",
"testConsoleTimeEnd is on the stack"
);
},
}, },
check(markers) { ];
markers = markers.filter(m => m.name == "DOMEvent");
ok(markers.length > 0, "DOMEvent marker includes stack");
ok(markers[0].stack.functionDisplayName == "testSendingEvent",
"testSendingEvent is on the stack");
},
}, {
desc: "Stack trace on console event",
searchFor: "ConsoleTime",
setup(docShell) {
testConsoleTime();
testConsoleTimeEnd();
},
check(markers) {
markers = markers.filter(m => m.name == "ConsoleTime");
ok(markers.length > 0, "ConsoleTime marker includes stack");
ok(markers[0].stack.functionDisplayName == "testConsoleTime",
"testConsoleTime is on the stack");
ok(markers[0].endStack.functionDisplayName == "testConsoleTimeEnd",
"testConsoleTimeEnd is on the stack");
},
}];
if (Services.prefs.getBoolPref("javascript.options.asyncstack")) { if (Services.prefs.getBoolPref("javascript.options.asyncstack")) {
TESTS.push({ TESTS.push({
@ -94,25 +108,37 @@ if (Services.prefs.getBoolPref("javascript.options.asyncstack")) {
check(markers) { check(markers) {
markers = markers.filter(m => m.name == "ConsoleTime"); markers = markers.filter(m => m.name == "ConsoleTime");
ok(markers.length > 0, "Promise marker includes stack"); ok(markers.length > 0, "Promise marker includes stack");
ok(markers[0].stack.functionDisplayName == "testConsoleTime", ok(
"testConsoleTime is on the stack"); markers[0].stack.functionDisplayName == "testConsoleTime",
"testConsoleTime is on the stack"
);
let frame = markers[0].endStack; let frame = markers[0].endStack;
ok(frame.functionDisplayName == "testConsoleTimeEnd", ok(
"testConsoleTimeEnd is on the stack"); frame.functionDisplayName == "testConsoleTimeEnd",
"testConsoleTimeEnd is on the stack"
);
frame = frame.parent; frame = frame.parent;
ok(frame.functionDisplayName == "makePromise/<", ok(
"makePromise/< is on the stack"); frame.functionDisplayName == "makePromise/<",
"makePromise/< is on the stack"
);
let asyncFrame = frame.asyncParent; let asyncFrame = frame.asyncParent;
ok(asyncFrame !== null, "Frame has async parent"); ok(asyncFrame !== null, "Frame has async parent");
is(asyncFrame.asyncCause, "promise callback", is(
"Async parent has correct cause"); asyncFrame.asyncCause,
"promise callback",
"Async parent has correct cause"
);
// Skip over self-hosted parts of our Promise implementation. // Skip over self-hosted parts of our Promise implementation.
while (asyncFrame.source === "self-hosted") { while (asyncFrame.source === "self-hosted") {
asyncFrame = asyncFrame.parent; asyncFrame = asyncFrame.parent;
} }
is(asyncFrame.functionDisplayName, "makePromise", is(
"Async parent has correct function name"); asyncFrame.functionDisplayName,
"makePromise",
"Async parent has correct function name"
);
}, },
}); });
} }

View file

@ -8,29 +8,50 @@ const URL = "data:text/html;charset=utf-8,<iframe id='test-iframe'></iframe>";
// Test that the docShell UA emulation works // Test that the docShell UA emulation works
async function contentTask() { async function contentTask() {
let docshell = docShell; let docshell = docShell;
is(docshell.customUserAgent, "", "There should initially be no customUserAgent"); is(
docshell.customUserAgent,
"",
"There should initially be no customUserAgent"
);
docshell.customUserAgent = "foo"; docshell.customUserAgent = "foo";
is(content.navigator.userAgent, "foo", "The user agent should be changed to foo"); is(
content.navigator.userAgent,
"foo",
"The user agent should be changed to foo"
);
let frameWin = content.document.querySelector("#test-iframe").contentWindow; let frameWin = content.document.querySelector("#test-iframe").contentWindow;
is(frameWin.navigator.userAgent, "foo", "The UA should be passed on to frames."); is(
frameWin.navigator.userAgent,
"foo",
"The UA should be passed on to frames."
);
let newFrame = content.document.createElement("iframe"); let newFrame = content.document.createElement("iframe");
content.document.body.appendChild(newFrame); content.document.body.appendChild(newFrame);
let newFrameWin = newFrame.contentWindow; let newFrameWin = newFrame.contentWindow;
is(newFrameWin.navigator.userAgent, "foo", "Newly created frames should use the new UA"); is(
newFrameWin.navigator.userAgent,
"foo",
"Newly created frames should use the new UA"
);
newFrameWin.location.reload(); newFrameWin.location.reload();
await ContentTaskUtils.waitForEvent(newFrameWin, "load"); await ContentTaskUtils.waitForEvent(newFrameWin, "load");
is(newFrameWin.navigator.userAgent, "foo", "New UA should persist across reloads"); is(
newFrameWin.navigator.userAgent,
"foo",
"New UA should persist across reloads"
);
} }
add_task(async function() { add_task(async function() {
await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function(
async function(browser) { browser
await ContentTask.spawn(browser, null, contentTask); ) {
}); await ContentTask.spawn(browser, null, contentTask);
});
}); });

View file

@ -1,29 +1,44 @@
"use strict"; "use strict";
const REDIRECTURL = "http://www.example.com/browser/docshell/test/browser/redirect_to_example.sjs"; const REDIRECTURL =
"http://www.example.com/browser/docshell/test/browser/redirect_to_example.sjs";
add_task(async function() { add_task(async function() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
gURLBar.value = REDIRECTURL; gURLBar.value = REDIRECTURL;
gURLBar.select(); gURLBar.select();
let errorPageLoaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser); let errorPageLoaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser);
EventUtils.sendKey("return"); EventUtils.sendKey("return");
await errorPageLoaded; await errorPageLoaded;
let [contentURL, originalURL] = await ContentTask.spawn(tab.linkedBrowser, null, () => { let [contentURL, originalURL] = await ContentTask.spawn(
return [ tab.linkedBrowser,
content.document.documentURI, null,
content.document.mozDocumentURIIfNotForErrorPages.spec, () => {
]; return [
}); content.document.documentURI,
content.document.mozDocumentURIIfNotForErrorPages.spec,
];
}
);
info("Page that loaded: " + contentURL); info("Page that loaded: " + contentURL);
const errorURI = "about:neterror?"; const errorURI = "about:neterror?";
ok(contentURL.startsWith(errorURI), "Should be on an error page"); ok(contentURL.startsWith(errorURI), "Should be on an error page");
const contentPrincipal = tab.linkedBrowser.contentPrincipal; const contentPrincipal = tab.linkedBrowser.contentPrincipal;
ok(contentPrincipal.URI.spec.startsWith(errorURI), "Principal should be for the error page"); ok(
contentPrincipal.URI.spec.startsWith(errorURI),
"Principal should be for the error page"
);
originalURL = new URL(originalURL); originalURL = new URL(originalURL);
is(originalURL.host, "example", "Should be an error for http://example, not http://www.example.com/"); is(
originalURL.host,
"example",
"Should be an error for http://example, not http://www.example.com/"
);
BrowserTestUtils.removeTab(tab); BrowserTestUtils.removeTab(tab);
}); });

View file

@ -8,11 +8,15 @@ const kSearchEngineURL = "http://example.com/?search={searchTerms}";
add_task(async function setup() { add_task(async function setup() {
// Add a new fake search engine. // Add a new fake search engine.
await Services.search.addEngineWithDetails(kSearchEngineID, await Services.search.addEngineWithDetails(kSearchEngineID, {
{method: "get", template: kSearchEngineURL}); method: "get",
template: kSearchEngineURL,
});
let oldDefaultEngine = await Services.search.getDefault(); let oldDefaultEngine = await Services.search.getDefault();
await Services.search.setDefault(Services.search.getEngineByName(kSearchEngineID)); await Services.search.setDefault(
Services.search.getEngineByName(kSearchEngineID)
);
// Remove the fake engine when done. // Remove the fake engine when done.
registerCleanupFunction(async () => { registerCleanupFunction(async () => {
@ -42,8 +46,11 @@ add_task(async function test() {
// Check that we arrived at the correct URL. // Check that we arrived at the correct URL.
let escapedParams = encodeURIComponent(searchParams).replace("%20", "+"); let escapedParams = encodeURIComponent(searchParams).replace("%20", "+");
let expectedURL = kSearchEngineURL.replace("{searchTerms}", escapedParams); let expectedURL = kSearchEngineURL.replace("{searchTerms}", escapedParams);
is(gBrowser.selectedBrowser.currentURI.spec, expectedURL, is(
"New tab should have loaded with expected url."); gBrowser.selectedBrowser.currentURI.spec,
expectedURL,
"New tab should have loaded with expected url."
);
// Cleanup. // Cleanup.
gBrowser.removeCurrentTab(); gBrowser.removeCurrentTab();

View file

@ -2,8 +2,12 @@
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
addEventListener("frames-loaded", addEventListener(
e => sendAsyncMessage("test:frames-loaded"), true, true); "frames-loaded",
e => sendAsyncMessage("test:frames-loaded"),
true,
true
);
let requestObserver = { let requestObserver = {
observe(subject, topic, data) { observe(subject, topic, data) {
@ -11,15 +15,13 @@ let requestObserver = {
// Get DOMWindow on all child docshells to force about:blank // Get DOMWindow on all child docshells to force about:blank
// content viewers being created. // content viewers being created.
getChildDocShells().map(ds => { getChildDocShells().map(ds => {
ds.QueryInterface(Ci.nsIInterfaceRequestor) ds
.getInterface(Ci.nsILoadContext) .QueryInterface(Ci.nsIInterfaceRequestor)
.associatedWindow; .getInterface(Ci.nsILoadContext).associatedWindow;
}); });
} }
}, },
QueryInterface: ChromeUtils.generateQI([ QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
Ci.nsIObserver,
]),
}; };
Services.obs.addObserver(requestObserver, "http-on-opening-request"); Services.obs.addObserver(requestObserver, "http-on-opening-request");
addEventListener("unload", e => { addEventListener("unload", e => {

View file

@ -1,7 +1,6 @@
/* eslint-env mozilla/frame-script */ /* eslint-env mozilla/frame-script */
function SHistoryListener() { function SHistoryListener() {}
}
SHistoryListener.prototype = { SHistoryListener.prototype = {
retval: true, retval: true,
@ -26,14 +25,15 @@ SHistoryListener.prototype = {
OnHistoryReplaceEntry() {}, OnHistoryReplaceEntry() {},
QueryInterface: ChromeUtils.generateQI([Ci.nsISHistoryListener, QueryInterface: ChromeUtils.generateQI([
Ci.nsISupportsWeakReference]), Ci.nsISHistoryListener,
Ci.nsISupportsWeakReference,
]),
}; };
let testAPI = { let testAPI = {
shistory: null, shistory: null,
listeners: [ new SHistoryListener(), listeners: [new SHistoryListener(), new SHistoryListener()],
new SHistoryListener() ],
init() { init() {
this.shistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory; this.shistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
@ -51,8 +51,10 @@ let testAPI = {
}, },
getListenerStatus() { getListenerStatus() {
sendAsyncMessage("bug422543:getListenerStatus:return", sendAsyncMessage(
this.listeners.map(l => l.last)); "bug422543:getListenerStatus:return",
this.listeners.map(l => l.last)
);
}, },
resetListeners() { resetListeners() {
@ -75,10 +77,20 @@ let testAPI = {
}, },
}; };
addMessageListener("bug422543:cleanup", () => { testAPI.cleanup(); }); addMessageListener("bug422543:cleanup", () => {
addMessageListener("bug422543:getListenerStatus", () => { testAPI.getListenerStatus(); }); testAPI.cleanup();
addMessageListener("bug422543:notifyReload", () => { testAPI.notifyReload(); }); });
addMessageListener("bug422543:resetListeners", () => { testAPI.resetListeners(); }); addMessageListener("bug422543:getListenerStatus", () => {
addMessageListener("bug422543:setRetval", (msg) => { testAPI.setRetval(msg.data); }); testAPI.getListenerStatus();
});
addMessageListener("bug422543:notifyReload", () => {
testAPI.notifyReload();
});
addMessageListener("bug422543:resetListeners", () => {
testAPI.resetListeners();
});
addMessageListener("bug422543:setRetval", msg => {
testAPI.setRetval(msg.data);
});
testAPI.init(); testAPI.init();

View file

@ -6,7 +6,7 @@
// Functions that are automatically loaded as frame scripts for // Functions that are automatically loaded as frame scripts for
// timeline tests. // timeline tests.
const {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm"); const { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
// Functions that look like mochitest functions but forward to the // Functions that look like mochitest functions but forward to the
// browser process. // browser process.
@ -14,7 +14,8 @@ const {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm");
this.ok = function(value, message) { this.ok = function(value, message) {
sendAsyncMessage("browser:test:ok", { sendAsyncMessage("browser:test:ok", {
value: !!value, value: !!value,
message}); message,
});
}; };
this.is = function(v1, v2, message) { this.is = function(v1, v2, message) {
@ -22,7 +23,7 @@ this.is = function(v1, v2, message) {
}; };
this.info = function(message) { this.info = function(message) {
sendAsyncMessage("browser:test:info", {message}); sendAsyncMessage("browser:test:info", { message });
}; };
this.finish = function() { this.finish = function() {
@ -54,7 +55,7 @@ this.timelineContentTest = function(tests) {
info("Start recording"); info("Start recording");
docShell.recordProfileTimelineMarkers = true; docShell.recordProfileTimelineMarkers = true;
for (let {desc, searchFor, setup, check} of tests) { for (let { desc, searchFor, setup, check } of tests) {
info("Running test: " + desc); info("Running test: " + desc);
info("Flushing the previous markers if any"); info("Flushing the previous markers if any");
@ -81,7 +82,7 @@ this.timelineContentTest = function(tests) {
}; };
function timelineWaitForMarkers(docshell, searchFor) { function timelineWaitForMarkers(docshell, searchFor) {
if (typeof(searchFor) == "string") { if (typeof searchFor == "string") {
let searchForString = searchFor; let searchForString = searchFor;
let f = function(markers) { let f = function(markers) {
return markers.some(m => m.name == searchForString); return markers.some(m => m.name == searchForString);

View file

@ -42,14 +42,18 @@ function timelineTestOpenUrl(url) {
window.focus(); window.focus();
let tabSwitchPromise = new Promise((resolve, reject) => { let tabSwitchPromise = new Promise((resolve, reject) => {
window.gBrowser.addEventListener("TabSwitchDone", function() { window.gBrowser.addEventListener(
resolve(); "TabSwitchDone",
}, {once: true}); function() {
resolve();
},
{ once: true }
);
}); });
let loadPromise = new Promise(function(resolve, reject) { let loadPromise = new Promise(function(resolve, reject) {
let browser = window.gBrowser; let browser = window.gBrowser;
let tab = browser.selectedTab = BrowserTestUtils.addTab(browser, url); let tab = (browser.selectedTab = BrowserTestUtils.addTab(browser, url));
let linkedBrowser = tab.linkedBrowser; let linkedBrowser = tab.linkedBrowser;
BrowserTestUtils.browserLoaded(linkedBrowser).then(() => resolve(tab)); BrowserTestUtils.browserLoaded(linkedBrowser).then(() => resolve(tab));
@ -74,7 +78,9 @@ function runCharsetTest(url, check1, charset, check2) {
function afterOpen() { function afterOpen() {
if (charset) { if (charset) {
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterChangeCharset); BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(
afterChangeCharset
);
ContentTask.spawn(gBrowser.selectedBrowser, null, check1).then(() => { ContentTask.spawn(gBrowser.selectedBrowser, null, check1).then(() => {
BrowserSetForcedCharacterSet(charset); BrowserSetForcedCharacterSet(charset);

View file

@ -1,13 +1,23 @@
/** /**
* Import common SimpleTest methods so that they're usable in this window. * Import common SimpleTest methods so that they're usable in this window.
*/ */
var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror", "todo", var imports = [
"todo_is", "todo_isnot" ]; "SimpleTest",
"is",
"isnot",
"ok",
"onerror",
"todo",
"todo_is",
"todo_isnot",
];
for (var name of imports) { for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name]; window[name] = window.opener.wrappedJSObject[name];
} }
const {BrowserTestUtils} = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm"); const { BrowserTestUtils } = ChromeUtils.import(
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); "resource://testing-common/BrowserTestUtils.jsm"
);
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
// Some functions assume chrome-harness.js has been loaded. // Some functions assume chrome-harness.js has been loaded.
/* import-globals-from ../../../testing/mochitest/chrome-harness.js */ /* import-globals-from ../../../testing/mochitest/chrome-harness.js */
@ -22,16 +32,15 @@ const NAV_URI = 3;
const NAV_RELOAD = 4; const NAV_RELOAD = 4;
var gExpectedEvents; // an array of events which are expected to var gExpectedEvents; // an array of events which are expected to
// be triggered by this navigation // be triggered by this navigation
var gUnexpectedEvents; // an array of event names which are NOT expected var gUnexpectedEvents; // an array of event names which are NOT expected
// to be triggered by this navigation // to be triggered by this navigation
var gFinalEvent; // true if the last expected event has fired var gFinalEvent; // true if the last expected event has fired
var gUrisNotInBFCache = []; // an array of uri's which shouldn't be stored var gUrisNotInBFCache = []; // an array of uri's which shouldn't be stored
// in the bfcache // in the bfcache
var gNavType = NAV_NONE; // defines the most recent navigation type var gNavType = NAV_NONE; // defines the most recent navigation type
// executed by doPageNavigation // executed by doPageNavigation
var gOrigMaxTotalViewers = // original value of max_total_viewers, var gOrigMaxTotalViewers = undefined; // original value of max_total_viewers, // to be restored at end of test
undefined; // to be restored at end of test
var gExtractedPath = null; // used to cache file path for extracting files from a .jar file var gExtractedPath = null; // used to cache file path for extracting files from a .jar file
@ -99,57 +108,87 @@ function doPageNavigation(params) {
let forward = params.forward ? params.forward : false; let forward = params.forward ? params.forward : false;
let reload = params.reload ? params.reload : false; let reload = params.reload ? params.reload : false;
let uri = params.uri ? params.uri : false; let uri = params.uri ? params.uri : false;
let eventsToListenFor = typeof(params.eventsToListenFor) != "undefined" ? let eventsToListenFor =
params.eventsToListenFor : ["pageshow"]; typeof params.eventsToListenFor != "undefined"
gExpectedEvents = typeof(params.eventsToListenFor) == "undefined" || ? params.eventsToListenFor
eventsToListenFor.length == 0 ? undefined : params.expectedEvents; : ["pageshow"];
gUnexpectedEvents = typeof(params.eventsToListenFor) == "undefined" || gExpectedEvents =
eventsToListenFor.length == 0 ? undefined : params.unexpectedEvents; typeof params.eventsToListenFor == "undefined" ||
let preventBFCache = (typeof[params.preventBFCache] == "undefined") ? eventsToListenFor.length == 0
false : params.preventBFCache; ? undefined
let waitOnly = (typeof(params.waitForEventsOnly) == "boolean" : params.expectedEvents;
&& params.waitForEventsOnly); gUnexpectedEvents =
typeof params.eventsToListenFor == "undefined" ||
eventsToListenFor.length == 0
? undefined
: params.unexpectedEvents;
let preventBFCache =
typeof [params.preventBFCache] == "undefined"
? false
: params.preventBFCache;
let waitOnly =
typeof params.waitForEventsOnly == "boolean" && params.waitForEventsOnly;
// Do some sanity checking on arguments. // Do some sanity checking on arguments.
if (back && forward) if (back && forward) {
throw new Error("Can't specify both back and forward"); throw new Error("Can't specify both back and forward");
if (back && uri) }
if (back && uri) {
throw new Error("Can't specify both back and a uri"); throw new Error("Can't specify both back and a uri");
if (forward && uri) }
if (forward && uri) {
throw new Error("Can't specify both forward and a uri"); throw new Error("Can't specify both forward and a uri");
if (reload && (forward || back || uri)) }
if (reload && (forward || back || uri)) {
throw new Error("Can't specify reload and another navigation type"); throw new Error("Can't specify reload and another navigation type");
if (!back && !forward && !uri && !reload && !waitOnly) }
if (!back && !forward && !uri && !reload && !waitOnly) {
throw new Error("Must specify back or foward or reload or uri"); throw new Error("Must specify back or foward or reload or uri");
if (params.onNavComplete && eventsToListenFor.length == 0) }
if (params.onNavComplete && eventsToListenFor.length == 0) {
throw new Error("Can't use onNavComplete when eventsToListenFor == []"); throw new Error("Can't use onNavComplete when eventsToListenFor == []");
if (params.preventBFCache && eventsToListenFor.length == 0) }
if (params.preventBFCache && eventsToListenFor.length == 0) {
throw new Error("Can't use preventBFCache when eventsToListenFor == []"); throw new Error("Can't use preventBFCache when eventsToListenFor == []");
if (params.preventBFCache && waitOnly) }
if (params.preventBFCache && waitOnly) {
throw new Error("Can't prevent bfcaching when only waiting for events"); throw new Error("Can't prevent bfcaching when only waiting for events");
if (waitOnly && typeof(params.onNavComplete) == "undefined") }
throw new Error("Must specify onNavComplete when specifying waitForEventsOnly"); if (waitOnly && typeof params.onNavComplete == "undefined") {
if (waitOnly && (back || forward || reload || uri)) throw new Error(
throw new Error("Can't specify a navigation type when using waitForEventsOnly"); "Must specify onNavComplete when specifying waitForEventsOnly"
);
}
if (waitOnly && (back || forward || reload || uri)) {
throw new Error(
"Can't specify a navigation type when using waitForEventsOnly"
);
}
for (let anEventType of eventsToListenFor) { for (let anEventType of eventsToListenFor) {
let eventFound = false; let eventFound = false;
if ( (anEventType == "pageshow") && (!gExpectedEvents) ) if (anEventType == "pageshow" && !gExpectedEvents) {
eventFound = true; eventFound = true;
}
if (gExpectedEvents) { if (gExpectedEvents) {
for (let anExpectedEvent of gExpectedEvents) { for (let anExpectedEvent of gExpectedEvents) {
if (anExpectedEvent.type == anEventType) if (anExpectedEvent.type == anEventType) {
eventFound = true; eventFound = true;
}
} }
} }
if (gUnexpectedEvents) { if (gUnexpectedEvents) {
for (let anExpectedEventType of gUnexpectedEvents) { for (let anExpectedEventType of gUnexpectedEvents) {
if (anExpectedEventType == anEventType) if (anExpectedEventType == anEventType) {
eventFound = true; eventFound = true;
}
} }
} }
if (!eventFound) if (!eventFound) {
throw new Error(`Event type ${anEventType} is specified in ` + throw new Error(
"eventsToListenFor, but not in expectedEvents"); `Event type ${anEventType} is specified in ` +
"eventsToListenFor, but not in expectedEvents"
);
}
} }
// If the test explicitly sets .eventsToListenFor to [], don't wait for any // If the test explicitly sets .eventsToListenFor to [], don't wait for any
@ -160,8 +199,11 @@ function doPageNavigation(params) {
// property of the input parameters. // property of the input parameters.
for (let eventType of eventsToListenFor) { for (let eventType of eventsToListenFor) {
dump("TEST: registering a listener for " + eventType + " events\n"); dump("TEST: registering a listener for " + eventType + " events\n");
TestWindow.getBrowser().addEventListener(eventType, pageEventListener, TestWindow.getBrowser().addEventListener(
true); eventType,
pageEventListener,
true
);
} }
// Perform the specified navigation. // Perform the specified navigation.
@ -187,11 +229,17 @@ function doPageNavigation(params) {
// wait for all events to occur, and then call doPageNavigation_complete(). // wait for all events to occur, and then call doPageNavigation_complete().
if (eventsToListenFor.length > 0 && params.onNavComplete) { if (eventsToListenFor.length > 0 && params.onNavComplete) {
waitForTrue( waitForTrue(
function() { return gFinalEvent; },
function() { function() {
doPageNavigation_complete(eventsToListenFor, params.onNavComplete, return gFinalEvent;
preventBFCache); },
} ); function() {
doPageNavigation_complete(
eventsToListenFor,
params.onNavComplete,
preventBFCache
);
}
);
} }
} }
@ -201,23 +249,35 @@ function doPageNavigation(params) {
* function is called after all the expected events for this navigation have * function is called after all the expected events for this navigation have
* occurred. * occurred.
*/ */
function doPageNavigation_complete(eventsToListenFor, onNavComplete, function doPageNavigation_complete(
preventBFCache) { eventsToListenFor,
onNavComplete,
preventBFCache
) {
// Unregister our event listeners. // Unregister our event listeners.
dump("TEST: removing event listeners\n"); dump("TEST: removing event listeners\n");
for (let eventType of eventsToListenFor) { for (let eventType of eventsToListenFor) {
TestWindow.getBrowser().removeEventListener(eventType, pageEventListener, TestWindow.getBrowser().removeEventListener(
true); eventType,
pageEventListener,
true
);
} }
// If the .preventBFCache property was set, add an empty unload handler to // If the .preventBFCache property was set, add an empty unload handler to
// prevent the page from being bfcached. // prevent the page from being bfcached.
let uri = TestWindow.getBrowser().currentURI.spec; let uri = TestWindow.getBrowser().currentURI.spec;
if (preventBFCache) { if (preventBFCache) {
TestWindow.getWindow().addEventListener("unload", function() { TestWindow.getWindow().addEventListener(
dump("TEST: Called dummy unload function to prevent page from " + "unload",
"being bfcached.\n"); function() {
}, true); dump(
"TEST: Called dummy unload function to prevent page from " +
"being bfcached.\n"
);
},
true
);
// Save the current uri in an array of uri's which shouldn't be // Save the current uri in an array of uri's which shouldn't be
// stored in the bfcache, for later verification. // stored in the bfcache, for later verification.
@ -227,12 +287,11 @@ function doPageNavigation_complete(eventsToListenFor, onNavComplete,
} else if (gNavType == NAV_URI) { } else if (gNavType == NAV_URI) {
// If we're navigating to a uri and .preventBFCache was not // If we're navigating to a uri and .preventBFCache was not
// specified, splice it out of gUrisNotInBFCache if it's there. // specified, splice it out of gUrisNotInBFCache if it's there.
gUrisNotInBFCache.forEach( gUrisNotInBFCache.forEach(function(element, index, array) {
function(element, index, array) { if (element == uri) {
if (element == uri) { array.splice(index, 1);
array.splice(index, 1); }
} }, this);
}, this);
} }
// Notify the callback now that we're done. // Notify the callback now that we're done.
@ -254,8 +313,15 @@ function waitForPageEvents(params) {
*/ */
function pageEventListener(event) { function pageEventListener(event) {
try { try {
dump("TEST: eventListener received a " + event.type + " event for page " + dump(
event.originalTarget.title + ", persisted=" + event.persisted + "\n"); "TEST: eventListener received a " +
event.type +
" event for page " +
event.originalTarget.title +
", persisted=" +
event.persisted +
"\n"
);
} catch (e) { } catch (e) {
// Ignore any exception. // Ignore any exception.
} }
@ -264,25 +330,35 @@ function pageEventListener(event) {
// loaded with .preventBFCache, make sure that its pageshow event // loaded with .preventBFCache, make sure that its pageshow event
// has .persisted = false, even if the test doesn't explicitly test // has .persisted = false, even if the test doesn't explicitly test
// for .persisted. // for .persisted.
if ( (event.type == "pageshow") && if (
(gNavType == NAV_BACK || gNavType == NAV_FORWARD) ) { event.type == "pageshow" &&
(gNavType == NAV_BACK || gNavType == NAV_FORWARD)
) {
let uri = TestWindow.getBrowser().currentURI.spec; let uri = TestWindow.getBrowser().currentURI.spec;
if (uri in gUrisNotInBFCache) { if (uri in gUrisNotInBFCache) {
ok(!event.persisted, "pageshow event has .persisted = false, even " + ok(
"though it was loaded with .preventBFCache previously\n"); !event.persisted,
"pageshow event has .persisted = false, even " +
"though it was loaded with .preventBFCache previously\n"
);
} }
} }
if (typeof(gUnexpectedEvents) != "undefined") { if (typeof gUnexpectedEvents != "undefined") {
is(gUnexpectedEvents.indexOf(event.type), -1, is(
"Should not get unexpected event " + event.type); gUnexpectedEvents.indexOf(event.type),
-1,
"Should not get unexpected event " + event.type
);
} }
// If no expected events were specified, mark the final event as having been // If no expected events were specified, mark the final event as having been
// triggered when a pageshow event is fired; this will allow // triggered when a pageshow event is fired; this will allow
// doPageNavigation() to return. // doPageNavigation() to return.
if ((typeof(gExpectedEvents) == "undefined") && event.type == "pageshow") { if (typeof gExpectedEvents == "undefined" && event.type == "pageshow") {
waitForNextPaint(function() { gFinalEvent = true; }); waitForNextPaint(function() {
gFinalEvent = true;
});
return; return;
} }
@ -297,41 +373,71 @@ function pageEventListener(event) {
// actual event. // actual event.
let expected = gExpectedEvents.shift(); let expected = gExpectedEvents.shift();
is(event.type, expected.type, is(
"A " + expected.type + " event was expected, but a " + event.type,
event.type + " event occurred"); expected.type,
"A " +
expected.type +
" event was expected, but a " +
event.type +
" event occurred"
);
if (typeof(expected.title) != "undefined") { if (typeof expected.title != "undefined") {
ok(event.originalTarget instanceof HTMLDocument, ok(
"originalTarget for last " + event.type + event.originalTarget instanceof HTMLDocument,
" event not an HTMLDocument"); "originalTarget for last " + event.type + " event not an HTMLDocument"
is(event.originalTarget.title, expected.title, );
"A " + event.type + " event was expected for page " + is(
expected.title + ", but was fired for page " + event.originalTarget.title,
event.originalTarget.title); expected.title,
"A " +
event.type +
" event was expected for page " +
expected.title +
", but was fired for page " +
event.originalTarget.title
);
} }
if (typeof(expected.persisted) != "undefined") { if (typeof expected.persisted != "undefined") {
is(event.persisted, expected.persisted, is(
"The persisted property of the " + event.type + " event on page " + event.persisted,
event.originalTarget.location + " had an unexpected value"); expected.persisted,
"The persisted property of the " +
event.type +
" event on page " +
event.originalTarget.location +
" had an unexpected value"
);
} }
if ("visibilityState" in expected) { if ("visibilityState" in expected) {
is(event.originalTarget.visibilityState, expected.visibilityState, is(
"The visibilityState property of the document on page " + event.originalTarget.visibilityState,
event.originalTarget.location + " had an unexpected value"); expected.visibilityState,
"The visibilityState property of the document on page " +
event.originalTarget.location +
" had an unexpected value"
);
} }
if ("hidden" in expected) { if ("hidden" in expected) {
is(event.originalTarget.hidden, expected.hidden, is(
"The hidden property of the document on page " + event.originalTarget.hidden,
event.originalTarget.location + " had an unexpected value"); expected.hidden,
"The hidden property of the document on page " +
event.originalTarget.location +
" had an unexpected value"
);
} }
// If we're out of expected events, let doPageNavigation() return. // If we're out of expected events, let doPageNavigation() return.
if (gExpectedEvents.length == 0) if (gExpectedEvents.length == 0) {
waitForNextPaint(function() { gFinalEvent = true; }); waitForNextPaint(function() {
gFinalEvent = true;
});
}
} }
/** /**
@ -344,9 +450,11 @@ function finish() {
// If the test changed the value of max_total_viewers via a call to // If the test changed the value of max_total_viewers via a call to
// enableBFCache(), then restore it now. // enableBFCache(), then restore it now.
if (typeof(gOrigMaxTotalViewers) != "undefined") { if (typeof gOrigMaxTotalViewers != "undefined") {
Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", Services.prefs.setIntPref(
gOrigMaxTotalViewers); "browser.sessionhistory.max_total_viewers",
gOrigMaxTotalViewers
);
} }
// Close the test window and signal the framework that the test is done. // Close the test window and signal the framework that the test is done.
@ -383,33 +491,31 @@ function finish() {
*/ */
function waitForTrue(fn, onWaitComplete, timeout) { function waitForTrue(fn, onWaitComplete, timeout) {
var start = new Date().valueOf(); var start = new Date().valueOf();
if (typeof(timeout) != "undefined") { if (typeof timeout != "undefined") {
// If timeoutWait is less than 500, assume it represents seconds, and // If timeoutWait is less than 500, assume it represents seconds, and
// convert to ms. // convert to ms.
if (timeout < 500) if (timeout < 500) {
timeout *= 1000; timeout *= 1000;
}
} }
// Loop until the test function returns true, or until a timeout occurs, // Loop until the test function returns true, or until a timeout occurs,
// if a timeout is defined. // if a timeout is defined.
var intervalid; var intervalid;
intervalid = intervalid = setInterval(function() {
setInterval( var timeoutHit = false;
function() { if (typeof timeout != "undefined") {
var timeoutHit = false; timeoutHit = new Date().valueOf() - start >= timeout;
if (typeof(timeout) != "undefined") { if (timeoutHit) {
timeoutHit = new Date().valueOf() - start >= ok(false, "Timed out waiting for condition");
timeout; }
if (timeoutHit) { }
ok(false, "Timed out waiting for condition"); if (timeoutHit || fn.call()) {
} // Stop calling the test function and notify the callback.
} clearInterval(intervalid);
if (timeoutHit || fn.call()) { onWaitComplete.call();
// Stop calling the test function and notify the callback. }
clearInterval(intervalid); }, 20);
onWaitComplete.call();
}
}, 20);
} }
function waitForNextPaint(cb) { function waitForNextPaint(cb) {
@ -428,18 +534,23 @@ function enableBFCache(enable) {
// If this is the first time the test called enableBFCache(), // If this is the first time the test called enableBFCache(),
// store the original value of max_total_viewers, so it can // store the original value of max_total_viewers, so it can
// be restored at the end of the test. // be restored at the end of the test.
if (typeof(gOrigMaxTotalViewers) == "undefined") { if (typeof gOrigMaxTotalViewers == "undefined") {
gOrigMaxTotalViewers = gOrigMaxTotalViewers = Services.prefs.getIntPref(
Services.prefs.getIntPref("browser.sessionhistory.max_total_viewers"); "browser.sessionhistory.max_total_viewers"
);
} }
if (typeof(enable) == "boolean") { if (typeof enable == "boolean") {
if (enable) if (enable) {
Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1); Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1);
else } else {
Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", 0); Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", 0);
} else if (typeof(enable) == "number") { }
Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", enable); } else if (typeof enable == "number") {
Services.prefs.setIntPref(
"browser.sessionhistory.max_total_viewers",
enable
);
} }
} }

View file

@ -36,7 +36,8 @@ function navigateByForm(name) {
var form = document.createElement("form"); var form = document.createElement("form");
form.action = target_url; form.action = target_url;
form.method = "POST"; form.method = "POST";
form.target = name; document.body.appendChild(form); form.target = name;
document.body.appendChild(form);
form.submit(); form.submit();
} }
@ -48,7 +49,7 @@ function navigateByHyperlink(name) {
link.target = name; link.target = name;
link.id = "navigation_hyperlink_" + hyperlink_count++; link.id = "navigation_hyperlink_" + hyperlink_count++;
document.body.appendChild(link); document.body.appendChild(link);
sendMouseEvent({type: "click"}, link.id); sendMouseEvent({ type: "click" }, link.id);
} }
// ///////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////
@ -58,8 +59,9 @@ function navigateByHyperlink(name) {
async function isNavigated(wnd, message) { async function isNavigated(wnd, message) {
var result = null; var result = null;
try { try {
result = await SpecialPowers.spawn( result = await SpecialPowers.spawn(wnd, [], () =>
wnd, [], () => this.content.document.body.innerHTML.trim()); this.content.document.body.innerHTML.trim()
);
} catch (ex) { } catch (ex) {
result = ex; result = ex;
} }
@ -101,8 +103,9 @@ function isInaccessible(wnd, message) {
/* eslint-disable mozilla/use-services */ /* eslint-disable mozilla/use-services */
function xpcEnumerateContentWindows(callback) { function xpcEnumerateContentWindows(callback) {
var Ci = SpecialPowers.Ci; var Ci = SpecialPowers.Ci;
var ww = SpecialPowers.Cc["@mozilla.org/embedcomp/window-watcher;1"] var ww = SpecialPowers.Cc[
.getService(Ci.nsIWindowWatcher); "@mozilla.org/embedcomp/window-watcher;1"
].getService(Ci.nsIWindowWatcher);
var contentWindows = []; var contentWindows = [];
@ -114,8 +117,12 @@ function xpcEnumerateContentWindows(callback) {
var childTreeNode = docshellTreeNode.getChildAt(i); var childTreeNode = docshellTreeNode.getChildAt(i);
// we're only interested in content docshells // we're only interested in content docshells
if (SpecialPowers.unwrap(childTreeNode.itemType) != Ci.nsIDocShellTreeItem.typeContent) if (
SpecialPowers.unwrap(childTreeNode.itemType) !=
Ci.nsIDocShellTreeItem.typeContent
) {
continue; continue;
}
var webNav = childTreeNode.QueryInterface(Ci.nsIWebNavigation); var webNav = childTreeNode.QueryInterface(Ci.nsIWebNavigation);
contentWindows.push(webNav.document.defaultView); contentWindows.push(webNav.document.defaultView);
@ -125,8 +132,9 @@ function xpcEnumerateContentWindows(callback) {
} }
} }
while (contentWindows.length > 0) while (contentWindows.length > 0) {
callback(contentWindows.pop()); callback(contentWindows.pop());
}
} }
/* eslint-enable mozilla/use-services */ /* eslint-enable mozilla/use-services */
@ -135,8 +143,9 @@ function xpcGetFramesByName(name) {
var results = []; var results = [];
xpcEnumerateContentWindows(function(win) { xpcEnumerateContentWindows(function(win) {
if (win.name == name) if (win.name == name) {
results.push(win); results.push(win);
}
}); });
return results; return results;
@ -144,9 +153,11 @@ function xpcGetFramesByName(name) {
function xpcCleanupWindows() { function xpcCleanupWindows() {
xpcEnumerateContentWindows(function(win) { xpcEnumerateContentWindows(function(win) {
if (win.location && if (
(win.location.href.endsWith(target_url) || win.location &&
win.location.href.endsWith(target_popup_url))) { (win.location.href.endsWith(target_url) ||
win.location.href.endsWith(target_popup_url))
) {
win.close(); win.close();
} }
}); });
@ -163,36 +174,41 @@ function xpcWaitForFinishedFrames(callback, numFrames) {
return; return;
} }
if (finishedFrameCount > numFrames) if (finishedFrameCount > numFrames) {
throw new Error("Too many frames loaded."); throw new Error("Too many frames loaded.");
}
} }
var finishedWindows = []; var finishedWindows = [];
function contains(obj, arr) { function contains(obj, arr) {
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
if (obj === arr[i]) if (obj === arr[i]) {
return true; return true;
}
} }
return false; return false;
} }
function searchForFinishedFrames(win) { function searchForFinishedFrames(win) {
if ((win.location.href.endsWith(target_url) || if (
win.location.href.endsWith(target_popup_url)) && (win.location.href.endsWith(target_url) ||
win.document && win.location.href.endsWith(target_popup_url)) &&
win.document.body && win.document &&
(win.document.body.textContent.trim() == body || win.document.body &&
win.document.body.textContent.trim() == popup_body) && (win.document.body.textContent.trim() == body ||
win.document.readyState == "complete") { win.document.body.textContent.trim() == popup_body) &&
win.document.readyState == "complete"
) {
var windowId = win.windowUtils.outerWindowID; var windowId = win.windowUtils.outerWindowID;
if (!contains(windowId, finishedWindows)) { if (!contains(windowId, finishedWindows)) {
finishedWindows.push(windowId); finishedWindows.push(windowId);
frameFinished(); frameFinished();
} }
} }
for (var i = 0; i < win.frames.length; i++) for (var i = 0; i < win.frames.length; i++) {
searchForFinishedFrames(win.frames[i]); searchForFinishedFrames(win.frames[i]);
}
} }
function poll() { function poll() {

View file

@ -12,15 +12,20 @@ var ctx = {};
function nShotsListener(aBrowser, aType, aCallback, aCount) { function nShotsListener(aBrowser, aType, aCallback, aCount) {
let count = aCount; let count = aCount;
let removeFunc; let removeFunc;
removeFunc = BrowserTestUtils.addContentEventListener(aBrowser, aType, function listenerCallback() { removeFunc = BrowserTestUtils.addContentEventListener(
if (--count == 0) { aBrowser,
removeFunc(); aType,
function listenerCallback() {
if (--count == 0) {
removeFunc();
// aCallback is executed asynchronously, which is handy because load // aCallback is executed asynchronously, which is handy because load
// events fire before mIsDocumentLoaded is actually set to true. :( // events fire before mIsDocumentLoaded is actually set to true. :(
executeSoon(aCallback); executeSoon(aCallback);
} }
}, true); },
true
);
} }
function oneShotListener(aBrowser, aType, aCallback) { function oneShotListener(aBrowser, aType, aCallback) {
@ -47,8 +52,10 @@ async function step1() {
ctx.tab0 = gBrowser.selectedTab; ctx.tab0 = gBrowser.selectedTab;
ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0); ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0);
await BrowserTestUtils.waitForCondition(() => ctx.tab0Browser.docShellIsActive, await BrowserTestUtils.waitForCondition(
"Timed out waiting for initial tab to be active."); () => ctx.tab0Browser.docShellIsActive,
"Timed out waiting for initial tab to be active."
);
// Open a New Tab // Open a New Tab
ctx.tab1 = BrowserTestUtils.addTab(gBrowser, testPath + "bug343515_pg1.html"); ctx.tab1 = BrowserTestUtils.addTab(gBrowser, testPath + "bug343515_pg1.html");
@ -57,8 +64,11 @@ async function step1() {
} }
function step2() { function step2() {
is(testPath + "bug343515_pg1.html", ctx.tab1Browser.currentURI.spec, is(
"Got expected tab 1 url in step 2"); testPath + "bug343515_pg1.html",
ctx.tab1Browser.currentURI.spec,
"Got expected tab 1 url in step 2"
);
// Our current tab should still be active // Our current tab should still be active
ok(ctx.tab0Browser.docShellIsActive, "Tab 0 should still be active"); ok(ctx.tab0Browser.docShellIsActive, "Tab 0 should still be active");
@ -71,7 +81,10 @@ function step2() {
ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
// Open another tab // Open another tab
ctx.tab2 = BrowserTestUtils.addTab(gBrowser, testPath + "bug343515_pg2.html"); ctx.tab2 = BrowserTestUtils.addTab(
gBrowser,
testPath + "bug343515_pg2.html"
);
ctx.tab2Browser = gBrowser.getBrowserForTab(ctx.tab2); ctx.tab2Browser = gBrowser.getBrowserForTab(ctx.tab2);
// bug343515_pg2.html consists of a page with two iframes, // bug343515_pg2.html consists of a page with two iframes,
@ -81,8 +94,11 @@ function step2() {
} }
function step3() { function step3() {
is(testPath + "bug343515_pg2.html", ctx.tab2Browser.currentURI.spec, is(
"Got expected tab 2 url in step 3"); testPath + "bug343515_pg2.html",
ctx.tab2Browser.currentURI.spec,
"Got expected tab 2 url in step 3"
);
// Tab 0 should be inactive, Tab 1 should be active // Tab 0 should be inactive, Tab 1 should be active
ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
@ -110,7 +126,9 @@ function step3() {
function step4() { function step4() {
/* eslint-disable no-shadow */ /* eslint-disable no-shadow */
function checkTab2Active(expected) { function checkTab2Active(expected) {
return ContentTask.spawn(ctx.tab2Browser, expected, async function(expected) { return ContentTask.spawn(ctx.tab2Browser, expected, async function(
expected
) {
function isActive(aWindow) { function isActive(aWindow) {
var docshell = aWindow.docShell; var docshell = aWindow.docShell;
return docshell.isActive; return docshell.isActive;
@ -118,39 +136,61 @@ function step4() {
let active = expected ? "active" : "inactive"; let active = expected ? "active" : "inactive";
Assert.equal(content.frames.length, 2, "Tab 2 should have 2 iframes"); Assert.equal(content.frames.length, 2, "Tab 2 should have 2 iframes");
for (var i = 0; i < content.frames.length; i++) for (var i = 0; i < content.frames.length; i++) {
info("step 4, frame " + i + " info: " + content.frames[i].location); info("step 4, frame " + i + " info: " + content.frames[i].location);
Assert.equal(content.frames[0].frames.length, 1, "Tab 2 iframe 0 should have 1 iframes"); }
Assert.equal(isActive(content.frames[0]), expected, `Tab2 iframe 0 should be ${active}`); Assert.equal(
Assert.equal(isActive(content.frames[0].frames[0]), expected, content.frames[0].frames.length,
`Tab2 iframe 0 subiframe 0 should be ${active}`); 1,
Assert.equal(isActive(content.frames[1]), expected, `Tab2 iframe 1 should be ${active}`); "Tab 2 iframe 0 should have 1 iframes"
);
Assert.equal(
isActive(content.frames[0]),
expected,
`Tab2 iframe 0 should be ${active}`
);
Assert.equal(
isActive(content.frames[0].frames[0]),
expected,
`Tab2 iframe 0 subiframe 0 should be ${active}`
);
Assert.equal(
isActive(content.frames[1]),
expected,
`Tab2 iframe 1 should be ${active}`
);
}); });
} }
/* eslint-enable no-shadow */ /* eslint-enable no-shadow */
is(testPath + "bug343515_pg3.html", ctx.tab2Browser.currentURI.spec, is(
"Got expected tab 2 url in step 4"); testPath + "bug343515_pg3.html",
ctx.tab2Browser.currentURI.spec,
"Got expected tab 2 url in step 4"
);
// Tab 0 should be inactive, Tab 1 should be active // Tab 0 should be inactive, Tab 1 should be active
ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
// Tab2 and all descendants should be inactive // Tab2 and all descendants should be inactive
checkTab2Active(false).then(() => { checkTab2Active(false)
// Switch to Tab 2 .then(() => {
return BrowserTestUtils.switchTab(gBrowser, ctx.tab2); // Switch to Tab 2
}).then(() => { return BrowserTestUtils.switchTab(gBrowser, ctx.tab2);
// Check everything })
ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); .then(() => {
ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should be inactive"); // Check everything
ok(ctx.tab2Browser.docShellIsActive, "Tab 2 should be active"); ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
ok(!ctx.tab1Browser.docShellIsActive, "Tab 1 should be inactive");
ok(ctx.tab2Browser.docShellIsActive, "Tab 2 should be active");
return checkTab2Active(true); return checkTab2Active(true);
}).then(() => { })
// Go back .then(() => {
waitForPageshow(ctx.tab2Browser, step5); // Go back
ctx.tab2Browser.goBack(); waitForPageshow(ctx.tab2Browser, step5);
}); ctx.tab2Browser.goBack();
});
} }
function step5() { function step5() {
@ -163,17 +203,22 @@ function step5() {
let docShell = content.frames[i].docShell; let docShell = content.frames[i].docShell;
Assert.ok(docShell.isActive, `Tab2 iframe ${i} should be active`); Assert.ok(docShell.isActive, `Tab2 iframe ${i} should be active`);
} }
}).then(() => { })
// Switch to tab 1 .then(() => {
return BrowserTestUtils.switchTab(gBrowser, ctx.tab1); // Switch to tab 1
}).then(() => { return BrowserTestUtils.switchTab(gBrowser, ctx.tab1);
// Navigate to page 3 })
BrowserTestUtils.loadURI(ctx.tab1Browser, testPath + "bug343515_pg3.html"); .then(() => {
// Navigate to page 3
BrowserTestUtils.loadURI(
ctx.tab1Browser,
testPath + "bug343515_pg3.html"
);
// bug343515_pg3.html consists of a page with two iframes, one of which // bug343515_pg3.html consists of a page with two iframes, one of which
// contains another iframe, so there'll be a total of 4 load events // contains another iframe, so there'll be a total of 4 load events
nShotsListener(ctx.tab1Browser, "load", step6, 4); nShotsListener(ctx.tab1Browser, "load", step6, 4);
}); });
} }
function step6() { function step6() {
@ -187,56 +232,73 @@ function step6() {
} }
Assert.ok(isActive(content.frames[0]), "Tab1 iframe 0 should be active"); Assert.ok(isActive(content.frames[0]), "Tab1 iframe 0 should be active");
Assert.ok(isActive(content.frames[0].frames[0]), "Tab1 iframe 0 subiframe 0 should be active"); Assert.ok(
isActive(content.frames[0].frames[0]),
"Tab1 iframe 0 subiframe 0 should be active"
);
Assert.ok(isActive(content.frames[1]), "Tab1 iframe 1 should be active"); Assert.ok(isActive(content.frames[1]), "Tab1 iframe 1 should be active");
}).then(() => { })
ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive"); .then(() => {
return ContentTask.spawn(ctx.tab2Browser, null, async function() { ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
for (var i = 0; i < content.frames.length; i++) { return ContentTask.spawn(ctx.tab2Browser, null, async function() {
let docShell = content.frames[i].docShell; for (var i = 0; i < content.frames.length; i++) {
Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`); let docShell = content.frames[i].docShell;
} Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`);
}
});
})
.then(() => {
// Go forward on tab 2
waitForPageshow(ctx.tab2Browser, step7);
ctx.tab2Browser.goForward();
}); });
}).then(() => {
// Go forward on tab 2
waitForPageshow(ctx.tab2Browser, step7);
ctx.tab2Browser.goForward();
});
} }
function step7() { function step7() {
/* eslint-disable no-shadow */ /* eslint-disable no-shadow */
function checkBrowser(browser, tabNum, active) { function checkBrowser(browser, tabNum, active) {
return ContentTask.spawn(browser, { tabNum, active }, return ContentTask.spawn(browser, { tabNum, active }, async function({
async function({ tabNum, active }) { tabNum,
function isActive(aWindow) { active,
var docshell = aWindow.docShell; }) {
return docshell.isActive; function isActive(aWindow) {
} var docshell = aWindow.docShell;
return docshell.isActive;
}
let activestr = active ? "active" : "inactive"; let activestr = active ? "active" : "inactive";
Assert.equal(isActive(content.frames[0]), active, Assert.equal(
`Tab${tabNum} iframe 0 should be ${activestr}`); isActive(content.frames[0]),
Assert.equal(isActive(content.frames[0].frames[0]), active, active,
`Tab${tabNum} iframe 0 subiframe 0 should be ${activestr}`); `Tab${tabNum} iframe 0 should be ${activestr}`
Assert.equal(isActive(content.frames[1]), active, );
`Tab${tabNum} iframe 1 should be ${activestr}`); Assert.equal(
}); isActive(content.frames[0].frames[0]),
active,
`Tab${tabNum} iframe 0 subiframe 0 should be ${activestr}`
);
Assert.equal(
isActive(content.frames[1]),
active,
`Tab${tabNum} iframe 1 should be ${activestr}`
);
});
} }
/* eslint-enable no-shadow */ /* eslint-enable no-shadow */
// Check everything // Check everything
ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive"); ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active"); ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
checkBrowser(ctx.tab1Browser, 1, true).then(() => { checkBrowser(ctx.tab1Browser, 1, true)
ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive"); .then(() => {
return checkBrowser(ctx.tab2Browser, 2, false); ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
}).then(() => { return checkBrowser(ctx.tab2Browser, 2, false);
// That's probably enough })
allDone(); .then(() => {
}); // That's probably enough
allDone();
});
} }
function allDone() { function allDone() {
// Close the tabs we made // Close the tabs we made
gBrowser.removeTab(ctx.tab1); gBrowser.removeTab(ctx.tab1);

View file

@ -10,34 +10,37 @@ add_task(async function() {
// Make sure that the window.open call will open a new // Make sure that the window.open call will open a new
// window instead of a new tab. // window instead of a new tab.
await new Promise(resolve => { await new Promise(resolve => {
SpecialPowers.pushPrefEnv({ SpecialPowers.pushPrefEnv(
"set": [ {
["browser.link.open_newwindow", 2], set: [["browser.link.open_newwindow", 2]],
], },
}, resolve); resolve
);
}); });
await BrowserTestUtils.withNewTab({ await BrowserTestUtils.withNewTab(
gBrowser, {
url: TEST_PAGE, gBrowser,
}, async function(browser) { url: TEST_PAGE,
let openedPromise = BrowserTestUtils.waitForNewWindow(); },
BrowserTestUtils.synthesizeMouse("a", 0, 0, {}, browser); async function(browser) {
let win = await openedPromise; let openedPromise = BrowserTestUtils.waitForNewWindow();
BrowserTestUtils.synthesizeMouse("a", 0, 0, {}, browser);
let win = await openedPromise;
let chromeFlags = win.docShell let chromeFlags = win.docShell.treeOwner
.treeOwner .QueryInterface(Ci.nsIInterfaceRequestor)
.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIXULWindow).chromeFlags;
.getInterface(Ci.nsIXULWindow)
.chromeFlags;
// In the multi-process case, the new window will have the // In the multi-process case, the new window will have the
// CHROME_REMOTE_WINDOW flag set. // CHROME_REMOTE_WINDOW flag set.
const EXPECTED = gMultiProcessBrowser ? CHROME_ALL | CHROME_REMOTE_WINDOW const EXPECTED = gMultiProcessBrowser
: CHROME_ALL; ? CHROME_ALL | CHROME_REMOTE_WINDOW
: CHROME_ALL;
is(chromeFlags, EXPECTED, "Window should have opened with all chrome"); is(chromeFlags, EXPECTED, "Window should have opened with all chrome");
BrowserTestUtils.closeWindow(win); BrowserTestUtils.closeWindow(win);
}); }
);
}); });

View file

@ -1,7 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var dirSvc = Services.dirSvc; var dirSvc = Services.dirSvc;
var profileDir = do_get_profile(); var profileDir = do_get_profile();

View file

@ -6,20 +6,26 @@ add_task(async function test_BrowsingContext_structured_clone() {
let frame = browser.document.createElement("iframe"); let frame = browser.document.createElement("iframe");
browser.document.body.appendChild(frame); browser.document.body.appendChild(frame);
let {browsingContext} = frame; let { browsingContext } = frame;
let sch = new StructuredCloneHolder({browsingContext}); let sch = new StructuredCloneHolder({ browsingContext });
let deserialize = () => sch.deserialize({}, true); let deserialize = () => sch.deserialize({}, true);
// Check that decoding a live browsing context produces the correct // Check that decoding a live browsing context produces the correct
// object. // object.
equal(deserialize().browsingContext, browsingContext, equal(
"Got correct browsing context from StructuredClone deserialize"); deserialize().browsingContext,
browsingContext,
"Got correct browsing context from StructuredClone deserialize"
);
// Check that decoding a second time still succeeds. // Check that decoding a second time still succeeds.
equal(deserialize().browsingContext, browsingContext, equal(
"Got correct browsing context from second StructuredClone deserialize"); deserialize().browsingContext,
browsingContext,
"Got correct browsing context from second StructuredClone deserialize"
);
// Destroy the browsing context and make sure that the decode fails // Destroy the browsing context and make sure that the decode fails
// with a DataCloneError. // with a DataCloneError.
@ -57,6 +63,9 @@ add_task(async function test_BrowsingContext_structured_clone() {
// OK. We can be fairly confident that the BrowsingContext object // OK. We can be fairly confident that the BrowsingContext object
// stored in our structured clone data has been destroyed. Make sure // stored in our structured clone data has been destroyed. Make sure
// that attempting to decode it again leads to the appropriate error. // that attempting to decode it again leads to the appropriate error.
Assert.throws(deserialize, e => e.name === "DataCloneError", Assert.throws(
"Should get a DataCloneError when trying to decode a dead BrowsingContext"); deserialize,
e => e.name === "DataCloneError",
"Should get a DataCloneError when trying to decode a dead BrowsingContext"
);
}); });

View file

@ -1,5 +1,6 @@
var prefetch = Cc["@mozilla.org/prefetch-service;1"]. var prefetch = Cc["@mozilla.org/prefetch-service;1"].getService(
getService(Ci.nsIPrefetchService); Ci.nsIPrefetchService
);
function run_test() { function run_test() {
// Fill up the queue // Fill up the queue

View file

@ -60,9 +60,10 @@ add_task(function test_unset_pref_fixes_typos() {
Services.prefs.clearUserPref(pref); Services.prefs.clearUserPref(pref);
for (let i = 0; i < len; ++i) { for (let i = 0; i < len; ++i) {
let item = data[i]; let item = data[i];
let result = let result = Services.uriFixup.createFixupURI(
Services.uriFixup.createFixupURI(item.wrong, item.wrong,
Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec; Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS
).spec;
Assert.equal(result, item.fixed); Assert.equal(result, item.fixed);
} }
}); });
@ -73,9 +74,10 @@ add_task(function test_false_pref_keeps_typos() {
Services.prefs.setBoolPref(pref, false); Services.prefs.setBoolPref(pref, false);
for (let i = 0; i < len; ++i) { for (let i = 0; i < len; ++i) {
let item = data[i]; let item = data[i];
let result = let result = Services.uriFixup.createFixupURI(
Services.uriFixup.createFixupURI(item.wrong, item.wrong,
Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec; Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS
).spec;
Assert.equal(result, item.wrong); Assert.equal(result, item.wrong);
} }
}); });
@ -86,9 +88,10 @@ add_task(function test_true_pref_fixes_typos() {
Services.prefs.setBoolPref(pref, true); Services.prefs.setBoolPref(pref, true);
for (let i = 0; i < len; ++i) { for (let i = 0; i < len; ++i) {
let item = data[i]; let item = data[i];
let result = let result = Services.uriFixup.createFixupURI(
Services.uriFixup.createFixupURI(item.wrong, item.wrong,
Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec; Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS
).spec;
Assert.equal(result, item.fixed); Assert.equal(result, item.fixed);
} }
}); });

View file

@ -1,5 +1,9 @@
const {AddonTestUtils} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm"); const { AddonTestUtils } = ChromeUtils.import(
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); "resource://testing-common/AddonTestUtils.jsm"
);
const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
const kSearchEngineID = "test_urifixup_search_engine"; const kSearchEngineID = "test_urifixup_search_engine";
const kSearchEngineURL = "http://www.example.org/?search={searchTerms}"; const kSearchEngineURL = "http://www.example.org/?search={searchTerms}";
@ -7,7 +11,12 @@ const kForceHostLookup = "browser.fixup.dns_first_for_single_words";
AddonTestUtils.init(this); AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB(); AddonTestUtils.overrideCertDB();
AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42"); AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",
"XPCShell",
"1",
"42"
);
// TODO(bug 1522134), this test should also use // TODO(bug 1522134), this test should also use
// combinations of the following flags. // combinations of the following flags.
@ -29,431 +38,524 @@ var flagInputs = [
affectedByDNSForSingleHosts: false, // Whether the input host could be a host, but is normally assumed to be a keyword query affectedByDNSForSingleHosts: false, // Whether the input host could be a host, but is normally assumed to be a keyword query
} }
*/ */
var testcases = [ { var testcases = [
{
input: "http://www.mozilla.org", input: "http://www.mozilla.org",
fixedURI: "http://www.mozilla.org/", fixedURI: "http://www.mozilla.org/",
}, { },
{
input: "http://127.0.0.1/", input: "http://127.0.0.1/",
fixedURI: "http://127.0.0.1/", fixedURI: "http://127.0.0.1/",
}, { },
{
input: "file:///foo/bar", input: "file:///foo/bar",
fixedURI: "file:///foo/bar", fixedURI: "file:///foo/bar",
}, { },
{
input: "://www.mozilla.org", input: "://www.mozilla.org",
fixedURI: "http://www.mozilla.org/", fixedURI: "http://www.mozilla.org/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "www.mozilla.org", input: "www.mozilla.org",
fixedURI: "http://www.mozilla.org/", fixedURI: "http://www.mozilla.org/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "http://mozilla/", input: "http://mozilla/",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
}, { },
{
input: "http://test./", input: "http://test./",
fixedURI: "http://test./", fixedURI: "http://test./",
alternateURI: "http://www.test./", alternateURI: "http://www.test./",
}, { },
{
input: "127.0.0.1", input: "127.0.0.1",
fixedURI: "http://127.0.0.1/", fixedURI: "http://127.0.0.1/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3.4/", input: "1.2.3.4/",
fixedURI: "http://1.2.3.4/", fixedURI: "http://1.2.3.4/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3.4/foo", input: "1.2.3.4/foo",
fixedURI: "http://1.2.3.4/foo", fixedURI: "http://1.2.3.4/foo",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3.4:8000", input: "1.2.3.4:8000",
fixedURI: "http://1.2.3.4:8000/", fixedURI: "http://1.2.3.4:8000/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3.4:8000/", input: "1.2.3.4:8000/",
fixedURI: "http://1.2.3.4:8000/", fixedURI: "http://1.2.3.4:8000/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3.4:8000/foo", input: "1.2.3.4:8000/foo",
fixedURI: "http://1.2.3.4:8000/foo", fixedURI: "http://1.2.3.4:8000/foo",
protocolChange: true, protocolChange: true,
}, { },
{
input: "192.168.10.110", input: "192.168.10.110",
fixedURI: "http://192.168.10.110/", fixedURI: "http://192.168.10.110/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "192.168.10.110/123", input: "192.168.10.110/123",
fixedURI: "http://192.168.10.110/123", fixedURI: "http://192.168.10.110/123",
protocolChange: true, protocolChange: true,
}, { },
{
input: "192.168.10.110/123foo", input: "192.168.10.110/123foo",
fixedURI: "http://192.168.10.110/123foo", fixedURI: "http://192.168.10.110/123foo",
protocolChange: true, protocolChange: true,
}, { },
{
input: "192.168.10.110:1234/123", input: "192.168.10.110:1234/123",
fixedURI: "http://192.168.10.110:1234/123", fixedURI: "http://192.168.10.110:1234/123",
protocolChange: true, protocolChange: true,
}, { },
{
input: "192.168.10.110:1234/123foo", input: "192.168.10.110:1234/123foo",
fixedURI: "http://192.168.10.110:1234/123foo", fixedURI: "http://192.168.10.110:1234/123foo",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3", input: "1.2.3",
fixedURI: "http://1.2.0.3/", fixedURI: "http://1.2.0.3/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3/", input: "1.2.3/",
fixedURI: "http://1.2.0.3/", fixedURI: "http://1.2.0.3/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3/foo", input: "1.2.3/foo",
fixedURI: "http://1.2.0.3/foo", fixedURI: "http://1.2.0.3/foo",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3/123", input: "1.2.3/123",
fixedURI: "http://1.2.0.3/123", fixedURI: "http://1.2.0.3/123",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3:8000", input: "1.2.3:8000",
fixedURI: "http://1.2.0.3:8000/", fixedURI: "http://1.2.0.3:8000/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3:8000/", input: "1.2.3:8000/",
fixedURI: "http://1.2.0.3:8000/", fixedURI: "http://1.2.0.3:8000/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3:8000/foo", input: "1.2.3:8000/foo",
fixedURI: "http://1.2.0.3:8000/foo", fixedURI: "http://1.2.0.3:8000/foo",
protocolChange: true, protocolChange: true,
}, { },
{
input: "1.2.3:8000/123", input: "1.2.3:8000/123",
fixedURI: "http://1.2.0.3:8000/123", fixedURI: "http://1.2.0.3:8000/123",
protocolChange: true, protocolChange: true,
}, { },
{
input: "http://1.2.3", input: "http://1.2.3",
fixedURI: "http://1.2.0.3/", fixedURI: "http://1.2.0.3/",
}, { },
{
input: "http://1.2.3/", input: "http://1.2.3/",
fixedURI: "http://1.2.0.3/", fixedURI: "http://1.2.0.3/",
}, { },
{
input: "http://1.2.3/foo", input: "http://1.2.3/foo",
fixedURI: "http://1.2.0.3/foo", fixedURI: "http://1.2.0.3/foo",
}, { },
{
input: "[::1]", input: "[::1]",
fixedURI: "http://[::1]/", fixedURI: "http://[::1]/",
alternateURI: "http://[::1]/", alternateURI: "http://[::1]/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "[::1]/", input: "[::1]/",
fixedURI: "http://[::1]/", fixedURI: "http://[::1]/",
alternateURI: "http://[::1]/", alternateURI: "http://[::1]/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "[::1]:8000", input: "[::1]:8000",
fixedURI: "http://[::1]:8000/", fixedURI: "http://[::1]:8000/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "[::1]:8000/", input: "[::1]:8000/",
fixedURI: "http://[::1]:8000/", fixedURI: "http://[::1]:8000/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "[[::1]]/", input: "[[::1]]/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "[fe80:cd00:0:cde:1257:0:211e:729c]", input: "[fe80:cd00:0:cde:1257:0:211e:729c]",
fixedURI: "http://[fe80:cd00:0:cde:1257:0:211e:729c]/", fixedURI: "http://[fe80:cd00:0:cde:1257:0:211e:729c]/",
alternateURI: "http://[fe80:cd00:0:cde:1257:0:211e:729c]/", alternateURI: "http://[fe80:cd00:0:cde:1257:0:211e:729c]/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "[64:ff9b::8.8.8.8]", input: "[64:ff9b::8.8.8.8]",
fixedURI: "http://[64:ff9b::808:808]/", fixedURI: "http://[64:ff9b::808:808]/",
alternateURI: "http://[64:ff9b::808:808]/", alternateURI: "http://[64:ff9b::808:808]/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "[64:ff9b::8.8.8.8]/~moz", input: "[64:ff9b::8.8.8.8]/~moz",
fixedURI: "http://[64:ff9b::808:808]/~moz", fixedURI: "http://[64:ff9b::808:808]/~moz",
alternateURI: "http://[64:ff9b::808:808]/~moz", alternateURI: "http://[64:ff9b::808:808]/~moz",
protocolChange: true, protocolChange: true,
}, { },
{
input: "[::1][::1]", input: "[::1][::1]",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "[::1][100", input: "[::1][100",
fixedURI: null, fixedURI: null,
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "[::1]]", input: "[::1]]",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "1234", input: "1234",
fixedURI: "http://0.0.4.210/", fixedURI: "http://0.0.4.210/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "host/foo.txt", input: "host/foo.txt",
fixedURI: "http://host/foo.txt", fixedURI: "http://host/foo.txt",
alternateURI: "http://www.host.com/foo.txt", alternateURI: "http://www.host.com/foo.txt",
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla", input: "mozilla",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "test.", input: "test.",
fixedURI: "http://test./", fixedURI: "http://test./",
alternateURI: "http://www.test./", alternateURI: "http://www.test./",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: ".test", input: ".test",
fixedURI: "http://.test/", fixedURI: "http://.test/",
alternateURI: "http://www..test/", alternateURI: "http://www..test/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "mozilla is amazing", input: "mozilla is amazing",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "search ?mozilla", input: "search ?mozilla",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla .com", input: "mozilla .com",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "what if firefox?", input: "what if firefox?",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "london's map", input: "london's map",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla ", input: "mozilla ",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: " mozilla ", input: " mozilla ",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "mozilla \\", input: "mozilla \\",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla \\ foo.txt", input: "mozilla \\ foo.txt",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla \\\r foo.txt", input: "mozilla \\\r foo.txt",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla\n", input: "mozilla\n",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "mozilla \r\n", input: "mozilla \r\n",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "moz\r\nfirefox\nos\r", input: "moz\r\nfirefox\nos\r",
fixedURI: "http://mozfirefoxos/", fixedURI: "http://mozfirefoxos/",
alternateURI: "http://www.mozfirefoxos.com/", alternateURI: "http://www.mozfirefoxos.com/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "moz\r\n firefox\n", input: "moz\r\n firefox\n",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "", input: "",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "[]", input: "[]",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "http://whitelisted/", input: "http://whitelisted/",
fixedURI: "http://whitelisted/", fixedURI: "http://whitelisted/",
alternateURI: "http://www.whitelisted.com/", alternateURI: "http://www.whitelisted.com/",
inWhitelist: true, inWhitelist: true,
}, { },
{
input: "café.local", input: "café.local",
fixedURI: "http://xn--caf-dma.local/", fixedURI: "http://xn--caf-dma.local/",
alternateURI: "http://www.xn--caf-dma.local/", alternateURI: "http://www.xn--caf-dma.local/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "47.6182,-122.830", input: "47.6182,-122.830",
fixedURI: "http://47.6182,-122.830/", fixedURI: "http://47.6182,-122.830/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "-47.6182,-23.51", input: "-47.6182,-23.51",
fixedURI: "http://-47.6182,-23.51/", fixedURI: "http://-47.6182,-23.51/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "-22.14,23.51-", input: "-22.14,23.51-",
fixedURI: "http://-22.14,23.51-/", fixedURI: "http://-22.14,23.51-/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "32.7", input: "32.7",
fixedURI: "http://32.0.0.7/", fixedURI: "http://32.0.0.7/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "5+2", input: "5+2",
fixedURI: "http://5+2/", fixedURI: "http://5+2/",
alternateURI: "http://www.5+2.com/", alternateURI: "http://www.5+2.com/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "5/2", input: "5/2",
fixedURI: "http://0.0.0.5/2", fixedURI: "http://0.0.0.5/2",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "moz ?.::%27", input: "moz ?.::%27",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla.com/?q=search", input: "mozilla.com/?q=search",
fixedURI: "http://mozilla.com/?q=search", fixedURI: "http://mozilla.com/?q=search",
alternateURI: "http://www.mozilla.com/?q=search", alternateURI: "http://www.mozilla.com/?q=search",
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla.com?q=search", input: "mozilla.com?q=search",
fixedURI: "http://mozilla.com/?q=search", fixedURI: "http://mozilla.com/?q=search",
alternateURI: "http://www.mozilla.com/?q=search", alternateURI: "http://www.mozilla.com/?q=search",
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla.com ?q=search", input: "mozilla.com ?q=search",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla.com.?q=search", input: "mozilla.com.?q=search",
fixedURI: "http://mozilla.com./?q=search", fixedURI: "http://mozilla.com./?q=search",
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla.com'?q=search", input: "mozilla.com'?q=search",
fixedURI: "http://mozilla.com'/?q=search", fixedURI: "http://mozilla.com'/?q=search",
alternateURI: "http://www.mozilla.com'/?q=search", alternateURI: "http://www.mozilla.com'/?q=search",
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla.com':search", input: "mozilla.com':search",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "[mozilla]", input: "[mozilla]",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "':?", input: "':?",
fixedURI: "http://'/?", fixedURI: "http://'/?",
alternateURI: "http://www.'.com/?", alternateURI: "http://www.'.com/?",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "a?.com", input: "a?.com",
fixedURI: "http://a/?.com", fixedURI: "http://a/?.com",
alternateURI: "http://www.a.com/?.com", alternateURI: "http://www.a.com/?.com",
protocolChange: true, protocolChange: true,
}, { },
{
input: "?'.com", input: "?'.com",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "' ?.com", input: "' ?.com",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "?mozilla", input: "?mozilla",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "??mozilla", input: "??mozilla",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla/", input: "mozilla/",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla", input: "mozilla",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
protocolChange: true, protocolChange: true,
keywordLookup: true, keywordLookup: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "mozilla5/2", input: "mozilla5/2",
fixedURI: "http://mozilla5/2", fixedURI: "http://mozilla5/2",
alternateURI: "http://www.mozilla5.com/2", alternateURI: "http://www.mozilla5.com/2",
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla/foo", input: "mozilla/foo",
fixedURI: "http://mozilla/foo", fixedURI: "http://mozilla/foo",
alternateURI: "http://www.mozilla.com/foo", alternateURI: "http://www.mozilla.com/foo",
protocolChange: true, protocolChange: true,
}, { },
{
input: "mozilla\\", input: "mozilla\\",
fixedURI: "http://mozilla/", fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/", alternateURI: "http://www.mozilla.com/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "localhost", input: "localhost",
fixedURI: "http://localhost/", fixedURI: "http://localhost/",
keywordLookup: true, keywordLookup: true,
protocolChange: true, protocolChange: true,
affectedByDNSForSingleHosts: true, affectedByDNSForSingleHosts: true,
}, { },
{
input: "localhost:8080", input: "localhost:8080",
fixedURI: "http://localhost:8080/", fixedURI: "http://localhost:8080/",
protocolChange: true, protocolChange: true,
}, { },
{
input: "plonk:8080", input: "plonk:8080",
fixedURI: "http://plonk:8080/", fixedURI: "http://plonk:8080/",
protocolChange: true, protocolChange: true,
}, { },
input: "\u10E0\u10D4\u10D2\u10D8\u10E1\u10E2\u10E0\u10D0\u10EA\u10D8\u10D0.\u10D2\u10D4", {
input:
"\u10E0\u10D4\u10D2\u10D8\u10E1\u10E2\u10E0\u10D0\u10EA\u10D8\u10D0.\u10D2\u10D4",
fixedURI: "http://xn--lodaehvb5cdik4g.xn--node/", fixedURI: "http://xn--lodaehvb5cdik4g.xn--node/",
alternateURI: "http://www.xn--lodaehvb5cdik4g.xn--node/", alternateURI: "http://www.xn--lodaehvb5cdik4g.xn--node/",
protocolChange: true, protocolChange: true,
@ -500,24 +602,34 @@ function sanitize(input) {
} }
add_task(async function setup() { add_task(async function setup() {
var prefList = ["browser.fixup.typo.scheme", "keyword.enabled", var prefList = [
"browser.fixup.domainwhitelist.whitelisted"]; "browser.fixup.typo.scheme",
"keyword.enabled",
"browser.fixup.domainwhitelist.whitelisted",
];
for (let pref of prefList) { for (let pref of prefList) {
Services.prefs.setBoolPref(pref, true); Services.prefs.setBoolPref(pref, true);
} }
await AddonTestUtils.promiseStartupManager(); await AddonTestUtils.promiseStartupManager();
Services.io.getProtocolHandler("resource") Services.io
.QueryInterface(Ci.nsIResProtocolHandler) .getProtocolHandler("resource")
.setSubstitution("search-extensions", .QueryInterface(Ci.nsIResProtocolHandler)
Services.io.newURI("chrome://mozapps/locale/searchextensions/")); .setSubstitution(
"search-extensions",
Services.io.newURI("chrome://mozapps/locale/searchextensions/")
);
await Services.search.addEngineWithDetails(kSearchEngineID, await Services.search.addEngineWithDetails(kSearchEngineID, {
{method: "get", template: kSearchEngineURL}); method: "get",
template: kSearchEngineURL,
});
var oldCurrentEngine = await Services.search.getDefault(); var oldCurrentEngine = await Services.search.getDefault();
await Services.search.setDefault(Services.search.getEngineByName(kSearchEngineID)); await Services.search.setDefault(
Services.search.getEngineByName(kSearchEngineID)
);
var selectedName = (await Services.search.getDefault()).name; var selectedName = (await Services.search.getDefault()).name;
Assert.equal(selectedName, kSearchEngineID); Assert.equal(selectedName, kSearchEngineID);
@ -539,8 +651,12 @@ add_task(async function setup() {
var gSingleWordHostLookup = false; var gSingleWordHostLookup = false;
add_task(async function run_test() { add_task(async function run_test() {
// Only keywordlookup things should be affected by requiring a DNS lookup for single-word hosts: // Only keywordlookup things should be affected by requiring a DNS lookup for single-word hosts:
info("Check only keyword lookup testcases should be affected by requiring DNS for single hosts"); info(
let affectedTests = testcases.filter(t => !t.keywordLookup && t.affectedByDNSForSingleHosts); "Check only keyword lookup testcases should be affected by requiring DNS for single hosts"
);
let affectedTests = testcases.filter(
t => !t.keywordLookup && t.affectedByDNSForSingleHosts
);
if (affectedTests.length) { if (affectedTests.length) {
for (let testcase of affectedTests) { for (let testcase of affectedTests) {
info("Affected: " + testcase.input); info("Affected: " + testcase.input);
@ -555,24 +671,28 @@ add_task(async function run_test() {
function do_single_test_run() { function do_single_test_run() {
Services.prefs.setBoolPref(kForceHostLookup, gSingleWordHostLookup); Services.prefs.setBoolPref(kForceHostLookup, gSingleWordHostLookup);
let relevantTests = gSingleWordHostLookup ? testcases.filter(t => t.keywordLookup) : let relevantTests = gSingleWordHostLookup
testcases; ? testcases.filter(t => t.keywordLookup)
: testcases;
for (let { input: testInput, for (let {
fixedURI: expectedFixedURI, input: testInput,
alternateURI: alternativeURI, fixedURI: expectedFixedURI,
keywordLookup: expectKeywordLookup, alternateURI: alternativeURI,
protocolChange: expectProtocolChange, keywordLookup: expectKeywordLookup,
inWhitelist: inWhitelist, protocolChange: expectProtocolChange,
affectedByDNSForSingleHosts: affectedByDNSForSingleHosts, inWhitelist: inWhitelist,
} of relevantTests) { affectedByDNSForSingleHosts: affectedByDNSForSingleHosts,
} of relevantTests) {
// Explicitly force these into a boolean // Explicitly force these into a boolean
expectKeywordLookup = !!expectKeywordLookup; expectKeywordLookup = !!expectKeywordLookup;
expectProtocolChange = !!expectProtocolChange; expectProtocolChange = !!expectProtocolChange;
inWhitelist = !!inWhitelist; inWhitelist = !!inWhitelist;
affectedByDNSForSingleHosts = !!affectedByDNSForSingleHosts; affectedByDNSForSingleHosts = !!affectedByDNSForSingleHosts;
expectKeywordLookup = expectKeywordLookup && (!affectedByDNSForSingleHosts || !gSingleWordHostLookup); expectKeywordLookup =
expectKeywordLookup &&
(!affectedByDNSForSingleHosts || !gSingleWordHostLookup);
for (let flags of flagInputs) { for (let flags of flagInputs) {
let URIInfo; let URIInfo;
@ -594,47 +714,94 @@ function do_single_test_run() {
continue; continue;
} }
info("Checking \"" + testInput + "\" with flags " + flags + info(
" (host lookup for single words: " + (gSingleWordHostLookup ? "yes" : "no") + ")"); 'Checking "' +
testInput +
'" with flags ' +
flags +
" (host lookup for single words: " +
(gSingleWordHostLookup ? "yes" : "no") +
")"
);
// Both APIs should then also be using the same spec. // Both APIs should then also be using the same spec.
Assert.equal(!!fixupURIOnly, !!URIInfo.preferredURI); Assert.equal(!!fixupURIOnly, !!URIInfo.preferredURI);
if (fixupURIOnly) { if (fixupURIOnly) {
Assert.equal(fixupURIOnly.spec, URIInfo.preferredURI.spec, "Fixed and preferred URI should match"); Assert.equal(
fixupURIOnly.spec,
URIInfo.preferredURI.spec,
"Fixed and preferred URI should match"
);
} }
// Check the fixedURI: // Check the fixedURI:
let makeAlternativeURI = flags & Services.uriFixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI; let makeAlternativeURI =
flags & Services.uriFixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI;
if (makeAlternativeURI && alternativeURI != null) { if (makeAlternativeURI && alternativeURI != null) {
Assert.equal(URIInfo.fixedURI.spec, alternativeURI, "should have gotten alternate URI"); Assert.equal(
URIInfo.fixedURI.spec,
alternativeURI,
"should have gotten alternate URI"
);
} else { } else {
Assert.equal(URIInfo.fixedURI && URIInfo.fixedURI.spec, expectedFixedURI, "should get correct fixed URI"); Assert.equal(
URIInfo.fixedURI && URIInfo.fixedURI.spec,
expectedFixedURI,
"should get correct fixed URI"
);
} }
// Check booleans on input: // Check booleans on input:
let couldDoKeywordLookup = flags & Services.uriFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP; let couldDoKeywordLookup =
Assert.equal(!!URIInfo.keywordProviderName, couldDoKeywordLookup && expectKeywordLookup, "keyword lookup as expected"); flags & Services.uriFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
Assert.equal(URIInfo.fixupChangedProtocol, expectProtocolChange, "protocol change as expected"); Assert.equal(
Assert.equal(URIInfo.fixupCreatedAlternateURI, makeAlternativeURI && alternativeURI != null, "alternative URI as expected"); !!URIInfo.keywordProviderName,
couldDoKeywordLookup && expectKeywordLookup,
"keyword lookup as expected"
);
Assert.equal(
URIInfo.fixupChangedProtocol,
expectProtocolChange,
"protocol change as expected"
);
Assert.equal(
URIInfo.fixupCreatedAlternateURI,
makeAlternativeURI && alternativeURI != null,
"alternative URI as expected"
);
// Check the preferred URI // Check the preferred URI
if (couldDoKeywordLookup) { if (couldDoKeywordLookup) {
if (expectKeywordLookup) { if (expectKeywordLookup) {
if (!inWhitelist) { if (!inWhitelist) {
let urlparamInput = encodeURIComponent(sanitize(testInput)).replace(/%20/g, "+"); let urlparamInput = encodeURIComponent(sanitize(testInput)).replace(
/%20/g,
"+"
);
// If the input starts with `?`, then URIInfo.preferredURI.spec will omit it // If the input starts with `?`, then URIInfo.preferredURI.spec will omit it
// In order to test this behaviour, remove `?` only if it is the first character // In order to test this behaviour, remove `?` only if it is the first character
if (urlparamInput.startsWith("%3F")) { if (urlparamInput.startsWith("%3F")) {
urlparamInput = urlparamInput.replace("%3F", ""); urlparamInput = urlparamInput.replace("%3F", "");
} }
let searchURL = kSearchEngineURL.replace("{searchTerms}", urlparamInput); let searchURL = kSearchEngineURL.replace(
"{searchTerms}",
urlparamInput
);
let spec = URIInfo.preferredURI.spec.replace(/%27/g, "'"); let spec = URIInfo.preferredURI.spec.replace(/%27/g, "'");
Assert.equal(spec, searchURL, "should get correct search URI"); Assert.equal(spec, searchURL, "should get correct search URI");
} else { } else {
Assert.equal(URIInfo.preferredURI, null, "not expecting a preferred URI"); Assert.equal(
URIInfo.preferredURI,
null,
"not expecting a preferred URI"
);
} }
} else { } else {
Assert.equal(URIInfo.preferredURI.spec, URIInfo.fixedURI.spec, "fixed URI should match"); Assert.equal(
URIInfo.preferredURI.spec,
URIInfo.fixedURI.spec,
"fixed URI should match"
);
} }
} else { } else {
// In these cases, we should never be doing a keyword lookup and // In these cases, we should never be doing a keyword lookup and
@ -643,7 +810,11 @@ function do_single_test_run() {
let fixedURI = URIInfo.fixedURI && URIInfo.fixedURI.spec; let fixedURI = URIInfo.fixedURI && URIInfo.fixedURI.spec;
Assert.equal(prefURI, fixedURI, "fixed URI should be same as expected"); Assert.equal(prefURI, fixedURI, "fixed URI should be same as expected");
} }
Assert.equal(sanitize(testInput), URIInfo.originalInput, "should mirror original input"); Assert.equal(
sanitize(testInput),
URIInfo.originalInput,
"should mirror original input"
);
} }
} }
} }

View file

@ -1,5 +1,9 @@
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); const { AppConstants } = ChromeUtils.import(
const {AddonTestUtils} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm"); "resource://gre/modules/AppConstants.jsm"
);
const { AddonTestUtils } = ChromeUtils.import(
"resource://testing-common/AddonTestUtils.jsm"
);
const kSearchEngineID = "test_urifixup_search_engine"; const kSearchEngineID = "test_urifixup_search_engine";
const kSearchEngineURL = "http://www.example.org/?search={searchTerms}"; const kSearchEngineURL = "http://www.example.org/?search={searchTerms}";
@ -15,7 +19,10 @@ var data = [
{ {
// Unrecognized protocols should be changed. // Unrecognized protocols should be changed.
wrong: "whatever://this/is/a/test.html", wrong: "whatever://this/is/a/test.html",
fixed: kSearchEngineURL.replace("{searchTerms}", encodeURIComponent("whatever://this/is/a/test.html")), fixed: kSearchEngineURL.replace(
"{searchTerms}",
encodeURIComponent("whatever://this/is/a/test.html")
),
}, },
// The following tests check that when a user:password is present in the URL // The following tests check that when a user:password is present in the URL
@ -47,7 +54,8 @@ var data = [
}, },
{ {
wrong: "gobbledygook:user:pass@example.com:8080/this/is/a/test.html", wrong: "gobbledygook:user:pass@example.com:8080/this/is/a/test.html",
fixed: "http://gobbledygook:user%3Apass@example.com:8080/this/is/a/test.html", fixed:
"http://gobbledygook:user%3Apass@example.com:8080/this/is/a/test.html",
}, },
{ {
wrong: "user:@example.com:8080/this/is/a/test.html", wrong: "user:@example.com:8080/this/is/a/test.html",
@ -55,7 +63,9 @@ var data = [
}, },
{ {
wrong: "//user:pass@example.com:8080/this/is/a/test.html", wrong: "//user:pass@example.com:8080/this/is/a/test.html",
fixed: (isWin ? "http:" : "file://") + "//user:pass@example.com:8080/this/is/a/test.html", fixed:
(isWin ? "http:" : "file://") +
"//user:pass@example.com:8080/this/is/a/test.html",
}, },
{ {
wrong: "://user:pass@example.com:8080/this/is/a/test.html", wrong: "://user:pass@example.com:8080/this/is/a/test.html",
@ -63,12 +73,16 @@ var data = [
}, },
{ {
wrong: "whatever://this/is/a@b/test.html", wrong: "whatever://this/is/a@b/test.html",
fixed: kSearchEngineURL.replace("{searchTerms}", encodeURIComponent("whatever://this/is/a@b/test.html")), fixed: kSearchEngineURL.replace(
"{searchTerms}",
encodeURIComponent("whatever://this/is/a@b/test.html")
),
}, },
]; ];
var extProtocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"] var extProtocolSvc = Cc[
.getService(Ci.nsIExternalProtocolService); "@mozilla.org/uriloader/external-protocol-service;1"
].getService(Ci.nsIExternalProtocolService);
if (extProtocolSvc && extProtocolSvc.externalProtocolHandlerExists("mailto")) { if (extProtocolSvc && extProtocolSvc.externalProtocolHandlerExists("mailto")) {
data.push({ data.push({
@ -81,22 +95,34 @@ var len = data.length;
AddonTestUtils.init(this); AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB(); AddonTestUtils.overrideCertDB();
AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42"); AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",
"XPCShell",
"1",
"42"
);
add_task(async function setup() { add_task(async function setup() {
await AddonTestUtils.promiseStartupManager(); await AddonTestUtils.promiseStartupManager();
Services.prefs.setBoolPref("keyword.enabled", true); Services.prefs.setBoolPref("keyword.enabled", true);
Services.io.getProtocolHandler("resource") Services.io
.QueryInterface(Ci.nsIResProtocolHandler) .getProtocolHandler("resource")
.setSubstitution("search-extensions", .QueryInterface(Ci.nsIResProtocolHandler)
Services.io.newURI("chrome://mozapps/locale/searchextensions/")); .setSubstitution(
"search-extensions",
Services.io.newURI("chrome://mozapps/locale/searchextensions/")
);
await Services.search.addEngineWithDetails(kSearchEngineID, await Services.search.addEngineWithDetails(kSearchEngineID, {
{method: "get", template: kSearchEngineURL}); method: "get",
template: kSearchEngineURL,
});
var oldCurrentEngine = await Services.search.getDefault(); var oldCurrentEngine = await Services.search.getDefault();
await Services.search.setDefault(Services.search.getEngineByName(kSearchEngineID)); await Services.search.setDefault(
Services.search.getEngineByName(kSearchEngineID)
);
var selectedName = (await Services.search.getDefault()).name; var selectedName = (await Services.search.getDefault()).name;
Assert.equal(selectedName, kSearchEngineID); Assert.equal(selectedName, kSearchEngineID);
@ -117,9 +143,10 @@ add_task(async function setup() {
add_task(function test_fix_unknown_schemes() { add_task(function test_fix_unknown_schemes() {
for (let i = 0; i < len; ++i) { for (let i = 0; i < len; ++i) {
let item = data[i]; let item = data[i];
let result = let result = Services.uriFixup.createFixupURI(
Services.uriFixup.createFixupURI(item.wrong, item.wrong,
Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec; Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS
).spec;
Assert.equal(result, item.fixed); Assert.equal(result, item.fixed);
} }
}); });

View file

@ -1,6 +1,6 @@
function destroy_transient_docshell() { function destroy_transient_docshell() {
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false); let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
windowlessBrowser.docShell.setOriginAttributes({privateBrowsingId: 1}); windowlessBrowser.docShell.setOriginAttributes({ privateBrowsingId: 1 });
windowlessBrowser.close(); windowlessBrowser.close();
do_test_pending(); do_test_pending();
do_timeout(0, Cu.forceGC); do_timeout(0, Cu.forceGC);

View file

@ -1,7 +1,10 @@
var gNotifications = 0; var gNotifications = 0;
var observer = { var observer = {
QueryInterface: ChromeUtils.generateQI(["nsIPrivacyTransitionObserver", "nsISupportsWeakReference"]), QueryInterface: ChromeUtils.generateQI([
"nsIPrivacyTransitionObserver",
"nsISupportsWeakReference",
]),
privateModeChanged(enabled) { privateModeChanged(enabled) {
gNotifications++; gNotifications++;
@ -11,8 +14,8 @@ var observer = {
function run_test() { function run_test() {
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false); let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
windowlessBrowser.docShell.addWeakPrivacyTransitionObserver(observer); windowlessBrowser.docShell.addWeakPrivacyTransitionObserver(observer);
windowlessBrowser.docShell.setOriginAttributes({privateBrowsingId: 1}); windowlessBrowser.docShell.setOriginAttributes({ privateBrowsingId: 1 });
windowlessBrowser.docShell.setOriginAttributes({privateBrowsingId: 0}); windowlessBrowser.docShell.setOriginAttributes({ privateBrowsingId: 0 });
windowlessBrowser.close(); windowlessBrowser.close();
Assert.equal(gNotifications, 2); Assert.equal(gNotifications, 2);
} }

View file

@ -1,6 +1,8 @@
"use strict"; "use strict";
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
add_task(async function() { add_task(async function() {
let webNav = Services.appShell.createWindowlessBrowser(false); let webNav = Services.appShell.createWindowlessBrowser(false);
@ -9,29 +11,45 @@ add_task(async function() {
let loadContext = docShell.QueryInterface(Ci.nsILoadContext); let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
equal(loadContext.usePrivateBrowsing, false, "Should start out in non-private mode"); equal(
loadContext.usePrivateBrowsing,
false,
"Should start out in non-private mode"
);
loadContext.usePrivateBrowsing = true; loadContext.usePrivateBrowsing = true;
equal(loadContext.usePrivateBrowsing, true, equal(
"Should be able to change to private mode prior to a document load"); loadContext.usePrivateBrowsing,
true,
"Should be able to change to private mode prior to a document load"
);
loadContext.usePrivateBrowsing = false; loadContext.usePrivateBrowsing = false;
equal(loadContext.usePrivateBrowsing, false, equal(
"Should be able to change to non-private mode prior to a document load"); loadContext.usePrivateBrowsing,
false,
"Should be able to change to non-private mode prior to a document load"
);
let oa = docShell.getOriginAttributes(); let oa = docShell.getOriginAttributes();
oa.privateBrowsingId = 1; oa.privateBrowsingId = 1;
docShell.setOriginAttributes(oa); docShell.setOriginAttributes(oa);
equal(loadContext.usePrivateBrowsing, true, equal(
"Should be able to change origin attributes prior to a document load"); loadContext.usePrivateBrowsing,
true,
"Should be able to change origin attributes prior to a document load"
);
oa.privateBrowsingId = 0; oa.privateBrowsingId = 0;
docShell.setOriginAttributes(oa); docShell.setOriginAttributes(oa);
equal(loadContext.usePrivateBrowsing, false, equal(
"Should be able to change origin attributes prior to a document load"); loadContext.usePrivateBrowsing,
false,
"Should be able to change origin attributes prior to a document load"
);
let loadURIOptions = { let loadURIOptions = {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
@ -44,20 +62,34 @@ add_task(async function() {
// This causes a failed assertion rather than an exception on debug // This causes a failed assertion rather than an exception on debug
// builds. // builds.
if (!AppConstants.DEBUG) { if (!AppConstants.DEBUG) {
Assert.throws(() => { loadContext.usePrivateBrowsing = true; }, Assert.throws(
/NS_ERROR_FAILURE/, () => {
"Should not be able to change private browsing state after initial load has started"); loadContext.usePrivateBrowsing = true;
},
/NS_ERROR_FAILURE/,
"Should not be able to change private browsing state after initial load has started"
);
oa.privateBrowsingId = 1; oa.privateBrowsingId = 1;
Assert.throws(() => { docShell.setOriginAttributes(oa); }, Assert.throws(
/NS_ERROR_FAILURE/, () => {
"Should not be able to change origin attributes after initial load has started"); docShell.setOriginAttributes(oa);
},
/NS_ERROR_FAILURE/,
"Should not be able to change origin attributes after initial load has started"
);
equal(loadContext.usePrivateBrowsing, false, equal(
"Should not be able to change private browsing state after initial load has started"); loadContext.usePrivateBrowsing,
false,
"Should not be able to change private browsing state after initial load has started"
);
loadContext.usePrivateBrowsing = false; loadContext.usePrivateBrowsing = false;
ok(true, "Should be able to set usePrivateBrowsing to its current value even after initial load"); ok(
true,
"Should be able to set usePrivateBrowsing to its current value even after initial load"
);
} }
webNav.close(); webNav.close();

View file

@ -1,4 +1,4 @@
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
function run_test() { function run_test() {
var notifications = 0; var notifications = 0;
@ -10,9 +10,8 @@ function run_test() {
}; };
Services.os.addObserver(obs, "last-pb-context-exited"); Services.os.addObserver(obs, "last-pb-context-exited");
run_test_in_child("../unit/test_pb_notification.js", run_test_in_child("../unit/test_pb_notification.js", function() {
function() { Assert.equal(notifications, 1);
Assert.equal(notifications, 1); do_test_finished();
do_test_finished(); });
});
} }