test: Fixed running tests for pinned tabs and exported machitests, b=no-bug, c=tabs, glance, tests, folders, workspaces

This commit is contained in:
mr. m
2026-01-16 21:33:45 +01:00
parent 6d9347acec
commit fa7186b3d8
55 changed files with 263 additions and 3198 deletions

View File

@@ -20,6 +20,7 @@ import testPathsConfig from "./engine/eslint-test-paths.config.mjs";
import repositoryGlobals from "./engine/eslint-file-globals.config.mjs"; import repositoryGlobals from "./engine/eslint-file-globals.config.mjs";
import rollouts from "./engine/eslint-rollouts.config.mjs"; import rollouts from "./engine/eslint-rollouts.config.mjs";
import subdirConfigs from "./engine/eslint-subdirs.config.mjs"; import subdirConfigs from "./engine/eslint-subdirs.config.mjs";
import { globalIgnores as globalIgnoresPath } from "eslint/config";
const testPaths = testPathsConfig.testPaths; const testPaths = testPathsConfig.testPaths;
@@ -451,6 +452,7 @@ let config = [
}, },
}, },
...wrapPathsInConfig(rollouts), ...wrapPathsInConfig(rollouts),
globalIgnoresPath(["src/zen/tests/"]),
]; ];
// The various places we get our globals from use true/false rather than // The various places we get our globals from use true/false rather than

View File

@@ -21,7 +21,7 @@
"sync:raw": "surfer update", "sync:raw": "surfer update",
"sync:rc": "python3 scripts/update_ff.py --rc", "sync:rc": "python3 scripts/update_ff.py --rc",
"sync:l10n": "python3 scripts/update_ff.py --just-l10n", "sync:l10n": "python3 scripts/update_ff.py --just-l10n",
"pretty": "prettier . --write --cache && autopep8 -r --in-place scripts/ src/ --exclude */tests/*", "pretty": "prettier . --write --cache && autopep8 -r --in-place scripts/ src/ --exclude src/zen/tests/",
"lint": "npx eslint src/ && prettier . --check --cache", "lint": "npx eslint src/ && prettier . --check --cache",
"lint:fix": "npm run pretty && npx eslint src/ --fix", "lint:fix": "npm run pretty && npx eslint src/ --fix",
"prepare": "husky", "prepare": "husky",

View File

