forked from mirrors/gecko-dev
		
	 b58db9232d
			
		
	
	
		b58db9232d
		
	
	
	
	
		
			
			Sometimes this entry can be at the bottom of the table and therefore there's no nextSibling. Differential Revision: https://phabricator.services.mozilla.com/D161003
		
			
				
	
	
		
			425 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			425 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* Any copyright is dedicated to the Public Domain.
 | |
|  * http://creativecommons.org/publicdomain/zero/1.0/ */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| async function setup_tab(url) {
 | |
|   info(`Setting up ${url}`);
 | |
|   let tabContent = BrowserTestUtils.addTab(gBrowser, url);
 | |
| 
 | |
|   await BrowserTestUtils.browserLoaded(tabContent.linkedBrowser);
 | |
| 
 | |
|   // For some of these tests we have to wait for the test to consume some
 | |
|   // computation or memory.
 | |
|   await SpecialPowers.spawn(tabContent.linkedBrowser, [], async () => {
 | |
|     await content.wrappedJSObject.waitForTestReady();
 | |
|   });
 | |
| 
 | |
|   return tabContent;
 | |
| }
 | |
| 
 | |
| async function setup_about_performance() {
 | |
|   info("Setting up about:performance");
 | |
|   let tabAboutPerformance = (gBrowser.selectedTab = BrowserTestUtils.addTab(
 | |
|     gBrowser,
 | |
|     "about:performance"
 | |
|   ));
 | |
| 
 | |
|   await BrowserTestUtils.browserLoaded(tabAboutPerformance.linkedBrowser);
 | |
| 
 | |
|   let doc = tabAboutPerformance.linkedBrowser.contentDocument;
 | |
|   let tbody = doc.getElementById("dispatch-tbody");
 | |
| 
 | |
|   // Wait until the table has first been populated.
 | |
|   await TestUtils.waitForCondition(() => tbody.childElementCount);
 | |
| 
 | |
|   // And wait for another update using a mutation observer, to give our newly created test tab some time
 | |
|   // to burn some CPU.
 | |
|   await new Promise(resolve => {
 | |
|     let observer = new doc.ownerGlobal.MutationObserver(() => {
 | |
|       observer.disconnect();
 | |
|       resolve();
 | |
|     });
 | |
|     observer.observe(tbody, { childList: true });
 | |
|   });
 | |
| 
 | |
|   return {
 | |
|     tab: tabAboutPerformance,
 | |
|     doc,
 | |
|     tbody,
 | |
|   };
 | |
| }
 | |
| 
 | |
| function find_row(tbody, title, tab) {
 | |
|   // Find the row for our test tab.
 | |
|   let row = tbody.firstChild;
 | |
|   while (row && row.firstChild.textContent != title) {
 | |
|     row = row.nextSibling;
 | |
|   }
 | |
| 
 | |
|   Assert.ok(row, "found a table row for our test tab");
 | |
|   Assert.equal(
 | |
|     row.windowId,
 | |
|     tab.linkedBrowser.outerWindowID,
 | |
|     "the correct window id is set"
 | |
|   );
 | |
| 
 | |
|   return row;
 | |
| }
 | |
| 
 | |
| function checkEnergyMedHigh(row) {
 | |
|   let l10nId = row.children[2].getAttribute("data-l10n-id");
 | |
|   Assert.ok(
 | |
|     ["energy-impact-medium", "energy-impact-high"].includes(l10nId),
 | |
|     "our test tab is medium or high energy impact"
 | |
|   );
 | |
| }
 | |
| 
 | |
