diff --git a/devtools/client/aboutdebugging/test/.eslintrc.js b/devtools/client/aboutdebugging/test/.eslintrc.js index 8c4bee0ef57a0..b9d9b5fcf9420 100644 --- a/devtools/client/aboutdebugging/test/.eslintrc.js +++ b/devtools/client/aboutdebugging/test/.eslintrc.js @@ -9,18 +9,15 @@ module.exports = { "addTab": true, "assertHasTarget": true, "CHROME_ROOT": true, - "changeAboutDebuggingHash": true, "closeAboutDebugging": true, "getServiceWorkerList": true, "getSupportsFile": true, "installAddon": true, "openAboutDebugging": true, - "openPanel": true, "removeTab": true, "uninstallAddon": true, "unregisterServiceWorker": true, "waitForInitialAddonList": true, - "waitForMutation": true, "waitForServiceWorkerRegistered": true } }; diff --git a/devtools/client/aboutdebugging/test/browser_page_not_found.js b/devtools/client/aboutdebugging/test/browser_page_not_found.js index 107bc8b915d80..2a126c53d91a0 100644 --- a/devtools/client/aboutdebugging/test/browser_page_not_found.js +++ b/devtools/client/aboutdebugging/test/browser_page_not_found.js @@ -11,25 +11,29 @@ add_task(function* () { let element = document.querySelector(".header-name"); is(element.textContent, "Page not found", "Show error page"); - yield openPanel(document, "addons-panel"); + info("Opening addons-panel panel"); + document.querySelector("[aria-controls='addons-panel']").click(); + yield waitUntilElement("#addons-panel", document); + yield waitForInitialAddonList(document); element = document.querySelector(".header-name"); is(element.textContent, "Add-ons", "Show Addons"); - yield changeAboutDebuggingHash(document, "invalid-hash"); + info("Opening about:debugging#invalid-hash"); + window.openUILinkIn("about:debugging#invalid-hash", "current"); + yield waitUntilElement(".error-page", document); + element = document.querySelector(".header-name"); is(element.textContent, "Page not found", "Show error page"); gBrowser.goBack(); - yield waitForMutation( - document.querySelector(".main-content"), {childList: true}); + yield waitUntilElement("#addons-panel", document); yield waitForInitialAddonList(document); element = document.querySelector(".header-name"); is(element.textContent, "Add-ons", "Show Addons"); gBrowser.goBack(); - yield waitForMutation( - document.querySelector(".main-content"), {childList: true}); + yield waitUntilElement(".error-page", document); element = document.querySelector(".header-name"); is(element.textContent, "Page not found", "Show error page"); diff --git a/devtools/client/aboutdebugging/test/browser_tabs.js b/devtools/client/aboutdebugging/test/browser_tabs.js index 99e76be5d969f..6a1c9934bd1f3 100644 --- a/devtools/client/aboutdebugging/test/browser_tabs.js +++ b/devtools/client/aboutdebugging/test/browser_tabs.js @@ -10,44 +10,30 @@ add_task(function* () { // Wait for initial tabs list which may be empty let tabsElement = getTabList(document); - if (tabsElement.querySelectorAll(".target-name").length == 0) { - yield waitForMutation(tabsElement, { childList: true }); - } + yield waitUntilElement(".target-name", tabsElement); + // Refresh tabsElement to get the .target-list element tabsElement = getTabList(document); let names = [...tabsElement.querySelectorAll(".target-name")]; let initialTabCount = names.length; - // Open a new tab in background and wait for its addition in the UI - let onNewTab = waitForMutation(tabsElement, { childList: true }); + info("Open a new background tab"); let newTab = yield addTab(TAB_URL, { background: true }); - yield onNewTab; - - // Check that the new tab appears in the UI, but with an empty name - let newNames = [...tabsElement.querySelectorAll(".target-name")]; - newNames = newNames.filter(node => !names.includes(node)); - is(newNames.length, 1, "A new tab appeared in the list"); - let newTabTarget = newNames[0]; - - // Then wait for title update, but on slow test runner, the title may already - // be set to the expected value - if (newTabTarget.textContent != "foo") { - yield waitForContentMutation(newTabTarget); - } - // Then wait for title update, but on slow test runner, the title may already - // be set to the expected value - yield waitUntil(() => newTabTarget.title === TAB_URL); + info("Wait for the tab to appear in the list with the correct name"); + let container = yield waitUntilTabContainer("foo", document); - // Check that the new tab appears in the UI - is(newTabTarget.textContent, "foo", "The tab title got updated"); - is(newTabTarget.title, TAB_URL, "The tab tooltip is the url"); + info("Wait until the title to update"); + yield waitUntil(() => { + return container.querySelector(".target-name").title === TAB_URL; + }, 100); // Finally, close the tab - let onTabsUpdate = waitForMutation(tabsElement, { childList: true }); yield removeTab(newTab); - yield onTabsUpdate; + + info("Wait until the tab container is removed"); + yield waitUntil(() => !getTabContainer("foo", document), 100); // Check that the tab disappeared from the UI names = [...tabsElement.querySelectorAll("#tabs .target-name")]; @@ -55,3 +41,20 @@ add_task(function* () { yield closeAboutDebugging(tab); }); + +function getTabContainer(name, document) { + let nameElements = [...document.querySelectorAll("#tabs .target-name")]; + let nameElement = nameElements.filter(element => element.textContent === name)[0]; + if (nameElement) { + return nameElement.closest(".target-container"); + } + + return null; +} + +function* waitUntilTabContainer(name, document) { + yield waitUntil(() => { + return getTabContainer(name, document); + }); + return getTabContainer(name, document); +} diff --git a/devtools/client/aboutdebugging/test/head.js b/devtools/client/aboutdebugging/test/head.js index 12664c9fbd5eb..9c5ab4e4d746c 100644 --- a/devtools/client/aboutdebugging/test/head.js +++ b/devtools/client/aboutdebugging/test/head.js @@ -32,34 +32,12 @@ function* openAboutDebugging(page, win) { let document = browser.contentDocument; let window = browser.contentWindow; - if (!document.querySelector(".app")) { - yield waitForMutation(document.body, { childList: true }); - } + info("Wait until the main about debugging container is available"); + yield waitUntilElement(".app", document); return { tab, document, window }; } -/** - * Change url hash for current about:debugging tab, return a promise after - * new content is loaded. - * @param {DOMDocument} document container document from current tab - * @param {String} hash hash for about:debugging - * @return {Promise} - */ -function changeAboutDebuggingHash(document, hash) { - info(`Opening about:debugging#${hash}`); - window.openUILinkIn(`about:debugging#${hash}`, "current"); - return waitForMutation( - document.querySelector(".main-content"), {childList: true}); -} - -function openPanel(document, panelId) { - info(`Opening ${panelId} panel`); - document.querySelector(`[aria-controls="${panelId}"]`).click(); - return waitForMutation( - document.querySelector(".main-content"), {childList: true}); -} - function closeAboutDebugging(tab) { info("Closing about:debugging"); return removeTab(tab); @@ -289,39 +267,6 @@ function* waitUntilAddonContainer(name, document) { return getAddonContainer(name, document); } -/** - * Returns a promise that will resolve after receiving a mutation matching the - * provided mutation options on the provided target. - * @param {Node} target - * @param {Object} mutationOptions - * @return {Promise} - */ -function waitForMutation(target, mutationOptions) { - return new Promise(resolve => { - let observer = new MutationObserver(() => { - observer.disconnect(); - resolve(); - }); - observer.observe(target, mutationOptions); - }); -} - -/** - * Returns a promise that will resolve after receiving a mutation in the subtree of the - * provided target. Depending on the current React implementation, a text change might be - * observable as a childList mutation or a characterData mutation. - * - * @param {Node} target - * @return {Promise} - */ -function waitForContentMutation(target) { - return waitForMutation(target, { - characterData: true, - childList: true, - subtree: true - }); -} - /** * Checks if an about:debugging TargetList element contains a Target element * corresponding to the specified name.