@@ -1,5 +1,5 @@
diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css diff --git a/browser/themes/shared/tabbrowser/tabs.css b/browser/themes/shared/tabbrowser/tabs.css
index 310e7866b942df5c3c34815f4612a2a2ad8c42a6..c474e1cddcecd3def3b255c5c530c0b36a38e6b0 100644 index 310e7866b942df5c3c34815f4612a2a2ad8c42a6..d4931a0184209951ced288c894613dccdf3b11fc 100644
--- a/browser/themes/shared/tabbrowser/tabs.css --- a/browser/themes/shared/tabbrowser/tabs.css
+++ b/browser/themes/shared/tabbrowser/tabs.css +++ b/browser/themes/shared/tabbrowser/tabs.css
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
@@ -152,7 +152,17 @@ index 310e7866b942df5c3c34815f4612a2a2ad8c42a6..c474e1cddcecd3def3b255c5c530c0b3
&:-moz-window-inactive { &:-moz-window-inactive {
background-image: background-image:
@@ -2382,7 +2373,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button { @@ -2348,9 +2339,6 @@ tab-group {
:root:not([privatebrowsingmode]) :is(toolbarbutton, toolbarpaletteitem) ~ #tabbrowser-tabs,
:root[privatebrowsingmode] :is(toolbarbutton:not(#firefox-view-button), toolbarpaletteitem:not(#wrapper-firefox-view-button)) ~ #tabbrowser-tabs {
- border-inline-start: var(--tabstrip-inner-border);
- padding-inline-start: 2px;
- margin-inline-start: 2px;
}
:root[privatebrowsingmode] :is(#firefox-view-button, #menu_openFirefoxView) {
@@ -2382,7 +2370,6 @@ toolbar:not(#TabsToolbar) #firefox-view-button {
list-style-image: url(chrome://global/skin/icons/plus.svg); list-style-image: url(chrome://global/skin/icons/plus.svg);
} }

View File

@@ -1,8 +1,8 @@
diff --git a/testing/profiles/mochitest/user.js b/testing/profiles/mochitest/user.js diff --git a/testing/profiles/mochitest/user.js b/testing/profiles/mochitest/user.js
index 782258420cdce901f182897b796731a1fdf69ecf..59b2827a7cd8a8580ba5061cabb36a2ba13240ba 100644 index 782258420cdce901f182897b796731a1fdf69ecf..a762067169b1cf3cd05147f9e715eb0db56a3299 100644
--- a/testing/profiles/mochitest/user.js --- a/testing/profiles/mochitest/user.js
+++ b/testing/profiles/mochitest/user.js +++ b/testing/profiles/mochitest/user.js
@@ -36,3 +36,8 @@ user_pref("places.history.floodingPrevention.enabled", false); @@ -36,3 +36,9 @@ user_pref("places.history.floodingPrevention.enabled", false);
// permission, and we can open it and wait for the user to give permission, then // permission, and we can open it and wait for the user to give permission, then
// don't do that. // don't do that.
user_pref("geo.prompt.open_system_prefs", false); user_pref("geo.prompt.open_system_prefs", false);
@@ -11,3 +11,4 @@ index 782258420cdce901f182897b796731a1fdf69ecf..59b2827a7cd8a8580ba5061cabb36a2b
+user_pref("zen.watermark.enabled", false); +user_pref("zen.watermark.enabled", false);
+user_pref("zen.testing.enabled", true); +user_pref("zen.testing.enabled", true);
+user_pref("zen.window-sync.enabled", true); +user_pref("zen.window-sync.enabled", true);
+user_pref("widget.macos.native-context-menus", false);

View File

@@ -811,7 +811,12 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
return; return;
} }
this.#animateGlanceClosing(onTabClose, browserSidebarContainer, sidebarButtons, setNewID); return this.#animateGlanceClosing(
onTabClose,
browserSidebarContainer,
sidebarButtons,
setNewID
);
} }
/** /**

View File

@@ -189,7 +189,8 @@ class nsZenWindowSync {
for (let tab of gZenWorkspaces.allStoredTabs) { for (let tab of gZenWorkspaces.allStoredTabs) {
if (!tab.id) { if (!tab.id) {
tab.id = this.#newTabSyncId; tab.id = this.#newTabSyncId;
lazy.TabStateFlusher.flush(tab.linkedBrowser); // Don't call with await here to avoid blocking the loop.
this.#maybeFlushTabState(tab);
} }
if (tab.pinned && !tab._zenPinnedInitialState) { if (tab.pinned && !tab._zenPinnedInitialState) {
await this.setPinnedTabState(tab); await this.setPinnedTabState(tab);
@@ -407,7 +408,7 @@ class nsZenWindowSync {
this.#syncItemPosition(aOriginalItem, aTargetItem, aWindow); this.#syncItemPosition(aOriginalItem, aTargetItem, aWindow);
} }
if (gBrowser.isTab(aTargetItem)) { if (gBrowser.isTab(aTargetItem)) {
lazy.TabStateFlusher.flush(aTargetItem.linkedBrowser); this.#maybeFlushTabState(aTargetItem);
} }
} }
@@ -540,7 +541,7 @@ class nsZenWindowSync {
* @param {object} aOtherTab - The tab in the other window. * @param {object} aOtherTab - The tab in the other window.
*/ */
async #swapBrowserDocShellsAsync(aOurTab, aOtherTab) { async #swapBrowserDocShellsAsync(aOurTab, aOtherTab) {
lazy.TabStateFlusher.flush(aOtherTab.linkedBrowser); this.#maybeFlushTabState(aOtherTab);
await this.#styleSwapedBrowsers(aOurTab, aOtherTab, () => { await this.#styleSwapedBrowsers(aOurTab, aOtherTab, () => {
this.#swapBrowserDocSheellsInner(aOurTab, aOtherTab); this.#swapBrowserDocSheellsInner(aOurTab, aOtherTab);
}); });
@@ -601,7 +602,7 @@ class nsZenWindowSync {
// See https://github.com/zen-browser/desktop/issues/11851, swapping the browsers // See https://github.com/zen-browser/desktop/issues/11851, swapping the browsers
// don't seem to update the state's cache properly, leading to issues when restoring // don't seem to update the state's cache properly, leading to issues when restoring
// the session later on. // the session later on.
let tabState = this.#getTabState(aOtherTab); let tabStateEntries = this.#getTabEntriesFromCache(aOtherTab);
// Running `swapBrowsersAndCloseOther` doesn't expect us to use the tab after // Running `swapBrowsersAndCloseOther` doesn't expect us to use the tab after
// the operation, so it doesn't really care about cleaning up the other tab. // the operation, so it doesn't really care about cleaning up the other tab.
// We need to make a new tab progress listener for the other tab after the swap. // We need to make a new tab progress listener for the other tab after the swap.
@@ -656,13 +657,13 @@ class nsZenWindowSync {
// It's also important to note that if we don't flush the state here, // It's also important to note that if we don't flush the state here,
// we would start receiving invalid history changes from the the incorrect // we would start receiving invalid history changes from the the incorrect
// browser view that was just swapped out. // browser view that was just swapped out.
lazy.TabStateFlusher.flush(aOurTab.linkedBrowser).finally(() => { this.#maybeFlushTabState(aOurTab).finally(() => {
if (!tabState.entries?.length) { if (!tabStateEntries?.length) {
this.log(`Error: No tab state entries found for tab ${aOtherTab.id} during swap`); this.log(`Error: No tab state entries found for tab ${aOtherTab.id} during swap`);
return; return;
} }
lazy.TabStateCache.update(aOurTab.linkedBrowser.permanentKey, { lazy.TabStateCache.update(aOurTab.linkedBrowser.permanentKey, {
entries: tabState.entries, entries: tabStateEntries,
}); });
}); });
return true; return true;
@@ -849,13 +850,30 @@ class nsZenWindowSync {
} }
/** /**
* Retrieves the tab state for a given tab. * Retrieves the tab state entries from the cache for a given tab.
* *
* @param {object} tab - The tab to retrieve the state for. * @param {object} aTab - The tab to retrieve the state for.
* @returns {object} The tab state. * @returns {Array} The tab state entries.
*/ */
#getTabState(tab) { #getTabEntriesFromCache(aTab) {
return JSON.parse(lazy.SessionStore.getTabState(tab)); if (!aTab.linkedBrowser) {
return [];
}
let cachedState = lazy.TabStateCache.get(aTab.linkedBrowser.permanentKey) || { entries: [] };
return cachedState.entries || [];
}
/**
* Flushes the tab state for a given tab if it has a linked browser.
*
* @param {object} aTab - The tab to flush the state for.
* @returns {Promise} A promise that resolves when the operation is complete.
*/
#maybeFlushTabState(aTab) {
if (!aTab.linkedBrowser) {
return Promise.resolve();
}
return lazy.TabStateFlusher.flush(aTab.linkedBrowser);
} }
/* Mark: Public API */ /* Mark: Public API */
@@ -867,15 +885,15 @@ class nsZenWindowSync {
* @returns {Promise} A promise that resolves when the operation is complete. * @returns {Promise} A promise that resolves when the operation is complete.
*/ */
setPinnedTabState(aTab) { setPinnedTabState(aTab) {
return lazy.TabStateFlusher.flush(aTab.linkedBrowser).finally(() => { return this.#maybeFlushTabState(aTab).finally(() => {
this.log(`Setting pinned initial state for tab ${aTab.id}`); this.log(`Setting pinned initial state for tab ${aTab.id}`);
const state = this.#getTabState(aTab); const entries = this.#getTabEntriesFromCache(aTab);
let activeIndex = "index" in state ? state.index : state.entries.length - 1; let activeIndex = "index" in entries ? entries.index : entries.entries.length - 1;
activeIndex = Math.min(activeIndex, state.entries.length - 1); activeIndex = Math.min(activeIndex, entries.entries.length - 1);
activeIndex = Math.max(activeIndex, 0); activeIndex = Math.max(activeIndex, 0);
const initialState = { const initialState = {
entry: state.entries[activeIndex], entry: entries.entries[activeIndex],
image: state.image, image: entries.image,
}; };
this.#runOnAllWindows(null, (win) => { this.#runOnAllWindows(null, (win) => {
const targetTab = this.getItemFromWindow(win, aTab.id); const targetTab = this.getItemFromWindow(win, aTab.id);
@@ -973,7 +991,7 @@ class nsZenWindowSync {
SYNC_FLAG_ICON | SYNC_FLAG_LABEL | SYNC_FLAG_MOVE SYNC_FLAG_ICON | SYNC_FLAG_LABEL | SYNC_FLAG_MOVE
); );
}); });
lazy.TabStateFlusher.flush(tab.linkedBrowser); this.#maybeFlushTabState(tab);
} }
on_ZenTabIconChanged(aEvent) { on_ZenTabIconChanged(aEvent) {

View File

@@ -5,7 +5,7 @@
add_task(async function test_Container_Essentials_Auto_Swithc() { add_task(async function test_Container_Essentials_Auto_Swithc() {
await gZenWorkspaces.createAndSaveWorkspace("Container Profile 1", undefined, false, 1); await gZenWorkspaces.createAndSaveWorkspace("Container Profile 1", undefined, false, 1);
const workspaces = await gZenWorkspaces._workspaces(); const workspaces = gZenWorkspaces.getWorkspaces();
Assert.strictEqual(workspaces.length, 2, "Two workspaces should exist."); Assert.strictEqual(workspaces.length, 2, "Two workspaces should exist.");
let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank", { let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank", {

View File

@@ -5,7 +5,7 @@
add_task(async function test_Check_Creation() { add_task(async function test_Check_Creation() {
await gZenWorkspaces.createAndSaveWorkspace("Container Profile 1", undefined, false, 1); await gZenWorkspaces.createAndSaveWorkspace("Container Profile 1", undefined, false, 1);
const workspaces = await gZenWorkspaces._workspaces(); const workspaces = gZenWorkspaces.getWorkspaces();
Assert.strictEqual(workspaces.length, 2, "Two workspaces should exist."); Assert.strictEqual(workspaces.length, 2, "Two workspaces should exist.");
await gZenWorkspaces.changeWorkspace(workspaces[1]); await gZenWorkspaces.changeWorkspace(workspaces[1]);

View File

@@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
[DEFAULT] [DEFAULT]
prefs = ["widget.macos.native-context-menus=false"]
support-files = [ support-files = [
"head.js", "head.js",
] ]

View File

@@ -3,16 +3,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
[reportbrokensite]
source = "browser/components/reportbrokensite/test/browser"
is_direct_path = true
disable = [
"browser_addon_data_sent.js"
]
[reportbrokensite.replace-manifest]
"../../../../../" = "../../../../"
[safebrowsing] [safebrowsing]
source = "browser/components/safebrowsing/content/test" source = "browser/components/safebrowsing/content/test"
is_direct_path = true is_direct_path = true

View File

@@ -7,7 +7,6 @@
# Do not edit manually. # Do not edit manually.
BROWSER_CHROME_MANIFESTS += [ BROWSER_CHROME_MANIFESTS += [
"reportbrokensite/browser.toml",
"safebrowsing/browser.toml", "safebrowsing/browser.toml",
"shell/browser.toml", "shell/browser.toml",
"tooltiptext/browser.toml", "tooltiptext/browser.toml",

View File

@@ -1,57 +0,0 @@
[DEFAULT]
tags = "report-broken-site"
support-files = [
"example_report_page.html",
"head.js",
"sendMoreInfoTestEndpoint.html",
]
["browser_addon_data_sent.js"]
disabled="Disabled by import_external_tests.py"
support-files = [ "send_more_info.js" ]
skip-if = ["os == 'win' && os_version == '11.26100' && processor == 'x86_64' && opt"] # Bug 1955805
["browser_antitracking_data_sent.js"]
support-files = [ "send_more_info.js" ]
["browser_back_buttons.js"]
["browser_error_messages.js"]
["browser_experiment_data_sent.js"]
support-files = [ "send_more_info.js" ]
["browser_keyboard_navigation.js"]
skip-if = [
"os == 'linux' && os_version == '24.04' && processor == 'x86_64' && tsan", # Bug 1867132
"os == 'linux' && os_version == '24.04' && processor == 'x86_64' && asan", # Bug 1867132
"os == 'linux' && os_version == '24.04' && processor == 'x86_64' && debug", # Bug 1867132
"os == 'win' && os_version == '11.26100' && processor == 'x86_64' && asan", # Bug 1867132
]
["browser_learn_more_link.js"]
["browser_parent_menuitems.js"]
["browser_prefers_contrast.js"]
["browser_reason_dropdown.js"]
["browser_report_send.js"]
support-files = [ "send.js" ]
["browser_send_more_info.js"]
support-files = [
"send_more_info.js",
"../../../../toolkit/components/gfx/content/videotest.mp4",
]
["browser_tab_key_order.js"]
["browser_tab_switch_handling.js"]
["browser_webcompat.com_fallback.js"]
support-files = [
"send_more_info.js",
"../../../../toolkit/components/gfx/content/videotest.mp4",
]

View File

@@ -1,99 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that the right data is sent for
* private windows and when ETP blocks content.
*/
/* import-globals-from send.js */
/* import-globals-from send_more_info.js */
"use strict";
const { AddonTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/AddonTestUtils.sys.mjs"
);
AddonTestUtils.initMochitest(this);
Services.scriptloader.loadSubScript(
getRootDirectory(gTestPath) + "send_more_info.js",
this
);
add_common_setup();
const TEMP_ID = "testtempaddon@tests.mozilla.org";
const TEMP_NAME = "Temporary Addon";
const TEMP_VERSION = "0.1.0";
const PERM_ID = "testpermaddon@tests.mozilla.org";
const PERM_NAME = "Permanent Addon";
const PERM_VERSION = "0.2.0";
const DISABLED_ID = "testdisabledaddon@tests.mozilla.org";
const DISABLED_NAME = "Disabled Addon";
const DISABLED_VERSION = "0.3.0";
const EXPECTED_ADDONS = [
{ id: PERM_ID, name: PERM_NAME, temporary: false, version: PERM_VERSION },
{ id: TEMP_ID, name: TEMP_NAME, temporary: true, version: TEMP_VERSION },
];
function loadAddon(id, name, version, isTemp = false) {
return ExtensionTestUtils.loadExtension({
manifest: {
browser_specific_settings: { gecko: { id } },
name,
version,
},
useAddonManager: isTemp ? "temporary" : "permanent",
});
}
async function installAddons() {
const temp = await loadAddon(TEMP_ID, TEMP_NAME, TEMP_VERSION, true);
await temp.startup();
const perm = await loadAddon(PERM_ID, PERM_NAME, PERM_VERSION);
await perm.startup();
const dis = await loadAddon(DISABLED_ID, DISABLED_NAME, DISABLED_VERSION);
await dis.startup();
await (await AddonManager.getAddonByID(DISABLED_ID)).disable();
return async () => {
await temp.unload();
await perm.unload();
await dis.unload();
};
}
add_task(async function testSendButton() {
ensureReportBrokenSitePreffedOn();
ensureReasonOptional();
const addonCleanup = await installAddons();
const tab = await openTab(REPORTABLE_PAGE_URL);
await testSend(tab, AppMenu(), {
addons: EXPECTED_ADDONS,
});
closeTab(tab);
await addonCleanup();
});
add_task(async function testSendingMoreInfo() {
ensureReportBrokenSitePreffedOn();
ensureSendMoreInfoEnabled();
const addonCleanup = await installAddons();
const tab = await openTab(REPORTABLE_PAGE_URL);
await testSendMoreInfo(tab, HelpMenu(), {
addons: EXPECTED_ADDONS,
});
closeTab(tab);
await addonCleanup();
});

View File

@@ -1,126 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that the right data is sent for
* private windows and when ETP blocks content.
*/
/* import-globals-from send.js */
/* import-globals-from send_more_info.js */
"use strict";
Services.scriptloader.loadSubScript(
getRootDirectory(gTestPath) + "send_more_info.js",
this
);
add_common_setup();
add_task(setupStrictETP);
function getEtpCategory() {
return Services.prefs.getStringPref(
"browser.contentblocking.category",
"standard"
);
}
add_task(async function testSendButton() {
ensureReportBrokenSitePreffedOn();
ensureReasonOptional();
const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
const blockedPromise = waitForContentBlockingEvent(3, win);
const tab = await openTab(REPORTABLE_PAGE_URL3, win);
await blockedPromise;
await testSend(tab, AppMenu(win), {
breakageCategory: "adblocker",
description: "another test description",
antitracking: {
blockList: "strict",
blockedOrigins: null,
isPrivateBrowsing: true,
hasTrackingContentBlocked: true,
hasMixedActiveContentBlocked: true,
hasMixedDisplayContentBlocked: true,
btpHasPurgedSite: false,
etpCategory: getEtpCategory(),
},
frameworks: {
fastclick: true,
marfeel: true,
mobify: true,
},
});
await BrowserTestUtils.closeWindow(win);
});
add_task(async function testSendingMoreInfo() {
ensureReportBrokenSitePreffedOn();
ensureSendMoreInfoEnabled();
const win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
const blockedPromise = waitForContentBlockingEvent(3, win);
const tab = await openTab(REPORTABLE_PAGE_URL3, win);
await blockedPromise;
await testSendMoreInfo(tab, HelpMenu(win), {
antitracking: {
blockList: "strict",
blockedOrigins: ["https://trackertest.org"],
isPrivateBrowsing: true,
hasTrackingContentBlocked: true,
hasMixedActiveContentBlocked: true,
hasMixedDisplayContentBlocked: true,
btpHasPurgedSite: false,
etpCategory: getEtpCategory(),
},
frameworks: { fastclick: true, mobify: true, marfeel: true },
consoleLog: [
{
level: "error",
log(actual) {
// "Blocked loading mixed display content http://example.com/tests/image/test/mochitest/blue.png"
return (
Array.isArray(actual) &&
actual.length == 1 &&
actual[0].includes("blue.png")
);
},
pos: "0:1",
uri: REPORTABLE_PAGE_URL3,
},
{
level: "error",
log(actual) {
// "Blocked loading mixed active content http://tracking.example.org/browser/browser/base/content/test/protectionsUI/benignPage.html",
return (
Array.isArray(actual) &&
actual.length == 1 &&
actual[0].includes("benignPage.html")
);
},
pos: "0:1",
uri: REPORTABLE_PAGE_URL3,
},
{
level: "warn",
log(actual) {
// "The resource at https://trackertest.org/ was blocked because content blocking is enabled.",
return (
Array.isArray(actual) &&
actual.length == 1 &&
actual[0].includes("trackertest.org")
);
},
pos: "0:1",
uri: REPORTABLE_PAGE_URL3,
},
],
});
await BrowserTestUtils.closeWindow(win);
});

View File

@@ -1,34 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that Report Broken Site popups will be
* reset to whichever tab the user is on as they change
* between windows and tabs. */
"use strict";
add_common_setup();
add_task(async function testBackButtonsAreAdded() {
ensureReportBrokenSitePreffedOn();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
let rbs = await AppMenu().openReportBrokenSite();
rbs.isBackButtonEnabled();
await rbs.clickBack();
await rbs.close();
rbs = await HelpMenu().openReportBrokenSite();
ok(!rbs.backButton, "Back button is not shown for Help Menu");
await rbs.close();
rbs = await ProtectionsPanel().openReportBrokenSite();
rbs.isBackButtonEnabled();
await rbs.clickBack();
await rbs.close();
rbs = await HelpMenu().openReportBrokenSite();
ok(!rbs.backButton, "Back button is not shown for Help Menu");
await rbs.close();
});
});

View File

@@ -1,64 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Test that the Report Broken Site errors messages are shown on
* the UI if the user enters an invalid URL or clicks the send
* button while it is disabled due to not selecting a "reason"
*/
"use strict";
add_common_setup();
add_task(async function test() {
ensureReportBrokenSitePreffedOn();
ensureReasonRequired();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
for (const menu of [AppMenu(), ProtectionsPanel(), HelpMenu()]) {
const rbs = await menu.openReportBrokenSite();
const { sendButton, URLInput } = rbs;
rbs.isURLInvalidMessageHidden();
rbs.isReasonNeededMessageHidden();
rbs.setURL("");
window.document.activeElement.blur();
rbs.isURLInvalidMessageShown();
rbs.isReasonNeededMessageHidden();
rbs.setURL("https://asdf");
window.document.activeElement.blur();
rbs.isURLInvalidMessageHidden();
rbs.isReasonNeededMessageHidden();
rbs.setURL("http:/ /asdf");
window.document.activeElement.blur();
rbs.isURLInvalidMessageShown();
rbs.isReasonNeededMessageHidden();
rbs.setURL("https://asdf");
const selectPromise = BrowserTestUtils.waitForSelectPopupShown(window);
EventUtils.synthesizeMouseAtCenter(sendButton, {}, window);
await selectPromise;
rbs.isURLInvalidMessageHidden();
rbs.isReasonNeededMessageShown();
await rbs.dismissDropdownPopup();
rbs.chooseReason("slow");
rbs.isURLInvalidMessageHidden();
rbs.isReasonNeededMessageHidden();
rbs.setURL("");
rbs.chooseReason("choose");
window.ownerGlobal.document.activeElement?.blur();
const focusPromise = BrowserTestUtils.waitForEvent(URLInput, "focus");
EventUtils.synthesizeMouseAtCenter(sendButton, {}, window);
await focusPromise;
rbs.isURLInvalidMessageShown();
rbs.isReasonNeededMessageShown();
rbs.clickCancel();
}
});
});

View File

@@ -1,88 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that the right data is sent for
* private windows and when ETP blocks content.
*/
/* import-globals-from send.js */
/* import-globals-from send_more_info.js */
"use strict";
Services.scriptloader.loadSubScript(
getRootDirectory(gTestPath) + "send_more_info.js",
this
);
const { ExperimentAPI } = ChromeUtils.importESModule(
"resource://nimbus/ExperimentAPI.sys.mjs"
);
const { NimbusTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/NimbusTestUtils.sys.mjs"
);
add_common_setup();
const EXPECTED_EXPERIMENTS_IN_REPORT = [
{ slug: "test-experiment", branch: "branch", kind: "nimbusExperiment" },
{ slug: "test-experiment-rollout", branch: "branch", kind: "nimbusRollout" },
];
let EXPERIMENT_CLEANUPS;
add_setup(async function () {
await ExperimentAPI.ready();
EXPERIMENT_CLEANUPS = [
await NimbusTestUtils.enrollWithFeatureConfig(
{ featureId: "no-feature-firefox-desktop", value: {} },
{ slug: "test-experiment", branchSlug: "branch" }
),
await NimbusTestUtils.enrollWithFeatureConfig(
{ featureId: "no-feature-firefox-desktop", value: {} },
{ slug: "test-experiment-rollout", isRollout: true, branchSlug: "branch" }
),
async () => {
ExperimentAPI.manager.store._deleteForTests("test-experiment-disabled");
await NimbusTestUtils.flushStore();
},
];
await NimbusTestUtils.enrollWithFeatureConfig(
{ featureId: "no-feature-firefox-desktop", value: {} },
{ slug: "test-experiment-disabled" }
);
await ExperimentAPI.manager.unenroll("test-experiment-disabled");
});
add_task(async function testSendButton() {
ensureReportBrokenSitePreffedOn();
ensureReasonOptional();
const tab = await openTab(REPORTABLE_PAGE_URL);
await testSend(tab, AppMenu(), {
experiments: EXPECTED_EXPERIMENTS_IN_REPORT,
});
closeTab(tab);
});
add_task(async function testSendingMoreInfo() {
ensureReportBrokenSitePreffedOn();
ensureSendMoreInfoEnabled();
const tab = await openTab(REPORTABLE_PAGE_URL);
await testSendMoreInfo(tab, HelpMenu(), {
experiments: EXPECTED_EXPERIMENTS_IN_REPORT,
});
closeTab(tab);
});
add_task(async function teardown() {
for (const cleanup of EXPERIMENT_CLEANUPS) {
await cleanup();
}
});

View File

@@ -1,107 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that sending or canceling reports with
* the Send and Cancel buttons work (as well as the Okay button)
*/
"use strict";
add_common_setup();
requestLongerTimeout(2);
async function testPressingKey(key, tabToMatch, makePromise, followUp) {
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
for (const menu of [AppMenu(), ProtectionsPanel(), HelpMenu()]) {
info(
`Opening RBS to test pressing ${key} for ${tabToMatch} on ${menu.menuDescription}`
);
const rbs = await menu.openReportBrokenSite();
const promise = makePromise(rbs);
if (tabToMatch) {
if (await tabTo(tabToMatch)) {
await pressKeyAndAwait(promise, key);
followUp && (await followUp(rbs));
await rbs.close();
ok(true, `was able to activate ${tabToMatch} with keyboard`);
} else {
await rbs.close();
ok(false, `could not tab to ${tabToMatch}`);
}
} else {
await pressKeyAndAwait(promise, key);
followUp && (await followUp(rbs));
await rbs.close();
ok(true, `was able to use keyboard`);
}
}
});
}
add_task(async function testSendMoreInfo() {
ensureReportBrokenSitePreffedOn();
ensureSendMoreInfoEnabled();
await testPressingKey(
"KEY_Enter",
"#report-broken-site-popup-send-more-info-link",
rbs => rbs.waitForSendMoreInfoTab(),
() => gBrowser.removeCurrentTab()
);
});
add_task(async function testCancel() {
ensureReportBrokenSitePreffedOn();
await testPressingKey(
"KEY_Enter",
"#report-broken-site-popup-cancel-button",
rbs => BrowserTestUtils.waitForEvent(rbs.mainView, "ViewHiding")
);
});
add_task(async function testSendAndOkay() {
ensureReportBrokenSitePreffedOn();
await testPressingKey(
"KEY_Enter",
"#report-broken-site-popup-send-button",
rbs => rbs.awaitReportSentViewOpened(),
async rbs => {
await tabTo("#report-broken-site-popup-okay-button");
const promise = BrowserTestUtils.waitForEvent(rbs.sentView, "ViewHiding");
await pressKeyAndAwait(promise, "KEY_Enter");
}
);
});
add_task(async function testESCOnMain() {
ensureReportBrokenSitePreffedOn();
await testPressingKey("KEY_Escape", undefined, rbs =>
BrowserTestUtils.waitForEvent(rbs.mainView, "ViewHiding")
);
});
add_task(async function testESCOnSent() {
ensureReportBrokenSitePreffedOn();
await testPressingKey(
"KEY_Enter",
"#report-broken-site-popup-send-button",
rbs => rbs.awaitReportSentViewOpened(),
async rbs => {
const promise = BrowserTestUtils.waitForEvent(rbs.sentView, "ViewHiding");
await pressKeyAndAwait(promise, "KEY_Escape");
}
);
});
add_task(async function testBackButtons() {
ensureReportBrokenSitePreffedOn();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
for (const menu of [AppMenu(), ProtectionsPanel()]) {
await menu.openReportBrokenSite();
await tabTo("#report-broken-site-popup-mainView .subviewbutton-back");
const promise = BrowserTestUtils.waitForEvent(menu.popup, "ViewShown");
await pressKeyAndAwait(promise, "KEY_Enter");
menu.close();
}
});
});

View File

@@ -1,36 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that the reason dropdown is shown or hidden
* based on its pref, and that its optional and required modes affect
* the Send button and report appropriately.
*/
"use strict";
add_common_setup();
async function ensureLearnMoreLinkWorks(menu) {
const rbs = await menu.openReportBrokenSite();
const { win, mainView, learnMoreLink } = rbs;
ok(learnMoreLink, "Found a learn more link");
const promises = [
BrowserTestUtils.waitForEvent(mainView, "ViewHiding"),
BrowserTestUtils.waitForNewTab(win.gBrowser, LEARN_MORE_TEST_URL),
];
EventUtils.synthesizeMouseAtCenter(learnMoreLink, {}, win);
const results = await Promise.all(promises);
gBrowser.removeTab(results[1]);
}
add_task(async function testLearnMoreLink() {
ensureReportBrokenSitePreffedOn();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
await ensureLearnMoreLinkWorks(AppMenu());
await ensureLearnMoreLinkWorks(HelpMenu());
await ensureLearnMoreLinkWorks(ProtectionsPanel());
});
const telemetry = Glean.webcompatreporting.learnMore.testGetValue();
is(telemetry.length, 3, "Got telemetry");
});

View File

@@ -1,96 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Test that the Report Broken Site menu items are disabled
* when the active tab is not on a reportable URL, and is hidden
* when the feature is disabled via pref. Also ensure that the
* Report Broken Site item that is automatically generated in
* the app menu's help sub-menu is hidden.
*/
"use strict";
add_common_setup();
add_task(async function testMenus() {
ensureReportBrokenSitePreffedOff();
const appMenu = AppMenu();
const menus = [appMenu, ProtectionsPanel(), HelpMenu()];
async function forceMenuItemStateUpdate() {
ReportBrokenSite.enableOrDisableMenuitems(window);
// the hidden/disabled state of all of the menuitems may not update until one
// is rendered; then the related <command>'s state is propagated to them all.
await appMenu.open();
await appMenu.close();
}
await BrowserTestUtils.withNewTab("about:blank", async function () {
await forceMenuItemStateUpdate();
for (const { menuDescription, reportBrokenSite } of menus) {
isMenuItemHidden(
reportBrokenSite,
`${menuDescription} option hidden on invalid page when preffed off`
);
}
});
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
await forceMenuItemStateUpdate();
for (const { menuDescription, reportBrokenSite } of menus) {
isMenuItemHidden(
reportBrokenSite,
`${menuDescription} option hidden on valid page when preffed off`
);
}
});
ensureReportBrokenSitePreffedOn();
await BrowserTestUtils.withNewTab("about:blank", async function () {
await forceMenuItemStateUpdate();
for (const { menuDescription, reportBrokenSite } of menus) {
isMenuItemDisabled(
reportBrokenSite,
`${menuDescription} option disabled on invalid page when preffed on`
);
}
});
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
await forceMenuItemStateUpdate();
for (const { menuDescription, reportBrokenSite } of menus) {
isMenuItemEnabled(
reportBrokenSite,
`${menuDescription} option enabled on valid page when preffed on`
);
}
});
ensureReportBrokenSitePreffedOff();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
await forceMenuItemStateUpdate();
for (const { menuDescription, reportBrokenSite } of menus) {
isMenuItemHidden(
reportBrokenSite,
`${menuDescription} option hidden again when pref toggled back off`
);
}
});
ensureReportBrokenSitePreffedOn();
ensureReportBrokenSiteDisabledByPolicy();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
await forceMenuItemStateUpdate();
for (const { menuDescription, reportBrokenSite } of menus) {
isMenuItemHidden(
reportBrokenSite,
`${menuDescription} option hidden when disabled by DisableFeedbackCommands enterprise policy`
);
}
});
});