| async function checkMemoryAtLeast(bytes, row) {
 | |
|   let memCell = row.children[3];
 | |
|   ok(memCell, "Found the cell containing the amount of memory");
 | |
| 
 | |
|   if (!memCell.innerText) {
 | |
|     info("There's no text yet, wait for an update");
 | |
|     await new Promise(resolve => {
 | |
|       let observer = new row.ownerDocument.ownerGlobal.MutationObserver(() => {
 | |
|         observer.disconnect();
 | |
|         resolve();
 | |
|       });
 | |
|       observer.observe(memCell, { childList: true });
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   let text = memCell.innerText;
 | |
|   ok(text, "Found the text from the memory cell");
 | |
|   // We only bother to work in Megabytes, there's currently no reason to
 | |
|   // make this more complex.
 | |
|   info(`Text is ${text}.`);
 | |
|   let mbStr = text.match(/^(\d+(\.\d+)?) MB$/);
 | |
|   ok(mbStr && mbStr[1], "Matched a memory size in Megabytes");
 | |
|   if (!mbStr) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   ok(bytes < Number(mbStr[1]) * 1024 * 1024, "Memory usage is high enough");
 | |
| }
 | |
| 
 | |
| // Test that we can select the row for a tab and close it using the close
 | |
| // button.
 | |
| add_task(async function test_tab_operations() {
 | |
|   let tabContent = await setup_tab(
 | |
|     "http://example.com/browser/toolkit/components/aboutperformance/tests/browser/browser_compartments.html?test=" +
 | |
|       Math.random()
 | |
|   );
 | |
| 
 | |
|   let aboutPerformance = await setup_about_performance();
 | |
| 
 | |
|   // Find the row corresponding to our tab.
 | |
|   let row = find_row(
 | |
|     aboutPerformance.tbody,
 | |
|     "Main frame for test browser_aboutperformance.js",
 | |
|     tabContent
 | |
|   );
 | |
| 
 | |
|   // Verify selecting a row works.
 | |
|   EventUtils.synthesizeMouseAtCenter(
 | |
|     row,
 | |
|     {},
 | |
|     aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|   );
 | |
| 
 | |
|   Assert.equal(
 | |
|     row.getAttribute("selected"),
 | |
|     "true",
 | |
|     "doing a single click selects the row"
 | |
|   );
 | |
| 
 | |
|   // Verify selecting a tab with a double click.
 | |
|   Assert.equal(
 | |
|     gBrowser.selectedTab,
 | |
|     aboutPerformance.tab,
 | |
|     "the about:performance tab is selected"
 | |
|   );
 | |
|   EventUtils.synthesizeMouseAtCenter(
 | |
|     row,
 | |
|     { clickCount: 2 },
 | |
|     aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|   );
 | |
|   Assert.equal(
 | |
|     gBrowser.selectedTab,
 | |
|     tabContent,
 | |
|     "after a double click the test tab is selected"
 | |
|   );
 | |
| 
 | |
|   info("Verify we can toggle subitems using a twisty image button");
 | |
| 
 | |
|   // Find the row with subtitems for twisty toggle test group.
 | |
|   let twistyBtn = aboutPerformance.doc.querySelector("tr > td.root > .twisty");
 | |
| 
 | |
|   // When "toolkit.aboutPerformance.showInternals=false", there is no Twisty.
 | |
|   if (
 | |
|     Services.prefs.getBoolPref("toolkit.aboutPerformance.showInternals", false)
 | |
|   ) {
 | |
|     Assert.ok(twistyBtn, "A twisty button was found");
 | |
|     let groupRow = twistyBtn.parentNode.parentNode;
 | |
| 
 | |
|     // Verify twisty button is properly set up.
 | |
|     Assert.ok(
 | |
|       twistyBtn.hasAttribute("aria-label"),
 | |
|       "the Twisty image button has an aria-label"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       twistyBtn.getAttribute("aria-label"),
 | |
|       groupRow.firstChild.textContent,
 | |
|       "the Twisty image button's aria-label is the same as the Name of its row"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       twistyBtn.getAttribute("role"),
 | |
|       "button",
 | |
|       "the Twisty image is programmatically a button"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       twistyBtn.getAttribute("tabindex"),
 | |
|       "0",
 | |
|       "the Twisty image button is included in the focus order"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       twistyBtn.getAttribute("aria-expanded"),
 | |
|       "false",
 | |
|       "the Twisty image button is collapsed by default"
 | |
|     );
 | |
| 
 | |
|     // Verify we can toggle/show subitems by clicking the twisty button.
 | |
|     EventUtils.synthesizeMouseAtCenter(
 | |
|       twistyBtn,
 | |
|       {},
 | |
|       aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|     );
 | |
|     Assert.ok(
 | |
|       groupRow.nextSibling.children[0].classList.contains("indent"),
 | |
|       "clicking a collapsed Twisty adds subitems after the row"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       twistyBtn.getAttribute("aria-expanded"),
 | |
|       "true",
 | |
|       "the Twisty image button is expanded after a click"
 | |
|     );
 | |
| 
 | |
|     // Verify the twisty button can be focused with a keyboard.
 | |
|     twistyBtn.focus();
 | |
|     Assert.equal(
 | |
|       twistyBtn,
 | |
|       aboutPerformance.doc.activeElement,
 | |
|       "the Twisty image button can be focused"
 | |
|     );
 | |
|     // Verify we can toggle subitems with a keyboard.
 | |
|     // Twisty is expanded
 | |
|     EventUtils.synthesizeKey(
 | |
|       "KEY_Enter",
 | |
|       {},
 | |
|       aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|     );
 | |
|     Assert.ok(
 | |
|       !groupRow.nextSibling ||
 | |
|         !groupRow.nextSibling.children[0].classList.contains("indent"),
 | |
|       "pressing Enter on expanded Twisty removes subitems after the row"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       twistyBtn.getAttribute("aria-expanded"),
 | |
|       "false",
 | |
|       "the Twisty image button is collapsed after a keypress"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       twistyBtn,
 | |
|       aboutPerformance.doc.activeElement,
 | |
|       "the Twisty retains focus after the page is updated"
 | |
|     );
 | |
|     // Twisty is collapsed
 | |
|     EventUtils.synthesizeKey(
 | |
|       " ",
 | |
|       {},
 | |
|       aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|     );
 | |
|     Assert.ok(
 | |
|       groupRow.nextSibling.children[0].classList.contains("indent"),
 | |
|       "pressing Space on collapsed Twisty adds subitems after the row"
 | |
|     );
 | |
|     Assert.equal(
 | |
|       twistyBtn.getAttribute("aria-expanded"),
 | |
|       "true",
 | |
|       "the Twisty image button is expanded after a keypress"
 | |
|     );
 | |
| 
 | |
|     info("Verify the focus stays on a twisty image button");
 | |
| 
 | |
|     Assert.equal(
 | |
|       twistyBtn,
 | |
|       aboutPerformance.doc.activeElement,
 | |
|       "the Twisty retains focus after the page is updated"
 | |
|     );
 | |
|     Assert.notEqual(
 | |
|       aboutPerformance.doc.activeElement.tagName,
 | |
|       "body",
 | |
|       "the body does not pull the focus after the page is updated"
 | |
|     );
 | |
|     EventUtils.synthesizeKey(
 | |
|       "KEY_Tab",
 | |
|       { shiftKey: true },
 | |
|       aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|     );
 | |
|     Assert.notEqual(
 | |
|       twistyBtn,
 | |
|       aboutPerformance.doc.activeElement,
 | |
|       "the Twisty does not pull the focus after the page is updated"
 | |
|     );
 | |
|   } else {
 | |
|     Assert.ok(
 | |
|       !twistyBtn,
 | |
|       "No twisty button should exist when the showInternals pref is false"
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   info("Verify we can close a tab using the X button");
 | |
|   // Switch back to about:performance...
 | |
|   await BrowserTestUtils.switchTab(gBrowser, aboutPerformance.tab);
 | |
|   // ... and click the X button at the end of the row.
 | |
|   let tabClosing = BrowserTestUtils.waitForTabClosing(tabContent);
 | |
|   EventUtils.synthesizeMouseAtCenter(
 | |
|     row.children[4],
 | |
|     {},
 | |
|     aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|   );
 | |
|   await tabClosing;
 | |
| 
 | |
|   BrowserTestUtils.removeTab(aboutPerformance.tab);
 | |
| });
 | |
| 
 | |
| add_task(async function test_tab_energy() {
 | |
|   let tabContent = await setup_tab(
 | |
|     "http://example.com/browser/toolkit/components/aboutperformance/tests/browser/browser_compartments.html?test=" +
 | |
|       Math.random()
 | |
|   );
 | |
| 
 | |
|   let aboutPerformance = await setup_about_performance();
 | |
| 
 | |
|   // Find the row corresponding to our tab.
 | |
|   let row = find_row(
 | |
|     aboutPerformance.tbody,
 | |
|     "Main frame for test browser_aboutperformance.js",
 | |
|     tabContent
 | |
|   );
 | |
| 
 | |
|   // Ensure it is reported as a medium or high energy impact.
 | |
|   checkEnergyMedHigh(row);
 | |
| 
 | |
|   await BrowserTestUtils.removeTab(tabContent);
 | |
|   await BrowserTestUtils.removeTab(aboutPerformance.tab);
 | |
| });
 | |
| 
 | |
| add_task(async function test_tab_memory() {
 | |
|   let tabContent = await setup_tab(
 | |
|     "http://example.com/browser/toolkit/components/aboutperformance/tests/browser/tab_use_memory.html"
 | |
|   );
 | |
| 
 | |
|   let aboutPerformance = await setup_about_performance();
 | |
| 
 | |
|   // Find the row corresponding to our tab.
 | |
|   let row = find_row(
 | |
|     aboutPerformance.tbody,
 | |
|     "Main frame for test browser_aboutperformance.js",
 | |
|     tabContent
 | |
|   );
 | |
| 
 | |
|   // The page is using at least 32 MB, due to the big array that it
 | |
|   // contains.
 | |
|   await checkMemoryAtLeast(32 * 1024 * 1024, row);
 | |
| 
 | |
|   await BrowserTestUtils.removeTab(tabContent);
 | |
|   await BrowserTestUtils.removeTab(aboutPerformance.tab);
 | |
| });
 | |
| 
 | |
| add_task(async function test_worker_energy() {
 | |
|   let tabContent = await setup_tab(
 | |
|     "http://example.com/browser/toolkit/components/aboutperformance/tests/browser/workers.html"
 | |
|   );
 | |
| 
 | |
|   let aboutPerformance = await setup_about_performance();
 | |
| 
 | |
|   // Find the row corresponding to our tab.
 | |
|   let row = find_row(
 | |
|     aboutPerformance.tbody,
 | |
|     "Main frame for test browser_aboutperformance.js",
 | |
|     tabContent
 | |
|   );
 | |
| 
 | |
|   // Find the worker under this row.
 | |
|   let button = row.firstChild.firstChild;
 | |
|   Assert.ok(button && button.classList, "Has a span to create the button");
 | |
|   Assert.ok(button.classList.contains("twisty"), "Button is expandable.");
 | |
|   Assert.ok(!button.classList.contains("open"), "Not already open");
 | |
| 
 | |
|   // Click the expand button.
 | |
|   EventUtils.synthesizeMouseAtCenter(
 | |
|     button,
 | |
|     {},
 | |
|     aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|   );
 | |
| 
 | |
|   Assert.ok(button.classList.contains("open"), "It's now open");
 | |
| 
 | |
|   // Move to the next row which is the worker we want to imspect.
 | |
|   row = row.nextSibling;
 | |
| 
 | |
|   // Check that it is a worker.
 | |
|   Assert.equal(row.children[1].getAttribute("data-l10n-id"), "type-worker");
 | |
| 
 | |
|   // Ensure it is reported as a medium or high energy impact.
 | |
|   checkEnergyMedHigh(row);
 | |
| 
 | |
|   await BrowserTestUtils.removeTab(tabContent);
 | |
|   await BrowserTestUtils.removeTab(aboutPerformance.tab);
 | |
| });
 | |
| 
 | |
| add_task(async function test_worker_memory() {
 | |
|   let tabContent = await setup_tab(
 | |
|     "http://example.com/browser/toolkit/components/aboutperformance/tests/browser/workers_memory.html"
 | |
|   );
 | |
| 
 | |
|   let aboutPerformance = await setup_about_performance();
 | |
| 
 | |
|   // Find the row corresponding to our tab.
 | |
|   let row = find_row(
 | |
|     aboutPerformance.tbody,
 | |
|     "Main frame for test browser_aboutperformance.js",
 | |
|     tabContent
 | |
|   );
 | |
|   Assert.ok(row, "Found the row for our test tab");
 | |
| 
 | |
|   // Find the worker under this row.
 | |
|   let button = row.firstChild.firstChild;
 | |
|   Assert.ok(button && button.classList, "Has a span to create the button");
 | |
|   Assert.ok(button.classList.contains("twisty"), "Button is expandable.");
 | |
|   Assert.ok(!button.classList.contains("open"), "Not already open");
 | |
| 
 | |
|   // Click the expand button.
 | |
|   EventUtils.synthesizeMouseAtCenter(
 | |
|     button,
 | |
|     {},
 | |
|     aboutPerformance.tab.linkedBrowser.contentWindow
 | |
|   );
 | |
| 
 | |
|   Assert.ok(button.classList.contains("open"), "It's now open");
 | |
| 
 | |
|   // Move to the next row which is the worker we want to imspect.
 | |
|   row = row.nextSibling;
 | |
| 
 | |
|   // Check that it is a worker.
 | |
|   Assert.equal(row.children[1].getAttribute("data-l10n-id"), "type-worker");
 | |
| 
 | |
|   // The page is using at least 32 MB, due to the big array that it
 | |
|   // contains.
 | |
|   await checkMemoryAtLeast(32 * 1024 * 1024, row);
 | |
| 
 | |
|   await BrowserTestUtils.removeTab(tabContent);
 | |
|   await BrowserTestUtils.removeTab(aboutPerformance.tab);
 | |
| });
 |