diff options
Diffstat (limited to 'toolkit/components/aboutthirdparty/tests/browser/browser_aboutthirdparty.js')
-rw-r--r-- | toolkit/components/aboutthirdparty/tests/browser/browser_aboutthirdparty.js | 317 |
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..e4c8ca35ca --- /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", + "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", + "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", + "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); + }); +}); |