View File

@@ -1,56 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Test that the background color of the "report sent"
* view is not green in non-default contrast modes.
*/
"use strict";
add_common_setup();
const HIGH_CONTRAST_MODE_OFF = [[PREFS.USE_ACCESSIBILITY_THEME, 0]];
const HIGH_CONTRAST_MODE_ON = [[PREFS.USE_ACCESSIBILITY_THEME, 1]];
add_task(async function testReportSentViewBGColor() {
ensureReportBrokenSitePreffedOn();
ensureReasonDisabled();
await BrowserTestUtils.withNewTab(
REPORTABLE_PAGE_URL,
async function (browser) {
const { defaultView } = browser.ownerGlobal.document;
const menu = AppMenu();
await SpecialPowers.pushPrefEnv({ set: HIGH_CONTRAST_MODE_OFF });
const rbs = await menu.openReportBrokenSite();
const { mainView, sentView } = rbs;
mainView.style.backgroundColor = "var(--background-color-success)";
const expectedReportSentBGColor =
defaultView.getComputedStyle(mainView).backgroundColor;
mainView.style.backgroundColor = "";
const expectedPrefersReducedBGColor =
defaultView.getComputedStyle(mainView).backgroundColor;
await rbs.clickSend();
is(
defaultView.getComputedStyle(sentView).backgroundColor,
expectedReportSentBGColor,
"Using green bgcolor when not prefers-contrast"
);
await rbs.clickOkay();
await SpecialPowers.pushPrefEnv({ set: HIGH_CONTRAST_MODE_ON });
await menu.openReportBrokenSite();
await rbs.clickSend();
is(
defaultView.getComputedStyle(sentView).backgroundColor,
expectedPrefersReducedBGColor,
"Using default bgcolor when prefers-contrast"
);
await rbs.clickOkay();
}
);
});

View File

@@ -1,156 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that the reason dropdown is shown or hidden
* based on its pref, and that its optional and required modes affect
* the Send button and report appropriately.
*/
"use strict";
add_common_setup();
requestLongerTimeout(2);
async function clickSendAndCheckPing(rbs, expectedReason = null) {
await GleanPings.brokenSiteReport.testSubmission(
() =>
Assert.equal(
Glean.brokenSiteReport.breakageCategory.testGetValue(),
expectedReason
),
() => rbs.clickSend()
);
}
add_task(async function testReasonDropdown() {
ensureReportBrokenSitePreffedOn();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
ensureReasonDisabled();
let rbs = await AppMenu().openReportBrokenSite();
await rbs.isReasonHidden();
await rbs.isSendButtonEnabled();
await clickSendAndCheckPing(rbs);
await rbs.clickOkay();
ensureReasonOptional();
rbs = await AppMenu().openReportBrokenSite();
await rbs.isReasonOptional();
await rbs.isSendButtonEnabled();
await clickSendAndCheckPing(rbs);
await rbs.clickOkay();
rbs = await AppMenu().openReportBrokenSite();
await rbs.isReasonOptional();
rbs.chooseReason("slow");
await rbs.isSendButtonEnabled();
await clickSendAndCheckPing(rbs, "slow");
await rbs.clickOkay();
ensureReasonRequired();
rbs = await AppMenu().openReportBrokenSite();
await rbs.isReasonRequired();
await rbs.isSendButtonEnabled();
const selectPromise = BrowserTestUtils.waitForSelectPopupShown(window);
EventUtils.synthesizeMouseAtCenter(rbs.sendButton, {}, window);
await selectPromise;
rbs.chooseReason("media");
await rbs.dismissDropdownPopup();
await rbs.isSendButtonEnabled();
await clickSendAndCheckPing(rbs, "media");
await rbs.clickOkay();
});
});
async function getListItems(rbs) {
const items = Array.from(rbs.reasonInput.querySelectorAll("option")).map(i =>
i.id.replace("report-broken-site-popup-reason-", "")
);
Assert.equal(items[0], "choose", "First option is always 'choose'");
return items.join(",");
}
add_task(async function testReasonDropdownRandomized() {
ensureReportBrokenSitePreffedOn();
ensureReasonOptional();
const USER_ID_PREF = "app.normandy.user_id";
const RANDOMIZE_PREF = "ui.new-webcompat-reporter.reason-dropdown.randomized";
const origNormandyUserID = Services.prefs.getCharPref(
USER_ID_PREF,
undefined
);
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
// confirm that the default order is initially used
Services.prefs.setBoolPref(RANDOMIZE_PREF, false);
const rbs = await AppMenu().openReportBrokenSite();
const defaultOrder = [
"choose",
"checkout",
"load",
"slow",
"media",
"content",
"account",
"adblocker",
"notsupported",
"other",
];
Assert.deepEqual(
await getListItems(rbs),
defaultOrder,
"non-random order is correct"
);
// confirm that a random order happens per user
let randomOrder;
let isRandomized = false;
Services.prefs.setBoolPref(RANDOMIZE_PREF, true);
// This becomes ClientEnvironment.randomizationId, which we can set to
// any value which results in a different order from the default ordering.
Services.prefs.setCharPref("app.normandy.user_id", "dummy");
// clicking cancel triggers a reset, which is when the randomization
// logic is called. so we must click cancel after pref-changes here.
rbs.clickCancel();
await AppMenu().openReportBrokenSite();
randomOrder = await getListItems(rbs);
Assert.notEqual(
randomOrder,
defaultOrder,
"options are randomized with pref on"
);
// confirm that the order doesn't change per user
isRandomized = false;
for (let attempt = 0; attempt < 5; ++attempt) {
rbs.clickCancel();
await AppMenu().openReportBrokenSite();
const order = await getListItems(rbs);
if (order != randomOrder) {
isRandomized = true;
break;
}
}
Assert.ok(!isRandomized, "options keep the same order per user");
// confirm that the order reverts to the default if pref flipped to false
Services.prefs.setBoolPref(RANDOMIZE_PREF, false);
rbs.clickCancel();
await AppMenu().openReportBrokenSite();
Assert.deepEqual(
defaultOrder,
await getListItems(rbs),
"reverts to non-random order correctly"
);
rbs.clickCancel();
});
Services.prefs.setCharPref(USER_ID_PREF, origNormandyUserID);
});

View File

@@ -1,79 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that sending or canceling reports with
* the Send and Cancel buttons work (as well as the Okay button)
*/
/* import-globals-from send.js */
"use strict";
Services.scriptloader.loadSubScript(
getRootDirectory(gTestPath) + "send.js",
this
);
add_common_setup();
requestLongerTimeout(10);
async function testCancel(menu, url, description) {
let rbs = await menu.openAndPrefillReportBrokenSite(url, description);
await rbs.clickCancel();
ok(!rbs.opened, "clicking Cancel closes Report Broken Site");
// re-opening the panel, the url and description should be reset
rbs = await menu.openReportBrokenSite();
rbs.isMainViewResetToCurrentTab();
rbs.close();
}
add_task(async function testSendButton() {
ensureReportBrokenSitePreffedOn();
ensureReasonOptional();
const tab1 = await openTab(REPORTABLE_PAGE_URL);
await testSend(tab1, AppMenu());
const tab2 = await openTab(REPORTABLE_PAGE_URL);
await testSend(tab2, ProtectionsPanel(), {
url: "https://test.org/test/#fake",
breakageCategory: "media",
description: "test description",
});
closeTab(tab1);
closeTab(tab2);
});
add_task(async function testCancelButton() {
ensureReportBrokenSitePreffedOn();
const tab1 = await openTab(REPORTABLE_PAGE_URL);
await testCancel(AppMenu());
await testCancel(ProtectionsPanel());
await testCancel(HelpMenu());
const tab2 = await openTab(REPORTABLE_PAGE_URL);
await testCancel(AppMenu());
await testCancel(ProtectionsPanel());
await testCancel(HelpMenu());
const win2 = await BrowserTestUtils.openNewBrowserWindow();
const tab3 = await openTab(REPORTABLE_PAGE_URL2, win2);
await testCancel(AppMenu(win2));
await testCancel(ProtectionsPanel(win2));
await testCancel(HelpMenu(win2));
closeTab(tab3);
await BrowserTestUtils.closeWindow(win2);
closeTab(tab1);
closeTab(tab2);
});

View File

@@ -1,65 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests that the send more info link appears only when its pref
* is set to true, and that when clicked it will open a tab to
* the webcompat.com endpoint and send the right data.
*/
/* import-globals-from send_more_info.js */
"use strict";
const VIDEO_URL = `${BASE_URL}/videotest.mp4`;
Services.scriptloader.loadSubScript(
getRootDirectory(gTestPath) + "send_more_info.js",
this
);
add_common_setup();
requestLongerTimeout(2);
add_task(async function testSendMoreInfoPref() {
ensureReportBrokenSitePreffedOn();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
await changeTab(gBrowser.selectedTab, REPORTABLE_PAGE_URL);
ensureSendMoreInfoDisabled();
let rbs = await AppMenu().openReportBrokenSite();
await rbs.isSendMoreInfoHidden();
await rbs.close();
ensureSendMoreInfoEnabled();
rbs = await AppMenu().openReportBrokenSite();
await rbs.isSendMoreInfoShown();
await rbs.close();
});
});
add_task(async function testSendingMoreInfo() {
ensureReportBrokenSitePreffedOn();
ensureSendMoreInfoEnabled();
const tab = await openTab(REPORTABLE_PAGE_URL);
await testSendMoreInfo(tab, AppMenu());
await changeTab(tab, REPORTABLE_PAGE_URL2);
await testSendMoreInfo(tab, ProtectionsPanel(), {
url: "https://override.com",
description: "another",
expectNoTabDetails: true,
});
// also load a video to ensure system codec
// information is loaded and properly sent
const tab2 = await openTab(VIDEO_URL);
await testSendMoreInfo(tab2, HelpMenu());
closeTab(tab2);
closeTab(tab);
});

View File

@@ -1,134 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests of the expected tab key element focus order */
"use strict";
add_common_setup();
requestLongerTimeout(2);
async function ensureTabOrder(order, win = window) {
const config = { window: win };
for (let matches of order) {
// We need to tab through all elements in each match array in any order
if (!Array.isArray(matches)) {
matches = [matches];
}
let matchesLeft = matches.length;
while (matchesLeft--) {
const target = await pressKeyAndGetFocus("VK_TAB", config);
let foundMatch = false;
for (const [i, selector] of matches.entries()) {
foundMatch = selector && target.matches(selector);
if (foundMatch) {
matches[i] = "";
break;
}
}
ok(
foundMatch,
`Expected [${matches}] next, got id=${target.id}, class=${target.className}, ${target}`
);
if (!foundMatch) {
return false;
}
}
}
return true;
}
async function ensureExpectedTabOrder(
expectBackButton,
expectReason,
expectSendMoreInfo
) {
const { activeElement } = window.document;
is(
activeElement?.id,
"report-broken-site-popup-url",
"URL is already focused"
);
const order = [];
if (expectReason) {
order.push("#report-broken-site-popup-reason");
}
order.push("#report-broken-site-popup-description");
order.push("#report-broken-site-popup-blocked-trackers-checkbox");
if (expectSendMoreInfo) {
order.push("#report-broken-site-popup-send-more-info-link");
}
// moz-button-groups swap the order of buttons to follow
// platform conventions, so the order of send/cancel will vary.
order.push([
"#report-broken-site-popup-cancel-button",
"#report-broken-site-popup-send-button",
]);
if (expectBackButton) {
order.push(".subviewbutton-back");
}
order.push("#report-broken-site-popup-learn-more-link");
order.push("#report-broken-site-popup-url"); // check that we've cycled back
return ensureTabOrder(order);
}
async function testTabOrder(menu) {
ensureReasonDisabled();
ensureSendMoreInfoDisabled();
const { showsBackButton } = menu;
let rbs = await menu.openReportBrokenSite();
await ensureExpectedTabOrder(showsBackButton, false, false);
await rbs.close();
ensureSendMoreInfoEnabled();
rbs = await menu.openReportBrokenSite();
await ensureExpectedTabOrder(showsBackButton, false, true);
await rbs.close();
ensureReasonOptional();
rbs = await menu.openReportBrokenSite();
await ensureExpectedTabOrder(showsBackButton, true, true);
await rbs.close();
ensureReasonRequired();
rbs = await menu.openReportBrokenSite();
await ensureExpectedTabOrder(showsBackButton, true, true);
await rbs.close();
rbs = await menu.openReportBrokenSite();
rbs.chooseReason("slow");
await ensureExpectedTabOrder(showsBackButton, true, true);
await rbs.clickCancel();
ensureSendMoreInfoDisabled();
rbs = await menu.openReportBrokenSite();
await ensureExpectedTabOrder(showsBackButton, true, false);
await rbs.close();
rbs = await menu.openReportBrokenSite();
rbs.chooseReason("slow");
await ensureExpectedTabOrder(showsBackButton, true, false);
await rbs.clickCancel();
ensureReasonOptional();
rbs = await menu.openReportBrokenSite();
await ensureExpectedTabOrder(showsBackButton, true, false);
await rbs.close();
ensureReasonDisabled();
rbs = await menu.openReportBrokenSite();
await ensureExpectedTabOrder(showsBackButton, false, false);
await rbs.close();
}
add_task(async function testTabOrdering() {
ensureReportBrokenSitePreffedOn();
ensureSendMoreInfoEnabled();
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
await testTabOrder(AppMenu());
await testTabOrder(ProtectionsPanel());
await testTabOrder(HelpMenu());
});
});

