mirror of
https://github.com/zen-browser/desktop
synced 2026-04-25 17:15:00 +02:00
test: Fixed running tests for pinned tabs and exported machitests, b=no-bug, c=tabs, glance, tests, folders, workspaces
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -811,7 +811,12 @@ class nsZenGlanceManager extends nsZenDOMOperatedFeature {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#animateGlanceClosing(onTabClose, browserSidebarContainer, sidebarButtons, setNewID);
|
return this.#animateGlanceClosing(
|
||||||
|
onTabClose,
|
||||||
|
browserSidebarContainer,
|
||||||
|
sidebarButtons,
|
||||||
|
setNewID
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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", {
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
@@ -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",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
|
||||||
]
|
|
||||||
@@ -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();
|
|
||||||
});
|
|
||||||
@@ -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);
|
|
||||||
});
|
|
||||||
@@ -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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -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");
|
|
||||||
});
|
|
||||||
@@ -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`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
@@ -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);
|
|
||||||
});
|
|
||||||
@@ -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);
|
|
||||||
});
|
|
||||||
@@ -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);
|
|
||||||
});
|
|
||||||
@@ -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());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -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);
|
|
||||||
});
|
|
||||||
@@ -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);
|
|
||||||
});
|
|
||||||
@@ -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>
|
|
||||||
@@ -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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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");
|
|
||||||
}
|
|
||||||
@@ -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"]
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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 () {
|
||||||
|
|||||||
@@ -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}`);
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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'",
|
||||||
|
]
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
|
||||||
});
|
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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.");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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."
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user