fune/toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js
Paul Bone b58db9232d Bug 1760920 - pt 15. Fix timing in a test leading to a failure r=florian
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
2022-11-07 22:36:41 +00:00

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);
});