View File

@@ -1,81 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests to ensure that Report Broken Site popups will be
* reset to whichever tab the user is on as they change
* between windows and tabs. */
"use strict";
add_common_setup();
add_task(async function testResetsProperlyOnTabSwitch() {
ensureReportBrokenSitePreffedOn();
const badTab = await openTab("about:blank");
const goodTab1 = await openTab(REPORTABLE_PAGE_URL);
const goodTab2 = await openTab(REPORTABLE_PAGE_URL2);
const appMenu = AppMenu();
const protPanel = ProtectionsPanel();
let rbs = await appMenu.openReportBrokenSite();
rbs.isMainViewResetToCurrentTab();
rbs.close();
gBrowser.selectedTab = goodTab1;
rbs = await protPanel.openReportBrokenSite();
rbs.isMainViewResetToCurrentTab();
rbs.close();
gBrowser.selectedTab = badTab;
await appMenu.open();
appMenu.isReportBrokenSiteDisabled();
await appMenu.close();
gBrowser.selectedTab = goodTab1;
rbs = await protPanel.openReportBrokenSite();
rbs.isMainViewResetToCurrentTab();
rbs.close();
closeTab(badTab);
closeTab(goodTab1);
closeTab(goodTab2);
});
add_task(async function testResetsProperlyOnWindowSwitch() {
ensureReportBrokenSitePreffedOn();
const tab1 = await openTab(REPORTABLE_PAGE_URL);
const win2 = await BrowserTestUtils.openNewBrowserWindow();
const tab2 = await openTab(REPORTABLE_PAGE_URL2, win2);
const appMenu1 = AppMenu();
const appMenu2 = ProtectionsPanel(win2);
let rbs2 = await appMenu2.openReportBrokenSite();
rbs2.isMainViewResetToCurrentTab();
rbs2.close();
// flip back to tab1's window and ensure its URL pops up instead of tab2's URL
await switchToWindow(window);
isSelectedTab(window, tab1); // sanity check
let rbs1 = await appMenu1.openReportBrokenSite();
rbs1.isMainViewResetToCurrentTab();
rbs1.close();
// likewise flip back to tab2's window and ensure its URL pops up instead of tab1's URL
await switchToWindow(win2);
isSelectedTab(win2, tab2); // sanity check
rbs2 = await appMenu2.openReportBrokenSite();
rbs2.isMainViewResetToCurrentTab();
rbs2.close();
closeTab(tab1);
closeTab(tab2);
await BrowserTestUtils.closeWindow(win2);
});

View File

@@ -1,45 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Tests that when Report Broken Site is disabled, it will
* send the user to webcompat.com when clicked and it the
* relevant tab's report data.
*/
/* import-globals-from send_more_info.js */
"use strict";
Services.scriptloader.loadSubScript(
getRootDirectory(gTestPath) + "send_more_info.js",
this
);
add_common_setup();
const VIDEO_URL = `${BASE_URL}/videotest.mp4`;
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["test.wait300msAfterTabSwitch", true]],
});
});
add_task(async function testWebcompatComFallbacks() {
ensureReportBrokenSitePreffedOff();
const tab = await openTab(REPORTABLE_PAGE_URL);
await testWebcompatComFallback(tab, AppMenu());
await changeTab(tab, REPORTABLE_PAGE_URL2);
await testWebcompatComFallback(tab, ProtectionsPanel());
// also load a video to ensure system codec
// information is loaded and properly sent
const tab2 = await openTab(VIDEO_URL);
await testWebcompatComFallback(tab2, HelpMenu());
closeTab(tab2);
closeTab(tab);
});

View File

@@ -1,22 +0,0 @@
<!DOCTYPE HTML>
<!-- 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/. -->
<html dir="ltr" xml:lang="en-US" lang="en-US">
<head>
<meta charset="utf8">
<script>
window.marfeel = 1;
window.Mobify = { Tag: 1 };
window.FastClick = 1;
</script>
</head>
<body>
<!-- blocked tracking content -->
<iframe src="https://trackertest.org/"></iframe>
<!-- mixed active content -->
<iframe src="http://tracking.example.org/browser/browser/base/content/test/protectionsUI/benignPage.html"></iframe>
<!-- mixed display content -->
<img src="http://example.com/tests/image/test/mochitest/blue.png"></img>
</body>
</html>

View File

