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": [{
"files": [
"devtools/**",
"docshell/**",
"dom/**",
"editor/**",
"extensions/**",

View File

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

View File

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

View File

@ -6,75 +6,69 @@
const URL = "about:blank";
async function getBrowsingContextId(browser, id) {
return ContentTask.spawn(
browser,
id,
async function(id) {
let contextId = content.window.docShell.browsingContext.id;
return ContentTask.spawn(browser, id, async function(id) {
let contextId = content.window.docShell.browsingContext.id;
let frames = [content.window];
while (frames.length) {
let frame = frames.pop();
let target = frame.document.getElementById(id);
if (target) {
contextId = target.docShell.browsingContext.id;
break;
}
frames = frames.concat(Array.from(frame.frames));
let frames = [content.window];
while (frames.length) {
let frame = frames.pop();
let target = frame.document.getElementById(id);
if (target) {
contextId = target.docShell.browsingContext.id;
break;
}
return contextId;
});
frames = frames.concat(Array.from(frame.frames));
}
return contextId;
});
}
async function addFrame(browser, id, parentId) {
return ContentTask.spawn(
browser,
{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,
return ContentTask.spawn(browser, { parentId, id }, async function({
parentId,
id,
async function(id) {
}) {
let parent = null;
if (parentId) {
let frames = [content.window];
while (frames.length) {
let frame = frames.pop();
let target = frame.document.getElementById(id);
let target = frame.document.getElementById(parentId);
if (target) {
target.remove();
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, 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) {
@ -82,57 +76,76 @@ function getBrowsingContextById(id) {
}
add_task(async function() {
await BrowserTestUtils.withNewTab({ gBrowser, url: URL },
async function(browser) {
let topId = await getBrowsingContextId(browser, "");
let topContext = getBrowsingContextById(topId);
isnot(topContext, null);
is(topContext.parent, null);
is(topId, browser.browsingContext.id, "<browser> has the correct browsingContext");
await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function(
browser
) {
let topId = await getBrowsingContextId(browser, "");
let topContext = getBrowsingContextById(topId);
isnot(topContext, null);
is(topContext.parent, null);
is(
topId,
browser.browsingContext.id,
"<browser> has the correct browsingContext"
);
let id0 = await addFrame(browser, "frame0");
let browsingContext0 = getBrowsingContextById(id0);
isnot(browsingContext0, null);
is(browsingContext0.parent, topContext);
let id0 = await addFrame(browser, "frame0");
let browsingContext0 = getBrowsingContextById(id0);
isnot(browsingContext0, null);
is(browsingContext0.parent, topContext);
let id1 = await addFrame(browser, "frame1", "frame0");
let browsingContext1 = getBrowsingContextById(id1);
isnot(browsingContext1, null);
is(browsingContext1.parent, browsingContext0);
let id1 = await addFrame(browser, "frame1", "frame0");
let browsingContext1 = getBrowsingContextById(id1);
isnot(browsingContext1, null);
is(browsingContext1.parent, browsingContext0);
let id2 = await addFrame(browser, "frame2", "frame1");
let browsingContext2 = getBrowsingContextById(id2);
isnot(browsingContext2, null);
is(browsingContext2.parent, browsingContext1);
let id2 = await addFrame(browser, "frame2", "frame1");
let browsingContext2 = getBrowsingContextById(id2);
isnot(browsingContext2, null);
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_isnot(browsingContext2.parent, browsingContext1);
// TODO(farre): Handle browsingContext removal [see Bug 1486719].
todo_isnot(browsingContext2.parent, browsingContext1);
});
});
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) {
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) {
function waitForMessage(command) {
let r;
let p = new Promise(resolve => {
content.window.addEventListener("message", e => resolve({result: r, event: e}),
{once: true});
content.window.addEventListener(
"message",
e => resolve({ result: r, event: e }),
{ once: true }
);
});
r = command();
return p;
}
// Open a new window and wait for the message.
let { result: win, event: e1 } =
await waitForMessage(
_ => content.window.open(path + "onpageshow_message.html"));
let { result: win, event: e1 } = await waitForMessage(_ =>
content.window.open(path + "onpageshow_message.html")
);
is(e1.data, "pageshow");
@ -152,7 +165,8 @@ add_task(async function() {
// Navigate the window and wait for the message.
let { event: e2 } = await waitForMessage(
_ => win.location = path + "onload_message.html");
_ => (win.location = path + "onload_message.html")
);
is(e2.data, "load");
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(winDocShell, win.frames[0].docShell, "BF cache cached docshell");
is(frameBC, win.frames[0].docShell.browsingContext, "BF cache cached BC");
is(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");
is(
frameBC,
win.frames[0].docShell.browsingContext,
"BF cache cached BC"
);
is(
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();
});
});
}
);
});

View File

@ -5,114 +5,144 @@
add_task(async function() {
await BrowserTestUtils.withNewTab(
{gBrowser, url: "about:blank"}, async function(browser) {
const BASE1 = getRootDirectory(gTestPath)
.replace("chrome://mochitests/content", "http://example.com");
const BASE2 = getRootDirectory(gTestPath)
.replace("chrome://mochitests/content", "http://test1.example.com");
{ gBrowser, url: "about:blank" },
async function(browser) {
const BASE1 = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
const BASE2 = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://test1.example.com"
);
const URL = BASE1 + "onload_message.html";
let sixth = BrowserTestUtils.waitForNewTab(gBrowser, URL + "#sixth", true, true);
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 sixth = BrowserTestUtils.waitForNewTab(
gBrowser,
URL + "#sixth",
true,
true
);
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 = {
top: top.location.href,
first: base1 + "dummy_page.html#first",
third: base2 + "dummy_page.html#third",
second: base1 + "dummy_page.html#second",
fourth: base2 + "dummy_page.html#fourth",
fifth: base1 + "dummy_page.html#fifth",
sixth: base1 + "onload_message.html#sixth",
seventh: base1 + "onload_message.html#seventh",
};
let contexts = {
top: top.location.href,
first: base1 + "dummy_page.html#first",
third: base2 + "dummy_page.html#third",
second: base1 + "dummy_page.html#second",
fourth: base2 + "dummy_page.html#fourth",
fifth: base1 + "dummy_page.html#fifth",
sixth: base1 + "onload_message.html#sixth",
seventh: base1 + "onload_message.html#seventh",
};
function addFrame(target, name) {
let doc = (target.contentWindow || target).document;
let frame = doc.createElement("iframe");
let p = new Promise(resolve => (frame.onload = () => resolve(frame)));
doc.body.appendChild(frame);
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)));
function addFrame(target, name) {
let doc = (target.contentWindow || target).document;
let frame = doc.createElement("iframe");
let p = new Promise(
resolve => (frame.onload = () => resolve(frame))
);
doc.body.appendChild(frame);
frame.name = name;
frame.src = contexts[name];
return p;
}
return Promise.resolve({name});
}
// We're going to create a tree that looks like the
// 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 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 });
}
function bc(frame) {
return (frame.contentWindow || frame).docShell.browsingContext;
}
// We're going to create a tree that looks like the
// 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) {
for (let target of targets) {
is(bc(start).findWithName(target.name), bc(target),
[bc(start).name, "can reach", target.name].join(" "));
function bc(frame) {
return (frame.contentWindow || frame).docShell.browsingContext;
}
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])) {
BrowserTestUtils.removeTab(tab);
}
});
}
);
});

View File

@ -5,132 +5,169 @@
add_task(async function() {
await BrowserTestUtils.withNewTab(
{gBrowser, url: "about:blank"}, async function(browser) {
const BASE1 = getRootDirectory(gTestPath)
.replace("chrome://mochitests/content", "http://example.com");
const BASE2 = getRootDirectory(gTestPath)
.replace("chrome://mochitests/content", "http://test1.example.com");
{ gBrowser, url: "about:blank" },
async function(browser) {
const BASE1 = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://example.com"
);
const BASE2 = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"http://test1.example.com"
);
const URL = BASE1 + "onload_message.html";
let sixth = BrowserTestUtils.waitForNewTab(gBrowser, URL + "#sixth", 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 sixth = BrowserTestUtils.waitForNewTab(
gBrowser,
URL + "#sixth",
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 = {
top: top.location.href,
first: base1 + "dummy_page.html#first",
third: base2 + "dummy_page.html#third",
second: base1 + "dummy_page.html#second",
fourth: base2 + "dummy_page.html#fourth",
fifth: base1 + "dummy_page.html#fifth",
sixth: base1 + "onload_message.html#sixth",
};
let contexts = {
top: top.location.href,
first: base1 + "dummy_page.html#first",
third: base2 + "dummy_page.html#third",
second: base1 + "dummy_page.html#second",
fourth: base2 + "dummy_page.html#fourth",
fifth: base1 + "dummy_page.html#fifth",
sixth: base1 + "onload_message.html#sixth",
};
function addFrame(target, name) {
let doc = (target.contentWindow || target).document;
let frame = doc.createElement("iframe");
let p = new Promise(resolve => (frame.onload = () => resolve(frame)));
doc.body.appendChild(frame);
frame.name = name;
frame.src = contexts[name];
return p;
}
function addFrame(target, name) {
let doc = (target.contentWindow || target).document;
let frame = doc.createElement("iframe");
let p = new Promise(
resolve => (frame.onload = () => resolve(frame))
);
doc.body.appendChild(frame);
frame.name = name;
frame.src = contexts[name];
return p;
}
function addWindow(target, name) {
var win = target.contentWindow.open(contexts[name], name);
function addWindow(target, name) {
var win = target.contentWindow.open(contexts[name], name);
return new Promise(
resolve => target.contentWindow.addEventListener(
"message", () => resolve(win)));
}
return new Promise(resolve =>
target.contentWindow.addEventListener("message", () =>
resolve(win)
)
);
}
// Generate all lists of length length with every combination of
// values in input
function* generate(input, length) {
let list = new Array(length);
// Generate all lists of length length with every combination of
// values in input
function* generate(input, length) {
let list = new Array(length);
function* values(pos) {
if (pos >= list.length) {
yield list;
} else {
for (let v of input) {
list[pos] = v;
yield* values(pos + 1);
function* values(pos) {
if (pos >= list.length) {
yield list;
} else {
for (let v of input) {
list[pos] = v;
yield* values(pos + 1);
}
}
}
}
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];
yield* values(0);
}
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");
}
}
// 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.
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);
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) {
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);
});
}
);
});

View File

