diff options
Diffstat (limited to 'browser/base/content/test/about/head.js')
-rw-r--r-- | browser/base/content/test/about/head.js | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/browser/base/content/test/about/head.js b/browser/base/content/test/about/head.js new file mode 100644 index 0000000000..60b152fdf9 --- /dev/null +++ b/browser/base/content/test/about/head.js @@ -0,0 +1,278 @@ +/* eslint-env mozilla/frame-script */ + +XPCOMUtils.defineLazyModuleGetters(this, { + FormHistory: "resource://gre/modules/FormHistory.jsm", +}); + +function getSecurityInfo(securityInfoAsString) { + const serhelper = Cc[ + "@mozilla.org/network/serialization-helper;1" + ].getService(Ci.nsISerializationHelper); + let securityInfo = serhelper.deserializeObject(securityInfoAsString); + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + return securityInfo; +} + +function getCertChain(securityInfoAsString) { + let certChain = ""; + let securityInfo = getSecurityInfo(securityInfoAsString); + for (let cert of securityInfo.failedCertChain) { + certChain += getPEMString(cert); + } + return certChain; +} + +function getPEMString(cert) { + var derb64 = cert.getBase64DERString(); + // 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); + await injectErrorPageFrame(tab, src, sandboxed); + } 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(); + }; +} + +function whenTabLoaded(aTab, aCallback) { + promiseTabLoadEvent(aTab).then(aCallback); +} + +function promiseTabLoaded(aTab) { + return new Promise(resolve => { + whenTabLoaded(aTab, resolve); + }); +} + +/** + * Waits for a load (or custom) event to finish in a given tab. If provided + * load an uri into the tab. + * + * @param tab + * The tab to load into. + * @param [optional] url + * The url to load, or the current url. + * @return {Promise} resolved when the event is handled. + * @resolves to the received event + * @rejects if a valid load event is not received within a meaningful interval + */ +function promiseTabLoadEvent(tab, url) { + info("Wait tab event: load"); + + function handle(loadedUrl) { + if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) { + info(`Skipping spurious load event for ${loadedUrl}`); + return false; + } + + info("Tab event received: load"); + return true; + } + + let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle); + + if (url) { + BrowserTestUtils.loadURI(tab.linkedBrowser, url); + } + + return loaded; +} + +/** + * Wait for the search engine to change. searchEngineChangeFn is a function + * that will be called to change the search engine. + */ +async function promiseContentSearchChange(browser, searchEngineChangeFn) { + // Add an event listener manually then perform the action, rather than using + // BrowserTestUtils.addContentEventListener as that doesn't add the listener + // early enough. + await SpecialPowers.spawn(browser, [], async () => { + // Store the results in a temporary place. + content._searchDetails = { + defaultEnginesList: [], + listener: event => { + if (event.detail.type == "CurrentState") { + content._searchDetails.defaultEnginesList.push( + content.wrappedJSObject.gContentSearchController.defaultEngine.name + ); + } + }, + }; + + // Listen using the system group to ensure that it fires after + // the default behaviour. + content.addEventListener( + "ContentSearchService", + content._searchDetails.listener, + { mozSystemGroup: true } + ); + }); + + let expectedEngineName = await searchEngineChangeFn(); + + await SpecialPowers.spawn( + browser, + [expectedEngineName], + async expectedEngineNameChild => { + await ContentTaskUtils.waitForCondition( + () => + content._searchDetails.defaultEnginesList && + content._searchDetails.defaultEnginesList[ + content._searchDetails.defaultEnginesList.length - 1 + ] == expectedEngineNameChild + ); + content.removeEventListener( + "ContentSearchService", + content._searchDetails.listener, + { mozSystemGroup: true } + ); + delete content._searchDetails; + } + ); +} + +/** + * Wait for the search engine to be added. + */ +async function promiseNewEngine(basename) { + info("Waiting for engine to be added: " + basename); + let url = getRootDirectory(gTestPath) + basename; + let engine; + try { + engine = await Services.search.addOpenSearchEngine(url, ""); + } catch (errCode) { + ok(false, "addEngine failed with error code " + errCode); + throw errCode; + } + + info("Search engine added: " + basename); + registerCleanupFunction(async () => { + try { + await Services.search.removeEngine(engine); + } catch (ex) { + /* Can't remove the engine more than once */ + } + }); + + return engine; +} + +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; +} + +async function waitForBookmarksToolbarVisibilityWithExitConditions({ + win = window, + exitConditions, + message, +}) { + let result = await TestUtils.waitForCondition(() => { + if (exitConditions.earlyExit) { + return exitConditions.earlyExit; + } + let toolbar = win.document.getElementById("PersonalToolbar"); + return ( + toolbar && + (exitConditions.visible ? !toolbar.collapsed : toolbar.collapsed) + ); + }, message || "waiting for toolbar to become " + (exitConditions.visible ? "visible" : "hidden")); + if (exitConditions.earlyExit) { + ok(true, "Early exit condition met"); + } else { + ok(false, message); + } + return exitConditions.earlyExit || result; +} |