@@ -1,922 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
const { CustomizableUITestUtils } = ChromeUtils.importESModule(
"resource://testing-common/CustomizableUITestUtils.sys.mjs"
);
const { EnterprisePolicyTesting, PoliciesPrefTracker } =
ChromeUtils.importESModule(
"resource://testing-common/EnterprisePolicyTesting.sys.mjs"
);
const { UrlClassifierTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/UrlClassifierTestUtils.sys.mjs"
);
const { ReportBrokenSite } = ChromeUtils.importESModule(
"moz-src:///browser/components/reportbrokensite/ReportBrokenSite.sys.mjs"
);
const BASE_URL =
"https://example.com/browser/browser/components/reportbrokensite/test/browser/";
const REPORTABLE_PAGE_URL = "https://example.com";
const REPORTABLE_PAGE_URL2 = REPORTABLE_PAGE_URL.replace(".com", ".org");
const REPORTABLE_PAGE_URL3 = `${BASE_URL}example_report_page.html`;
const SUMO_BASE_URL = Services.urlFormatter.formatURLPref(
"app.support.baseURL"
);
const LEARN_MORE_TEST_URL = `${SUMO_BASE_URL}report-broken-site`;
const NEW_REPORT_ENDPOINT_TEST_URL = `${BASE_URL}sendMoreInfoTestEndpoint.html`;
const PREFS = {
DATAREPORTING_ENABLED: "datareporting.healthreport.uploadEnabled",
REPORTER_ENABLED: "ui.new-webcompat-reporter.enabled",
REASON: "ui.new-webcompat-reporter.reason-dropdown",
SEND_MORE_INFO: "ui.new-webcompat-reporter.send-more-info-link",
NEW_REPORT_ENDPOINT: "ui.new-webcompat-reporter.new-report-endpoint",
TOUCH_EVENTS: "dom.w3c_touch_events.enabled",
USE_ACCESSIBILITY_THEME: "ui.useAccessibilityTheme",
};
function add_common_setup() {
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [
[PREFS.NEW_REPORT_ENDPOINT, NEW_REPORT_ENDPOINT_TEST_URL],
// set touch events to auto-detect, as the pref gets set to 1 somewhere
// while tests are running, making hasTouchScreen checks unreliable.
[PREFS.TOUCH_EVENTS, 2],
],
});
registerCleanupFunction(function () {
for (const prefName of Object.values(PREFS)) {
Services.prefs.clearUserPref(prefName);
}
Services.telemetry.clearEvents();
Services.fog.testResetFOG();
});
});
}
function areObjectsEqual(actual, expected, path = "") {
if (typeof expected == "function") {
try {
const passes = expected(actual);
if (!passes) {
info(`${path} not pass check function: ${actual}`);
}
return passes;
} catch (e) {
info(`${path} threw exception:
got: ${typeof actual}, ${actual}
expected: ${typeof expected}, ${expected}
exception: ${e.message}
${e.stack}`);
return false;
}
}
if (typeof actual != typeof expected) {
info(`${path} types do not match:
got: ${typeof actual}, ${actual}
expected: ${typeof expected}, ${expected}`);
return false;
}
if (typeof actual != "object" || actual === null || expected === null) {
if (actual !== expected) {
info(`${path} does not match
got: ${typeof actual}, ${actual}
expected: ${typeof expected}, ${expected}`);
return false;
}
return true;
}
const prefix = path ? `${path}.` : path;
for (const [key, val] of Object.entries(actual)) {
if (!(key in expected)) {
info(`Extra ${prefix}${key}: ${val}`);
return false;
}
}
let result = true;
for (const [key, expectedVal] of Object.entries(expected)) {
if (key in actual) {
if (!areObjectsEqual(actual[key], expectedVal, `${prefix}${key}`)) {
result = false;
}
} else {
info(`Missing ${prefix}${key} (${expectedVal})`);
result = false;
}
}
return result;
}
function clickAndAwait(toClick, evt, target) {
const menuPromise = BrowserTestUtils.waitForEvent(target, evt);
EventUtils.synthesizeMouseAtCenter(toClick, {}, window);
return menuPromise;
}
async function openTab(url, win) {
const options = {
gBrowser:
win?.gBrowser ||
Services.wm.getMostRecentWindow("navigator:browser").gBrowser,
url,
};
return BrowserTestUtils.openNewForegroundTab(options);
}
async function changeTab(tab, url) {
BrowserTestUtils.startLoadingURIString(tab.linkedBrowser, url);
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
}
function closeTab(tab) {
BrowserTestUtils.removeTab(tab);
}
function switchToWindow(win) {
const promises = [
BrowserTestUtils.waitForEvent(win, "focus"),
BrowserTestUtils.waitForEvent(win, "activate"),
];
win.focus();
return Promise.all(promises);
}
function isSelectedTab(win, tab) {
const selectedTab = win.document.querySelector(".tabbrowser-tab[selected]");
is(selectedTab, tab);
}
async function setupPolicyEngineWithJson(json, customSchema) {
PoliciesPrefTracker.restoreDefaultValues();
if (typeof json != "object") {
let filePath = getTestFilePath(json ? json : "non-existing-file.json");
return EnterprisePolicyTesting.setupPolicyEngineWithJson(
filePath,
customSchema
);
}
return EnterprisePolicyTesting.setupPolicyEngineWithJson(json, customSchema);
}
async function ensureReportBrokenSiteDisabledByPolicy() {
await setupPolicyEngineWithJson({
policies: {
DisableFeedbackCommands: true,
},
});
}
registerCleanupFunction(async function resetPolicies() {
if (Services.policies.status != Ci.nsIEnterprisePolicies.INACTIVE) {
await setupPolicyEngineWithJson("");
}
EnterprisePolicyTesting.resetRunOnceState();
PoliciesPrefTracker.restoreDefaultValues();
PoliciesPrefTracker.stop();
});
function ensureReportBrokenSitePreffedOn() {
Services.prefs.setBoolPref(PREFS.DATAREPORTING_ENABLED, true);
Services.prefs.setBoolPref(PREFS.REPORTER_ENABLED, true);
ensureReasonDisabled();
}
function ensureReportBrokenSitePreffedOff() {
Services.prefs.setBoolPref(PREFS.REPORTER_ENABLED, false);
}
function ensureSendMoreInfoEnabled() {
Services.prefs.setBoolPref(PREFS.SEND_MORE_INFO, true);
}
function ensureSendMoreInfoDisabled() {
Services.prefs.setBoolPref(PREFS.SEND_MORE_INFO, false);
}
function ensureReasonDisabled() {
Services.prefs.setIntPref(PREFS.REASON, 0);
}
function ensureReasonOptional() {
Services.prefs.setIntPref(PREFS.REASON, 1);
}
function ensureReasonRequired() {
Services.prefs.setIntPref(PREFS.REASON, 2);
}
function isMenuItemEnabled(menuItem, itemDesc) {
ok(!menuItem.hidden, `${itemDesc} menu item is shown`);
ok(!menuItem.disabled, `${itemDesc} menu item is enabled`);
}
function isMenuItemHidden(menuItem, itemDesc) {
ok(
!menuItem || menuItem.hidden || !BrowserTestUtils.isVisible(menuItem),
`${itemDesc} menu item is hidden`
);
}
function isMenuItemDisabled(menuItem, itemDesc) {
ok(!menuItem.hidden, `${itemDesc} menu item is shown`);
ok(menuItem.disabled, `${itemDesc} menu item is disabled`);
}
function waitForWebcompatComTab(gBrowser) {
return BrowserTestUtils.waitForNewTab(gBrowser, NEW_REPORT_ENDPOINT_TEST_URL);
}
class ReportBrokenSiteHelper {
sourceMenu = undefined;
win = undefined;
constructor(sourceMenu) {
this.sourceMenu = sourceMenu;
this.win = sourceMenu.win;
}
getViewNode(id) {
return PanelMultiView.getViewNode(this.win.document, id);
}
get mainView() {
return this.getViewNode("report-broken-site-popup-mainView");
}
get sentView() {
return this.getViewNode("report-broken-site-popup-reportSentView");
}
get openPanel() {
return this.mainView?.closest("panel");
}
get opened() {
return this.openPanel?.hasAttribute("panelopen");
}
async click(triggerMenuItem) {
const window = triggerMenuItem.ownerGlobal;
await EventUtils.synthesizeMouseAtCenter(triggerMenuItem, {}, window);
}
async open(triggerMenuItem) {
const shownPromise = BrowserTestUtils.waitForEvent(
this.mainView,
"ViewShown"
);
const focusPromise = BrowserTestUtils.waitForEvent(this.URLInput, "focus");
await this.click(triggerMenuItem);
await shownPromise;
await focusPromise;
await BrowserTestUtils.waitForCondition(
() => this.URLInput.selectionStart === 0
);
}
async #assertClickAndViewChanges(button, view, newView, newFocus) {
ok(view.closest("panel").hasAttribute("panelopen"), "Panel is open");
ok(BrowserTestUtils.isVisible(button), "Button is visible");
ok(!button.disabled, "Button is enabled");
const promises = [];
if (newView) {
if (newView.nodeName == "panel") {
promises.push(BrowserTestUtils.waitForEvent(newView, "popupshown"));
} else {
promises.push(BrowserTestUtils.waitForEvent(newView, "ViewShown"));
}
} else {
promises.push(BrowserTestUtils.waitForEvent(view, "ViewHiding"));
}
if (newFocus) {
promises.push(BrowserTestUtils.waitForEvent(newFocus, "focus"));
}
EventUtils.synthesizeMouseAtCenter(button, {}, this.win);
await Promise.all(promises);
}
async awaitReportSentViewOpened() {
await Promise.all([
BrowserTestUtils.waitForEvent(this.sentView, "ViewShown"),
BrowserTestUtils.waitForEvent(this.okayButton, "focus"),
]);
}
async clickSend() {
await this.#assertClickAndViewChanges(
this.sendButton,
this.mainView,
this.sentView,
this.okayButton
);
}
waitForSendMoreInfoTab() {
return BrowserTestUtils.waitForNewTab(
this.win.gBrowser,
NEW_REPORT_ENDPOINT_TEST_URL
);
}
async clickSendMoreInfo() {
const newTabPromise = waitForWebcompatComTab(this.win.gBrowser);
EventUtils.synthesizeMouseAtCenter(this.sendMoreInfoLink, {}, this.win);
const newTab = await newTabPromise;
const receivedData = await SpecialPowers.spawn(
newTab.linkedBrowser,
[],
async function () {
await content.wrappedJSObject.messageArrived;
return content.wrappedJSObject.message;
}
);
this.win.gBrowser.removeCurrentTab();
return receivedData;
}
async clickCancel() {
await this.#assertClickAndViewChanges(this.cancelButton, this.mainView);
}
async clickOkay() {
await this.#assertClickAndViewChanges(this.okayButton, this.sentView);
}
async clickBack() {
await this.#assertClickAndViewChanges(
this.backButton,
this.sourceMenu.popup
);
}
isBackButtonEnabled() {
ok(BrowserTestUtils.isVisible(this.backButton), "Back button is visible");
ok(!this.backButton.disabled, "Back button is enabled");
}
close() {
if (this.opened) {
this.openPanel?.hidePopup(false);
}
this.sourceMenu?.close();
}
// UI element getters
get URLInput() {
return this.getViewNode("report-broken-site-popup-url");
}
get URLInvalidMessage() {
return this.getViewNode("report-broken-site-popup-invalid-url-msg");
}
get reasonInput() {
return this.getViewNode("report-broken-site-popup-reason");
}
get reasonDropdownPopup() {
return this.win.document.getElementById("ContentSelectDropdown").menupopup;
}
get reasonRequiredMessage() {
return this.getViewNode("report-broken-site-popup-missing-reason-msg");
}
get reasonLabelRequired() {
return this.getViewNode("report-broken-site-popup-reason-label");
}
get reasonLabelOptional() {
return this.getViewNode("report-broken-site-popup-reason-optional-label");
}
get descriptionTextarea() {
return this.getViewNode("report-broken-site-popup-description");
}
get learnMoreLink() {
return this.getViewNode("report-broken-site-popup-learn-more-link");
}
get sendMoreInfoLink() {
return this.getViewNode("report-broken-site-popup-send-more-info-link");
}
get backButton() {
return this.mainView.querySelector(".subviewbutton-back");
}
get blockedTrackersCheckbox() {
return this.getViewNode(
"report-broken-site-popup-blocked-trackers-checkbox"
);
}
set blockedTrackersCheckbox(checked) {
this.blockedTrackersCheckbox.checked = checked;
}
get sendButton() {
return this.getViewNode("report-broken-site-popup-send-button");
}
get cancelButton() {
return this.getViewNode("report-broken-site-popup-cancel-button");
}
get okayButton() {
return this.getViewNode("report-broken-site-popup-okay-button");
}
// Test helpers
#setInput(input, value) {
input.value = value;
input.dispatchEvent(
new UIEvent("input", { bubbles: true, view: this.win })
);
}
setURL(value) {
this.#setInput(this.URLInput, value);
}
chooseReason(value) {
const item = this.getViewNode(`report-broken-site-popup-reason-${value}`);
this.reasonInput.selectedIndex = item.index;
}
dismissDropdownPopup() {
const popup = this.reasonDropdownPopup;
const menuPromise = BrowserTestUtils.waitForPopupEvent(popup, "hidden");
popup.hidePopup();
return menuPromise;
}
setDescription(value) {
this.#setInput(this.descriptionTextarea, value);
}
isURL(expected) {
is(this.URLInput.value, expected);
}
isURLInvalidMessageShown() {
ok(
BrowserTestUtils.isVisible(this.URLInvalidMessage),
"'Please enter a valid URL' message is shown"
);
}
isURLInvalidMessageHidden() {
ok(
!BrowserTestUtils.isVisible(this.URLInvalidMessage),
"'Please enter a valid URL' message is hidden"
);
}
isReasonNeededMessageShown() {
ok(
BrowserTestUtils.isVisible(this.reasonRequiredMessage),
"'Please choose a reason' message is shown"
);
}
isReasonNeededMessageHidden() {
ok(
!BrowserTestUtils.isVisible(this.reasonRequiredMessage),
"'Please choose a reason' message is hidden"
);
}
isSendButtonEnabled() {
ok(BrowserTestUtils.isVisible(this.sendButton), "Send button is visible");
ok(!this.sendButton.disabled, "Send button is enabled");
}
isSendButtonDisabled() {
ok(BrowserTestUtils.isVisible(this.sendButton), "Send button is visible");
ok(this.sendButton.disabled, "Send button is disabled");
}
isSendMoreInfoShown() {
ok(
BrowserTestUtils.isVisible(this.sendMoreInfoLink),
"send more info is shown"
);
}
isSendMoreInfoHidden() {
ok(
!BrowserTestUtils.isVisible(this.sendMoreInfoLink),
"send more info is hidden"
);
}
isSendMoreInfoShownOrHiddenAppropriately() {
if (Services.prefs.getBoolPref(PREFS.SEND_MORE_INFO)) {
this.isSendMoreInfoShown();
} else {
this.isSendMoreInfoHidden();
}
}
isReasonHidden() {
ok(
!BrowserTestUtils.isVisible(this.reasonInput),
"reason drop-down is hidden"
);
ok(
!BrowserTestUtils.isVisible(this.reasonLabelOptional),
"optional reason label is hidden"
);
ok(
!BrowserTestUtils.isVisible(this.reasonLabelRequired),
"required reason label is hidden"
);
}
isReasonRequired() {
ok(
BrowserTestUtils.isVisible(this.reasonInput),
"reason drop-down is shown"
);
ok(
!BrowserTestUtils.isVisible(this.reasonLabelOptional),
"optional reason label is hidden"
);
ok(
BrowserTestUtils.isVisible(this.reasonLabelRequired),
"required reason label is shown"
);
}
isReasonOptional() {
ok(
BrowserTestUtils.isVisible(this.reasonInput),
"reason drop-down is shown"
);
ok(
BrowserTestUtils.isVisible(this.reasonLabelOptional),
"optional reason label is shown"
);
ok(
!BrowserTestUtils.isVisible(this.reasonLabelRequired),
"required reason label is hidden"
);
}
isReasonShownOrHiddenAppropriately() {
const pref = Services.prefs.getIntPref(PREFS.REASON);
if (pref == 2) {
this.isReasonOptional();
} else if (pref == 1) {
this.isReasonOptional();
} else {
this.isReasonHidden();
}
}
isDescription(expected) {
return this.descriptionTextarea.value == expected;
}
isMainViewResetToCurrentTab() {
this.isURL(this.win.gBrowser.selectedBrowser.currentURI.spec);
this.isDescription("");
this.isReasonShownOrHiddenAppropriately();
this.isSendMoreInfoShownOrHiddenAppropriately();
}
}
class MenuHelper {
menuDescription = undefined;
win = undefined;
constructor(win = window) {
this.win = win;
}
getViewNode(id) {
return PanelMultiView.getViewNode(this.win.document, id);
}
get showsBackButton() {
return true;
}
get reportBrokenSite() {
throw new Error("Should be defined in derived class");
}
get popup() {
throw new Error("Should be defined in derived class");
}
get opened() {
return this.popup?.hasAttribute("panelopen");
}
async open() {}
async close() {}
isReportBrokenSiteDisabled() {
return isMenuItemDisabled(this.reportBrokenSite, this.menuDescription);
}
isReportBrokenSiteEnabled() {
return isMenuItemEnabled(this.reportBrokenSite, this.menuDescription);
}
isReportBrokenSiteHidden() {
return isMenuItemHidden(this.reportBrokenSite, this.menuDescription);
}
async clickReportBrokenSiteAndAwaitWebCompatTabData() {
const newTabPromise = waitForWebcompatComTab(this.win.gBrowser);
await this.clickReportBrokenSite();
const newTab = await newTabPromise;
const receivedData = await SpecialPowers.spawn(
newTab.linkedBrowser,
[],
async function () {
await content.wrappedJSObject.messageArrived;
return content.wrappedJSObject.message;
}
);
this.win.gBrowser.removeCurrentTab();
return receivedData;
}
async clickReportBrokenSite() {
if (!this.opened) {
await this.open();
}
isMenuItemEnabled(this.reportBrokenSite, this.menuDescription);
const rbs = new ReportBrokenSiteHelper(this);
await rbs.click(this.reportBrokenSite);
return rbs;
}
async openReportBrokenSite() {
if (!this.opened) {
await this.open();
}
isMenuItemEnabled(this.reportBrokenSite, this.menuDescription);
const rbs = new ReportBrokenSiteHelper(this);
await rbs.open(this.reportBrokenSite);
return rbs;
}
async openAndPrefillReportBrokenSite(url = null, description = "") {
let rbs = await this.openReportBrokenSite();
rbs.isMainViewResetToCurrentTab();
if (url) {
rbs.setURL(url);
}
if (description) {
rbs.setDescription(description);
}
return rbs;
}
}
class AppMenuHelper extends MenuHelper {
menuDescription = "AppMenu";
get reportBrokenSite() {
return this.getViewNode("appMenu-report-broken-site-button");
}
get popup() {
return this.win.document.getElementById("appMenu-popup");
}
async open() {
await new CustomizableUITestUtils(this.win).openMainMenu();
}
async close() {
if (this.opened) {
await new CustomizableUITestUtils(this.win).hideMainMenu();
}
}
}
class HelpMenuHelper extends MenuHelper {
menuDescription = "Help Menu";
get showsBackButton() {
return false;
}
get reportBrokenSite() {
return this.win.document.getElementById("help_reportBrokenSite");
}
get popup() {
return this.getViewNode("PanelUI-helpView");
}
get helpMenu() {
return this.win.document.getElementById("menu_HelpPopup");
}
async openReportBrokenSite() {
// We can't actually open the Help menu properly in testing, so the best
// we can do to open its Report Broken Site panel is to force its DOM to be
// prepared, and then soft-click the Report Broken Site menuitem to open it.
await this.open();
const shownPromise = BrowserTestUtils.waitForEvent(
this.win,
"ViewShown",
true,
e => e.target.classList.contains("report-broken-site-view")
);
this.reportBrokenSite.click();
await shownPromise;
return new ReportBrokenSiteHelper(this);
}
async clickReportBrokenSite() {
await this.open();
this.reportBrokenSite.click();
return new ReportBrokenSiteHelper(this);
}
async open() {
const { helpMenu } = this;
const promise = BrowserTestUtils.waitForEvent(helpMenu, "popupshown");
// This event-faking method was copied from browser_title_case_menus.js.
// We can't actually open the Help menu in testing, but this lets us
// force its DOM to be properly built.
helpMenu.dispatchEvent(new MouseEvent("popupshowing", { bubbles: true }));
helpMenu.dispatchEvent(new MouseEvent("popupshown", { bubbles: true }));
await promise;
}
async close() {
const { helpMenu } = this;
const promise = BrowserTestUtils.waitForPopupEvent(helpMenu, "hidden");
// (Also copied from browser_title_case_menus.js)
// Just for good measure, we'll fire the popuphiding/popuphidden events
// after we close the menupopups.
helpMenu.dispatchEvent(new MouseEvent("popuphiding", { bubbles: true }));
helpMenu.dispatchEvent(new MouseEvent("popuphidden", { bubbles: true }));
await promise;
}
}
class ProtectionsPanelHelper extends MenuHelper {
menuDescription = "Protections Panel";
get reportBrokenSite() {
this.win.gProtectionsHandler._initializePopup();
return this.getViewNode("protections-popup-report-broken-site-button");
}
get popup() {
this.win.gProtectionsHandler._initializePopup();
return this.win.document.getElementById("protections-popup");
}
async open() {
const promise = BrowserTestUtils.waitForEvent(
this.win,
"popupshown",
true,
e => e.target.id == "protections-popup"
);
this.win.gProtectionsHandler.showProtectionsPopup();
await promise;
}
async close() {
if (this.opened) {
const popup = this.popup;
const promise = BrowserTestUtils.waitForPopupEvent(popup, "hidden");
PanelMultiView.hidePopup(popup, false);
await promise;
}
}
}
function AppMenu(win = window) {
return new AppMenuHelper(win);
}
function HelpMenu(win = window) {
return new HelpMenuHelper(win);
}
function ProtectionsPanel(win = window) {
return new ProtectionsPanelHelper(win);
}
function pressKeyAndAwait(event, key, config = {}) {
const win = config.window || window;
if (!event.then) {
event = BrowserTestUtils.waitForEvent(win, event, config.timeout || 200);
}
EventUtils.synthesizeKey(key, config, win);
return event;
}
async function pressKeyAndGetFocus(key, config = {}) {
return (await pressKeyAndAwait("focus", key, config)).target;
}
async function tabTo(match, win = window) {
const config = { window: win };
const { activeElement } = win.document;
if (activeElement?.matches(match)) {
return activeElement;
}
let initial = await pressKeyAndGetFocus("VK_TAB", config);
let target = initial;
do {
if (target.matches(match)) {
return target;
}
target = await pressKeyAndGetFocus("VK_TAB", config);
} while (target && target !== initial);
return undefined;
}
function filterFrameworkDetectorFails(ping, expected) {
// the framework detector's frame-script may fail to run in low memory or other
// weird corner-cases, so we ignore the results in that case if they don't match.
if (!areObjectsEqual(ping.frameworks, expected.frameworks)) {
const { fastclick, mobify, marfeel } = ping.frameworks;
if (!fastclick && !mobify && !marfeel) {
console.info("Ignoring failure to get framework data");
expected.frameworks = ping.frameworks;
}
}
}
async function setupStrictETP() {
await UrlClassifierTestUtils.addTestTrackers();
registerCleanupFunction(() => {
UrlClassifierTestUtils.cleanupTestTrackers();
});
await SpecialPowers.pushPrefEnv({
set: [
["security.mixed_content.block_active_content", true],
["security.mixed_content.block_display_content", true],
["security.mixed_content.upgrade_display_content", false],
[
"urlclassifier.trackingTable",
"content-track-digest256,mochitest2-track-simple",
],
["browser.contentblocking.category", "strict"],
],
});
}
// copied from browser/base/content/test/protectionsUI/head.js
function waitForContentBlockingEvent(numChanges = 1, win = null) {
if (!win) {
win = window;
}
return new Promise(resolve => {
let n = 0;
let listener = {
onContentBlockingEvent(webProgress, request, event) {
n = n + 1;
info(
`Received onContentBlockingEvent event: ${event} (${n} of ${numChanges})`
);
if (n >= numChanges) {
win.gBrowser.removeProgressListener(listener);
resolve(n);
}
},
};
win.gBrowser.addProgressListener(listener);
});
}

View File