@ -12,8 +12,9 @@ function observeOnce(topic) {
}
add_task(async function setPrefs() {
await SpecialPowers.pushPrefEnv({"set": [["fission.oopif.attribute", true],
["dom.ipc.processCount", 10000]]});
await SpecialPowers.pushPrefEnv({
set: [["fission.oopif.attribute", true], ["dom.ipc.processCount", 10000]],
});
});
add_task(async function runTest() {
@ -25,13 +26,21 @@ add_task(async function runTest() {
is(chromeBC.parent, null, "chrome has no parent");
// 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`);
let rootBC = tab.linkedBrowser.browsingContext;
ok(rootBC.currentWindowGlobal, "[parent] root has a window global");
is(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.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");
// Test with an in-process frame
@ -55,7 +64,11 @@ add_task(async function runTest() {
info(`frame, parent`);
let frameBC = BrowsingContext.get(frameId);
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.parent, rootBC, "[parent] frame has root as parent");
@ -86,20 +99,32 @@ add_task(async function runTest() {
info(`oop frame, child`);
let oopBC = oop.frameLoader.browsingContext;
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;
});
info(`oop frame, parent`);
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.parent, rootBC, "[parent] oop frame has root as parent");
info(`waiting for oop window global`);
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.
@ -108,7 +133,11 @@ add_task(async function runTest() {
info(`new chrome, parent`);
let newChromeBC = newWindow.docShell.browsingContext;
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.parent, null, "new chrome has no parent");
@ -117,9 +146,21 @@ add_task(async function runTest() {
info(`adopting tab`);
let newTab = newWindow.gBrowser.adoptTab(tab);
is(newTab.linkedBrowser.browsingContext, 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(
newTab.linkedBrowser.browsingContext,
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");
info(`closing window`);

View File

@ -26,6 +26,9 @@ add_task(async function() {
gBrowser.removeTab(tab);
gBrowser.removeTabsProgressListener(listener);
is(numLocationChanges, 1,
"pushState with a different URI should cause a LocationChange event.");
is(
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/. */
add_task(async function runTests() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:about");
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:about"
);
registerCleanupFunction(function() {
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
// the test browser load detection mechanism from working.
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;
is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>",
"Check data URL loaded");
is(
href,
"data:text/html,<body%20onunload=''><iframe></iframe></body>",
"Check data URL loaded"
);
loaded = BrowserTestUtils.browserLoaded(browser);
browser.goBack();
@ -34,6 +43,9 @@ add_task(async function runTests() {
loaded = BrowserTestUtils.browserLoaded(browser);
browser.goForward();
href = await loaded;
is(href, "data:text/html,<body%20onunload=''><iframe></iframe></body>",
"Check we've gone forward to data URL");
is(
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 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";
const HTML_URL =
"http://mochi.test:8888/browser/docshell/test/browser/file_bug1328501.html";
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() {
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.
let browserLoaded = BrowserTestUtils.browserLoaded(browser);
await ContentTask.spawn(browser, FRAME_URL, async function(FRAME_URL) {
function frameLoaded(frame) {
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 frame2 = content.document.querySelector("#testFrame2");
@ -25,15 +30,26 @@ add_task(async function testMultiFrameRestore() {
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
// 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();
await framesLoaded;
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(r => setTimeout(r, 1000));
await ContentTask.spawn(browser, FRAME_URL, (FRAME_URL) => {
is(content.document.querySelector("#testFrame1").contentWindow.location.href, FRAME_URL);
is(content.document.querySelector("#testFrame2").contentWindow.location.href, FRAME_URL);
await ContentTask.spawn(browser, FRAME_URL, FRAME_URL => {
is(
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(
{gBrowser, url: "data:text/html;charset=utf-8,page1"},
{ gBrowser, url: "data:text/html;charset=utf-8,page1" },
async function(browser) {
// Make a simple modification for bfcache testing.
await ContentTask.spawn(browser, null, () => {
@ -23,13 +23,17 @@ add_task(async function testValidCache() {
await BrowserTestUtils.browserLoaded(browser);
// Go back and verify text content.
let awaitPageShow = BrowserTestUtils.waitForContentEvent(browser, "pageshow");
let awaitPageShow = BrowserTestUtils.waitForContentEvent(
browser,
"pageshow"
);
browser.goBack();
await awaitPageShow;
await ContentTask.spawn(browser, null, () => {
is(content.document.body.textContent, "modified");
});
});
}
);
});
// With bfcache expired.
@ -40,7 +44,7 @@ add_task(async function testExpiredCache() {
});
await BrowserTestUtils.withNewTab(
{gBrowser, url: "data:text/html;charset=utf-8,page1"},
{ gBrowser, url: "data:text/html;charset=utf-8,page1" },
async function(browser) {
// Make a simple modification for bfcache testing.
await ContentTask.spawn(browser, null, () => {
@ -59,11 +63,15 @@ add_task(async function testExpiredCache() {
});
// Go back and verify text content.
let awaitPageShow = BrowserTestUtils.waitForContentEvent(browser, "pageshow");
let awaitPageShow = BrowserTestUtils.waitForContentEvent(
browser,
"pageshow"
);
browser.goBack();
await awaitPageShow;
await ContentTask.spawn(browser, null, () => {
is(content.document.body.textContent, "page1");
});
});
}
);
});

View File

@ -1,21 +1,28 @@
const TEXT = {
/* 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",
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() {
waitForExplicitFinish();
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);
}
function afterOpen() {
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(afterChangeCharset);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(
afterChangeCharset
);
ContentTask.spawn(gBrowser.selectedBrowser, TEXT, function(TEXT) {
content.document.getElementById("testtextarea").value = TEXT.enteredText1;
@ -28,12 +35,21 @@ function afterOpen() {
function afterChangeCharset() {
ContentTask.spawn(gBrowser.selectedBrowser, TEXT, function(TEXT) {
is(content.document.getElementById("testpar").innerHTML, TEXT.rightText,
"encoding successfully changed");
is(content.document.getElementById("testtextarea").value, TEXT.enteredText1,
"text preserved in <textarea>");
is(content.document.getElementById("testinput").value, TEXT.enteredText2,
"text preserved in <input>");
is(
content.document.getElementById("testpar").innerHTML,
TEXT.rightText,
"encoding successfully changed"
);
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(() => {
gBrowser.removeCurrentTab();
finish();

View File

@ -1,15 +1,17 @@
/* Any copyright is dedicated to the Public Domain.
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() {
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({
"set": [
["dom.require_user_interaction_for_beforeunload", false],
],
set: [["dom.require_user_interaction_for_beforeunload", false]],
});
let url = TEST_PATH + "file_bug1415918_beforeunload.html";
@ -21,7 +23,11 @@ add_task(async function test() {
let observer = new MutationObserver(function(mutations) {
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];
prompt.querySelector(`.tabmodalprompt-${buttonId}`).click();
promptShown = true;
@ -42,11 +48,17 @@ add_task(async function test() {
// Check that all beforeunload handlers fired and reset attributes.
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");
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");
}
});
@ -60,40 +72,64 @@ add_task(async function test() {
// Check that only the parent beforeunload handler fired, and reset attribute.
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");
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.
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");
// Check that only the parent beforeunload handler fired, and reset attribute.
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");
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.
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");
// Check that all beforeunload handlers fired.
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)) {
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.
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");
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");
}
});
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");
// Check that all beforeunload handlers fired and reset attributes.
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");
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");
}
});
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");
// Check that all beforeunload handlers fired.
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)) {
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.
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");
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");
}
});
@ -187,7 +253,10 @@ add_task(async function test() {
// Check that the parent beforeunload handler fired, and only one child beforeunload
// handler fired. Reset attributes.
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");
let count = 0;
@ -202,13 +271,19 @@ add_task(async function test() {
// Prompt is not shown, don't permit unload.
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");
// Check that the parent beforeunload handler fired, and only one child beforeunload
// handler fired. Reset attributes.
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");
let count = 0;
@ -223,15 +298,24 @@ add_task(async function test() {
// Prompt is not shown, permit unload.
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");
// Check that all beforeunload handlers fired.
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)) {
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";
BrowserTestUtils.removeTab(tab);
});

View File

@ -1,18 +1,47 @@
function test() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "EUC-JP", "Child doc should report EUC-JP subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "Shift_JIS", "Child doc should report Shift_JIS subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "ISO-2022-JP", "Child doc should report ISO-2022-JP subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "Shift_JIS", "Child doc should report Shift_JIS subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "UTF-8", "Child doc should report UTF-8 subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "UTF-16LE", "Child doc should report UTF-16LE subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "UTF-16BE", "Child doc should report UTF-16 subsequently");
is(
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() {
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() {
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() {
is(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.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(content.frames[0].document.characterSet, "windows-1251", "Child doc should report windows-1251 subsequently");
is(
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() {
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() {
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) {
return ContentTask.spawn(newBrowser, uri, async function(uri) {
var prin = content.document.nodePrincipal;
Assert.notEqual(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.notEqual(
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,
"Loaded principal must not be system when loading " + uri);
Assert.equal(
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);
var prin = newBrowser.contentPrincipal;
isnot(prin, null, "Forced principal must not be null 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);
isnot(
prin,
null,
"Forced principal must not be null 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
// true in the content process.
@ -32,9 +53,16 @@ add_task(async function test() {
prin = newBrowser.contentPrincipal;
isnot(prin, null, "Loaded principal must not be null when adding " + uri);
isnot(prin, undefined, "Loaded principal must not be undefined when loading " + uri);
is(prin.isSystemPrincipal, false,
"Loaded principal must not be system when loading " + uri);
isnot(
prin,
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
// 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() {
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" }, async function(newBrowser) {
await ContentTask.spawn(newBrowser, null, async function() {
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");
await BrowserTestUtils.withNewTab(
{ gBrowser, url: "about:blank" },
async function(newBrowser) {
await ContentTask.spawn(newBrowser, null, async function() {
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,
"Loaded principal must not be system");
});
});
Assert.equal(
prin.isSystemPrincipal,
false,
"Loaded principal must not be system"
);
});
}
);
});

View File

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

View File

@ -3,109 +3,123 @@
*/
function test() {
waitForExplicitFinish();
waitForExplicitFinish();
var pageurl = "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 pageurl =
"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"]
.getService(Ci.nsINavHistoryService);
var historyService = Cc[
"@mozilla.org/browser/nav-history-service;1"
].getService(Ci.nsINavHistoryService);
/* 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;
/* 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 query = historyService.getNewQuery();
query.uri = aURI;
var result = historyService.executeQuery(query, options);
result.root.containerOpen = true;
var result = historyService.executeQuery(query, options);
result.root.containerOpen = true;
if (!result.root.childCount) {
return null;
}
return result.root.getChild(0);
if (!result.root.childCount) {
return null;
}
return result.root.getChild(0);
}
// We'll save the favicon URL of the orignal page here and check that the
// page with a hash has the same favicon.
var originalFavicon;
// We'll save the favicon URL of the orignal page here and check that the
// page with a hash has the same favicon.
var originalFavicon;
// Control flow in this test is a bit complicated.
//
// When the page loads, onPageLoad (the DOMContentLoaded handler) and
// historyObserver::onPageChanged are both called, in some order. Once
// they've both run, we click a fragment link in the content page
// (clickLinkIfReady), which should trigger another onPageChanged event,
// this time for the fragment's URL.
// Control flow in this test is a bit complicated.
//
// When the page loads, onPageLoad (the DOMContentLoaded handler) and
// historyObserver::onPageChanged are both called, in some order. Once
// they've both run, we click a fragment link in the content page
// (clickLinkIfReady), which should trigger another onPageChanged event,
// this time for the fragment's URL.
var _clickLinkTimes = 0;
function clickLinkIfReady() {
_clickLinkTimes++;
if (_clickLinkTimes == 2) {
BrowserTestUtils.synthesizeMouseAtCenter("#firefox-link", {},
gBrowser.selectedBrowser);
var _clickLinkTimes = 0;
function clickLinkIfReady() {
_clickLinkTimes++;
if (_clickLinkTimes == 2) {
BrowserTestUtils.synthesizeMouseAtCenter(
"#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. */
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;
// Now that the favicon has loaded, click on fragment link.
// This should trigger the |case fragmenturl| below.
clickLinkIfReady();
// Now that the favicon has loaded, click on fragment link.
// This should trigger the |case fragmenturl| below.
clickLinkIfReady();
return;
case fragmenturl:
// If the fragment URL's favicon isn't set, this branch won't
// be called and the test will time out.
return;
case fragmenturl:
// If the fragment URL's favicon isn't set, this branch won't
// be called and the test will time out.
is(
aValue,
originalFavicon,
"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
// 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);
function onPageLoad() {
clickLinkIfReady();
}
function onPageLoad() {
clickLinkIfReady();
}
// Make sure neither of the test pages haven't been loaded before.
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.
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.");
// Now open the test page in a new tab.
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
BrowserTestUtils.waitForContentEvent(gBrowser.selectedBrowser, "DOMContentLoaded", true).then(onPageLoad);
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, pageurl);
// Now open the test page in a new tab.
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
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.
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");
ok(browser.canGoBack, "we can go back");
@ -28,7 +30,7 @@ add_task(async function runTests() {
// Check nsISHistory.notifyOnHistoryReload
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");
// Let the first listener cancel the reload action.
@ -66,7 +68,7 @@ function listenOnce(message, arg = {}) {
}
function checkListeners(aLast, aMessage) {
return listenOnce("bug422543:getListenerStatus").then((listenerStatuses) => {
return listenOnce("bug422543:getListenerStatus").then(listenerStatuses => {
is(listenerStatuses[0], aLast, aMessage);
is(listenerStatuses[1], aLast, aMessage);
});
@ -87,27 +89,34 @@ function setListenerRetval(num, val) {
}
function setup() {
return BrowserTestUtils.openNewForegroundTab(gBrowser,
"http://mochi.test:8888")
.then(function(tab) {
return BrowserTestUtils.openNewForegroundTab(
gBrowser,
"http://mochi.test:8888"
).then(function(tab) {
let browser = tab.linkedBrowser;
registerCleanupFunction(async function() {
await listenOnce("bug422543:cleanup");
gBrowser.removeTab(tab);
});
browser.messageManager
.loadFrameScript(getRootDirectory(gTestPath) + "file_bug422543_script.js", false);
browser.messageManager.loadFrameScript(
getRootDirectory(gTestPath) + "file_bug422543_script.js",
false
);
});
}
function whenPageShown(aBrowser, aNavigation) {
let listener = ContentTask.spawn(aBrowser, null, function() {
return new Promise(resolve => {
addEventListener("pageshow", function onLoad() {
removeEventListener("pageshow", onLoad, true);
resolve();
}, true);
addEventListener(
"pageshow",
function onLoad() {
removeEventListener("pageshow", onLoad, true);
resolve();
},
true
);
});
});

View File

@ -3,7 +3,9 @@ var newBrowser;
function task() {
let resolve;
let promise = new Promise(r => { resolve = r; });
let promise = new Promise(r => {
resolve = r;
});
addEventListener("DOMContentLoaded", checkPage, false);
@ -13,11 +15,16 @@ function task() {
}
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();
}
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;
return promise;

View File

@ -3,77 +3,83 @@
*/
add_task(async function() {
var pagetitle = "Page Title for Bug 503832";
var pageurl = "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 pagetitle = "Page Title for Bug 503832";
var pageurl =
"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"]
.getService(Ci.nsINavHistoryService);
var historyService = Cc[
"@mozilla.org/browser/nav-history-service;1"
].getService(Ci.nsINavHistoryService);
let fragmentPromise = new Promise(resolve => {
/* Global history observer that triggers for the two test URLs above. */
var historyObserver = {
onBeginUpdateBatch() {},
onEndUpdateBatch() {},
onTitleChanged(aURI, aPageTitle) {
aURI = aURI.spec;
switch (aURI) {
case pageurl:
is(aPageTitle, pagetitle, "Correct page title for " + aURI);
return;
case fragmenturl:
is(aPageTitle, pagetitle, "Correct page title for " + aURI);
// If titles for fragment URLs aren't set, this code
// branch won't be called and the test will timeout,
// resulting in a failure
historyService.removeObserver(historyObserver, false);
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;
let fragmentPromise = new Promise(resolve => {
/* Global history observer that triggers for the two test URLs above. */
var historyObserver = {
onBeginUpdateBatch() {},
onEndUpdateBatch() {},
onTitleChanged(aURI, aPageTitle) {
aURI = aURI.spec;
switch (aURI) {
case pageurl:
is(aPageTitle, pagetitle, "Correct page title for " + aURI);
return;
case fragmenturl:
is(aPageTitle, pagetitle, "Correct page title for " + aURI);
// If titles for fragment URLs aren't set, this code
// branch won't be called and the test will timeout,
// resulting in a failure
historyService.removeObserver(historyObserver, false);
resolve();
}
var node = result.root.getChild(0);
result.root.containerOpen = false;
return node;
},
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;
return node;
}
// Make sure neither of the test pages haven't been loaded before.
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.
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.");
// Now open the test page in a new tab
await BrowserTestUtils.openNewForegroundTab(gBrowser, pageurl);
// Now open the test page in a new tab
await BrowserTestUtils.openNewForegroundTab(gBrowser, pageurl);
// Now that the page is loaded, click on fragment link
await BrowserTestUtils.synthesizeMouseAtCenter("#firefox-link", {},
gBrowser.selectedBrowser);
await fragmentPromise;
// Now that the page is loaded, click on fragment link
await BrowserTestUtils.synthesizeMouseAtCenter(
"#firefox-link",
{},
gBrowser.selectedBrowser
);
await fragmentPromise;
gBrowser.removeCurrentTab();
gBrowser.removeCurrentTab();
});

View File

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

View File

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

View File

@ -11,7 +11,8 @@
add_task(async function test() {
waitForExplicitFinish();
await BrowserTestUtils.withNewTab({ gBrowser, url: "http://example.com" },
await BrowserTestUtils.withNewTab(
{ gBrowser, url: "http://example.com" },
async function(browser) {
await ContentTask.spawn(browser, null, async function() {
let cw = content;
@ -19,12 +20,15 @@ add_task(async function test() {
ok(oldTitle, "Content window should initially have a title.");
cw.history.pushState("", "", "new_page");
let shistory = cw.docShell
.QueryInterface(Ci.nsIWebNavigation)
.sessionHistory;
let shistory = cw.docShell.QueryInterface(Ci.nsIWebNavigation)
.sessionHistory;
is(shistory.legacySHistory.getEntryAtIndex(shistory.index).title,
oldTitle, "SHEntry title after pushstate.");
is(
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).
*/
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() {
await BrowserTestUtils.withNewTab({ gBrowser, url: "about:blank" },
async function(browser) {
await ContentTask.spawn(browser, URL, async function(URL) {
let history = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
let count = 0;
await BrowserTestUtils.withNewTab(
{ gBrowser, url: "about:blank" },
async function(browser) {
await ContentTask.spawn(browser, URL, async function(URL) {
let history = docShell.QueryInterface(Ci.nsIWebNavigation)
.sessionHistory;
let count = 0;
let testDone = {};
testDone.promise = new Promise(resolve => { testDone.resolve = resolve; });
let testDone = {};
testDone.promise = new Promise(resolve => {
testDone.resolve = resolve;
});
let listener = {
OnHistoryNewEntry(aNewURI) {
if (aNewURI.spec == URL && 5 == ++count) {
addEventListener("load", function onLoad() {
removeEventListener("load", onLoad, true);
let listener = {
OnHistoryNewEntry(aNewURI) {
if (aNewURI.spec == URL && 5 == ++count) {
addEventListener(
"load",
function onLoad() {
removeEventListener("load", onLoad, true);
Assert.ok(history.index < history.count, "history.index is valid");
testDone.resolve();
}, true);
Assert.ok(
history.index < history.count,
"history.index is valid"
);
testDone.resolve();
},
true
);
history.legacySHistory.removeSHistoryListener(listener);
delete content._testListener;
content.setTimeout(() => { content.location.reload(); }, 0);
}
},
history.legacySHistory.removeSHistoryListener(listener);
delete content._testListener;
content.setTimeout(() => {
content.location.reload();
}, 0);
}
},
OnHistoryReload: () => true,
OnHistoryGotoIndex: () => {},
OnHistoryPurge: () => {},
OnHistoryReplaceEntry: () => {
// The initial load of about:blank causes a transient entry to be
// created, so our first navigation to a real page is a replace
// instead of a new entry.
++count;
},
OnHistoryReload: () => true,
OnHistoryGotoIndex: () => {},
OnHistoryPurge: () => {},
OnHistoryReplaceEntry: () => {
// The initial load of about:blank causes a transient entry to be
// created, so our first navigation to a real page is a replace
// instead of a new entry.
++count;
},
QueryInterface: ChromeUtils.generateQI([Ci.nsISHistoryListener,
Ci.nsISupportsWeakReference]),
};
QueryInterface: ChromeUtils.generateQI([
Ci.nsISHistoryListener,
Ci.nsISupportsWeakReference,
]),
};
history.legacySHistory.addSHistoryListener(listener);
// Since listener implements nsISupportsWeakReference, we are
// responsible for keeping it alive so that the GC doesn't clear
// it before the test completes. We do this by anchoring the listener
// to the content global window, and clearing it just before the test
// completes.
content._testListener = listener;
content.location = URL;
history.legacySHistory.addSHistoryListener(listener);
// Since listener implements nsISupportsWeakReference, we are
// responsible for keeping it alive so that the GC doesn't clear
// it before the test completes. We do this by anchoring the listener
// to the content global window, and clearing it just before the test
// completes.
content._testListener = listener;
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
// create just one SHEntry.
var doc = "data:text/html,<html><body onload='load()'>" +
"<script>" +
" var iframe = document.createElement('iframe');" +
" iframe.id = 'iframe';" +
" document.documentElement.appendChild(iframe);" +
" function load() {" +
" iframe.src = 'data:text/html,Hello!';" +
" }" +
"</script>" +
"</body></html>";
var doc =
"data:text/html,<html><body onload='load()'>" +
"<script>" +
" var iframe = document.createElement('iframe');" +
" iframe.id = 'iframe';" +
" document.documentElement.appendChild(iframe);" +
" function load() {" +
" iframe.src = 'data:text/html,Hello!';" +
" }" +
"</script>" +
"</body></html>";
function test() {
waitForExplicitFinish();
let taskFinished;
let tab = BrowserTestUtils.addTab(gBrowser, doc, {}, (tab) => {
let tab = BrowserTestUtils.addTab(gBrowser, doc, {}, tab => {
taskFinished = ContentTask.spawn(tab.linkedBrowser, null, () => {
return new Promise(resolve => {
addEventListener("load", function() {
// The main page has loaded. Now wait for the iframe to load.
let iframe = content.document.getElementById("iframe");
iframe.addEventListener("load", function listener(aEvent) {
// Wait for the iframe to load the new document, not about:blank.
if (!iframe.src)
return;
addEventListener(
"load",
function() {
// The main page has loaded. Now wait for the iframe to load.
let iframe = content.document.getElementById("iframe");
iframe.addEventListener(
"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);
let shistory = content.docShell
.QueryInterface(Ci.nsIWebNavigation)
.sessionHistory;
iframe.removeEventListener("load", listener, true);
let shistory = content.docShell.QueryInterface(
Ci.nsIWebNavigation
).sessionHistory;
Assert.equal(shistory.count, 1, "shistory count should be 1.");
resolve();
}, true);
}, true);
Assert.equal(shistory.count, 1, "shistory count should be 1.");
resolve();
},
true
);
},
true
);
});
});
});

View File

@ -3,20 +3,32 @@ var rootDir = "http://mochi.test:8888/browser/docshell/test/browser/";
function test() {
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);
}
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.selectedTab = BrowserTestUtils.addTab(gBrowser, rootDir + "file_bug852909.pdf");
gBrowser.selectedTab = BrowserTestUtils.addTab(
gBrowser,
rootDir + "file_bug852909.pdf"
);
BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser).then(pdf);
}
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();
finish();

View File

@ -4,21 +4,33 @@
function testContent(text) {
return ContentTask.spawn(gBrowser.selectedBrowser, text, text => {
Assert.equal(content.document.getElementById("testpar").innerHTML, text,
"<p> 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");
Assert.equal(
content.document.getElementById("testpar").innerHTML,
text,
"<p> 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() {
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
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 */
testContent(wrongText).then(() => {
@ -28,7 +40,8 @@ function afterOpen() {
function afterChangeCharset() {
/* 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 */
testContent(rightText).then(() => {
@ -44,11 +57,14 @@ function test() {
// are always UTF-8 (bug 617339) and we are testing decoding from other
// charsets.
var jar = getJar(getRootDirectory(gTestPath));
var dir = jar ?
extractJarToTmp(jar) :
getChromeDir(getResolvedURI(gTestPath));
var dir = jar
? extractJarToTmp(jar)
: getChromeDir(getResolvedURI(gTestPath));
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);
}

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) {
let tabSpec = gBrowser.selectedBrowser.currentURI.spec;
info("loading: " + tabSpec);
ok(tabSpec.startsWith("file://") && tabSpec.endsWith(TEST_FILE),
"sanity check to make sure html loaded");
ok(
tabSpec.startsWith("file://") && tabSpec.endsWith(TEST_FILE),
"sanity check to make sure html loaded"
);
info("click view-source of html");
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
@ -31,19 +33,33 @@ add_task(async function test_click_link_within_view_source() {
let tab = await tabPromise;
tabSpec = gBrowser.selectedBrowser.currentURI.spec;
info("loading: " + tabSpec);
ok(tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(TEST_FILE),
"loading view-source of html succeeded");
ok(
tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(TEST_FILE),
"loading view-source of html succeeded"
);
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() {
if (content.document.readyState != "complete") {
await ContentTaskUtils.waitForEvent(content.document, "readystatechange", false, () =>
content.document.readyState == "complete");
await ContentTaskUtils.waitForEvent(
content.document,
"readystatechange",
false,
() => content.document.readyState == "complete"
);
}
// document.getElementById() does not work on a view-source page, hence we use 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];
myLink.click();
});
@ -52,8 +68,10 @@ add_task(async function test_click_link_within_view_source() {
tabSpec = gBrowser.selectedBrowser.currentURI.spec;
info("loading: " + tabSpec);
ok(tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(DUMMY_FILE),
"loading view-source of html succeeded");
ok(
tabSpec.startsWith("view-source:file://") && tabSpec.endsWith(DUMMY_FILE),
"loading view-source of html succeeded"
);
BrowserTestUtils.removeTab(tab);
});

View File

@ -3,9 +3,13 @@
"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 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) {
return ContentTask.spawn(aBrowser, null, () => {
@ -21,26 +25,38 @@ function getCurrentURI(aBrowser) {
}
function verifyResult(aTestName, aBrowser, aDataURI, aPID, aSamePID) {
return ContentTask.spawn(aBrowser, {aTestName, aDataURI, aPID, aSamePID}, 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");
return ContentTask.spawn(
aBrowser,
{ aTestName, aDataURI, aPID, aSamePID },
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
let pid = Services.appinfo.processID;
if (aSamePID) {
is(pid, aPID, aTestName + ": process ID needs to be identical");
} else {
isnot(pid, aPID, aTestName + ": process ID needs to be different");
// check that the process ID is the same/different when opening the new tab
let pid = Services.appinfo.processID;
if (aSamePID) {
is(pid, aPID, aTestName + ": process ID needs to be identical");
} else {
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) {
@ -52,11 +68,20 @@ async function simulateCspInheritanceForNewTab(aTestName, aSamePID) {
let pid = await getCurrentPID(gBrowser.selectedBrowser);
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
// simulate click
BrowserTestUtils.synthesizeMouseAtCenter("#testLink", {},
gBrowser.selectedBrowser);
BrowserTestUtils.synthesizeMouseAtCenter(
"#testLink",
{},
gBrowser.selectedBrowser
);
let tab = await loadPromise;
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);
});
}
@ -64,13 +89,17 @@ async function simulateCspInheritanceForNewTab(aTestName, aSamePID) {
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
// 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);
});
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
// 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);
});

View File

@ -1,11 +1,18 @@
"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 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) {
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;
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() {
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
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", {},
gBrowser.selectedBrowser);
BrowserTestUtils.synthesizeMouseAtCenter(
"#testlink",
{},
gBrowser.selectedBrowser
);
await loadPromise;
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) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, RESULT_URI);
// set the data href + simulate ctrl+click
BrowserTestUtils.synthesizeMouseAtCenter("#testlink",
{ ctrlKey: true, metaKey: true },
gBrowser.selectedBrowser);
BrowserTestUtils.synthesizeMouseAtCenter(
"#testlink",
{ ctrlKey: true, metaKey: true },
gBrowser.selectedBrowser
);
let tab = await loadPromise;
gBrowser.selectTabAtIndex(2);
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() {
await BrowserTestUtils.withNewTab(TEST_URI, async function(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, RESULT_URI);
// set the data href + simulate right-click open link in tab
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
// These are operations that must be executed synchronously with the event.
document.getElementById("context-openlinkintab").doCommand();
event.target.hidePopup();
return true;
});
BrowserTestUtils.synthesizeMouseAtCenter("#testlink",
{ type: "contextmenu", button: 2 },
gBrowser.selectedBrowser);
add_task(
async function test_csp_inheritance_right_click_open_link_in_new_tab() {
await BrowserTestUtils.withNewTab(TEST_URI, async function(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, RESULT_URI);
// set the data href + simulate right-click open link in tab
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
// These are operations that must be executed synchronously with the event.
document.getElementById("context-openlinkintab").doCommand();
event.target.hidePopup();
return true;
});
BrowserTestUtils.synthesizeMouseAtCenter(
"#testlink",
{ type: "contextmenu", button: 2 },
gBrowser.selectedBrowser
);
let tab = await loadPromise;
gBrowser.selectTabAtIndex(2);
await verifyCSP("right-click-open-in-new-tab()", gBrowser.selectedBrowser, RESULT_URI);
await BrowserTestUtils.removeTab(tab);
});
});
let tab = await loadPromise;
gBrowser.selectTabAtIndex(2);
await verifyCSP(
"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");
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);
Assert.ok(content.document.nodePrincipal.isNullPrincipal,
"data: URI should have NullPrincipal.");
Assert.ok(!content.document.nodePrincipal.equals(args.principal),
"data: URI should have unique opaque origin.");
Assert.ok(
content.document.nodePrincipal.isNullPrincipal,
"data: URI should have NullPrincipal."
);
Assert.ok(
!content.document.nodePrincipal.equals(args.principal),
"data: URI should have unique opaque origin."
);
});
gBrowser.removeTab(tab);

View File

@ -1,6 +1,9 @@
"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 DATA_URI = "data:text/html;html,<html><body>foo</body></html>";
@ -12,7 +15,10 @@ function setDataHrefOnLink(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;
is(channel.URI.spec, aDataURI, "testing CSP for " + aTestName);
let cspJSON = content.document.cspJSON;
@ -27,7 +33,7 @@ function verifyCSP(aTestName, aBrowser, aDataURI) {
add_task(async function setup() {
// allow top level data: URI navigations, otherwise clicking data: link fails
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);
// set the data href + simulate click
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", {},
gBrowser.selectedBrowser);
BrowserTestUtils.synthesizeMouseAtCenter(
"#testlink",
{},
gBrowser.selectedBrowser
);
await loadPromise;
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);
// set the data href + simulate ctrl+click
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.synthesizeMouseAtCenter("#testlink",
{ ctrlKey: true, metaKey: true },
gBrowser.selectedBrowser);
BrowserTestUtils.synthesizeMouseAtCenter(
"#testlink",
{ ctrlKey: true, metaKey: true },
gBrowser.selectedBrowser
);
let tab = await loadPromise;
gBrowser.selectTabAtIndex(2);
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() {
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
// set the data href + simulate right-click open link in tab
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
// These are operations that must be executed synchronously with the event.
document.getElementById("context-openlinkintab").doCommand();
event.target.hidePopup();
return true;
});
BrowserTestUtils.synthesizeMouseAtCenter("#testlink",
{ type: "contextmenu", button: 2 },
gBrowser.selectedBrowser);
add_task(
async function test_data_csp_inheritance_right_click_open_link_in_new_tab() {
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
// set the data href + simulate right-click open link in tab
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
// These are operations that must be executed synchronously with the event.
document.getElementById("context-openlinkintab").doCommand();
event.target.hidePopup();
return true;
});
BrowserTestUtils.synthesizeMouseAtCenter(
"#testlink",
{ type: "contextmenu", button: 2 },
gBrowser.selectedBrowser
);
let tab = await loadPromise;
gBrowser.selectTabAtIndex(2);
await verifyCSP("right-click-open-in-new-tab()", gBrowser.selectedBrowser, DATA_URI);
await BrowserTestUtils.removeTab(tab);
});
});
let tab = await loadPromise;
gBrowser.selectTabAtIndex(2);
await verifyCSP(
"right-click-open-in-new-tab()",
gBrowser.selectedBrowser,
DATA_URI
);
await BrowserTestUtils.removeTab(tab);
});
}
);

View File

@ -1,49 +1,87 @@
"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 VIEW_SRC_URI = "view-source:" + HTML_URI;
add_task(async function() {
info("load baseline html in new tab");
await BrowserTestUtils.withNewTab(HTML_URI, async function(aBrowser) {
is(gBrowser.selectedBrowser.currentURI.spec, HTML_URI,
"sanity check to make sure html loaded");
is(
gBrowser.selectedBrowser.currentURI.spec,
HTML_URI,
"sanity check to make sure html loaded"
);
info("right-click -> view-source of html");
let vSrcCtxtMenu = document.getElementById("contentAreaContextMenu");
let popupPromise = BrowserTestUtils.waitForEvent(vSrcCtxtMenu, "popupshown");
BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, aBrowser);
let popupPromise = BrowserTestUtils.waitForEvent(
vSrcCtxtMenu,
"popupshown"
);
BrowserTestUtils.synthesizeMouseAtCenter(
"body",
{ type: "contextmenu", button: 2 },
aBrowser
);
await popupPromise;
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();
vSrcCtxtMenu.hidePopup();
let tab = await tabPromise;
is(gBrowser.selectedBrowser.currentURI.spec, VIEW_SRC_URI,
"loading view-source of html succeeded");
is(
gBrowser.selectedBrowser.currentURI.spec,
VIEW_SRC_URI,
"loading view-source of html succeeded"
);
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 => {
content.document.location = HTML_URI;
});
await loadPromise;
is(gBrowser.selectedBrowser.currentURI.spec, HTML_URI,
"loading html another time succeeded");
is(
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");
popupPromise = BrowserTestUtils.waitForEvent(backCtxtMenu, "popupshown");
BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, aBrowser);
BrowserTestUtils.synthesizeMouseAtCenter(
"body",
{ type: "contextmenu", button: 2 },
aBrowser
);
await popupPromise;
loadPromise = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow");
loadPromise = BrowserTestUtils.waitForContentEvent(
tab.linkedBrowser,
"pageshow"
);
let backItem = backCtxtMenu.getElementsByAttribute("id", "context-back")[0];
backItem.click();
backCtxtMenu.hidePopup();
await loadPromise;
is(gBrowser.selectedBrowser.currentURI.spec, VIEW_SRC_URI,
"clicking .back() to view-source of html succeeded");
is(
gBrowser.selectedBrowser.currentURI.spec,
VIEW_SRC_URI,
"clicking .back() to view-source of html succeeded"
);
BrowserTestUtils.removeTab(tab);
});

View File

@ -8,17 +8,22 @@ function test() {
Services.prefs.setBoolPref("security.data_uri.unique_opaque_origin", 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.
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() {
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);
}
function startTest() {
let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser));
let browser = gBrowser.getBrowserForTab(tab);
@ -33,25 +38,39 @@ function startTest() {
function testURL(url, func) {
let secMan = Services.scriptSecurityManager;
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() {
let pagePrincipal = browser.contentPrincipal;
ok(pagePrincipal, "got principal for http:// page");
// Now load the URL normally
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
let webNav = Ci.nsIWebNavigation;
loadURL(url, webNav.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL, artificialPrincipal, 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");
loadURL(
url,
webNav.LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL,
artificialPrincipal,
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() {
waitForExplicitFinish();
let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser));
registerCleanupFunction(function() {
gBrowser.removeTab(tab);
});
var dataStream = Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(Ci.nsIStringInputStream);
var dataStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
Ci.nsIStringInputStream
);
dataStream.data = gPostData;
var postStream = Cc["@mozilla.org/network/mime-input-stream;1"].
createInstance(Ci.nsIMIMEInputStream);
var postStream = Cc[
"@mozilla.org/network/mime-input-stream;1"
].createInstance(Ci.nsIMIMEInputStream);
postStream.addHeader("Content-Type", "application/x-www-form-urlencoded");
postStream.setData(dataStream);
var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
.getService(Ci.nsIPrincipal);
var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].getService(
Ci.nsIPrincipal
);
tab.linkedBrowser.loadURI("http://mochi.test:8888/browser/docshell/test/browser/print_postdata.sjs", {
triggeringPrincipal: systemPrincipal,
postData: postStream,
});
tab.linkedBrowser.loadURI(
"http://mochi.test:8888/browser/docshell/test/browser/print_postdata.sjs",
{
triggeringPrincipal: systemPrincipal,
postData: postStream,
}
);
BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => {
ContentTask.spawn(tab.linkedBrowser, gPostData, function(postData) {
var bodyText = content.document.body.textContent;
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() {
await BrowserTestUtils.withNewTab({
gBrowser,
url: "http://example.org/browser/docshell/test/browser/file_multiple_pushState.html",
}, async function(browser) {
const kExpected = "http://example.org/bar/ABC/DEF?key=baz";
await BrowserTestUtils.withNewTab(
{
gBrowser,
url:
"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() {
return content.document.location.href;
});
let contentLocation = await ContentTask.spawn(
browser,
null,
async function() {
return content.document.location.href;
}
);
is(contentLocation, kExpected);
is(browser.documentURI.spec, kExpected);
});
is(contentLocation, kExpected);
is(browser.documentURI.spec, kExpected);
}
);
});

View File

@ -1,14 +1,19 @@
function contentTask() {
let finish;
let promise = new Promise(resolve => { finish = resolve; });
let promise = new Promise(resolve => {
finish = resolve;
});
let contentWindow;
let originalLocation;
let currentTest = -1;
let stayingOnPage = true;
const TEST_PAGE = "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>");
const TEST_PAGE =
"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;
var testsLength;
@ -16,13 +21,18 @@ function contentTask() {
function onTabLoaded(event) {
info("A document loaded in a tab!");
let loadedPage = event.target.location.href;
if (loadedPage == "about:blank" ||
event.originalTarget != content.document) {
if (
loadedPage == "about:blank" ||
event.originalTarget != content.document
) {
return;
}
if (!loadExpected) {
ok(false, "Expected no page loads, but loaded " + loadedPage + " instead!");
ok(
false,
"Expected no page loads, but loaded " + loadedPage + " instead!"
);
return;
}
@ -40,8 +50,15 @@ function contentTask() {
}
function onAfterTargetedPageLoad() {
ok(!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");
ok(
!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();
}
@ -49,10 +66,17 @@ function contentTask() {
function onTabModalDialogLoaded() {
info(content.location.href);
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.");
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;
addMessageListener("test-beforeunload:dialog-gone", function listener(msg) {
@ -93,7 +117,6 @@ function contentTask() {
currentTest = 0;
}
if (!stayingOnPage) {
// Right now we're on the data: page. Null contentWindow out to
// avoid CPOW errors when contentWindow is no longer the correct
@ -115,8 +138,12 @@ function contentTask() {
contentWindow.dialogWasInvoked = false;
originalLocation = contentWindow.location.href;
// And run this test:
info("Running test with onbeforeunload " + contentWindow.wrappedJSObject.testFns[currentTest].toSource());
contentWindow.onbeforeunload = contentWindow.wrappedJSObject.testFns[currentTest];
info(
"Running test with onbeforeunload " +
contentWindow.wrappedJSObject.testFns[currentTest].toSource()
);
contentWindow.onbeforeunload =
contentWindow.wrappedJSObject.testFns[currentTest];
sendAsyncMessage("test-beforeunload:reset");
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 loadStarted = false;
var tabStateListener = {
onStateChange(webprogress, request, stateFlags, status) {
let startDocumentFlags = Ci.nsIWebProgressListener.STATE_START |
Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
let startDocumentFlags =
Ci.nsIWebProgressListener.STATE_START |
Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
if ((stateFlags & startDocumentFlags) == startDocumentFlags) {
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) => {
let button = node.querySelector(stayingOnPage ? ".tabmodalprompt-button1" : ".tabmodalprompt-button0");
// ... and then actually make the dialog go away
info("Clicking button: " + button.label);
EventUtils.synthesizeMouseAtCenter(button, {});
});
BrowserTestUtils.waitForMessage(mm, "test-beforeunload:dialog-response").then(
stayingOnPage => {
let button = node.querySelector(
stayingOnPage ? ".tabmodalprompt-button1" : ".tabmodalprompt-button0"
);
// ... and then actually make the dialog go away
info("Clicking button: " + button.label);
EventUtils.synthesizeMouseAtCenter(button, {});
}
);
}
// Listen for the dialog being created
@ -202,9 +236,12 @@ function test() {
testTab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
testTab.linkedBrowser.messageManager.addMessageListener("test-beforeunload:reset", () => {
loadStarted = false;
});
testTab.linkedBrowser.messageManager.addMessageListener(
"test-beforeunload:reset",
() => {
loadStarted = false;
}
);
ContentTask.spawn(testTab.linkedBrowser, null, contentTask).then(finish);
}
@ -214,4 +251,3 @@ registerCleanupFunction(function() {
gBrowser.removeProgressListener(tabStateListener);
gBrowser.removeTab(testTab);
});

View File

@ -4,14 +4,22 @@
add_task(async function() {
const kSearchEngineID = "test_urifixup_search_engine";
const kSearchEngineURL = "http://localhost/?search={searchTerms}";
await Services.search.addEngineWithDetails(kSearchEngineID,
{method: "get", template: kSearchEngineURL});
await Services.search.addEngineWithDetails(kSearchEngineID, {
method: "get",
template: kSearchEngineURL,
});
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;
Assert.equal(selectedName, kSearchEngineID, "Check fake search engine is selected");
Assert.equal(
selectedName,
kSearchEngineID,
"Check fake search engine is selected"
);
registerCleanupFunction(async function() {
if (oldDefaultEngine) {
@ -34,7 +42,11 @@ add_task(async function() {
let engine = Services.search.defaultEngine;
Assert.ok(engine, "Have default search 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);
});

View File

@ -6,7 +6,9 @@
add_task(async function() {
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);
});
});
@ -14,30 +16,45 @@ add_task(async function() {
async function test_body() {
let docshell = docShell;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_NONE,
"touchEventsOverride flag should be initially set to NONE");
is(
docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_NONE,
"touchEventsOverride flag should be initially set to NONE"
);
docshell.touchEventsOverride = Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"touchEventsOverride flag should be changed to DISABLED");
is(
docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"touchEventsOverride flag should be changed to DISABLED"
);
let frameWin = content.document.querySelector("#test-iframe").contentWindow;
docshell = frameWin.docShell;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"touchEventsOverride flag should be passed on to frames.");
is(
docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"touchEventsOverride flag should be passed on to frames."
);
let newFrame = content.document.createElement("iframe");
content.document.body.appendChild(newFrame);
let newFrameWin = newFrame.contentWindow;
docshell = newFrameWin.docShell;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"Newly created frames should use the new touchEventsOverride flag");
is(
docshell.touchEventsOverride,
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"Newly created frames should use the new touchEventsOverride flag"
);
newFrameWin.location.reload();
await ContentTaskUtils.waitForEvent(newFrameWin, "load");
docshell = newFrameWin.docShell;
is(docshell.touchEventsOverride, Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_DISABLED,
"New touchEventsOverride flag should persist across reloads");
is(
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";
add_task(async function() {
await BrowserTestUtils.withNewTab({ gBrowser, url: URL },
async function(browser) {
await ContentTask.spawn(browser, null, function() {
ok("recordProfileTimelineMarkers" in docShell,
"The recordProfileTimelineMarkers attribute exists");
ok("popProfileTimelineMarkers" in docShell,
"The popProfileTimelineMarkers function exists");
ok(docShell.recordProfileTimelineMarkers === false,
"recordProfileTimelineMarkers is false by default");
ok(docShell.popProfileTimelineMarkers().length === 0,
"There are no markers by default");
await BrowserTestUtils.withNewTab({ gBrowser, url: URL }, async function(
browser
) {
await ContentTask.spawn(browser, null, function() {
ok(
"recordProfileTimelineMarkers" in docShell,
"The recordProfileTimelineMarkers attribute exists"
);
ok(
"popProfileTimelineMarkers" in docShell,
"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;
ok(docShell.recordProfileTimelineMarkers === true,
"recordProfileTimelineMarkers can be set to true");
docShell.recordProfileTimelineMarkers = true;
ok(
docShell.recordProfileTimelineMarkers === true,
"recordProfileTimelineMarkers can be set to true"
);
docShell.recordProfileTimelineMarkers = false;
ok(docShell.recordProfileTimelineMarkers === false,
"recordProfileTimelineMarkers can be set to false");
});
docShell.recordProfileTimelineMarkers = false;
ok(
docShell.recordProfileTimelineMarkers === false,
"recordProfileTimelineMarkers can be set to false"
);
});
});
});

View File

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

View File

@ -3,6 +3,7 @@
"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);

View File

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

View File

@ -10,8 +10,9 @@
// restyles, reflows and paints occur
function rectangleContains(rect, x, y, width, height) {
return rect.x <= x && rect.y <= y && rect.width >= width &&
rect.height >= height;
return (
rect.x <= x && rect.y <= y && rect.width >= width && rect.height >= height
);
}
function sanitizeMarkers(list) {
@ -20,117 +21,145 @@ function sanitizeMarkers(list) {
return list.filter(e => e.name != "Worker" && e.name != "MinorGC");
}
var TESTS = [{
desc: "Changing the width of the test element",
searchFor: "Paint",
setup(docShell) {
let div = content.document.querySelector("div");
div.setAttribute("class", "resize-change-color");
var TESTS = [
{
desc: "Changing the width of the test element",
searchFor: "Paint",
setup(docShell) {
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);
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");
{
desc: "Changing the test element's background color",
searchFor: "Paint",
setup(docShell) {
let div = content.document.querySelector("div");
div.setAttribute("class", "change-color");
},
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 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",
searchFor: "Paint",
setup(docShell) {
let div = content.document.querySelector("div");
div.setAttribute("class", "change-color");
{
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");
},
},
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 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 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");
{
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.timeEnd("FOO");
content.console.timeEnd("BAR");
content.console.time("BAR");
content.setTimeout(() => {
content.console.timeEnd("FOO");
content.console.timeEnd("BAR");
}, 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);
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");
{
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"
)
);
},
},
}, {
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);

View File

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

View File

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

View File

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

View File

@ -1,29 +1,44 @@
"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() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
"about:blank"
);
gURLBar.value = REDIRECTURL;
gURLBar.select();
let errorPageLoaded = BrowserTestUtils.waitForErrorPage(tab.linkedBrowser);
EventUtils.sendKey("return");
await errorPageLoaded;
let [contentURL, originalURL] = await ContentTask.spawn(tab.linkedBrowser, null, () => {
return [
content.document.documentURI,
content.document.mozDocumentURIIfNotForErrorPages.spec,
];
});
let [contentURL, originalURL] = await ContentTask.spawn(
tab.linkedBrowser,
null,
() => {
return [
content.document.documentURI,
content.document.mozDocumentURIIfNotForErrorPages.spec,
];
}
);
info("Page that loaded: " + contentURL);
const errorURI = "about:neterror?";
ok(contentURL.startsWith(errorURI), "Should be on an error page");
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);
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);
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,23 @@
/**
* Import common SimpleTest methods so that they're usable in this window.
*/
var imports = [ "SimpleTest", "is", "isnot", "ok", "onerror", "todo",
"todo_is", "todo_isnot" ];
var imports = [
"SimpleTest",
"is",
"isnot",
"ok",
"onerror",
"todo",
"todo_is",
"todo_isnot",
];
for (var name of imports) {
window[name] = window.opener.wrappedJSObject[name];
}
const {BrowserTestUtils} = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { BrowserTestUtils } = ChromeUtils.import(
"resource://testing-common/BrowserTestUtils.jsm"
);
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
// Some functions assume chrome-harness.js has been loaded.
/* import-globals-from ../../../testing/mochitest/chrome-harness.js */
@ -22,16 +32,15 @@ const NAV_URI = 3;
const NAV_RELOAD = 4;
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
// to be triggered by this navigation
// to be triggered by this navigation
var gFinalEvent; // true if the last expected event has fired
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
// executed by doPageNavigation
var gOrigMaxTotalViewers = // original value of max_total_viewers,
undefined; // to be restored at end of test
// executed by doPageNavigation
var gOrigMaxTotalViewers = undefined; // original value of max_total_viewers, // to be restored at end of test
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 reload = params.reload ? params.reload : false;
let uri = params.uri ? params.uri : false;
let eventsToListenFor = typeof(params.eventsToListenFor) != "undefined" ?
params.eventsToListenFor : ["pageshow"];
gExpectedEvents = typeof(params.eventsToListenFor) == "undefined" ||
eventsToListenFor.length == 0 ? undefined : params.expectedEvents;
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);
let eventsToListenFor =
typeof params.eventsToListenFor != "undefined"
? params.eventsToListenFor
: ["pageshow"];
gExpectedEvents =
typeof params.eventsToListenFor == "undefined" ||
eventsToListenFor.length == 0
? undefined
: params.expectedEvents;
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.
if (back && forward)
if (back && 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");
if (forward && uri)
}
if (forward && 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");
if (!back && !forward && !uri && !reload && !waitOnly)
}
if (!back && !forward && !uri && !reload && !waitOnly) {
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 == []");
if (params.preventBFCache && eventsToListenFor.length == 0)
}
if (params.preventBFCache && eventsToListenFor.length == 0) {
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");
if (waitOnly && typeof(params.onNavComplete) == "undefined")
throw new Error("Must specify onNavComplete when specifying waitForEventsOnly");
if (waitOnly && (back || forward || reload || uri))
throw new Error("Can't specify a navigation type when using waitForEventsOnly");
}
if (waitOnly && typeof params.onNavComplete == "undefined") {
throw new Error(
"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) {
let eventFound = false;
if ( (anEventType == "pageshow") && (!gExpectedEvents) )
if (anEventType == "pageshow" && !gExpectedEvents) {
eventFound = true;
}
if (gExpectedEvents) {
for (let anExpectedEvent of gExpectedEvents) {
if (anExpectedEvent.type == anEventType)
if (anExpectedEvent.type == anEventType) {
eventFound = true;
}
}
}
if (gUnexpectedEvents) {
for (let anExpectedEventType of gUnexpectedEvents) {
if (anExpectedEventType == anEventType)
if (anExpectedEventType == anEventType) {
eventFound = true;
}
}
}
if (!eventFound)
throw new Error(`Event type ${anEventType} is specified in ` +
"eventsToListenFor, but not in expectedEvents");
if (!eventFound) {
throw new Error(
`Event type ${anEventType} is specified in ` +
"eventsToListenFor, but not in expectedEvents"
);
}
}
// If the test explicitly sets .eventsToListenFor to [], don't wait for any
@ -160,8 +199,11 @@ function doPageNavigation(params) {
// property of the input parameters.
for (let eventType of eventsToListenFor) {
dump("TEST: registering a listener for " + eventType + " events\n");
TestWindow.getBrowser().addEventListener(eventType, pageEventListener,
true);
TestWindow.getBrowser().addEventListener(
eventType,
pageEventListener,
true
);
}
// Perform the specified navigation.
@ -187,11 +229,17 @@ function doPageNavigation(params) {
// wait for all events to occur, and then call doPageNavigation_complete().
if (eventsToListenFor.length > 0 && params.onNavComplete) {
waitForTrue(
function() { return gFinalEvent; },
function() {
doPageNavigation_complete(eventsToListenFor, params.onNavComplete,
preventBFCache);
} );
return gFinalEvent;
},
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
* occurred.
*/
function doPageNavigation_complete(eventsToListenFor, onNavComplete,
preventBFCache) {
function doPageNavigation_complete(
eventsToListenFor,
onNavComplete,
preventBFCache
) {
// Unregister our event listeners.
dump("TEST: removing event listeners\n");
for (let eventType of eventsToListenFor) {
TestWindow.getBrowser().removeEventListener(eventType, pageEventListener,
true);
TestWindow.getBrowser().removeEventListener(
eventType,
pageEventListener,
true
);
}
// If the .preventBFCache property was set, add an empty unload handler to
// prevent the page from being bfcached.
let uri = TestWindow.getBrowser().currentURI.spec;
if (preventBFCache) {
TestWindow.getWindow().addEventListener("unload", function() {
dump("TEST: Called dummy unload function to prevent page from " +
"being bfcached.\n");
}, true);
TestWindow.getWindow().addEventListener(
"unload",
function() {
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
// stored in the bfcache, for later verification.
@ -227,12 +287,11 @@ function doPageNavigation_complete(eventsToListenFor, onNavComplete,
} else if (gNavType == NAV_URI) {
// If we're navigating to a uri and .preventBFCache was not
// specified, splice it out of gUrisNotInBFCache if it's there.
gUrisNotInBFCache.forEach(
function(element, index, array) {
if (element == uri) {
array.splice(index, 1);
}
}, this);
gUrisNotInBFCache.forEach(function(element, index, array) {
if (element == uri) {
array.splice(index, 1);
}
}, this);
}
// Notify the callback now that we're done.
@ -254,8 +313,15 @@ function waitForPageEvents(params) {
*/
function pageEventListener(event) {
try {
dump("TEST: eventListener received a " + event.type + " event for page " +
event.originalTarget.title + ", persisted=" + event.persisted + "\n");
dump(
"TEST: eventListener received a " +
event.type +
" event for page " +
event.originalTarget.title +
", persisted=" +
event.persisted +
"\n"
);
} catch (e) {
// Ignore any exception.
}
@ -264,25 +330,35 @@ function pageEventListener(event) {
// loaded with .preventBFCache, make sure that its pageshow event
// has .persisted = false, even if the test doesn't explicitly test
// for .persisted.
if ( (event.type == "pageshow") &&
(gNavType == NAV_BACK || gNavType == NAV_FORWARD) ) {
if (
event.type == "pageshow" &&
(gNavType == NAV_BACK || gNavType == NAV_FORWARD)
) {
let uri = TestWindow.getBrowser().currentURI.spec;
if (uri in gUrisNotInBFCache) {
ok(!event.persisted, "pageshow event has .persisted = false, even " +
"though it was loaded with .preventBFCache previously\n");
ok(
!event.persisted,
"pageshow event has .persisted = false, even " +
"though it was loaded with .preventBFCache previously\n"
);
}
}
if (typeof(gUnexpectedEvents) != "undefined") {
is(gUnexpectedEvents.indexOf(event.type), -1,
"Should not get unexpected event " + event.type);
if (typeof gUnexpectedEvents != "undefined") {
is(
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
// triggered when a pageshow event is fired; this will allow
// doPageNavigation() to return.
if ((typeof(gExpectedEvents) == "undefined") && event.type == "pageshow") {
waitForNextPaint(function() { gFinalEvent = true; });
if (typeof gExpectedEvents == "undefined" && event.type == "pageshow") {
waitForNextPaint(function() {
gFinalEvent = true;
});
return;
}
@ -297,41 +373,71 @@ function pageEventListener(event) {
// actual event.
let expected = gExpectedEvents.shift();
is(event.type, expected.type,
"A " + expected.type + " event was expected, but a " +
event.type + " event occurred");
is(
event.type,
expected.type,
"A " +
expected.type +
" event was expected, but a " +
event.type +
" event occurred"
);
if (typeof(expected.title) != "undefined") {
ok(event.originalTarget instanceof HTMLDocument,
"originalTarget for last " + event.type +
" event not an HTMLDocument");
is(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.title != "undefined") {
ok(
event.originalTarget instanceof HTMLDocument,
"originalTarget for last " + event.type + " event not an HTMLDocument"
);
is(
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") {
is(event.persisted, expected.persisted,
"The persisted property of the " + event.type + " event on page " +
event.originalTarget.location + " had an unexpected value");
if (typeof expected.persisted != "undefined") {
is(
event.persisted,
expected.persisted,
"The persisted property of the " +
event.type +
" event on page " +
event.originalTarget.location +
" had an unexpected value"
);
}
if ("visibilityState" in expected) {
is(event.originalTarget.visibilityState, expected.visibilityState,
"The visibilityState property of the document on page " +
event.originalTarget.location + " had an unexpected value");
is(
event.originalTarget.visibilityState,
expected.visibilityState,
"The visibilityState property of the document on page " +
event.originalTarget.location +
" had an unexpected value"
);
}
if ("hidden" in expected) {
is(event.originalTarget.hidden, expected.hidden,
"The hidden property of the document on page " +
event.originalTarget.location + " had an unexpected value");
is(
event.originalTarget.hidden,
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 (gExpectedEvents.length == 0)
waitForNextPaint(function() { gFinalEvent = true; });
if (gExpectedEvents.length == 0) {
waitForNextPaint(function() {
gFinalEvent = true;
});
}
}
/**
@ -344,9 +450,11 @@ function finish() {
// If the test changed the value of max_total_viewers via a call to
// enableBFCache(), then restore it now.
if (typeof(gOrigMaxTotalViewers) != "undefined") {
Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers",
gOrigMaxTotalViewers);
if (typeof gOrigMaxTotalViewers != "undefined") {
Services.prefs.setIntPref(
"browser.sessionhistory.max_total_viewers",
gOrigMaxTotalViewers
);
}
// Close the test window and signal the framework that the test is done.
@ -383,33 +491,31 @@ function finish() {
*/
function waitForTrue(fn, onWaitComplete, timeout) {
var start = new Date().valueOf();
if (typeof(timeout) != "undefined") {
if (typeof timeout != "undefined") {
// If timeoutWait is less than 500, assume it represents seconds, and
// convert to ms.
if (timeout < 500)
if (timeout < 500) {
timeout *= 1000;
}
}
// Loop until the test function returns true, or until a timeout occurs,
// if a timeout is defined.
var intervalid;
intervalid =
setInterval(
function() {
var timeoutHit = false;
if (typeof(timeout) != "undefined") {
timeoutHit = new Date().valueOf() - start >=
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);
onWaitComplete.call();
}
}, 20);
intervalid = setInterval(function() {
var timeoutHit = false;
if (typeof timeout != "undefined") {
timeoutHit = new Date().valueOf() - start >= 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);
onWaitComplete.call();
}
}, 20);
}
function waitForNextPaint(cb) {
@ -428,18 +534,23 @@ function enableBFCache(enable) {
// If this is the first time the test called enableBFCache(),
// store the original value of max_total_viewers, so it can
// be restored at the end of the test.
if (typeof(gOrigMaxTotalViewers) == "undefined") {
gOrigMaxTotalViewers =
Services.prefs.getIntPref("browser.sessionhistory.max_total_viewers");
if (typeof gOrigMaxTotalViewers == "undefined") {
gOrigMaxTotalViewers = Services.prefs.getIntPref(
"browser.sessionhistory.max_total_viewers"
);
}
if (typeof(enable) == "boolean") {
if (enable)
if (typeof enable == "boolean") {
if (enable) {
Services.prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1);
else
} else {
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");
form.action = target_url;
form.method = "POST";
form.target = name; document.body.appendChild(form);
form.target = name;
document.body.appendChild(form);
form.submit();
}
@ -48,7 +49,7 @@ function navigateByHyperlink(name) {
link.target = name;
link.id = "navigation_hyperlink_" + hyperlink_count++;
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) {
var result = null;
try {
result = await SpecialPowers.spawn(
wnd, [], () => this.content.document.body.innerHTML.trim());
result = await SpecialPowers.spawn(wnd, [], () =>
this.content.document.body.innerHTML.trim()
);
} catch (ex) {
result = ex;
}
@ -101,8 +103,9 @@ function isInaccessible(wnd, message) {
/* eslint-disable mozilla/use-services */
function xpcEnumerateContentWindows(callback) {
var Ci = SpecialPowers.Ci;
var ww = SpecialPowers.Cc["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Ci.nsIWindowWatcher);
var ww = SpecialPowers.Cc[
"@mozilla.org/embedcomp/window-watcher;1"
].getService(Ci.nsIWindowWatcher);
var contentWindows = [];
@ -114,8 +117,12 @@ function xpcEnumerateContentWindows(callback) {
var childTreeNode = docshellTreeNode.getChildAt(i);
// we're only interested in content docshells
if (SpecialPowers.unwrap(childTreeNode.itemType) != Ci.nsIDocShellTreeItem.typeContent)
if (
SpecialPowers.unwrap(childTreeNode.itemType) !=
Ci.nsIDocShellTreeItem.typeContent
) {
continue;
}
var webNav = childTreeNode.QueryInterface(Ci.nsIWebNavigation);
contentWindows.push(webNav.document.defaultView);
@ -125,8 +132,9 @@ function xpcEnumerateContentWindows(callback) {
}
}
while (contentWindows.length > 0)
while (contentWindows.length > 0) {
callback(contentWindows.pop());
}
}
/* eslint-enable mozilla/use-services */
@ -135,8 +143,9 @@ function xpcGetFramesByName(name) {
var results = [];
xpcEnumerateContentWindows(function(win) {
if (win.name == name)
if (win.name == name) {
results.push(win);
}
});
return results;
@ -144,9 +153,11 @@ function xpcGetFramesByName(name) {
function xpcCleanupWindows() {
xpcEnumerateContentWindows(function(win) {
if (win.location &&
(win.location.href.endsWith(target_url) ||
win.location.href.endsWith(target_popup_url))) {
if (
win.location &&
(win.location.href.endsWith(target_url) ||
win.location.href.endsWith(target_popup_url))
) {
win.close();
}
});
@ -163,36 +174,41 @@ function xpcWaitForFinishedFrames(callback, numFrames) {
return;
}
if (finishedFrameCount > numFrames)
if (finishedFrameCount > numFrames) {
throw new Error("Too many frames loaded.");
}
}
var finishedWindows = [];
function contains(obj, arr) {
for (var i = 0; i < arr.length; i++) {
if (obj === arr[i])
if (obj === arr[i]) {
return true;
}
}
return false;
}
function searchForFinishedFrames(win) {
if ((win.location.href.endsWith(target_url) ||
win.location.href.endsWith(target_popup_url)) &&
win.document &&
win.document.body &&
(win.document.body.textContent.trim() == body ||
win.document.body.textContent.trim() == popup_body) &&
win.document.readyState == "complete") {
if (
(win.location.href.endsWith(target_url) ||
win.location.href.endsWith(target_popup_url)) &&
win.document &&
win.document.body &&
(win.document.body.textContent.trim() == body ||
win.document.body.textContent.trim() == popup_body) &&
win.document.readyState == "complete"
) {
var windowId = win.windowUtils.outerWindowID;
if (!contains(windowId, finishedWindows)) {
finishedWindows.push(windowId);
frameFinished();
}
}
for (var i = 0; i < win.frames.length; i++)
for (var i = 0; i < win.frames.length; i++) {
searchForFinishedFrames(win.frames[i]);
}
}
function poll() {

View File

@ -12,15 +12,20 @@ var ctx = {};
function nShotsListener(aBrowser, aType, aCallback, aCount) {
let count = aCount;
let removeFunc;
removeFunc = BrowserTestUtils.addContentEventListener(aBrowser, aType, function listenerCallback() {
if (--count == 0) {
removeFunc();
removeFunc = BrowserTestUtils.addContentEventListener(
aBrowser,
aType,
function listenerCallback() {
if (--count == 0) {
removeFunc();
// aCallback is executed asynchronously, which is handy because load
// events fire before mIsDocumentLoaded is actually set to true. :(
executeSoon(aCallback);
}
}, true);
// aCallback is executed asynchronously, which is handy because load
// events fire before mIsDocumentLoaded is actually set to true. :(
executeSoon(aCallback);
}
},
true
);
}
function oneShotListener(aBrowser, aType, aCallback) {
@ -47,8 +52,10 @@ async function step1() {
ctx.tab0 = gBrowser.selectedTab;
ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0);
await BrowserTestUtils.waitForCondition(() => ctx.tab0Browser.docShellIsActive,
"Timed out waiting for initial tab to be active.");
await BrowserTestUtils.waitForCondition(
() => ctx.tab0Browser.docShellIsActive,
"Timed out waiting for initial tab to be active."
);
// Open a New Tab
ctx.tab1 = BrowserTestUtils.addTab(gBrowser, testPath + "bug343515_pg1.html");
@ -57,8 +64,11 @@ async function step1() {
}
function step2() {
is(testPath + "bug343515_pg1.html", ctx.tab1Browser.currentURI.spec,
"Got expected tab 1 url in step 2");
is(
testPath + "bug343515_pg1.html",
ctx.tab1Browser.currentURI.spec,
"Got expected tab 1 url in step 2"
);
// Our current tab 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");
// 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);
// bug343515_pg2.html consists of a page with two iframes,
@ -81,8 +94,11 @@ function step2() {
}
function step3() {
is(testPath + "bug343515_pg2.html", ctx.tab2Browser.currentURI.spec,
"Got expected tab 2 url in step 3");
is(
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
ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
@ -110,7 +126,9 @@ function step3() {
function step4() {
/* eslint-disable no-shadow */
function checkTab2Active(expected) {
return ContentTask.spawn(ctx.tab2Browser, expected, async function(expected) {
return ContentTask.spawn(ctx.tab2Browser, expected, async function(
expected
) {
function isActive(aWindow) {
var docshell = aWindow.docShell;
return docshell.isActive;
@ -118,39 +136,61 @@ function step4() {
let active = expected ? "active" : "inactive";
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);
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(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}`);
}
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(
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 */
is(testPath + "bug343515_pg3.html", ctx.tab2Browser.currentURI.spec,
"Got expected tab 2 url in step 4");
is(
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
ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
// Tab2 and all descendants should be inactive
checkTab2Active(false).then(() => {
// Switch to Tab 2
return BrowserTestUtils.switchTab(gBrowser, ctx.tab2);
}).then(() => {
// Check everything
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");
checkTab2Active(false)
.then(() => {
// Switch to Tab 2
return BrowserTestUtils.switchTab(gBrowser, ctx.tab2);
})
.then(() => {
// Check everything
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);
}).then(() => {
// Go back
waitForPageshow(ctx.tab2Browser, step5);
ctx.tab2Browser.goBack();
});
return checkTab2Active(true);
})
.then(() => {
// Go back
waitForPageshow(ctx.tab2Browser, step5);
ctx.tab2Browser.goBack();
});
}
function step5() {
@ -163,17 +203,22 @@ function step5() {
let docShell = content.frames[i].docShell;
Assert.ok(docShell.isActive, `Tab2 iframe ${i} should be active`);
}
}).then(() => {
// Switch to tab 1
return BrowserTestUtils.switchTab(gBrowser, ctx.tab1);
}).then(() => {
// Navigate to page 3
BrowserTestUtils.loadURI(ctx.tab1Browser, testPath + "bug343515_pg3.html");
})
.then(() => {
// Switch to tab 1
return BrowserTestUtils.switchTab(gBrowser, ctx.tab1);
})
.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
// contains another iframe, so there'll be a total of 4 load events
nShotsListener(ctx.tab1Browser, "load", step6, 4);
});
// 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
nShotsListener(ctx.tab1Browser, "load", step6, 4);
});
}
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].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");
}).then(() => {
ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
return ContentTask.spawn(ctx.tab2Browser, null, async function() {
for (var i = 0; i < content.frames.length; i++) {
let docShell = content.frames[i].docShell;
Assert.ok(!docShell.isActive, `Tab2 iframe ${i} should be inactive`);
}
})
.then(() => {
ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
return ContentTask.spawn(ctx.tab2Browser, null, async function() {
for (var i = 0; i < content.frames.length; i++) {
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() {
/* eslint-disable no-shadow */
function checkBrowser(browser, tabNum, active) {
return ContentTask.spawn(browser, { tabNum, active },
async function({ tabNum, active }) {
function isActive(aWindow) {
var docshell = aWindow.docShell;
return docshell.isActive;
}
return ContentTask.spawn(browser, { tabNum, active }, async function({
tabNum,
active,
}) {
function isActive(aWindow) {
var docshell = aWindow.docShell;
return docshell.isActive;
}
let activestr = active ? "active" : "inactive";
Assert.equal(isActive(content.frames[0]), active,
`Tab${tabNum} iframe 0 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}`);
});
let activestr = active ? "active" : "inactive";
Assert.equal(
isActive(content.frames[0]),
active,
`Tab${tabNum} iframe 0 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 */
// Check everything
ok(!ctx.tab0Browser.docShellIsActive, "Tab 0 should be inactive");
ok(ctx.tab1Browser.docShellIsActive, "Tab 1 should be active");
checkBrowser(ctx.tab1Browser, 1, true).then(() => {
ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
return checkBrowser(ctx.tab2Browser, 2, false);
}).then(() => {
// That's probably enough
allDone();
});
checkBrowser(ctx.tab1Browser, 1, true)
.then(() => {
ok(!ctx.tab2Browser.docShellIsActive, "Tab 2 should be inactive");
return checkBrowser(ctx.tab2Browser, 2, false);
})
.then(() => {
// That's probably enough
allDone();
});
}
function allDone() {
// Close the tabs we made
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
// window instead of a new tab.
await new Promise(resolve => {
SpecialPowers.pushPrefEnv({
"set": [
["browser.link.open_newwindow", 2],
],
}, resolve);
SpecialPowers.pushPrefEnv(
{
set: [["browser.link.open_newwindow", 2]],
},
resolve
);
});
await BrowserTestUtils.withNewTab({
gBrowser,
url: TEST_PAGE,
}, async function(browser) {
let openedPromise = BrowserTestUtils.waitForNewWindow();
BrowserTestUtils.synthesizeMouse("a", 0, 0, {}, browser);
let win = await openedPromise;
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: TEST_PAGE,
},
async function(browser) {
let openedPromise = BrowserTestUtils.waitForNewWindow();
BrowserTestUtils.synthesizeMouse("a", 0, 0, {}, browser);
let win = await openedPromise;
let chromeFlags = win.docShell
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow)
.chromeFlags;
let chromeFlags = win.docShell.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow).chromeFlags;
// In the multi-process case, the new window will have the
// CHROME_REMOTE_WINDOW flag set.
const EXPECTED = gMultiProcessBrowser ? CHROME_ALL | CHROME_REMOTE_WINDOW
: CHROME_ALL;
// In the multi-process case, the new window will have the
// CHROME_REMOTE_WINDOW flag set.
const EXPECTED = gMultiProcessBrowser
? 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
* 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/. */
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var dirSvc = Services.dirSvc;
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");
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);
// Check that decoding a live browsing context produces the correct
// object.
equal(deserialize().browsingContext, browsingContext,
"Got correct browsing context from StructuredClone deserialize");
equal(
deserialize().browsingContext,
browsingContext,
"Got correct browsing context from StructuredClone deserialize"
);
// Check that decoding a second time still succeeds.
equal(deserialize().browsingContext, browsingContext,
"Got correct browsing context from second StructuredClone deserialize");
equal(
deserialize().browsingContext,
browsingContext,
"Got correct browsing context from second StructuredClone deserialize"
);
// Destroy the browsing context and make sure that the decode fails
// 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
// stored in our structured clone data has been destroyed. Make sure
// that attempting to decode it again leads to the appropriate error.
Assert.throws(deserialize, e => e.name === "DataCloneError",
"Should get a DataCloneError when trying to decode a dead BrowsingContext");
Assert.throws(
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"].
getService(Ci.nsIPrefetchService);
var prefetch = Cc["@mozilla.org/prefetch-service;1"].getService(
Ci.nsIPrefetchService
);
function run_test() {
// Fill up the queue

View File

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

View File

@ -1,5 +1,9 @@
const {AddonTestUtils} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm");
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
const { AddonTestUtils } = ChromeUtils.import(
"resource://testing-common/AddonTestUtils.jsm"
);
const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
const kSearchEngineID = "test_urifixup_search_engine";
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.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
// 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
}
*/
var testcases = [ {
var testcases = [
{
input: "http://www.mozilla.org",
fixedURI: "http://www.mozilla.org/",
}, {
},
{
input: "http://127.0.0.1/",
fixedURI: "http://127.0.0.1/",
}, {
},
{
input: "file:///foo/bar",
fixedURI: "file:///foo/bar",
}, {
},
{
input: "://www.mozilla.org",
fixedURI: "http://www.mozilla.org/",
protocolChange: true,
}, {
},
{
input: "www.mozilla.org",
fixedURI: "http://www.mozilla.org/",
protocolChange: true,
}, {
},
{
input: "http://mozilla/",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
}, {
},
{
input: "http://test./",
fixedURI: "http://test./",
alternateURI: "http://www.test./",
}, {
},
{
input: "127.0.0.1",
fixedURI: "http://127.0.0.1/",
protocolChange: true,
}, {
},
{
input: "1.2.3.4/",
fixedURI: "http://1.2.3.4/",
protocolChange: true,
}, {
},
{
input: "1.2.3.4/foo",
fixedURI: "http://1.2.3.4/foo",
protocolChange: true,
}, {
},
{
input: "1.2.3.4:8000",
fixedURI: "http://1.2.3.4:8000/",
protocolChange: true,
}, {
},
{
input: "1.2.3.4:8000/",
fixedURI: "http://1.2.3.4:8000/",
protocolChange: true,
}, {
},
{
input: "1.2.3.4:8000/foo",
fixedURI: "http://1.2.3.4:8000/foo",
protocolChange: true,
}, {
},
{
input: "192.168.10.110",
fixedURI: "http://192.168.10.110/",
protocolChange: true,
}, {
},
{
input: "192.168.10.110/123",
fixedURI: "http://192.168.10.110/123",
protocolChange: true,
}, {
},
{
input: "192.168.10.110/123foo",
fixedURI: "http://192.168.10.110/123foo",
protocolChange: true,
}, {
},
{
input: "192.168.10.110:1234/123",
fixedURI: "http://192.168.10.110:1234/123",
protocolChange: true,
}, {
},
{
input: "192.168.10.110:1234/123foo",
fixedURI: "http://192.168.10.110:1234/123foo",
protocolChange: true,
}, {
},
{
input: "1.2.3",
fixedURI: "http://1.2.0.3/",
protocolChange: true,
}, {
},
{
input: "1.2.3/",
fixedURI: "http://1.2.0.3/",
protocolChange: true,
}, {
},
{
input: "1.2.3/foo",
fixedURI: "http://1.2.0.3/foo",
protocolChange: true,
}, {
},
{
input: "1.2.3/123",
fixedURI: "http://1.2.0.3/123",
protocolChange: true,
}, {
},
{
input: "1.2.3:8000",
fixedURI: "http://1.2.0.3:8000/",
protocolChange: true,
}, {
},
{
input: "1.2.3:8000/",
fixedURI: "http://1.2.0.3:8000/",
protocolChange: true,
}, {
},
{
input: "1.2.3:8000/foo",
fixedURI: "http://1.2.0.3:8000/foo",
protocolChange: true,
}, {
},
{
input: "1.2.3:8000/123",
fixedURI: "http://1.2.0.3:8000/123",
protocolChange: true,
}, {
},
{
input: "http://1.2.3",
fixedURI: "http://1.2.0.3/",
}, {
},
{
input: "http://1.2.3/",
fixedURI: "http://1.2.0.3/",
}, {
},
{
input: "http://1.2.3/foo",
fixedURI: "http://1.2.0.3/foo",
}, {
},
{
input: "[::1]",
fixedURI: "http://[::1]/",
alternateURI: "http://[::1]/",
protocolChange: true,
}, {
},
{
input: "[::1]/",
fixedURI: "http://[::1]/",
alternateURI: "http://[::1]/",
protocolChange: true,
}, {
},
{
input: "[::1]:8000",
fixedURI: "http://[::1]:8000/",
protocolChange: true,
}, {
},
{
input: "[::1]:8000/",
fixedURI: "http://[::1]:8000/",
protocolChange: true,
}, {
},
{
input: "[[::1]]/",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "[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]/",
protocolChange: true,
}, {
},
{
input: "[64:ff9b::8.8.8.8]",
fixedURI: "http://[64:ff9b::808:808]/",
alternateURI: "http://[64:ff9b::808:808]/",
protocolChange: true,
}, {
},
{
input: "[64:ff9b::8.8.8.8]/~moz",
fixedURI: "http://[64:ff9b::808:808]/~moz",
alternateURI: "http://[64:ff9b::808:808]/~moz",
protocolChange: true,
}, {
},
{
input: "[::1][::1]",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "[::1][100",
fixedURI: null,
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "[::1]]",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "1234",
fixedURI: "http://0.0.4.210/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "host/foo.txt",
fixedURI: "http://host/foo.txt",
alternateURI: "http://www.host.com/foo.txt",
protocolChange: true,
}, {
},
{
input: "mozilla",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "test.",
fixedURI: "http://test./",
alternateURI: "http://www.test./",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: ".test",
fixedURI: "http://.test/",
alternateURI: "http://www..test/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "mozilla is amazing",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "search ?mozilla",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "mozilla .com",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "what if firefox?",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "london's map",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "mozilla ",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: " mozilla ",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "mozilla \\",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "mozilla \\ foo.txt",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "mozilla \\\r foo.txt",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "mozilla\n",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "mozilla \r\n",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "moz\r\nfirefox\nos\r",
fixedURI: "http://mozfirefoxos/",
alternateURI: "http://www.mozfirefoxos.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "moz\r\n firefox\n",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "[]",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "http://whitelisted/",
fixedURI: "http://whitelisted/",
alternateURI: "http://www.whitelisted.com/",
inWhitelist: true,
}, {
},
{
input: "café.local",
fixedURI: "http://xn--caf-dma.local/",
alternateURI: "http://www.xn--caf-dma.local/",
protocolChange: true,
}, {
},
{
input: "47.6182,-122.830",
fixedURI: "http://47.6182,-122.830/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "-47.6182,-23.51",
fixedURI: "http://-47.6182,-23.51/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "-22.14,23.51-",
fixedURI: "http://-22.14,23.51-/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "32.7",
fixedURI: "http://32.0.0.7/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "5+2",
fixedURI: "http://5+2/",
alternateURI: "http://www.5+2.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "5/2",
fixedURI: "http://0.0.0.5/2",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "moz ?.::%27",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "mozilla.com/?q=search",
fixedURI: "http://mozilla.com/?q=search",
alternateURI: "http://www.mozilla.com/?q=search",
protocolChange: true,
}, {
},
{
input: "mozilla.com?q=search",
fixedURI: "http://mozilla.com/?q=search",
alternateURI: "http://www.mozilla.com/?q=search",
protocolChange: true,
}, {
},
{
input: "mozilla.com ?q=search",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "mozilla.com.?q=search",
fixedURI: "http://mozilla.com./?q=search",
protocolChange: true,
}, {
},
{
input: "mozilla.com'?q=search",
fixedURI: "http://mozilla.com'/?q=search",
alternateURI: "http://www.mozilla.com'/?q=search",
protocolChange: true,
}, {
},
{
input: "mozilla.com':search",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "[mozilla]",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "':?",
fixedURI: "http://'/?",
alternateURI: "http://www.'.com/?",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "a?.com",
fixedURI: "http://a/?.com",
alternateURI: "http://www.a.com/?.com",
protocolChange: true,
}, {
},
{
input: "?'.com",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "' ?.com",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "?mozilla",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "??mozilla",
keywordLookup: true,
protocolChange: true,
}, {
},
{
input: "mozilla/",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
protocolChange: true,
}, {
},
{
input: "mozilla",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
protocolChange: true,
keywordLookup: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "mozilla5/2",
fixedURI: "http://mozilla5/2",
alternateURI: "http://www.mozilla5.com/2",
protocolChange: true,
}, {
},
{
input: "mozilla/foo",
fixedURI: "http://mozilla/foo",
alternateURI: "http://www.mozilla.com/foo",
protocolChange: true,
}, {
},
{
input: "mozilla\\",
fixedURI: "http://mozilla/",
alternateURI: "http://www.mozilla.com/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "localhost",
fixedURI: "http://localhost/",
keywordLookup: true,
protocolChange: true,
affectedByDNSForSingleHosts: true,
}, {
},
{
input: "localhost:8080",
fixedURI: "http://localhost:8080/",
protocolChange: true,
}, {
},
{
input: "plonk:8080",
fixedURI: "http://plonk:8080/",
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/",
alternateURI: "http://www.xn--lodaehvb5cdik4g.xn--node/",
protocolChange: true,
@ -500,24 +602,34 @@ function sanitize(input) {
}
add_task(async function setup() {
var prefList = ["browser.fixup.typo.scheme", "keyword.enabled",
"browser.fixup.domainwhitelist.whitelisted"];
var prefList = [
"browser.fixup.typo.scheme",
"keyword.enabled",
"browser.fixup.domainwhitelist.whitelisted",
];
for (let pref of prefList) {
Services.prefs.setBoolPref(pref, true);
}
await AddonTestUtils.promiseStartupManager();
Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler)
.setSubstitution("search-extensions",
Services.io.newURI("chrome://mozapps/locale/searchextensions/"));
Services.io
.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler)
.setSubstitution(
"search-extensions",
Services.io.newURI("chrome://mozapps/locale/searchextensions/")
);
await Services.search.addEngineWithDetails(kSearchEngineID,
{method: "get", template: kSearchEngineURL});
await Services.search.addEngineWithDetails(kSearchEngineID, {
method: "get",
template: kSearchEngineURL,
});
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;
Assert.equal(selectedName, kSearchEngineID);
@ -539,8 +651,12 @@ add_task(async function setup() {
var gSingleWordHostLookup = false;
add_task(async function run_test() {
// 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");
let affectedTests = testcases.filter(t => !t.keywordLookup && t.affectedByDNSForSingleHosts);
info(
"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) {
for (let testcase of affectedTests) {
info("Affected: " + testcase.input);
@ -555,24 +671,28 @@ add_task(async function run_test() {
function do_single_test_run() {
Services.prefs.setBoolPref(kForceHostLookup, gSingleWordHostLookup);
let relevantTests = gSingleWordHostLookup ? testcases.filter(t => t.keywordLookup) :
testcases;
let relevantTests = gSingleWordHostLookup
? testcases.filter(t => t.keywordLookup)
: testcases;
for (let { input: testInput,
fixedURI: expectedFixedURI,
alternateURI: alternativeURI,
keywordLookup: expectKeywordLookup,
protocolChange: expectProtocolChange,
inWhitelist: inWhitelist,
affectedByDNSForSingleHosts: affectedByDNSForSingleHosts,
} of relevantTests) {
for (let {
input: testInput,
fixedURI: expectedFixedURI,
alternateURI: alternativeURI,
keywordLookup: expectKeywordLookup,
protocolChange: expectProtocolChange,
inWhitelist: inWhitelist,
affectedByDNSForSingleHosts: affectedByDNSForSingleHosts,
} of relevantTests) {
// Explicitly force these into a boolean
expectKeywordLookup = !!expectKeywordLookup;
expectProtocolChange = !!expectProtocolChange;
inWhitelist = !!inWhitelist;
affectedByDNSForSingleHosts = !!affectedByDNSForSingleHosts;
expectKeywordLookup = expectKeywordLookup && (!affectedByDNSForSingleHosts || !gSingleWordHostLookup);
expectKeywordLookup =
expectKeywordLookup &&
(!affectedByDNSForSingleHosts || !gSingleWordHostLookup);
for (let flags of flagInputs) {
let URIInfo;
@ -594,47 +714,94 @@ function do_single_test_run() {
continue;
}
info("Checking \"" + testInput + "\" with flags " + flags +
" (host lookup for single words: " + (gSingleWordHostLookup ? "yes" : "no") + ")");
info(
'Checking "' +
testInput +
'" with flags ' +
flags +
" (host lookup for single words: " +
(gSingleWordHostLookup ? "yes" : "no") +
")"
);
// Both APIs should then also be using the same spec.
Assert.equal(!!fixupURIOnly, !!URIInfo.preferredURI);
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:
let makeAlternativeURI = flags & Services.uriFixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI;
let makeAlternativeURI =
flags & Services.uriFixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI;
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 {
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:
let couldDoKeywordLookup = flags & Services.uriFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
Assert.equal(!!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");
let couldDoKeywordLookup =
flags & Services.uriFixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
Assert.equal(
!!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
if (couldDoKeywordLookup) {
if (expectKeywordLookup) {
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
// In order to test this behaviour, remove `?` only if it is the first character
if (urlparamInput.startsWith("%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, "'");
Assert.equal(spec, searchURL, "should get correct search URI");
} else {
Assert.equal(URIInfo.preferredURI, null, "not expecting a preferred URI");
Assert.equal(
URIInfo.preferredURI,
null,
"not expecting a preferred URI"
);
}
} 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 {
// 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;
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 {AddonTestUtils} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm");
const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
const { AddonTestUtils } = ChromeUtils.import(
"resource://testing-common/AddonTestUtils.jsm"
);
const kSearchEngineID = "test_urifixup_search_engine";
const kSearchEngineURL = "http://www.example.org/?search={searchTerms}";
@ -15,7 +19,10 @@ var data = [
{
// Unrecognized protocols should be changed.
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
@ -47,7 +54,8 @@ var data = [
},
{
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",
@ -55,7 +63,9 @@ var data = [
},
{
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",
@ -63,12 +73,16 @@ var data = [
},
{
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"]
.getService(Ci.nsIExternalProtocolService);
var extProtocolSvc = Cc[
"@mozilla.org/uriloader/external-protocol-service;1"
].getService(Ci.nsIExternalProtocolService);
if (extProtocolSvc && extProtocolSvc.externalProtocolHandlerExists("mailto")) {
data.push({
@ -81,22 +95,34 @@ var len = data.length;
AddonTestUtils.init(this);
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() {
await AddonTestUtils.promiseStartupManager();
Services.prefs.setBoolPref("keyword.enabled", true);
Services.io.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler)
.setSubstitution("search-extensions",
Services.io.newURI("chrome://mozapps/locale/searchextensions/"));
Services.io
.getProtocolHandler("resource")
.QueryInterface(Ci.nsIResProtocolHandler)
.setSubstitution(
"search-extensions",
Services.io.newURI("chrome://mozapps/locale/searchextensions/")
);
await Services.search.addEngineWithDetails(kSearchEngineID,
{method: "get", template: kSearchEngineURL});
await Services.search.addEngineWithDetails(kSearchEngineID, {
method: "get",
template: kSearchEngineURL,
});
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;
Assert.equal(selectedName, kSearchEngineID);
@ -117,9 +143,10 @@ add_task(async function setup() {
add_task(function test_fix_unknown_schemes() {
for (let i = 0; i < len; ++i) {
let item = data[i];
let result =
Services.uriFixup.createFixupURI(item.wrong,
Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS).spec;
let result = Services.uriFixup.createFixupURI(
item.wrong,
Services.uriFixup.FIXUP_FLAG_FIX_SCHEME_TYPOS
).spec;
Assert.equal(result, item.fixed);
}
});

View File

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

View File

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

View File

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

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() {
var notifications = 0;
@ -10,9 +10,8 @@ function run_test() {
};
Services.os.addObserver(obs, "last-pb-context-exited");
run_test_in_child("../unit/test_pb_notification.js",
function() {
Assert.equal(notifications, 1);
do_test_finished();
});
run_test_in_child("../unit/test_pb_notification.js", function() {
Assert.equal(notifications, 1);
do_test_finished();
});
}