diff options
Diffstat (limited to 'devtools/startup/aboutdevtools/test')
7 files changed, 331 insertions, 0 deletions
diff --git a/devtools/startup/aboutdevtools/test/.eslintrc.js b/devtools/startup/aboutdevtools/test/.eslintrc.js new file mode 100644 index 0000000000..3d0bd99e1b --- /dev/null +++ b/devtools/startup/aboutdevtools/test/.eslintrc.js @@ -0,0 +1,6 @@ +"use strict"; + +module.exports = { + // Extend from the shared list of defined globals for mochitests. + extends: "../../../.eslintrc.mochitests.js", +}; diff --git a/devtools/startup/aboutdevtools/test/browser.ini b/devtools/startup/aboutdevtools/test/browser.ini new file mode 100644 index 0000000000..bcac4d3fbf --- /dev/null +++ b/devtools/startup/aboutdevtools/test/browser.ini @@ -0,0 +1,11 @@ +[DEFAULT] +tags = devtools +subsuite = devtools +support-files = + head.js + +[browser_aboutdevtools_closes_page.js] +[browser_aboutdevtools_enables_devtools.js] +[browser_aboutdevtools_focus_owner_tab.js] +[browser_aboutdevtools_reuse_existing.js] +skip-if = (verify && (os == 'mac' || os == 'linux')) diff --git a/devtools/startup/aboutdevtools/test/browser_aboutdevtools_closes_page.js b/devtools/startup/aboutdevtools/test/browser_aboutdevtools_closes_page.js new file mode 100644 index 0000000000..baa8f3f43e --- /dev/null +++ b/devtools/startup/aboutdevtools/test/browser_aboutdevtools_closes_page.js @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* eslint-env browser */ + +add_task(async function() { + pushPref("devtools.enabled", false); + + const { doc, win } = await openAboutDevTools(); + + info("Check that the close button is available on the page"); + const closeButton = doc.getElementById("close"); + ok(closeButton, "close button is displayed"); + + const onWindowUnload = new Promise(r => + win.addEventListener("unload", r, { once: true }) + ); + info("Click on the install button to enable DevTools."); + EventUtils.synthesizeMouseAtCenter(closeButton, {}, win); + + info("Wait for the about:devtools tab to be closed"); + await onWindowUnload; +}); diff --git a/devtools/startup/aboutdevtools/test/browser_aboutdevtools_enables_devtools.js b/devtools/startup/aboutdevtools/test/browser_aboutdevtools_enables_devtools.js new file mode 100644 index 0000000000..e0f7324ed8 --- /dev/null +++ b/devtools/startup/aboutdevtools/test/browser_aboutdevtools_enables_devtools.js @@ -0,0 +1,39 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* eslint-env browser */ + +add_task(async function() { + pushPref("devtools.enabled", false); + + const { tab, doc, win } = await openAboutDevTools(); + + const installPage = doc.getElementById("install-page"); + const welcomePage = doc.getElementById("welcome-page"); + + info( + "Check that about:devtools is in the correct state with devtools.enabled=false" + ); + ok(!installPage.hasAttribute("hidden"), "install screen is visible"); + ok(welcomePage.hasAttribute("hidden"), "welcome screen is hidden"); + + info("Click on the install button to enable DevTools."); + const installButton = doc.getElementById("install"); + EventUtils.synthesizeMouseAtCenter(installButton, {}, win); + + info("Wait until the UI updates"); + await waitUntil(() => installPage.hasAttribute("hidden") === true); + ok(!welcomePage.hasAttribute("hidden"), "welcome screen is visible"); + ok( + Services.prefs.getBoolPref("devtools.enabled"), + "The preference devtools.enabled has been flipped to true." + ); + + // Flip the devtools.enabled preference back to false, otherwise the pushPref cleanup + // times out. + Services.prefs.setBoolPref("devtools.enabled", false); + + await removeTab(tab); +}); diff --git a/devtools/startup/aboutdevtools/test/browser_aboutdevtools_focus_owner_tab.js b/devtools/startup/aboutdevtools/test/browser_aboutdevtools_focus_owner_tab.js new file mode 100644 index 0000000000..d0d9a96d79 --- /dev/null +++ b/devtools/startup/aboutdevtools/test/browser_aboutdevtools_focus_owner_tab.js @@ -0,0 +1,91 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* eslint-env browser */ + +/** + * When closing about:devtools, test that the tab where the user triggered about:devtools + * is selected again. + */ +add_task(async function() { + await pushPref("devtools.enabled", false); + + info("Add an about:blank tab"); + const tab1 = await addTab("data:text/html;charset=utf-8,tab1"); + const tab2 = await addTab("data:text/html;charset=utf-8,tab2"); + ok( + tab1 === gBrowser.tabs[1], + "tab1 is the second tab in the current browser window" + ); + + info("Select the first tab"); + gBrowser.selectedTab = tab1; + + synthesizeToggleToolboxKey(); + + info("Wait for the about:devtools tab to be selected"); + await waitUntil(() => isAboutDevtoolsTab(gBrowser.selectedTab)); + info("about:devtools was opened as expected."); + + const aboutDevtoolsTab = gBrowser.selectedTab; + ok( + aboutDevtoolsTab === gBrowser.tabs[2], + "about:devtools was opened next to its owner tab" + ); + + info("Move the owner tab to the end of the tabs array."); + gBrowser.moveTabTo(tab1, gBrowser.tabs.length - 1); + await removeTab(aboutDevtoolsTab); + + await waitUntil(() => tab1 == gBrowser.selectedTab); + info("The correct tab was selected after closing about:devtools."); + + await removeTab(tab1); + await removeTab(tab2); +}); + +/** + * When closing about:devtools, test that the current tab is not updated if + * about:devtools was not the selectedTab. + */ +add_task(async function() { + await pushPref("devtools.enabled", false); + + info("Add an about:blank tab"); + const tab1 = await addTab("data:text/html;charset=utf-8,tab1"); + const tab2 = await addTab("data:text/html;charset=utf-8,tab2"); + ok( + tab1 === gBrowser.tabs[1], + "tab1 is the second tab in the current browser window" + ); + + info("Select the first tab"); + gBrowser.selectedTab = tab1; + + synthesizeToggleToolboxKey(); + + info("Wait for the about:devtools tab to be selected"); + await waitUntil(() => isAboutDevtoolsTab(gBrowser.selectedTab)); + info("about:devtools was opened as expected."); + + const aboutDevtoolsTab = gBrowser.selectedTab; + ok( + aboutDevtoolsTab === gBrowser.tabs[2], + "about:devtools was opened next to its owner tab" + ); + + info("Select the second tab"); + gBrowser.selectedTab = tab2; + + const aboutDevtoolsDocument = aboutDevtoolsTab.linkedBrowser.contentDocument; + await waitUntil(() => aboutDevtoolsDocument.visibilityState === "hidden"); + + await removeTab(aboutDevtoolsTab); + + ok(tab2 == gBrowser.selectedTab, "Tab 2 should still be selected."); + + await removeTab(tab1); + await removeTab(tab2); +}); diff --git a/devtools/startup/aboutdevtools/test/browser_aboutdevtools_reuse_existing.js b/devtools/startup/aboutdevtools/test/browser_aboutdevtools_reuse_existing.js new file mode 100644 index 0000000000..96c7ddc10c --- /dev/null +++ b/devtools/startup/aboutdevtools/test/browser_aboutdevtools_reuse_existing.js @@ -0,0 +1,46 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/* eslint-env browser */ + +/** + * Test that only one tab of about:devtools is used for a given window. + */ +add_task(async function() { + await pushPref("devtools.enabled", false); + + info("Add an about:blank tab"); + const tab = await addTab("about:blank"); + + synthesizeToggleToolboxKey(); + + info("Wait for the about:devtools tab to be selected"); + await waitUntil(() => isAboutDevtoolsTab(gBrowser.selectedTab)); + + // Keep a reference on this tab to assert it later on. + const aboutDevtoolsTab = gBrowser.selectedTab; + + info("Select the about:blank tab again"); + gBrowser.selectedTab = tab; + + synthesizeToggleToolboxKey(); + + info("Wait for the about:devtools tab to be selected"); + await waitUntil(() => isAboutDevtoolsTab(gBrowser.selectedTab)); + + // filter is not available on gBrowser.tabs. + const aboutDevtoolsTabs = [...gBrowser.tabs].filter(isAboutDevtoolsTab); + ok( + aboutDevtoolsTabs.length === 1, + "Only one tab of about:devtools was opened." + ); + ok( + aboutDevtoolsTabs[0] === aboutDevtoolsTab, + "The existing about:devtools tab was reused." + ); + + await removeTab(aboutDevtoolsTab); + await removeTab(tab); +}); diff --git a/devtools/startup/aboutdevtools/test/head.js b/devtools/startup/aboutdevtools/test/head.js new file mode 100644 index 0000000000..d5f85d0aca --- /dev/null +++ b/devtools/startup/aboutdevtools/test/head.js @@ -0,0 +1,113 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint no-unused-vars: [2, {"vars": "local"}] */ + +"use strict"; + +// All test are asynchronous +waitForExplicitFinish(); + +/** + * Waits until a predicate returns true. + * + * @param function predicate + * Invoked once in a while until it returns true. + * @param number interval [optional] + * How often the predicate is invoked, in milliseconds. + */ +const waitUntil = function(predicate, interval = 100) { + if (predicate()) { + return Promise.resolve(true); + } + return new Promise(resolve => { + setTimeout(function() { + waitUntil(predicate, interval).then(() => resolve(true)); + }, interval); + }); +}; + +/** + * Open the provided url in a new tab. + */ +const addTab = async function(url) { + info("Adding a new tab with URL: " + url); + + const { gBrowser } = window; + + const tab = BrowserTestUtils.addTab(gBrowser, url); + gBrowser.selectedTab = tab; + + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + + info("Tab added and finished loading"); + + return tab; +}; + +/** + * Remove the given tab. + * @param {Object} tab The tab to be removed. + * @return Promise<undefined> resolved when the tab is successfully removed. + */ +const removeTab = async function(tab) { + info("Removing tab."); + + const { gBrowser } = tab.ownerGlobal; + + await new Promise(resolve => { + gBrowser.tabContainer.addEventListener("TabClose", resolve, { once: true }); + gBrowser.removeTab(tab); + }); + + info("Tab removed and finished closing"); +}; + +/** + * Open a new tab on about:devtools + */ +const openAboutDevTools = async function() { + info("Open about:devtools programmatically in a new tab"); + const tab = await addTab("about:devtools"); + + const browser = tab.linkedBrowser; + const doc = browser.contentDocument; + const win = browser.contentWindow; + + return { tab, doc, win }; +}; + +/** + * Copied from devtools shared-head.js. + * Set a temporary value for a preference, that will be cleaned up after the test. + */ +const pushPref = function(preferenceName, value) { + return new Promise(resolve => { + const options = { set: [[preferenceName, value]] }; + SpecialPowers.pushPrefEnv(options, resolve); + }); +}; + +/** + * Helper to call the toggle devtools shortcut. + */ +function synthesizeToggleToolboxKey() { + info("Trigger the toogle toolbox shortcut"); + if (Services.appinfo.OS == "Darwin") { + EventUtils.synthesizeKey("i", { accelKey: true, altKey: true }); + } else { + EventUtils.synthesizeKey("i", { accelKey: true, shiftKey: true }); + } +} + +/** + * Helper to check if a given tab is about:devtools. + */ +function isAboutDevtoolsTab(tab) { + const browser = tab.linkedBrowser; + // browser.documentURI might be unavailable if the tab is loading. + if (browser && browser.documentURI) { + const location = browser.documentURI.spec; + return location.startsWith("about:devtools"); + } + return false; +} |