@@ -1,355 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Helper methods for testing sending reports with
* the Report Broken Site feature.
*/
/* import-globals-from head.js */
"use strict";
const { Troubleshoot } = ChromeUtils.importESModule(
"resource://gre/modules/Troubleshoot.sys.mjs"
);
function getSysinfoProperty(propertyName, defaultValue) {
try {
return Services.sysinfo.getProperty(propertyName);
} catch (e) {}
return defaultValue;
}
function securityStringToArray(str) {
return str ? str.split(";") : null;
}
function getExpectedGraphicsDevices(snapshot) {
const { graphics } = snapshot;
return [
graphics.adapterDeviceID,
graphics.adapterVendorID,
graphics.adapterDeviceID2,
graphics.adapterVendorID2,
]
.filter(i => i)
.sort();
}
function compareGraphicsDevices(expected, rawActual) {
const actual = rawActual
.map(({ deviceID, vendorID }) => [deviceID, vendorID])
.flat()
.filter(i => i)
.sort();
return areObjectsEqual(actual, expected);
}
function getExpectedGraphicsDrivers(snapshot) {
const { graphics } = snapshot;
const expected = [];
for (let i = 1; i < 3; ++i) {
const version = graphics[`webgl${i}Version`];
if (version && version != "-") {
expected.push(graphics[`webgl${i}Renderer`]);
expected.push(version);
}
}
return expected.filter(i => i).sort();
}
function compareGraphicsDrivers(expected, rawActual) {
const actual = rawActual
.map(({ renderer, version }) => [renderer, version])
.flat()
.filter(i => i)
.sort();
return areObjectsEqual(actual, expected);
}
function getExpectedGraphicsFeatures(snapshot) {
const expected = {};
for (let { name, log, status } of snapshot.graphics.featureLog.features) {
for (const item of log?.reverse() ?? []) {
if (item.failureId && item.status == status) {
status = `${status} (${item.message || item.failureId})`;
}
}
expected[name] = status;
}
return expected;
}
async function getExpectedWebCompatInfo(tab, snapshot, fullAppData = false) {
const gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo);
const { application, graphics, intl, securitySoftware } = snapshot;
const { fissionAutoStart, memorySizeBytes, updateChannel, userAgent } =
application;
const app = {
defaultLocales: intl.localeService.available,
defaultUseragentString: userAgent,
fissionEnabled: fissionAutoStart,
};
if (fullAppData) {
app.applicationName = application.name;
app.osArchitecture = getSysinfoProperty("arch", null);
app.osName = getSysinfoProperty("name", null);
app.osVersion = getSysinfoProperty("version", null);
app.updateChannel = updateChannel;
app.version = application.version;
}
const hasTouchScreen = graphics.info.ApzTouchInput == 1;
const { registeredAntiVirus, registeredAntiSpyware, registeredFirewall } =
securitySoftware;
const browserInfo = {
addons: [],
app,
experiments: [],
graphics: {
devicesJson(actualStr) {
const expected = getExpectedGraphicsDevices(snapshot);
// If undefined is saved to the Glean value here, we'll get the string "undefined" (invalid JSON).
// We should stop using JSON like this in bug 1875185.
if (!actualStr || actualStr == "undefined") {
return !expected.length;
}
return compareGraphicsDevices(expected, JSON.parse(actualStr));
},
driversJson(actualStr) {
const expected = getExpectedGraphicsDrivers(snapshot);
// If undefined is saved to the Glean value here, we'll get the string "undefined" (invalid JSON).
// We should stop using JSON like this in bug 1875185.
if (!actualStr || actualStr == "undefined") {
return !expected.length;
}
return compareGraphicsDrivers(expected, JSON.parse(actualStr));
},
featuresJson(actualStr) {
const expected = getExpectedGraphicsFeatures(snapshot);
// If undefined is saved to the Glean value here, we'll get the string "undefined" (invalid JSON).
// We should stop using JSON like this in bug 1875185.
if (!actualStr || actualStr == "undefined") {
return !expected.length;
}
return areObjectsEqual(JSON.parse(actualStr), expected);
},
hasTouchScreen,
monitorsJson(actualStr) {
const expected = gfxInfo.getMonitors();
// If undefined is saved to the Glean value here, we'll get the string "undefined" (invalid JSON).
// We should stop using JSON like this in bug 1875185.
if (!actualStr || actualStr == "undefined") {
return !expected.length;
}
return areObjectsEqual(JSON.parse(actualStr), expected);
},
},
prefs: {
cookieBehavior: Services.prefs.getIntPref(
"network.cookie.cookieBehavior",
-1
),
forcedAcceleratedLayers: Services.prefs.getBoolPref(
"layers.acceleration.force-enabled",
false
),
globalPrivacyControlEnabled: Services.prefs.getBoolPref(
"privacy.globalprivacycontrol.enabled",
false
),
installtriggerEnabled: Services.prefs.getBoolPref(
"extensions.InstallTrigger.enabled",
false
),
opaqueResponseBlocking: Services.prefs.getBoolPref(
"browser.opaqueResponseBlocking",
false
),
resistFingerprintingEnabled: Services.prefs.getBoolPref(
"privacy.resistFingerprinting",
false
),
softwareWebrender: Services.prefs.getBoolPref(
"gfx.webrender.software",
false
),
thirdPartyCookieBlockingEnabled: Services.prefs.getBoolPref(
"network.cookie.cookieBehavior.optInPartitioning",
false
),
thirdPartyCookieBlockingEnabledInPbm: Services.prefs.getBoolPref(
"network.cookie.cookieBehavior.optInPartitioning.pbmode",
false
),
},
security: {
antispyware: securityStringToArray(registeredAntiSpyware),
antivirus: securityStringToArray(registeredAntiVirus),
firewall: securityStringToArray(registeredFirewall),
},
system: {
isTablet: getSysinfoProperty("tablet", false),
memory: Math.round(memorySizeBytes / 1024 / 1024),
},
};
const tabInfo = await tab.linkedBrowser.ownerGlobal.SpecialPowers.spawn(
tab.linkedBrowser,
[],
async function () {
return {
devicePixelRatio: `${content.devicePixelRatio}`,
antitracking: {
blockList: "basic",
blockedOrigins: null,
isPrivateBrowsing: false,
hasTrackingContentBlocked: false,
hasMixedActiveContentBlocked: false,
hasMixedDisplayContentBlocked: false,
btpHasPurgedSite: false,
etpCategory: "standard",
},
frameworks: {
fastclick: false,
marfeel: false,
mobify: false,
},
languages: content.navigator.languages,
useragentString: content.navigator.userAgent,
};
}
);
browserInfo.graphics.devicePixelRatio = tabInfo.devicePixelRatio;
delete tabInfo.devicePixelRatio;
return { browserInfo, tabInfo };
}
function extractPingData(branch) {
const data = {};
for (const [name, value] of Object.entries(branch)) {
data[name] = value.testGetValue();
}
return data;
}
function extractBrokenSiteReportFromGleanPing(Glean) {
const ping = extractPingData(Glean.brokenSiteReport);
ping.tabInfo = extractPingData(Glean.brokenSiteReportTabInfo);
ping.tabInfo.antitracking = extractPingData(
Glean.brokenSiteReportTabInfoAntitracking
);
ping.tabInfo.frameworks = extractPingData(
Glean.brokenSiteReportTabInfoFrameworks
);
ping.browserInfo = {
addons: Array.from(Glean.brokenSiteReportBrowserInfo.addons.testGetValue()),
app: extractPingData(Glean.brokenSiteReportBrowserInfoApp),
graphics: extractPingData(Glean.brokenSiteReportBrowserInfoGraphics),
experiments: Array.from(
Glean.brokenSiteReportBrowserInfo.experiments.testGetValue()
),
prefs: extractPingData(Glean.brokenSiteReportBrowserInfoPrefs),
security: extractPingData(Glean.brokenSiteReportBrowserInfoSecurity),
system: extractPingData(Glean.brokenSiteReportBrowserInfoSystem),
};
return ping;
}
async function testSend(tab, menu, expectedOverrides = {}) {
const url = expectedOverrides.url ?? menu.win.gBrowser.currentURI.spec;
const description = expectedOverrides.description ?? "";
const breakageCategory = expectedOverrides.breakageCategory ?? null;
let rbs = await menu.openAndPrefillReportBrokenSite(url, description);
const snapshot = await Troubleshoot.snapshot();
const expected = await getExpectedWebCompatInfo(tab, snapshot);
expected.url = url;
expected.description = description;
expected.breakageCategory = breakageCategory;
if (expectedOverrides.addons) {
expected.browserInfo.addons = expectedOverrides.addons;
}
if (expectedOverrides.experiments) {
expected.browserInfo.experiments = expectedOverrides.experiments;
}
if (expectedOverrides.antitracking) {
expected.tabInfo.antitracking = expectedOverrides.antitracking;
if (expectedOverrides.antitracking.blockedOrigins) {
rbs.blockedTrackersCheckbox = true;
}
}
if (expectedOverrides.frameworks) {
expected.tabInfo.frameworks = expectedOverrides.frameworks;
}
if (breakageCategory) {
rbs.chooseReason(breakageCategory);
}
Services.fog.testResetFOG();
await GleanPings.brokenSiteReport.testSubmission(
() => {
const ping = extractBrokenSiteReportFromGleanPing(Glean);
// sanity checks
const { browserInfo, tabInfo } = ping;
ok(ping.url?.length, "Got a URL");
ok(
["basic", "strict"].includes(tabInfo.antitracking.blockList),
"Got a blockList"
);
if (rbs.blockedTrackersCheckbox.checked) {
ok(
Array.isArray(tabInfo.antitracking.blockedOrigins),
"Got an array for blockedOrigins"
);
} else {
ok(!tabInfo.antitracking.blockedOrigins, "No blockedOrigins included");
}
ok(tabInfo.useragentString?.length, "Got a final UA string");
ok(
browserInfo.app.defaultUseragentString?.length,
"Got a default UA string"
);
filterFrameworkDetectorFails(ping.tabInfo, expected.tabInfo);
ok(areObjectsEqual(ping, expected), "ping matches expectations");
},
() => rbs.clickSend()
);
await rbs.clickOkay();
const telemetry = Glean.webcompatreporting.send.testGetValue();
is(telemetry?.length, 1, "Got a 'send' telemetry event");
is(
telemetry[0].extra.sent_with_blocked_trackers,
String(!!expectedOverrides.antitracking?.blockedOrigins),
"Got correct 'sent_with_blocked_trackers' flag"
);
// re-opening the panel, the url and description should be reset
rbs = await menu.openReportBrokenSite();
rbs.isMainViewResetToCurrentTab();
ok(
!rbs.blockedTrackersCheckbox.checked,
"blocked trackers checkbox is reset"
);
rbs.close();
}

View File

@@ -1,27 +0,0 @@
<!DOCTYPE HTML>
<!-- 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/. -->
<html dir="ltr" xml:lang="en-US" lang="en-US">
<head>
<meta charset="utf8">
</head>
<body>
<script>
let ready;
window.wrtReady = new Promise(r => ready = r);
let arrived;
window.messageArrived = new Promise(r => arrived = r);
window.addEventListener("message", e => {
window.message = e.data;
arrived();
});
window.addEventListener("load", () => {
setTimeout(ready, 100);
});
</script>
</body>
</html>

View File

@@ -1,308 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* Helper methods for testing the "send more info" link
* of the Report Broken Site feature.
*/
/* import-globals-from head.js */
/* import-globals-from send.js */
"use strict";
Services.scriptloader.loadSubScript(
getRootDirectory(gTestPath) + "send.js",
this
);
// eslint-disable-next-line complexity
async function reformatExpectedWebCompatInfo(tab, overrides) {
const gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo);
const snapshot = await Troubleshoot.snapshot();
const expected = await getExpectedWebCompatInfo(tab, snapshot, true);
const { browserInfo, tabInfo } = expected;
const { app, graphics, prefs, security } = browserInfo;
const {
applicationName,
defaultUseragentString,
fissionEnabled,
osArchitecture,
osName,
osVersion,
updateChannel,
version,
} = app;
const { devicePixelRatio, hasTouchScreen } = graphics;
const { antitracking, languages, useragentString } = tabInfo;
const addons = overrides.addons || [];
const experiments = overrides.experiments || [];
const atOverrides = overrides.antitracking;
const blockList = atOverrides?.blockList ?? antitracking.blockList;
const blockedOrigins =
atOverrides?.blockedOrigins ?? antitracking.blockedOrigins ?? [];
const hasMixedActiveContentBlocked =
atOverrides?.hasMixedActiveContentBlocked ??
antitracking.hasMixedActiveContentBlocked;
const hasMixedDisplayContentBlocked =
atOverrides?.hasMixedDisplayContentBlocked ??
antitracking.hasMixedDisplayContentBlocked;
const hasTrackingContentBlocked =
atOverrides?.hasTrackingContentBlocked ??
antitracking.hasTrackingContentBlocked;
const isPrivateBrowsing =
atOverrides?.isPrivateBrowsing ?? antitracking.isPrivateBrowsing;
const btpHasPurgedSite =
atOverrides?.btpHasPurgedSite ?? antitracking.btpHasPurgedSite;
const etpCategory = atOverrides?.etpCategory ?? antitracking.etpCategory;
const extra_labels = [];
const frameworks = overrides.frameworks ?? {
fastclick: false,
mobify: false,
marfeel: false,
};
// ignore the console log unless explicily testing for it.
const consoleLog = overrides.consoleLog ?? (() => true);
const finalPrefs = {};
for (const [key, pref] of Object.entries({
cookieBehavior: "network.cookie.cookieBehavior",
forcedAcceleratedLayers: "layers.acceleration.force-enabled",
globalPrivacyControlEnabled: "privacy.globalprivacycontrol.enabled",
installtriggerEnabled: "extensions.InstallTrigger.enabled",
opaqueResponseBlocking: "browser.opaqueResponseBlocking",
resistFingerprintingEnabled: "privacy.resistFingerprinting",
softwareWebrender: "gfx.webrender.software",
thirdPartyCookieBlockingEnabled:
"network.cookie.cookieBehavior.optInPartitioning",
thirdPartyCookieBlockingEnabledInPbm:
"network.cookie.cookieBehavior.optInPartitioning.pbmode",
})) {
if (key in prefs) {
finalPrefs[pref] = prefs[key];
}
}
const reformatted = {
blockList,
details: {
additionalData: {
addons,
applicationName,
blockList,
blockedOrigins,
buildId: snapshot.application.buildID,
devicePixelRatio: parseInt(devicePixelRatio),
experiments,
finalUserAgent: useragentString,
fissionEnabled,
gfxData: {
devices(actual) {
const devices = getExpectedGraphicsDevices(snapshot);
return compareGraphicsDevices(devices, actual);
},
drivers(actual) {
const drvs = getExpectedGraphicsDrivers(snapshot);
return compareGraphicsDrivers(drvs, actual);
},
features(actual) {
const features = getExpectedGraphicsFeatures(snapshot);
return areObjectsEqual(actual, features);
},
hasTouchScreen,
monitors(actual) {
return areObjectsEqual(actual, gfxInfo.getMonitors());
},
},
hasMixedActiveContentBlocked,
hasMixedDisplayContentBlocked,
hasTrackingContentBlocked,
btpHasPurgedSite,
isPB: isPrivateBrowsing,
etpCategory,
languages,
locales: snapshot.intl.localeService.available,
memoryMB: browserInfo.system.memory,
osArchitecture,
osName,
osVersion,
prefs: finalPrefs,
version,
},
blockList,
channel: updateChannel,
consoleLog,
defaultUserAgent: defaultUseragentString,
frameworks,
hasTouchScreen,
"gfx.webrender.software": prefs.softwareWebrender,
"mixed active content blocked": hasMixedActiveContentBlocked,
"mixed passive content blocked": hasMixedDisplayContentBlocked,
"tracking content blocked": hasTrackingContentBlocked
? `true (${blockList})`
: "false",
"btp has purged site": btpHasPurgedSite,
},
extra_labels,
src: "desktop-reporter",
utm_campaign: "report-broken-site",
utm_source: "desktop-reporter",
};
const { gfxData } = reformatted.details.additionalData;
for (const optional of [
"directWriteEnabled",
"directWriteVersion",
"clearTypeParameters",
"targetFrameRate",
]) {
if (optional in snapshot.graphics) {
gfxData[optional] = snapshot.graphics[optional];
}
}
// We only care about this pref on Linux right now on webcompat.com.
if (AppConstants.platform != "linux") {
delete finalPrefs["layers.acceleration.force-enabled"];
} else {
reformatted.details["layers.acceleration.force-enabled"] =
finalPrefs["layers.acceleration.force-enabled"];
}
// Only bother adding the security key if it has any data
if (Object.values(security).filter(e => e).length) {
reformatted.details.additionalData.sec = security;
}
const expectedCodecs = snapshot.media.codecSupportInfo
.replaceAll(" NONE", "")
.split("\n")
.sort()
.join("\n");
if (expectedCodecs) {
reformatted.details.additionalData.gfxData.codecSupport = rawActual => {
const actual = Object.entries(rawActual)
.map(
([
name,
{ hardwareDecode, softwareDecode, hardwareEncode, softwareEncode },
]) =>
(
`${name} ` +
`${softwareDecode ? "SWDEC " : ""}` +
`${hardwareDecode ? "HWDEC " : ""}` +
`${softwareEncode ? "SWENC " : ""}` +
`${hardwareEncode ? "HWENC " : ""}`
).trim()
)
.sort()
.join("\n");
return areObjectsEqual(actual, expectedCodecs);
};
}
if (blockList != "basic") {
extra_labels.push(`type-tracking-protection-${blockList}`);
}
if (overrides.expectNoTabDetails) {
delete reformatted.details.frameworks;
delete reformatted.details.consoleLog;
delete reformatted.details["mixed active content blocked"];
delete reformatted.details["mixed passive content blocked"];
delete reformatted.details["tracking content blocked"];
delete reformatted.details["btp has purged site"];
} else {
const { fastclick, mobify, marfeel } = frameworks;
if (fastclick) {
extra_labels.push("type-fastclick");
reformatted.details.fastclick = true;
}
if (mobify) {
extra_labels.push("type-mobify");
reformatted.details.mobify = true;
}
if (marfeel) {
extra_labels.push("type-marfeel");
reformatted.details.marfeel = true;
}
}
extra_labels.sort();
return reformatted;
}
async function testSendMoreInfo(tab, menu, expectedOverrides = {}) {
const url = expectedOverrides.url ?? menu.win.gBrowser.currentURI.spec;
const description = expectedOverrides.description ?? "";
let rbs = await menu.openAndPrefillReportBrokenSite(url, description);
const receivedData = await rbs.clickSendMoreInfo();
await checkWebcompatComPayload(
tab,
url,
description,
expectedOverrides,
receivedData
);
// re-opening the panel, the url and description should be reset
rbs = await menu.openReportBrokenSite();
rbs.isMainViewResetToCurrentTab();
rbs.close();
}
async function testWebcompatComFallback(tab, menu) {
const url = menu.win.gBrowser.currentURI.spec;
const receivedData =
await menu.clickReportBrokenSiteAndAwaitWebCompatTabData();
await checkWebcompatComPayload(tab, url, "", {}, receivedData);
menu.close();
}
async function checkWebcompatComPayload(
tab,
url,
description,
expectedOverrides,
receivedData
) {
const expected = await reformatExpectedWebCompatInfo(tab, expectedOverrides);
expected.url = url;
expected.description = description;
// sanity checks
const { message } = receivedData;
const { details } = message;
const { additionalData } = details;
ok(message.url?.length, "Got a URL");
ok(["basic", "strict"].includes(details.blockList), "Got a blockList");
ok(additionalData.applicationName?.length, "Got an app name");
ok(additionalData.osArchitecture?.length, "Got an OS arch");
ok(additionalData.osName?.length, "Got an OS name");
ok(additionalData.osVersion?.length, "Got an OS version");
ok(additionalData.version?.length, "Got an app version");
ok(details.channel?.length, "Got an app channel");
ok(details.defaultUserAgent?.length, "Got a default UA string");
ok(additionalData.finalUserAgent?.length, "Got a final UA string");
// If we're sending any tab-specific data (which includes console logs),
// check that there is also a valid screenshot.
if ("consoleLog" in details) {
const isScreenshotValid = await new Promise(done => {
var image = new Image();
image.onload = () => done(image.width > 0);
image.onerror = () => done(false);
image.src = receivedData.screenshot;
});
ok(isScreenshotValid, "Got a valid screenshot");
}
filterFrameworkDetectorFails(message.details, expected.details);
ok(areObjectsEqual(message, expected), "sent info matches expectations");
}

