ChromeUtils.defineESModuleGetters(
this, {
FormHistory:
"resource://gre/modules/FormHistory.sys.mjs",
SearchTestUtils:
"resource://testing-common/SearchTestUtils.sys.mjs",
});
SearchTestUtils.init(
this);
function getCertChainAsString(certBase64Array) {
let certChain =
"";
for (let cert of certBase64Array) {
certChain += getPEMString(cert);
}
return certChain;
}
function getPEMString(derb64) {
// Wrap the Base64 string into lines of 64 characters,
// with CRLF line breaks (as specified in RFC 1421).
var wrapped = derb64.replace(/(\S{
64}(?!$))/g,
"$1\r\n");
return (
"-----BEGIN CERTIFICATE-----\r\n" +
wrapped +
"\r\n-----END CERTIFICATE-----\r\n"
);
}
async
function injectErrorPageFrame(tab, src, sandboxed) {
let loadedPromise = BrowserTestUtils.browserLoaded(
tab.linkedBrowser,
true,
null,
true
);
await SpecialPowers.spawn(
tab.linkedBrowser,
[src, sandboxed],
async
function (frameSrc, frameSandboxed) {
let iframe = content.document.createElement(
"iframe");
iframe.src = frameSrc;
if (frameSandboxed) {
iframe.setAttribute(
"sandbox",
"allow-scripts");
}
content.document.body.appendChild(iframe);
}
);
await loadedPromise;
}
async
function openErrorPage(src, useFrame, sandboxed) {
let dummyPage =
getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.com"
) +
"dummy_page.html";
let tab;
if (useFrame) {
info(
"Loading cert error page in an iframe");
tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, dummyPage);
let errorCardReady = BrowserTestUtils.waitForContentEvent(
tab.linkedBrowser,
"AboutNetErrorLoad",
false,
null,
true
);
await injectErrorPageFrame(tab, src, sandboxed);
await errorCardReady;
}
else {
let certErrorLoaded;
tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
() => {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, src);
let browser = gBrowser.selectedBrowser;
certErrorLoaded = BrowserTestUtils.waitForErrorPage(browser);
},
false
);
info(
"Loading and waiting for the cert error");
await certErrorLoaded;
}
return tab;
}
function waitForCondition(condition, nextTest, errorMsg, retryTimes) {
retryTimes =
typeof retryTimes !==
"undefined" ? retryTimes :
30;
var tries =
0;
var interval = setInterval(
function () {
if (tries >= retryTimes) {
ok(
false, errorMsg);
moveOn();
}
var conditionPassed;
try {
conditionPassed = condition();
}
catch (e) {
ok(
false, e +
"\n" + e.stack);
conditionPassed =
false;
}
if (conditionPassed) {
moveOn();
}
tries++;
},
100);
var moveOn =
function () {
clearInterval(interval);
nextTest();
};
}
async
function waitForBookmarksToolbarVisibility({
win = window,
visible,
message,
}) {
let result = await TestUtils.waitForCondition(
() => {
let toolbar = win.document.getElementById(
"PersonalToolbar");
return toolbar && (visible ? !toolbar.collapsed : toolbar.collapsed);
},
message ||
"waiting for toolbar to become " + (visible ?
"visible" :
"hidden")
);
ok(result, message);
return result;
}
function isBookmarksToolbarVisible(win = window) {
let toolbar = win.document.getElementById(
"PersonalToolbar");
return !toolbar.collapsed;
}
const setSecurityCertErrorsFeltPrivacyToTrue = async () =>
await SpecialPowers.pushPrefEnv({
set: [[
"security.certerrors.felt-privacy-v1",
true]],
});
const setSecurityCertErrorsFeltPrivacyToFalse = async () =>
await SpecialPowers.pushPrefEnv({
set: [[
"security.certerrors.felt-privacy-v1",
false]],
});
// -- TRR-only test helpers --
// resetTRRPrefs is set by loadTRRErrorPage() as a closure over the proxy type
// value captured at call time, avoiding shared mutable state.
let resetTRRPrefs = () => {
throw new Error(
"resetTRRPrefs called before loadTRRErrorPage");
};
let _trrDnsOverrideSet =
false;
async
function loadTRRErrorPage() {
const oldProxyType = Services.prefs.getIntPref(
"network.proxy.type");
resetTRRPrefs =
function () {
Services.prefs.clearUserPref(
"network.trr.mode");
Services.prefs.clearUserPref(
"network.dns.native-is-localhost");
Services.prefs.setIntPref(
"network.proxy.type", oldProxyType);
};
registerCleanupFunction(resetTRRPrefs);
// See bug 1831731: prevent real connections to the DoH endpoint.
if (!_trrDnsOverrideSet) {
Cc[
"@mozilla.org/network/native-dns-override;1"]
.getService(Ci.nsINativeDNSResolverOverride)
.addIPOverride(
"mozilla.cloudflare-dns.com",
"127.0.0.1");
_trrDnsOverrideSet =
true;
}
Services.prefs.setBoolPref(
"network.dns.native-is-localhost",
true);
Services.prefs.setIntPref(
"network.trr.mode", Ci.nsIDNSService.MODE_TRRONLY);
// Disable proxy, otherwise TRR isn't used for name resolution.
Services.prefs.setIntPref(
"network.proxy.type",
0);
let browser;
let pageLoaded;
await BrowserTestUtils.openNewForegroundTab(
gBrowser,
() => {
gBrowser.selectedTab = BrowserTestUtils.addTab(
gBrowser,
"https://does-not-exist.test"
);
browser = gBrowser.selectedBrowser;
pageLoaded = BrowserTestUtils.waitForErrorPage(browser);
},
false
);
info(
"Loading and waiting for the TRR net error");
await pageLoaded;
return browser;
}
async
function loadNetErrorPage(errorType, hostAndPort) {
let browser, tab;
const url = `about:neterror?e=${errorType}&u=http%
3A%
2F%
2F${encod
eURIComponent(hostAndPort)}%2F`;
await BrowserTestUtils.openNewForegroundTab(
gBrowser,
() => {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
browser = gBrowser.selectedBrowser;
tab = gBrowser.selectedTab;
},
false
);
const pageLoaded = BrowserTestUtils.waitForErrorPage(browser);
SpecialPowers.spawn(browser, [url], errorUrl => {
content.location = errorUrl;
});
await pageLoaded;
return { browser, tab };
}