summaryrefslogtreecommitdiffstats
path: root/toolkit/components/aboutthirdparty/tests/browser/browser_aboutthirdparty.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/aboutthirdparty/tests/browser/browser_aboutthirdparty.js')
-rw-r--r--toolkit/components/aboutthirdparty/tests/browser/browser_aboutthirdparty.js317
1 files changed, 317 insertions, 0 deletions
diff --git a/toolkit/components/aboutthirdparty/tests/browser/browser_aboutthirdparty.js b/toolkit/components/aboutthirdparty/tests/browser/browser_aboutthirdparty.js
new file mode 100644
index 0000000000..0a53823a35
--- /dev/null
+++ b/toolkit/components/aboutthirdparty/tests/browser/browser_aboutthirdparty.js
@@ -0,0 +1,317 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Return card containers matching a given name
+function getCardsByName(aContainer, aLeafName) {
+ const matchedCards = [];
+ const allCards = aContainer.querySelectorAll(".card");
+ for (const card of allCards) {
+ const nameLabel = card.querySelector(".module-name");
+ if (nameLabel.textContent == aLeafName) {
+ matchedCards.push(card);
+ }
+ }
+ return matchedCards;
+}
+
+function getDetailRow(aContainer, aLabel) {
+ return aContainer.querySelector(`[data-l10n-id=${aLabel}]`).parentElement;
+}
+
+function verifyClipboardData(aModuleJson) {
+ Assert.ok(
+ aModuleJson.hasOwnProperty("blocked"),
+ "Clipboard data should have blocked property."
+ );
+ const blocked = aModuleJson.blocked.filter(
+ x => x.name == kUserBlockedModuleName
+ );
+ Assert.equal(
+ blocked.length,
+ 1,
+ "Blocked array should contain the blocked module one time."
+ );
+ Assert.ok(
+ aModuleJson.hasOwnProperty("modules"),
+ "Clipboard data should have modules property"
+ );
+ let aModuleArray = aModuleJson.modules;
+ const filtered = aModuleArray.filter(x => x.name == kExtensionModuleName);
+ Assert.equal(filtered.length, 1, "No duplicate data for the module.");
+
+ const kDeletedPropertiesOfModule = [
+ "application",
+ "dllFile",
+ "loadingOnMain",
+ "trustFlags",
+ ];
+ const kDeletedPropertiesOfLoadingEvent = [
+ "baseAddress",
+ "isDependent",
+ "mainThread",
+ "moduleIndex",
+ "processUptimeMS",
+ ];
+
+ for (const module of aModuleArray) {
+ for (const deletedProperty of kDeletedPropertiesOfModule) {
+ Assert.ok(
+ !module.hasOwnProperty(deletedProperty),
+ `The property \`${deletedProperty}\` is deleted.`
+ );
+ }
+
+ Assert.ok(
+ !module.hasOwnProperty("typeFlags") || module.typeFlags != 0,
+ "typeFlags does not exist or is non-zero."
+ );
+
+ for (const event of module.events) {
+ for (const deletedProperty of kDeletedPropertiesOfLoadingEvent) {
+ Assert.ok(
+ !event.hasOwnProperty(deletedProperty),
+ `The property \`${deletedProperty}\` is deleted.`
+ );
+ }
+ }
+ }
+}
+
+function verifyModuleSorting(compareFunc) {
+ const uninteresting = {
+ typeFlags: 0,
+ isCrasher: false,
+ loadingOnMain: 0,
+ };
+ const crasherNotBlocked = { ...uninteresting, isCrasher: true };
+ const crasherBlocked = {
+ ...uninteresting,
+ isCrasher: true,
+ typeFlags: Ci.nsIAboutThirdParty.ModuleType_BlockedByUserAtLaunch,
+ };
+ const justBlocked = {
+ ...uninteresting,
+ typeFlags: Ci.nsIAboutThirdParty.ModuleType_BlockedByUserAtLaunch,
+ };
+ const uninterestingButSlow = {
+ ...uninteresting,
+ loadingOnMain: 10,
+ };
+ let modules = [
+ uninteresting,
+ uninterestingButSlow,
+ crasherNotBlocked,
+ justBlocked,
+ crasherBlocked,
+ ];
+ modules.sort(compareFunc);
+ Assert.equal(
+ JSON.stringify([
+ crasherBlocked,
+ justBlocked,
+ crasherNotBlocked,
+ uninterestingButSlow,
+ uninteresting,
+ ]),
+ JSON.stringify(modules),
+ "Modules sort in expected order"
+ );
+}
+
+add_task(async () => {
+ registerCleanupFunction(() => {
+ unregisterAll();
+ });
+ await registerObject();
+ registerExtensions();
+ loadShellExtension();
+
+ await kATP.collectSystemInfo();
+ Assert.equal(
+ kATP.lookupModuleType(kExtensionModuleName),
+ Ci.nsIAboutThirdParty.ModuleType_ShellExtension,
+ "lookupModuleType() returns a correct type " +
+ "after system info was collected."
+ );
+
+ await BrowserTestUtils.withNewTab("about:third-party", async browser => {
+ if (!content.fetchDataDone) {
+ const mainDiv = content.document.getElementById("main");
+ await BrowserTestUtils.waitForMutationCondition(
+ mainDiv,
+ { childList: true },
+ () => mainDiv.childElementCount > 0
+ );
+ Assert.ok(content.fetchDataDone, "onLoad() is completed.");
+ }
+
+ const reload = content.document.getElementById("button-reload");
+ if (!reload.hidden) {
+ reload.click();
+ await BrowserTestUtils.waitForMutationCondition(
+ reload,
+ { attributes: true, attributeFilter: ["hidden"] },
+ () => reload.hidden
+ );
+ }
+
+ Assert.ok(
+ content.document.getElementById("no-data").hidden,
+ "The no-data message is hidden."
+ );
+ const blockedCards = getCardsByName(
+ content.document,
+ kUserBlockedModuleName
+ );
+ Assert.equal(
+ blockedCards.length,
+ 1,
+ "Only one card matching the blocked module exists."
+ );
+ const blockedCard = blockedCards[0];
+ Assert.equal(
+ blockedCard.querySelectorAll(".button-block.module-blocked").length,
+ 1,
+ "The blocked module has a button indicating it is blocked"
+ );
+ let blockedBlockButton = blockedCard.querySelector(
+ ".button-block.module-blocked"
+ );
+ Assert.equal(
+ blockedBlockButton.getAttribute("data-l10n-id"),
+ "third-party-button-to-unblock-module",
+ "Button to block the module has correct title"
+ );
+ blockedBlockButton.click();
+ await BrowserTestUtils.promiseAlertDialogOpen("cancel");
+ Assert.ok(
+ !blockedBlockButton.classList.contains("module-blocked"),
+ "After clicking to unblock a module, button should not have module-blocked class."
+ );
+ Assert.equal(
+ blockedBlockButton.getAttribute("data-l10n-id"),
+ "third-party-button-to-block-module",
+ "After clicking to unblock a module, button should have correct title."
+ );
+ // Restore this to blocked for later tests
+ blockedBlockButton.click();
+ await BrowserTestUtils.promiseAlertDialogOpen("cancel");
+ Assert.ok(
+ blockedBlockButton.classList.contains("module-blocked"),
+ "After clicking to block a module, button should have module-blocked class."
+ );
+ Assert.equal(
+ blockedBlockButton.getAttribute("data-l10n-id"),
+ "third-party-button-to-unblock-module",
+ "After clicking to block a module, button should have correct title."
+ );
+
+ const cards = getCardsByName(content.document, kExtensionModuleName);
+ Assert.equal(cards.length, 1, "Only one card matching the module exists.");
+ const card = cards[0];
+
+ const blockButton = card.querySelector(".button-block");
+ Assert.ok(
+ !blockButton.classList.contains("blocklist-disabled"),
+ "Button to block the module does not indicate the blocklist is disabled."
+ );
+ Assert.ok(
+ !blockButton.classList.contains("module-blocked"),
+ "Button to block the module does not indicate the module is blocked."
+ );
+
+ Assert.ok(
+ card.querySelector(".image-warning").hidden,
+ "No warning sign for the module."
+ );
+ Assert.equal(
+ card.querySelector(".image-unsigned").hidden,
+ false,
+ "The module is labeled as unsigned."
+ );
+ Assert.equal(
+ card.querySelector(".tag-shellex").hidden,
+ false,
+ "The module is labeled as a shell extension."
+ );
+ Assert.equal(
+ card.querySelector(".tag-ime").hidden,
+ true,
+ "The module is not labeled as an IME."
+ );
+
+ const versionRow = getDetailRow(card, "third-party-detail-version");
+ Assert.equal(
+ versionRow.childNodes[1].textContent,
+ "1.2.3.4",
+ "The version matches a value in TestShellEx.rc."
+ );
+ const vendorRow = getDetailRow(card, "third-party-detail-vendor");
+ Assert.equal(
+ vendorRow.childNodes[1].textContent,
+ "Mozilla Corporation",
+ "The vendor name matches a value in TestShellEx.rc."
+ );
+ const occurrencesRow = getDetailRow(card, "third-party-detail-occurrences");
+ Assert.equal(
+ Number(occurrencesRow.childNodes[1].textContent),
+ 1,
+ "The module was loaded once."
+ );
+ const durationRow = getDetailRow(card, "third-party-detail-duration");
+ Assert.ok(
+ Number(durationRow.childNodes[1].textContent),
+ "The duration row shows a valid number."
+ );
+
+ const eventTable = card.querySelector(".event-table");
+ const tableCells = eventTable.querySelectorAll("td");
+ Assert.equal(
+ tableCells.length,
+ 3,
+ "The table has three cells as there is only one event."
+ );
+ Assert.equal(
+ tableCells[0].querySelector(".process-type").getAttribute("data-l10n-id"),
+ "process-type-default",
+ "The module was loaded into the main process."
+ );
+ Assert.ok(
+ Number(tableCells[0].querySelector(".process-id").textContent),
+ "A valid process ID is displayed."
+ );
+ Assert.equal(
+ tableCells[1].querySelector(".event-duration").textContent,
+ durationRow.childNodes[1].textContent,
+ "The event's duration is the same as the average " +
+ "as there is only one event."
+ );
+ Assert.equal(
+ tableCells[1].querySelector(".tag-background").hidden,
+ true,
+ "The icon handler is loaded in the main thread."
+ );
+ Assert.equal(
+ tableCells[2].getAttribute("data-l10n-id"),
+ "third-party-status-loaded",
+ "The module was really loaded without being blocked."
+ );
+
+ const button = content.document.getElementById("button-copy-to-clipboard");
+ button.click();
+
+ // Wait until copying is done and the button becomes clickable.
+ await BrowserTestUtils.waitForMutationCondition(
+ button,
+ { attributes: true },
+ () => !button.disabled
+ );
+
+ const copiedJSON = JSON.parse(await navigator.clipboard.readText());
+ Assert.ok(copiedJSON instanceof Object, "Data is an object.");
+ verifyClipboardData(copiedJSON);
+
+ verifyModuleSorting(content.moduleCompareForDisplay);
+ });
+});