View File

@@ -7,7 +7,9 @@ support-files = [
["browser_bug400731.js"] ["browser_bug400731.js"]
["browser_bug415846.js"] ["browser_bug415846.js"]
skip-if = ["true"] # Bug 1248632 skip-if = [
"true", # Bug 1248632
]
["browser_mixedcontent_aboutblocked.js"] ["browser_mixedcontent_aboutblocked.js"]

View File

@@ -11,7 +11,7 @@ add_task(async function testMalware() {
await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
const url = "https://www.itisatrap.org/firefox/its-an-attack.html"; const url = "http://www.itisatrap.org/firefox/its-an-attack.html";
BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url); BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url);
await BrowserTestUtils.browserLoaded( await BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser, gBrowser.selectedBrowser,
@@ -28,7 +28,7 @@ add_task(async function testUnwanted() {
Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", false); Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", false);
// Now launch the unwanted software test // Now launch the unwanted software test
const url = "https://www.itisatrap.org/firefox/unwanted.html"; const url = "http://www.itisatrap.org/firefox/unwanted.html";
BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url); BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url);
await BrowserTestUtils.browserLoaded( await BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser, gBrowser.selectedBrowser,
@@ -49,7 +49,7 @@ add_task(async function testPhishing() {
Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", true); Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", true);
// Now launch the phishing test // Now launch the phishing test
const url = "https://www.itisatrap.org/firefox/its-a-trap.html"; const url = "http://www.itisatrap.org/firefox/its-a-trap.html";
BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url); BrowserTestUtils.startLoadingURIString(gBrowser.selectedBrowser, url);
await BrowserTestUtils.browserLoaded( await BrowserTestUtils.browserLoaded(
gBrowser.selectedBrowser, gBrowser.selectedBrowser,

View File

@@ -4,8 +4,8 @@ menu items.
Mac makes this astonishingly painful to test since their help menu is special magic, Mac makes this astonishingly painful to test since their help menu is special magic,
but we can at least test it on the other platforms.*/ but we can at least test it on the other platforms.*/
const NORMAL_PAGE = "https://example.com"; const NORMAL_PAGE = "http://example.com";
const PHISH_PAGE = "https://www.itisatrap.org/firefox/its-a-trap.html"; const PHISH_PAGE = "http://www.itisatrap.org/firefox/its-a-trap.html";
/** /**
* Opens a new tab and browses to some URL, tests for the existence * Opens a new tab and browses to some URL, tests for the existence
@@ -13,13 +13,14 @@ const PHISH_PAGE = "https://www.itisatrap.org/firefox/its-a-trap.html";
* the state of the menu once opened. This function will take care of * the state of the menu once opened. This function will take care of
* opening and closing the menu. * opening and closing the menu.
* *
* @param {string} url The URL to browse the tab to. * @param url (string)
* @param {Function} testFn * The URL to browse the tab to.
* @param testFn (function)
* The function to run once the menu has been opened. This * The function to run once the menu has been opened. This
* function will be passed the "reportMenu" and "errorMenu" * function will be passed the "reportMenu" and "errorMenu"
* DOM nodes as arguments, in that order. This function * DOM nodes as arguments, in that order. This function
* should not yield anything. * should not yield anything.
* @returns {Promise} Promise that resolves when the test is complete * @returns Promise
*/ */
function check_menu_at_page(url, testFn) { function check_menu_at_page(url, testFn) {
return BrowserTestUtils.withNewTab( return BrowserTestUtils.withNewTab(

View File

@@ -1,7 +1,7 @@
/* Ensure that hostnames in the whitelisted pref are not blocked. */ /* Ensure that hostnames in the whitelisted pref are not blocked. */
const PREF_WHITELISTED_HOSTNAMES = "urlclassifier.skipHostnames"; const PREF_WHITELISTED_HOSTNAMES = "urlclassifier.skipHostnames";
const TEST_PAGE = "https://www.itisatrap.org/firefox/its-an-attack.html"; const TEST_PAGE = "http://www.itisatrap.org/firefox/its-an-attack.html";
var tabbrowser = null; var tabbrowser = null;
registerCleanupFunction(function () { registerCleanupFunction(function () {

View File

@@ -6,10 +6,15 @@ const PHISH_URL = "https://www.itisatrap.org/firefox/its-a-trap.html";
* Waits for a load (or custom) event to finish in a given tab. If provided * Waits for a load (or custom) event to finish in a given tab. If provided
* load an uri into the tab. * load an uri into the tab.
* *
* @param {MozTabbrowserTab} tab The tab to load into. * @param tab
* @param {string} [url] The url to load, or the current url. * The tab to load into.
* @param {string} [eventType] The load event type to wait for. Defaults to "load". * @param [optional] url
* @returns {Promise<Event>} Promise resolved when the event is handled. * The url to load, or the current url.
* @param [optional] event
* The load event type to wait for. Defaults to "load".
* @return {Promise} resolved when the event is handled.
* @resolves to the received event
* @rejects if a valid load event is not received within a meaningful interval
*/ */
function promiseTabLoadEvent(tab, url, eventType = "load") { function promiseTabLoadEvent(tab, url, eventType = "load") {
info(`Wait tab event: ${eventType}`); info(`Wait tab event: ${eventType}`);

View File

@@ -3,18 +3,30 @@
["browser_1119088.js"] ["browser_1119088.js"]
disabled="Disabled by import_external_tests.py" disabled="Disabled by import_external_tests.py"
support-files = ["mac_desktop_image.py"] support-files = ["mac_desktop_image.py"]
run-if = ["os == 'mac'"] run-if = [
"os == 'mac'",
]
tags = "os_integration" tags = "os_integration"
skip-if = ["os == 'mac' && os_version == '14.70' && processor == 'x86_64'"] # Bug 1869703 skip-if = [
"os == 'mac' && os_version == '14.70' && arch == 'x86_64'", # Bug 1869703
]
["browser_420786.js"] ["browser_420786.js"]
run-if = ["os == 'linux'"] run-if = [
"os == 'linux' && os_version == '22.04' && arch == 'x86_64' && display == 'wayland'",
"os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11'",
]
["browser_633221.js"] ["browser_633221.js"]
run-if = ["os == 'linux'"] run-if = [
"os == 'linux' && os_version == '22.04' && arch == 'x86_64' && display == 'wayland'",
"os == 'linux' && os_version == '24.04' && arch == 'x86_64' && display == 'x11'",
]
["browser_createWindowsShortcut.js"] ["browser_createWindowsShortcut.js"]
run-if = ["os == 'win'"] run-if = [
"os == 'win'",
]
["browser_doesAppNeedPin.js"] ["browser_doesAppNeedPin.js"]
@@ -24,8 +36,8 @@ support-files = [
"headless.html", "headless.html",
] ]
skip-if = [ skip-if = [
"os == 'win'",
"ccov", "ccov",
"os == 'win'",
"tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449 "tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449
] ]
tags = "os_integration" tags = "os_integration"
@@ -36,8 +48,8 @@ support-files = [
"headless.html", "headless.html",
] ]
skip-if = [ skip-if = [
"os == 'win'",
"ccov", "ccov",
"os == 'win'",
"tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449 "tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449
] ]
@@ -47,8 +59,8 @@ support-files = [
"headless.html", "headless.html",
] ]
skip-if = [ skip-if = [
"os == 'win'",
"ccov", "ccov",
"os == 'win'",
"tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449 "tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449
] ]
@@ -58,8 +70,8 @@ support-files = [
"headless.html", "headless.html",
] ]
skip-if = [ skip-if = [
"os == 'win'",
"ccov", "ccov",
"os == 'win'",
"tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449 "tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449
] ]
@@ -70,8 +82,8 @@ support-files = [
"headless_iframe.html", "headless_iframe.html",
] ]
skip-if = [ skip-if = [
"os == 'win'",
"ccov", "ccov",
"os == 'win'",
"tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449 "tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449
] ]
@@ -83,19 +95,23 @@ support-files = [
"headless_redirect.html^headers^", "headless_redirect.html^headers^",
] ]
skip-if = [ skip-if = [
"os == 'win'",
"ccov", "ccov",
"os == 'win'",
"tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449 "tsan", # Bug 1429950, Bug 1583315, Bug 1696109, Bug 1701449
] ]
["browser_processAUMID.js"] ["browser_processAUMID.js"]
run-if = ["os == 'win'"] run-if = [
"os == 'win'",
]
["browser_setDefaultBrowser.js"] ["browser_setDefaultBrowser.js"]
tags = "os_integration" tags = "os_integration"
["browser_setDefaultPDFHandler.js"] ["browser_setDefaultPDFHandler.js"]
run-if = ["os == 'win'"] run-if = [
"os == 'win'",
]
tags = "os_integration" tags = "os_integration"
["browser_setDesktopBackgroundPreview.js"] ["browser_setDesktopBackgroundPreview.js"]

View File

@@ -31,138 +31,138 @@ from Cocoa import NSURL
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Utility to print, set, or " description="Utility to print, set, or "
+ "check the path to image being used as " + "check the path to image being used as "
+ "the desktop background image. By " + "the desktop background image. By "
+ "default, prints the path to the " + "default, prints the path to the "
+ "current desktop background image." + "current desktop background image."
)
parser.add_argument(
"-v",
"--verbose",
action="store_true",
help="print verbose debugging information",
default=False,
)
group = parser.add_mutually_exclusive_group()
group.add_argument(
"-s",
"--set-background-image",
dest="newBackgroundImagePath",
required=False,
help="path to the new background image to set. A zero "
+ "exit code indicates no errors occurred.",
default=None,
)
group.add_argument(
"-c",
"--check-background-image",
dest="checkBackgroundImagePath",
required=False,
help="check if the provided background image path "
+ "matches the provided path. A zero exit code "
+ "indicates the paths match.",
default=None,
)
args = parser.parse_args()
# Using logging for verbose output
if args.verbose:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.CRITICAL)
logger = logging.getLogger("desktopImage")
# Print what we're going to do
if args.checkBackgroundImagePath is not None:
logger.debug(
"checking provided desktop image %s matches current "
"image" % args.checkBackgroundImagePath
) )
parser.add_argument( elif args.newBackgroundImagePath is not None:
"-v", logger.debug("setting image to %s " % args.newBackgroundImagePath)
"--verbose", else:
action="store_true", logger.debug("retrieving desktop image path")
help="print verbose debugging information",
default=False, focussedScreen = NSScreen.mainScreen()
if not focussedScreen:
raise RuntimeError("mainScreen error")
ws = NSWorkspace.sharedWorkspace()
if not ws:
raise RuntimeError("sharedWorkspace error")
# If we're just checking the image path, check it and then return.
# A successful exit code (0) indicates the paths match.
if args.checkBackgroundImagePath is not None:
# Get existing desktop image path and resolve it
existingImageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
existingImagePath = existingImageURL.path()
existingImagePathReal = os.path.realpath(existingImagePath)
logger.debug("existing desktop image: %s" % existingImagePath)
logger.debug("existing desktop image realpath: %s" % existingImagePath)
# Resolve the path we're going to check
checkImagePathReal = os.path.realpath(args.checkBackgroundImagePath)
logger.debug("check desktop image: %s" % args.checkBackgroundImagePath)
logger.debug("check desktop image realpath: %s" % checkImagePathReal)
if existingImagePathReal == checkImagePathReal:
print("desktop image path matches provided path")
return True
print("desktop image path does NOT match provided path")
return False
# Log the current desktop image
if args.verbose:
existingImageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
logger.debug("existing desktop image: %s" % existingImageURL.path())
# Set the desktop image
if args.newBackgroundImagePath is not None:
newImagePath = args.newBackgroundImagePath
if not os.path.exists(newImagePath):
logger.critical("%s does not exist" % newImagePath)
return False
if not os.access(newImagePath, os.R_OK):
logger.critical("%s is not readable" % newImagePath)
return False
logger.debug("new desktop image to set: %s" % newImagePath)
newImageURL = NSURL.fileURLWithPath_(newImagePath)
logger.debug("new desktop image URL to set: %s" % newImageURL)
status = False
(status, error) = ws.setDesktopImageURL_forScreen_options_error_(
newImageURL, focussedScreen, None, None
) )
group = parser.add_mutually_exclusive_group() if not status:
group.add_argument( raise RuntimeError("setDesktopImageURL error")
"-s",
"--set-background-image",
dest="newBackgroundImagePath",
required=False,
help="path to the new background image to set. A zero "
+ "exit code indicates no errors occurred.",
default=None,
)
group.add_argument(
"-c",
"--check-background-image",
dest="checkBackgroundImagePath",
required=False,
help="check if the provided background image path "
+ "matches the provided path. A zero exit code "
+ "indicates the paths match.",
default=None,
)
args = parser.parse_args()
# Using logging for verbose output # Print the current desktop image
if args.verbose: imageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
logging.basicConfig(level=logging.DEBUG) imagePath = imageURL.path()
else: imagePathReal = os.path.realpath(imagePath)
logging.basicConfig(level=logging.CRITICAL) logger.debug("updated desktop image URL: %s" % imageURL)
logger = logging.getLogger("desktopImage") logger.debug("updated desktop image path: %s" % imagePath)
logger.debug("updated desktop image path (resolved): %s" % imagePathReal)
# Print what we're going to do print(imagePathReal)
if args.checkBackgroundImagePath is not None: return True
logger.debug(
"checking provided desktop image %s matches current "
"image" % args.checkBackgroundImagePath
)
elif args.newBackgroundImagePath is not None:
logger.debug("setting image to %s " % args.newBackgroundImagePath)
else:
logger.debug("retrieving desktop image path")
focussedScreen = NSScreen.mainScreen()
if not focussedScreen:
raise RuntimeError("mainScreen error")
ws = NSWorkspace.sharedWorkspace()
if not ws:
raise RuntimeError("sharedWorkspace error")
# If we're just checking the image path, check it and then return.
# A successful exit code (0) indicates the paths match.
if args.checkBackgroundImagePath is not None:
# Get existing desktop image path and resolve it
existingImageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
existingImagePath = existingImageURL.path()
existingImagePathReal = os.path.realpath(existingImagePath)
logger.debug("existing desktop image: %s" % existingImagePath)
logger.debug("existing desktop image realpath: %s" % existingImagePath)
# Resolve the path we're going to check
checkImagePathReal = os.path.realpath(args.checkBackgroundImagePath)
logger.debug("check desktop image: %s" % args.checkBackgroundImagePath)
logger.debug("check desktop image realpath: %s" % checkImagePathReal)
if existingImagePathReal == checkImagePathReal:
print("desktop image path matches provided path")
return True
print("desktop image path does NOT match provided path")
return False
# Log the current desktop image
if args.verbose:
existingImageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
logger.debug("existing desktop image: %s" % existingImageURL.path())
# Set the desktop image
if args.newBackgroundImagePath is not None:
newImagePath = args.newBackgroundImagePath
if not os.path.exists(newImagePath):
logger.critical("%s does not exist" % newImagePath)
return False
if not os.access(newImagePath, os.R_OK):
logger.critical("%s is not readable" % newImagePath)
return False
logger.debug("new desktop image to set: %s" % newImagePath)
newImageURL = NSURL.fileURLWithPath_(newImagePath)
logger.debug("new desktop image URL to set: %s" % newImageURL)
status = False
(status, error) = ws.setDesktopImageURL_forScreen_options_error_(
newImageURL, focussedScreen, None, None
)
if not status:
raise RuntimeError("setDesktopImageURL error")
# Print the current desktop image
imageURL = getCurrentDesktopImageURL(focussedScreen, ws, logger)
imagePath = imageURL.path()
imagePathReal = os.path.realpath(imagePath)
logger.debug("updated desktop image URL: %s" % imageURL)
logger.debug("updated desktop image path: %s" % imagePath)
logger.debug("updated desktop image path (resolved): %s" % imagePathReal)
print(imagePathReal)
return True
def getCurrentDesktopImageURL(focussedScreen, workspace, logger): def getCurrentDesktopImageURL(focussedScreen, workspace, logger):
imageURL = workspace.desktopImageURLForScreen_(focussedScreen) imageURL = workspace.desktopImageURLForScreen_(focussedScreen)
if not imageURL: if not imageURL:
raise RuntimeError("desktopImageURLForScreen returned invalid URL") raise RuntimeError("desktopImageURLForScreen returned invalid URL")
if not imageURL.isFileURL(): if not imageURL.isFileURL():
logger.warning("desktop image URL is not a file URL") logger.warning("desktop image URL is not a file URL")
return imageURL return imageURL
if __name__ == "__main__": if __name__ == "__main__":
if not main(): if not main():
sys.exit(1) sys.exit(1)
else: else:
sys.exit(0) sys.exit(0)

View File

@@ -36,6 +36,5 @@ add_task(async function test_prefsOpen() {
); );
shellSvc.showSecurityPreferences("Privacy_AllFiles"); shellSvc.showSecurityPreferences("Privacy_AllFiles");
// eslint-disable-next-line no-undef
equal(killSystemPreferences(), 0, "Ensure System Preferences was started"); equal(killSystemPreferences(), 0, "Ensure System Preferences was started");
}); });

