diff options
Diffstat (limited to 'browser/modules/test/browser_SelfSupportBackend.js')
-rw-r--r-- | browser/modules/test/browser_SelfSupportBackend.js | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/browser/modules/test/browser_SelfSupportBackend.js b/browser/modules/test/browser_SelfSupportBackend.js new file mode 100644 index 000000000..9e2c1d181 --- /dev/null +++ b/browser/modules/test/browser_SelfSupportBackend.js @@ -0,0 +1,214 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +// Pass an empty scope object to the import to prevent "leaked window property" +// errors in tests. +var Preferences = Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences; +var PromiseUtils = Cu.import("resource://gre/modules/PromiseUtils.jsm", {}).PromiseUtils; +var SelfSupportBackend = + Cu.import("resource:///modules/SelfSupportBackend.jsm", {}).SelfSupportBackend; + +const PREF_SELFSUPPORT_ENABLED = "browser.selfsupport.enabled"; +const PREF_SELFSUPPORT_URL = "browser.selfsupport.url"; +const PREF_UITOUR_ENABLED = "browser.uitour.enabled"; + +const TEST_WAIT_RETRIES = 60; + +const TEST_PAGE_URL = getRootDirectory(gTestPath) + "uitour.html"; +const TEST_PAGE_URL_HTTPS = TEST_PAGE_URL.replace("chrome://mochitests/content/", "https://example.com/"); + +function sendSessionRestoredNotification() { + let selfSupportBackendImpl = + Cu.import("resource:///modules/SelfSupportBackend.jsm", {}).SelfSupportBackendInternal; + selfSupportBackendImpl.observe(null, "sessionstore-windows-restored", null); +} + +/** + * Find a browser, with an IFRAME as parent, who has aURL as the source attribute. + * + * @param aURL The URL to look for to identify the browser. + * + * @returns {Object} The browser element or null on failure. + */ +function findSelfSupportBrowser(aURL) { + let frames = Services.appShell.hiddenDOMWindow.document.querySelectorAll('iframe'); + for (let frame of frames) { + try { + let browser = frame.contentDocument.getElementById("win").querySelectorAll('browser')[0]; + let url = browser.getAttribute("src"); + if (url == aURL) { + return browser; + } + } catch (e) { + continue; + } + } + return null; +} + +/** + * Wait for self support page to load. + * + * @param aURL The URL to look for to identify the browser. + * + * @returns {Promise} Return a promise which is resolved when SelfSupport page is fully + * loaded. + */ +function promiseSelfSupportLoad(aURL) { + return new Promise((resolve, reject) => { + // Find the SelfSupport browser. + let browserPromise = waitForConditionPromise(() => !!findSelfSupportBrowser(aURL), + "SelfSupport browser not found.", + TEST_WAIT_RETRIES); + + // Once found, append a "load" listener to catch page loads. + browserPromise.then(() => { + let browser = findSelfSupportBrowser(aURL); + if (browser.contentDocument.readyState === "complete") { + resolve(browser); + } else { + let handler = () => { + browser.removeEventListener("load", handler, true); + resolve(browser); + }; + browser.addEventListener("load", handler, true); + } + }, reject); + }); +} + +/** + * Wait for self support to close. + * + * @param aURL The URL to look for to identify the browser. + * + * @returns {Promise} Return a promise which is resolved when SelfSupport browser cannot + * be found anymore. + */ +function promiseSelfSupportClose(aURL) { + return waitForConditionPromise(() => !findSelfSupportBrowser(aURL), + "SelfSupport browser is still open.", TEST_WAIT_RETRIES); +} + +/** + * Prepare the test environment. + */ +add_task(function* setupEnvironment() { + // We always run the SelfSupportBackend in tests to check for weird behaviours. + // Disable it to test its start-up. + SelfSupportBackend.uninit(); + + // Testing prefs are set via |user_pref|, so we need to get their value in order + // to restore them. + let selfSupportEnabled = Preferences.get(PREF_SELFSUPPORT_ENABLED, true); + let uitourEnabled = Preferences.get(PREF_UITOUR_ENABLED, false); + let selfSupportURL = Preferences.get(PREF_SELFSUPPORT_URL, ""); + + // Enable the SelfSupport backend and set the page URL. We also make sure UITour + // is enabled. + Preferences.set(PREF_SELFSUPPORT_ENABLED, true); + Preferences.set(PREF_UITOUR_ENABLED, true); + Preferences.set(PREF_SELFSUPPORT_URL, TEST_PAGE_URL_HTTPS); + + // Whitelist the HTTPS page to use UITour. + let pageURI = Services.io.newURI(TEST_PAGE_URL_HTTPS, null, null); + Services.perms.add(pageURI, "uitour", Services.perms.ALLOW_ACTION); + + registerCleanupFunction(() => { + Services.perms.remove(pageURI, "uitour"); + Preferences.set(PREF_SELFSUPPORT_ENABLED, selfSupportEnabled); + Preferences.set(PREF_UITOUR_ENABLED, uitourEnabled); + Preferences.set(PREF_SELFSUPPORT_URL, selfSupportURL); + }); +}); + +/** + * Test that the self support page can use the UITour API and close itself. + */ +add_task(function* test_selfSupport() { + // Initialise the SelfSupport backend and trigger the load. + SelfSupportBackend.init(); + + // SelfSupportBackend waits for "sessionstore-windows-restored" to start loading. Send it. + info("Sending sessionstore-windows-restored"); + sendSessionRestoredNotification(); + + // Wait for the SelfSupport page to load. + info("Waiting for the SelfSupport local page to load."); + let selfSupportBrowser = yield promiseSelfSupportLoad(TEST_PAGE_URL_HTTPS); + Assert.ok(!!selfSupportBrowser, "SelfSupport browser must exist."); + + // Get a reference to the UITour API. + info("Testing access to the UITour API."); + let contentWindow = + Cu.waiveXrays(selfSupportBrowser.contentDocument.defaultView); + let uitourAPI = contentWindow.Mozilla.UITour; + + // Test the UITour API with a ping. + let pingPromise = new Promise((resolve) => { + uitourAPI.ping(resolve); + }); + yield pingPromise; + info("Ping succeeded"); + + let observePromise = ContentTask.spawn(selfSupportBrowser, null, function* checkObserve() { + yield new Promise(resolve => { + let win = Cu.waiveXrays(content); + win.Mozilla.UITour.observe((event, data) => { + if (event != "Heartbeat:Engaged") { + return; + } + Assert.equal(data.flowId, "myFlowID", "Check flowId"); + Assert.ok(!!data.timestamp, "Check timestamp"); + resolve(data); + }, () => {}); + }); + }); + + info("Notifying Heartbeat:Engaged"); + UITour.notify("Heartbeat:Engaged", { + flowId: "myFlowID", + timestamp: Date.now(), + }); + yield observePromise; + info("Observed in the hidden frame"); + + // Close SelfSupport from content. + contentWindow.close(); + + // Wait until SelfSupport closes. + info("Waiting for the SelfSupport to close."); + yield promiseSelfSupportClose(TEST_PAGE_URL_HTTPS); + + // Find the SelfSupport browser, again. We don't expect to find it. + selfSupportBrowser = findSelfSupportBrowser(TEST_PAGE_URL_HTTPS); + Assert.ok(!selfSupportBrowser, "SelfSupport browser must not exist."); + + // We shouldn't need this, but let's keep it to make sure closing SelfSupport twice + // doesn't create any problem. + SelfSupportBackend.uninit(); +}); + +/** + * Test that SelfSupportBackend only allows HTTPS. + */ +add_task(function* test_selfSupport_noHTTPS() { + Preferences.set(PREF_SELFSUPPORT_URL, TEST_PAGE_URL); + + SelfSupportBackend.init(); + + // SelfSupportBackend waits for "sessionstore-windows-restored" to start loading. Send it. + info("Sending sessionstore-windows-restored"); + sendSessionRestoredNotification(); + + // Find the SelfSupport browser. We don't expect to find it since we are not using https. + let selfSupportBrowser = findSelfSupportBrowser(TEST_PAGE_URL); + Assert.ok(!selfSupportBrowser, "SelfSupport browser must not exist."); + + // We shouldn't need this, but let's keep it to make sure closing SelfSupport twice + // doesn't create any problem. + SelfSupportBackend.uninit(); +}) |