summaryrefslogtreecommitdiffstats
path: root/toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js')
-rw-r--r--toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js425
1 files changed, 425 insertions, 0 deletions
diff --git a/toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js b/toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js
new file mode 100644
index 0000000000..605f10823e
--- /dev/null
+++ b/toolkit/components/aboutperformance/tests/browser/browser_aboutperformance.js
@@ -0,0 +1,425 @@
+/* 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);
+});