View File

@@ -1,7 +1,11 @@
[DEFAULT] [DEFAULT]
run-if = ["os != 'android'"] run-if = [
"os != 'android'",
]
firefox-appdir = "browser" firefox-appdir = "browser"
tags = "os_integration" tags = "os_integration"
["test_macOS_showSecurityPreferences.js"] ["test_macOS_showSecurityPreferences.js"]
run-if = ["os == 'mac'"] run-if = [
"os == 'mac'",
]

View File

@@ -2,7 +2,6 @@ function check(aBrowser, aElementName, aBarred, aType) {
return SpecialPowers.spawn( return SpecialPowers.spawn(
aBrowser, aBrowser,
[[aElementName, aBarred, aType]], [[aElementName, aBarred, aType]],
// eslint-disable-next-line no-shadow
async function ([aElementName, aBarred, aType]) { async function ([aElementName, aBarred, aType]) {
let e = content.document.createElement(aElementName); let e = content.document.createElement(aElementName);
let contentElement = content.document.getElementById("content"); let contentElement = content.document.getElementById("content");
@@ -56,7 +55,6 @@ function todo_check(aBrowser, aElementName, aBarred) {
return SpecialPowers.spawn( return SpecialPowers.spawn(
aBrowser, aBrowser,
[[aElementName, aBarred]], [[aElementName, aBarred]],
// eslint-disable-next-line no-shadow
async function ([aElementName]) { async function ([aElementName]) {
let e = content.document.createElement(aElementName); let e = content.document.createElement(aElementName);
let contentElement = content.document.getElementById("content"); let contentElement = content.document.getElementById("content");
@@ -65,7 +63,6 @@ function todo_check(aBrowser, aElementName, aBarred) {
let caught = false; let caught = false;
try { try {
e.setCustomValidity("foo"); e.setCustomValidity("foo");
// eslint-disable-next-line no-shadow
} catch (e) { } catch (e) {
caught = true; caught = true;
} }

View File

@@ -42,7 +42,6 @@ async function do_test(test) {
); );
info("creating input field"); info("creating input field");
// eslint-disable-next-line no-shadow
await SpecialPowers.spawn(tab.linkedBrowser, [test], async function (test) { await SpecialPowers.spawn(tab.linkedBrowser, [test], async function (test) {
let doc = content.document; let doc = content.document;
let input = doc.createElement("input"); let input = doc.createElement("input");

View File

@@ -15,6 +15,4 @@ prefs = ["zen.workspaces.separate-essentials=false"]
["browser_pinned_created.js"] ["browser_pinned_created.js"]
["browser_pinned_to_essential.js"] ["browser_pinned_to_essential.js"]
["browser_private_mode_no_ctx_menu.js"]
["browser_issue_8726.js"] ["browser_issue_8726.js"]

View File

@@ -15,6 +15,8 @@ add_task(async function test_Changed_Pinned() {
ok(tab.pinned, "The tab should be pinned after calling gBrowser.pinTab()"); ok(tab.pinned, "The tab should be pinned after calling gBrowser.pinTab()");
await gBrowser.TabStateFlusher.flush(browser);
await new Promise((r) => setTimeout(r, 500));
BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2"); BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2");
await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2"); await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2");
setTimeout(() => { setTimeout(() => {
@@ -23,7 +25,7 @@ add_task(async function test_Changed_Pinned() {
"The tab should have a zen-pinned-changed attribute after being pinned" "The tab should have a zen-pinned-changed attribute after being pinned"
); );
resolvePromise(); resolvePromise();
}, 0); }, 500);
await promise; await promise;
}); });

View File

@@ -13,9 +13,11 @@ add_task(async function test_Create_Pinned() {
const newTab = gBrowser.selectedTab; const newTab = gBrowser.selectedTab;
gBrowser.pinTab(newTab); gBrowser.pinTab(newTab);
await gBrowser.TabStateFlusher.flush(newTab.linkedBrowser);
ok(newTab.pinned, "The tab should be pinned after calling gBrowser.pinTab()"); ok(newTab.pinned, "The tab should be pinned after calling gBrowser.pinTab()");
await new Promise((r) => setTimeout(r, 500));
const pinObject = newTab._zenPinnedInitialState; const pinObject = newTab._zenPinnedInitialState;
ok(pinObject, "The pin object should be created in the tab's _zenPinnedInitialState"); ok(pinObject, "The pin object should be created in the tab's _zenPinnedInitialState");
Assert.equal( Assert.equal(

View File

@@ -19,6 +19,7 @@ add_task(async function test_NoUnload_Changed_Pinned() {
BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2"); BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2");
await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2"); await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2");
await gBrowser.TabStateFlusher.flush(browser);
setTimeout(() => { setTimeout(() => {
ok( ok(
tab.hasAttribute("zen-pinned-changed"), tab.hasAttribute("zen-pinned-changed"),

View File

@@ -19,6 +19,7 @@ add_task(async function test_Unload_NoReset_Pinned() {
BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2"); BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2");
await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2"); await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2");
await gBrowser.TabStateFlusher.flush(browser);
setTimeout(() => { setTimeout(() => {
ok( ok(
tab.hasAttribute("zen-pinned-changed"), tab.hasAttribute("zen-pinned-changed"),

View File

@@ -19,6 +19,7 @@ add_task(async function test_Unload_NoReset_Pinned() {
BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2"); BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2");
await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2"); await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2");
await gBrowser.TabStateFlusher.flush(browser);
setTimeout(() => { setTimeout(() => {
ok( ok(
tab.hasAttribute("zen-pinned-changed"), tab.hasAttribute("zen-pinned-changed"),

View File

@@ -19,6 +19,7 @@ add_task(async function test_Unload_Changed_Pinned() {
BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2"); BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2");
await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2"); await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2");
await gBrowser.TabStateFlusher.flush(browser);
setTimeout(() => { setTimeout(() => {
ok( ok(
tab.hasAttribute("zen-pinned-changed"), tab.hasAttribute("zen-pinned-changed"),

View File

@@ -19,6 +19,7 @@ add_task(async function test_Unload_NoReset_Pinned() {
BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2"); BrowserTestUtils.startLoadingURIString(browser, "https://example.com/2");
await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2"); await BrowserTestUtils.browserLoaded(browser, false, "https://example.com/2");
await gBrowser.TabStateFlusher.flush(browser);
/* eslint-disable-next-line mozilla/no-arbitrary-setTimeout */ /* eslint-disable-next-line mozilla/no-arbitrary-setTimeout */
setTimeout(() => { setTimeout(() => {
ok( ok(

View File

@@ -1,34 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
https://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_Private_Mode_No_Essentials() {
let privateWindow = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});
await privateWindow.gZenWorkspaces.promiseInitialized;
await BrowserTestUtils.openNewForegroundTab(privateWindow.gBrowser, "https://example.com/", true);
await new Promise((resolve) => {
privateWindow.gBrowser.selectedTab.addEventListener("popupshown", function () {
ok(
privateWindow.document.getElementById("context_zen-add-essentials").hidden,
"Context menu should not show Zen Essentials option in private mode"
);
ok(
privateWindow.document.getElementById("context_pinTab").hidden,
"Context menu should not show Pin Tab option in private mode"
);
resolve();
});
EventUtils.synthesizeMouseAtCenter(privateWindow.gBrowser.selectedTab, {
type: "contextmenu",
});
});
await BrowserTestUtils.closeWindow(privateWindow);
});

View File

@@ -8,7 +8,7 @@ add_setup(async function () {});
add_task(async function test_Check_Creation() { add_task(async function test_Check_Creation() {
const currentWorkspaceUUID = gZenWorkspaces.activeWorkspace; const currentWorkspaceUUID = gZenWorkspaces.activeWorkspace;
await gZenWorkspaces.createAndSaveWorkspace("Test Workspace 2"); await gZenWorkspaces.createAndSaveWorkspace("Test Workspace 2");
const workspaces = await gZenWorkspaces._workspaces(); const workspaces = gZenWorkspaces.getWorkspaces();
Assert.strictEqual(workspaces.length, 2, "Two workspaces should exist."); Assert.strictEqual(workspaces.length, 2, "Two workspaces should exist.");
Assert.notStrictEqual( Assert.notStrictEqual(
currentWorkspaceUUID, currentWorkspaceUUID,
@@ -24,7 +24,7 @@ add_task(async function test_Check_Creation() {
BrowserTestUtils.removeTab(newTab); BrowserTestUtils.removeTab(newTab);
await gZenWorkspaces.removeWorkspace(gZenWorkspaces.activeWorkspace); await gZenWorkspaces.removeWorkspace(gZenWorkspaces.activeWorkspace);
const workspacesAfterRemove = await gZenWorkspaces._workspaces(); const workspacesAfterRemove = gZenWorkspaces.getWorkspaces();
Assert.strictEqual(workspacesAfterRemove.workspaces.length, 1, "One workspace should exist."); Assert.strictEqual(workspacesAfterRemove.workspaces.length, 1, "One workspace should exist.");
Assert.strictEqual( Assert.strictEqual(
workspacesAfterRemove[0].uuid, workspacesAfterRemove[0].uuid,

View File

@@ -7,7 +7,7 @@ add_task(async function test_Change_To_Empty() {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const currentWorkspaceUUID = gZenWorkspaces.activeWorkspace; const currentWorkspaceUUID = gZenWorkspaces.activeWorkspace;
await gZenWorkspaces.createAndSaveWorkspace("Test Workspace 2"); await gZenWorkspaces.createAndSaveWorkspace("Test Workspace 2");
const workspaces = await gZenWorkspaces._workspaces(); const workspaces = gZenWorkspaces.getWorkspaces();
const secondWorkspace = workspaces.workspaces[1]; const secondWorkspace = workspaces.workspaces[1];
await gZenWorkspaces.changeWorkspace(secondWorkspace.uuid); await gZenWorkspaces.changeWorkspace(secondWorkspace.uuid);
@@ -24,7 +24,7 @@ add_task(async function test_Change_To_Empty() {
"The empty tab should not be selected anymore." "The empty tab should not be selected anymore."
); );
const workspacesAfterRemove = await gZenWorkspaces._workspaces(); const workspacesAfterRemove = gZenWorkspaces.getWorkspaces();
Assert.strictEqual(workspacesAfterRemove.length, 1, "One workspace should exist."); Assert.strictEqual(workspacesAfterRemove.length, 1, "One workspace should exist.");
Assert.strictEqual(gBrowser.tabs.length, 2, "There should be two tabs."); Assert.strictEqual(gBrowser.tabs.length, 2, "There should be two tabs.");
}); });

View File

@@ -109,7 +109,7 @@ add_task(async function test_workspace_bookmark() {
return; return;
await withBookmarksShowing(async () => { await withBookmarksShowing(async () => {
await gZenWorkspaces.createAndSaveWorkspace("Test Workspace 2"); await gZenWorkspaces.createAndSaveWorkspace("Test Workspace 2");
const workspaces = await gZenWorkspaces._workspaces(); const workspaces = gZenWorkspaces.getWorkspaces();
Assert.strictEqual(workspaces.length, 2, "Two workspaces should exist."); Assert.strictEqual(workspaces.length, 2, "Two workspaces should exist.");
const firstWorkspace = workspaces[0]; const firstWorkspace = workspaces[0];
const secondWorkspace = workspaces[1]; const secondWorkspace = workspaces[1];
@@ -156,7 +156,7 @@ add_task(async function test_workspace_bookmark() {
await gZenWorkspaces.removeWorkspace(secondWorkspace.uuid); await gZenWorkspaces.removeWorkspace(secondWorkspace.uuid);
Assert.equal( Assert.equal(
(await gZenWorkspaces._workspaces()).workspaces.length, gZenWorkspaces.getWorkspaces().workspaces.length,
1, 1,
"Only one workspace should remain after removing the second one." "Only one workspace should remain after removing the second one."
); );