зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1711497 - Remove browser.proton.enabled checks/setters from tests r=Gijs,marionette-reviewers,whimboo
Differential Revision: https://phabricator.services.mozilla.com/D115539
This commit is contained in:
Родитель
2b6deeb7f7
Коммит
16dd2093e1
|
@ -10,13 +10,6 @@ const BASE = getRootDirectory(gTestPath).replace(
|
|||
);
|
||||
const TEST_URL = BASE + "browser_contextmenu_shareurl.html";
|
||||
|
||||
// Setup.
|
||||
add_task(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", true]],
|
||||
});
|
||||
});
|
||||
|
||||
let mockShareData = [
|
||||
{
|
||||
name: "Test",
|
||||
|
|
|
@ -10,13 +10,6 @@ const BASE = getRootDirectory(gTestPath).replace(
|
|||
);
|
||||
const TEST_URL = BASE + "browser_contextmenu_shareurl.html";
|
||||
|
||||
// Setup.
|
||||
add_task(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", true]],
|
||||
});
|
||||
});
|
||||
|
||||
// Setup spies for observing function calls from MacSharingService
|
||||
let shareUrlSpy = sinon.spy();
|
||||
|
||||
|
|
|
@ -27,166 +27,156 @@ function openAboutPrefPromise(win) {
|
|||
];
|
||||
return Promise.all(promises);
|
||||
}
|
||||
add_task(async function setup() {
|
||||
let win = await BrowserTestUtils.openNewWindowWithFlushedXULCacheForMozSupports();
|
||||
// Open a new tab to keep the window open.
|
||||
await BrowserTestUtils.openNewForegroundTab(
|
||||
win.gBrowser,
|
||||
"https://example.com"
|
||||
);
|
||||
});
|
||||
|
||||
for (let protonEnabled of [true, false]) {
|
||||
add_task(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", protonEnabled]],
|
||||
});
|
||||
let win = await BrowserTestUtils.openNewWindowWithFlushedXULCacheForMozSupports();
|
||||
// Open a new tab to keep the window open.
|
||||
await BrowserTestUtils.openNewForegroundTab(
|
||||
win.gBrowser,
|
||||
"https://example.com"
|
||||
);
|
||||
});
|
||||
|
||||
// Test only displaying notification once within the given interval
|
||||
add_task(async function() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
const TEST_NOTIFICATION_INTERVAL_MS = 2000;
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"browser.storageManager.pressureNotification.minIntervalMS",
|
||||
TEST_NOTIFICATION_INTERVAL_MS,
|
||||
],
|
||||
// Test only displaying notification once within the given interval
|
||||
add_task(async function() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
const TEST_NOTIFICATION_INTERVAL_MS = 2000;
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"browser.storageManager.pressureNotification.minIntervalMS",
|
||||
TEST_NOTIFICATION_INTERVAL_MS,
|
||||
],
|
||||
});
|
||||
// Commenting this to see if we really need it
|
||||
// await SpecialPowers.pushPrefEnv({set: [["privacy.reduceTimerPrecision", false]]});
|
||||
|
||||
await notifyStoragePressure();
|
||||
await TestUtils.waitForCondition(() =>
|
||||
win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
)
|
||||
);
|
||||
let notification = win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
);
|
||||
is(
|
||||
notification.localName,
|
||||
protonEnabled ? "notification-message" : "notification",
|
||||
"Should display storage pressure notification"
|
||||
);
|
||||
notification.close();
|
||||
|
||||
await notifyStoragePressure();
|
||||
notification = win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
);
|
||||
is(
|
||||
notification,
|
||||
null,
|
||||
"Should not display storage pressure notification more than once within the given interval"
|
||||
);
|
||||
|
||||
await new Promise(resolve =>
|
||||
setTimeout(resolve, TEST_NOTIFICATION_INTERVAL_MS + 1)
|
||||
);
|
||||
await notifyStoragePressure();
|
||||
await TestUtils.waitForCondition(() =>
|
||||
win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
)
|
||||
);
|
||||
notification = win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
);
|
||||
is(
|
||||
notification.localName,
|
||||
protonEnabled ? "notification-message" : "notification",
|
||||
"Should display storage pressure notification after the given interval"
|
||||
);
|
||||
notification.close();
|
||||
],
|
||||
});
|
||||
// Commenting this to see if we really need it
|
||||
// await SpecialPowers.pushPrefEnv({set: [["privacy.reduceTimerPrecision", false]]});
|
||||
|
||||
// Test guiding user to the about:preferences when usage exceeds the given threshold
|
||||
add_task(async function() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.storageManager.pressureNotification.minIntervalMS", 0]],
|
||||
});
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
win.gBrowser,
|
||||
"https://example.com"
|
||||
);
|
||||
|
||||
const BYTES_IN_GIGABYTE = 1073741824;
|
||||
const USAGE_THRESHOLD_BYTES =
|
||||
BYTES_IN_GIGABYTE *
|
||||
Services.prefs.getIntPref(
|
||||
"browser.storageManager.pressureNotification.usageThresholdGB"
|
||||
);
|
||||
await notifyStoragePressure(USAGE_THRESHOLD_BYTES);
|
||||
await TestUtils.waitForCondition(() =>
|
||||
win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
)
|
||||
);
|
||||
let notification = win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
await notifyStoragePressure();
|
||||
await TestUtils.waitForCondition(() =>
|
||||
win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
);
|
||||
is(
|
||||
notification.localName,
|
||||
protonEnabled ? "notification-message" : "notification",
|
||||
"Should display storage pressure notification"
|
||||
);
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
)
|
||||
);
|
||||
let notification = win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
);
|
||||
is(
|
||||
notification.localName,
|
||||
"notification-message",
|
||||
"Should display storage pressure notification"
|
||||
);
|
||||
notification.close();
|
||||
|
||||
let prefBtn = notification.buttonContainer.getElementsByTagName(
|
||||
"button"
|
||||
)[0];
|
||||
ok(prefBtn, "Should have an open preferences button");
|
||||
let aboutPrefPromise = openAboutPrefPromise(win);
|
||||
EventUtils.synthesizeMouseAtCenter(prefBtn, {}, win);
|
||||
await aboutPrefPromise;
|
||||
let aboutPrefTab = win.gBrowser.selectedTab;
|
||||
let prefDoc = win.gBrowser.selectedBrowser.contentDocument;
|
||||
let siteDataGroup = prefDoc.getElementById("siteDataGroup");
|
||||
is_element_visible(
|
||||
siteDataGroup,
|
||||
"Should open to the siteDataGroup section in about:preferences"
|
||||
);
|
||||
BrowserTestUtils.removeTab(aboutPrefTab);
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
await notifyStoragePressure();
|
||||
notification = win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
);
|
||||
is(
|
||||
notification,
|
||||
null,
|
||||
"Should not display storage pressure notification more than once within the given interval"
|
||||
);
|
||||
|
||||
await new Promise(resolve =>
|
||||
setTimeout(resolve, TEST_NOTIFICATION_INTERVAL_MS + 1)
|
||||
);
|
||||
await notifyStoragePressure();
|
||||
await TestUtils.waitForCondition(() =>
|
||||
win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
)
|
||||
);
|
||||
notification = win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
);
|
||||
is(
|
||||
notification.localName,
|
||||
"notification-message",
|
||||
"Should display storage pressure notification after the given interval"
|
||||
);
|
||||
notification.close();
|
||||
});
|
||||
|
||||
// Test guiding user to the about:preferences when usage exceeds the given threshold
|
||||
add_task(async function() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.storageManager.pressureNotification.minIntervalMS", 0]],
|
||||
});
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
win.gBrowser,
|
||||
"https://example.com"
|
||||
);
|
||||
|
||||
// Test not displaying the 2nd notification if one is already being displayed
|
||||
add_task(async function() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
const TEST_NOTIFICATION_INTERVAL_MS = 0;
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"browser.storageManager.pressureNotification.minIntervalMS",
|
||||
TEST_NOTIFICATION_INTERVAL_MS,
|
||||
],
|
||||
const BYTES_IN_GIGABYTE = 1073741824;
|
||||
const USAGE_THRESHOLD_BYTES =
|
||||
BYTES_IN_GIGABYTE *
|
||||
Services.prefs.getIntPref(
|
||||
"browser.storageManager.pressureNotification.usageThresholdGB"
|
||||
);
|
||||
await notifyStoragePressure(USAGE_THRESHOLD_BYTES);
|
||||
await TestUtils.waitForCondition(() =>
|
||||
win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
)
|
||||
);
|
||||
let notification = win.gHighPriorityNotificationBox.getNotificationWithValue(
|
||||
"storage-pressure-notification"
|
||||
);
|
||||
is(
|
||||
notification.localName,
|
||||
"notification-message",
|
||||
"Should display storage pressure notification"
|
||||
);
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
let prefBtn = notification.buttonContainer.getElementsByTagName("button")[0];
|
||||
ok(prefBtn, "Should have an open preferences button");
|
||||
let aboutPrefPromise = openAboutPrefPromise(win);
|
||||
EventUtils.synthesizeMouseAtCenter(prefBtn, {}, win);
|
||||
await aboutPrefPromise;
|
||||
let aboutPrefTab = win.gBrowser.selectedTab;
|
||||
let prefDoc = win.gBrowser.selectedBrowser.contentDocument;
|
||||
let siteDataGroup = prefDoc.getElementById("siteDataGroup");
|
||||
is_element_visible(
|
||||
siteDataGroup,
|
||||
"Should open to the siteDataGroup section in about:preferences"
|
||||
);
|
||||
BrowserTestUtils.removeTab(aboutPrefTab);
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
// Test not displaying the 2nd notification if one is already being displayed
|
||||
add_task(async function() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
const TEST_NOTIFICATION_INTERVAL_MS = 0;
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[
|
||||
"browser.storageManager.pressureNotification.minIntervalMS",
|
||||
TEST_NOTIFICATION_INTERVAL_MS,
|
||||
],
|
||||
});
|
||||
|
||||
await notifyStoragePressure();
|
||||
await notifyStoragePressure();
|
||||
let allNotifications = win.gHighPriorityNotificationBox.allNotifications;
|
||||
let pressureNotificationCount = 0;
|
||||
allNotifications.forEach(notification => {
|
||||
if (
|
||||
notification.getAttribute("value") == "storage-pressure-notification"
|
||||
) {
|
||||
pressureNotificationCount++;
|
||||
}
|
||||
});
|
||||
is(
|
||||
pressureNotificationCount,
|
||||
1,
|
||||
"Should not display the 2nd notification when there is already one"
|
||||
);
|
||||
win.gHighPriorityNotificationBox.removeAllNotifications();
|
||||
],
|
||||
});
|
||||
|
||||
add_task(async function cleanup() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
await notifyStoragePressure();
|
||||
await notifyStoragePressure();
|
||||
let allNotifications = win.gHighPriorityNotificationBox.allNotifications;
|
||||
let pressureNotificationCount = 0;
|
||||
allNotifications.forEach(notification => {
|
||||
if (notification.getAttribute("value") == "storage-pressure-notification") {
|
||||
pressureNotificationCount++;
|
||||
}
|
||||
});
|
||||
}
|
||||
is(
|
||||
pressureNotificationCount,
|
||||
1,
|
||||
"Should not display the 2nd notification when there is already one"
|
||||
);
|
||||
win.gHighPriorityNotificationBox.removeAllNotifications();
|
||||
});
|
||||
|
||||
add_task(async function cleanup() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
|
|
@ -12,12 +12,6 @@ async function addNotification(box, label, value, priorityName) {
|
|||
return notification;
|
||||
}
|
||||
|
||||
add_task(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", true]],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function testStackingOrder() {
|
||||
const tabNotificationBox = gBrowser.getNotificationBox();
|
||||
ok(
|
||||
|
|
|
@ -44,12 +44,6 @@ function createNotification({ browser, label, value, priority }) {
|
|||
return notification;
|
||||
}
|
||||
|
||||
add_task(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", true]],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function testNotificationInBackgroundTab() {
|
||||
let firstTab = gBrowser.selectedTab;
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
[DEFAULT]
|
||||
prefs =
|
||||
browser.proton.enabled=true
|
||||
support-files =
|
||||
head.js
|
||||
|
||||
|
|
|
@ -168,11 +168,6 @@ add_task(async function bookmark() {
|
|||
});
|
||||
|
||||
add_task(async function test_disabledPageAction_hidden_in_protonOverflowMenu() {
|
||||
// Make sure that proton is enabled for this test (indipendently from its
|
||||
// default value set on the current build).
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", true]],
|
||||
});
|
||||
// Make sure the overflow menu urlbar button is visible (indipendently from
|
||||
// the current size of the Firefox window).
|
||||
BrowserPageActions.mainButtonNode.style.visibility = "visible";
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
extends: ["plugin:mozilla/browser-test"],
|
||||
};
|
|
@ -1,26 +0,0 @@
|
|||
[DEFAULT]
|
||||
prefs =
|
||||
browser.proton.enabled=false
|
||||
support-files =
|
||||
head.js
|
||||
|
||||
# Remove this folder and rename pageActions-proton once proton is released.
|
||||
|
||||
[browser_PageActions_removeExtension.js]
|
||||
[browser_page_action_menu_add_search_engine.js]
|
||||
support-files =
|
||||
page_action_menu_add_search_engine_invalid.html
|
||||
page_action_menu_add_search_engine_one.html
|
||||
page_action_menu_add_search_engine_many.html
|
||||
page_action_menu_add_search_engine_same_names.html
|
||||
page_action_menu_add_search_engine_0.xml
|
||||
page_action_menu_add_search_engine_1.xml
|
||||
page_action_menu_add_search_engine_2.xml
|
||||
[browser_page_action_menu_clipboard.js]
|
||||
[browser_page_action_menu_share_mac.js]
|
||||
skip-if = os != "mac" # Mac only feature
|
||||
[browser_page_action_menu_share_win.js]
|
||||
support-files =
|
||||
browser_page_action_menu_share_win.html
|
||||
skip-if = os != "win" # Windows only feature
|
||||
[browser_page_action_menu.js]
|
|
@ -1,320 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const { EnterprisePolicyTesting } = ChromeUtils.import(
|
||||
"resource://testing-common/EnterprisePolicyTesting.jsm"
|
||||
);
|
||||
|
||||
const { ExtensionCommon } = ChromeUtils.import(
|
||||
"resource://gre/modules/ExtensionCommon.jsm"
|
||||
);
|
||||
|
||||
const { TelemetryTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/TelemetryTestUtils.jsm"
|
||||
);
|
||||
|
||||
const TELEMETRY_EVENTS_FILTERS = {
|
||||
category: "addonsManager",
|
||||
method: "action",
|
||||
};
|
||||
|
||||
// Initialization. Must run first.
|
||||
add_task(async function init() {
|
||||
// The page action urlbar button, and therefore the panel, is only shown when
|
||||
// the current tab is actionable -- i.e., a normal web page. about:blank is
|
||||
// not, so open a new tab first thing, and close it when this test is done.
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: "http://example.com/",
|
||||
});
|
||||
|
||||
// The prompt service is mocked later, so set it up to be restored.
|
||||
let { prompt } = Services;
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
Services.prompt = prompt;
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function contextMenu_removeExtension_panel() {
|
||||
Services.telemetry.clearEvents();
|
||||
|
||||
// We use an extension that shows a page action so that we can test the
|
||||
// "remove extension" item in the context menu.
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
name: "Test contextMenu",
|
||||
page_action: { show_matches: ["<all_urls>"] },
|
||||
},
|
||||
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
let actionId = ExtensionCommon.makeWidgetId(extension.id);
|
||||
|
||||
// Open the panel and then open the context menu on the action's item.
|
||||
await promisePageActionPanelOpen();
|
||||
let panelButton = BrowserPageActions.panelButtonNodeForActionID(actionId);
|
||||
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(panelButton, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
let removeExtensionItem = getRemoveExtensionItem();
|
||||
Assert.ok(removeExtensionItem, "'Remove' item exists");
|
||||
Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
|
||||
Assert.ok(!removeExtensionItem.disabled, "'Remove' item is not disabled");
|
||||
|
||||
// Click the "remove extension" item, a prompt should be displayed and then
|
||||
// the add-on should be uninstalled. We mock the prompt service to confirm
|
||||
// the removal of the add-on.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
let addonUninstalledPromise = promiseAddonUninstalled(extension.id);
|
||||
mockPromptService();
|
||||
EventUtils.synthesizeMouseAtCenter(removeExtensionItem, {});
|
||||
await Promise.all([contextMenuPromise, addonUninstalledPromise]);
|
||||
|
||||
// Done, clean up.
|
||||
await extension.unload();
|
||||
|
||||
TelemetryTestUtils.assertEvents(
|
||||
[
|
||||
{
|
||||
object: "pageAction",
|
||||
value: "accepted",
|
||||
extra: { addonId: extension.id, action: "uninstall" },
|
||||
},
|
||||
],
|
||||
TELEMETRY_EVENTS_FILTERS
|
||||
);
|
||||
|
||||
// urlbar tests that run after this one can break if the mouse is left over
|
||||
// the area where the urlbar popup appears, which seems to happen due to the
|
||||
// above synthesized mouse events. Move it over the urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
|
||||
gURLBar.focus();
|
||||
});
|
||||
|
||||
add_task(async function contextMenu_removeExtension_urlbar() {
|
||||
Services.telemetry.clearEvents();
|
||||
|
||||
// We use an extension that shows a page action so that we can test the
|
||||
// "remove extension" item in the context menu.
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
name: "Test contextMenu",
|
||||
page_action: { show_matches: ["<all_urls>"] },
|
||||
},
|
||||
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
// The pageAction implementation enables the button at the next animation
|
||||
// frame, so before we look for the button we should wait one animation frame
|
||||
// as well.
|
||||
await promiseAnimationFrame();
|
||||
|
||||
let actionId = ExtensionCommon.makeWidgetId(extension.id);
|
||||
|
||||
// Open the context menu on the action's urlbar button.
|
||||
let urlbarButton = BrowserPageActions.urlbarButtonNodeForActionID(actionId);
|
||||
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(urlbarButton, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
let removeExtensionItem = getRemoveExtensionItem();
|
||||
Assert.ok(removeExtensionItem, "'Remove' item exists");
|
||||
Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
|
||||
Assert.ok(!removeExtensionItem.disabled, "'Remove' item is not disabled");
|
||||
|
||||
// Click the "remove extension" item, a prompt should be displayed and then
|
||||
// the add-on should be uninstalled. We mock the prompt service to cancel the
|
||||
// removal of the add-on.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
let promptService = mockPromptService();
|
||||
let promptCancelledPromise = new Promise(resolve => {
|
||||
promptService.confirmEx = () => resolve();
|
||||
});
|
||||
EventUtils.synthesizeMouseAtCenter(removeExtensionItem, {});
|
||||
await Promise.all([contextMenuPromise, promptCancelledPromise]);
|
||||
|
||||
// Done, clean up.
|
||||
await extension.unload();
|
||||
|
||||
TelemetryTestUtils.assertEvents(
|
||||
[
|
||||
{
|
||||
object: "pageAction",
|
||||
value: "cancelled",
|
||||
extra: { addonId: extension.id, action: "uninstall" },
|
||||
},
|
||||
],
|
||||
TELEMETRY_EVENTS_FILTERS
|
||||
);
|
||||
|
||||
// urlbar tests that run after this one can break if the mouse is left over
|
||||
// the area where the urlbar popup appears, which seems to happen due to the
|
||||
// above synthesized mouse events. Move it over the urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
|
||||
gURLBar.focus();
|
||||
});
|
||||
|
||||
add_task(async function contextMenu_removeExtension_disabled_in_panel() {
|
||||
// We use an extension that shows a page action so that we can test the
|
||||
// "remove extension" item in the context menu.
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
name: "Test contextMenu",
|
||||
page_action: { show_matches: ["<all_urls>"] },
|
||||
},
|
||||
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
// Add a policy to prevent the add-on from being uninstalled.
|
||||
await EnterprisePolicyTesting.setupPolicyEngineWithJson({
|
||||
policies: {
|
||||
Extensions: {
|
||||
Locked: [extension.id],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let actionId = ExtensionCommon.makeWidgetId(extension.id);
|
||||
|
||||
// Open the panel and then open the context menu on the action's item.
|
||||
await promisePageActionPanelOpen();
|
||||
let panelButton = BrowserPageActions.panelButtonNodeForActionID(actionId);
|
||||
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(panelButton, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
let removeExtensionItem = getRemoveExtensionItem();
|
||||
Assert.ok(removeExtensionItem, "'Remove' item exists");
|
||||
Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
|
||||
Assert.ok(removeExtensionItem.disabled, "'Remove' item is disabled");
|
||||
|
||||
// Press escape to hide the context menu.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
await contextMenuPromise;
|
||||
|
||||
// Done, clean up.
|
||||
await extension.unload();
|
||||
await EnterprisePolicyTesting.setupPolicyEngineWithJson("");
|
||||
|
||||
// urlbar tests that run after this one can break if the mouse is left over
|
||||
// the area where the urlbar popup appears, which seems to happen due to the
|
||||
// above synthesized mouse events. Move it over the urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
|
||||
gURLBar.focus();
|
||||
});
|
||||
|
||||
add_task(async function contextMenu_removeExtension_disabled_in_urlbar() {
|
||||
// We use an extension that shows a page action so that we can test the
|
||||
// "remove extension" item in the context menu.
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
name: "Test contextMenu",
|
||||
page_action: { show_matches: ["<all_urls>"] },
|
||||
},
|
||||
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
// The pageAction implementation enables the button at the next animation
|
||||
// frame, so before we look for the button we should wait one animation frame
|
||||
// as well.
|
||||
await promiseAnimationFrame();
|
||||
// Add a policy to prevent the add-on from being uninstalled.
|
||||
await EnterprisePolicyTesting.setupPolicyEngineWithJson({
|
||||
policies: {
|
||||
Extensions: {
|
||||
Locked: [extension.id],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let actionId = ExtensionCommon.makeWidgetId(extension.id);
|
||||
|
||||
// Open the context menu on the action's urlbar button.
|
||||
let urlbarButton = BrowserPageActions.urlbarButtonNodeForActionID(actionId);
|
||||
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
|
||||
EventUtils.synthesizeMouseAtCenter(urlbarButton, {
|
||||
type: "contextmenu",
|
||||
button: 2,
|
||||
});
|
||||
await contextMenuPromise;
|
||||
|
||||
let removeExtensionItem = getRemoveExtensionItem();
|
||||
Assert.ok(removeExtensionItem, "'Remove' item exists");
|
||||
Assert.ok(!removeExtensionItem.hidden, "'Remove' item is visible");
|
||||
Assert.ok(removeExtensionItem.disabled, "'Remove' item is disabled");
|
||||
|
||||
// Press escape to hide the context menu.
|
||||
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
await contextMenuPromise;
|
||||
|
||||
// Done, clean up.
|
||||
await extension.unload();
|
||||
await EnterprisePolicyTesting.setupPolicyEngineWithJson("");
|
||||
|
||||
// urlbar tests that run after this one can break if the mouse is left over
|
||||
// the area where the urlbar popup appears, which seems to happen due to the
|
||||
// above synthesized mouse events. Move it over the urlbar.
|
||||
EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, { type: "mousemove" });
|
||||
gURLBar.focus();
|
||||
});
|
||||
|
||||
function promiseAddonUninstalled(addonId) {
|
||||
return new Promise(resolve => {
|
||||
let listener = {};
|
||||
listener.onUninstalled = addon => {
|
||||
if (addon.id == addonId) {
|
||||
AddonManager.removeAddonListener(listener);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
AddonManager.addAddonListener(listener);
|
||||
});
|
||||
}
|
||||
|
||||
function mockPromptService() {
|
||||
let promptService = {
|
||||
// The prompt returns 1 for cancelled and 0 for accepted.
|
||||
_response: 0,
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]),
|
||||
confirmEx: () => promptService._response,
|
||||
};
|
||||
|
||||
Services.prompt = promptService;
|
||||
|
||||
return promptService;
|
||||
}
|
||||
|
||||
function getRemoveExtensionItem() {
|
||||
return document.querySelector(
|
||||
"#pageActionContextMenu > menuitem[label='Remove Extension']"
|
||||
);
|
||||
}
|
||||
|
||||
async function promiseAnimationFrame(win = window) {
|
||||
await new Promise(resolve => win.requestAnimationFrame(resolve));
|
||||
|
||||
let { tm } = Services;
|
||||
return new Promise(resolve => tm.dispatchToMainThread(resolve));
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,668 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const { PromptTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/PromptTestUtils.jsm"
|
||||
);
|
||||
|
||||
// Checks the panel button with a page that doesn't offer any engines.
|
||||
add_task(async function none() {
|
||||
let url = "http://mochi.test:8888/";
|
||||
await BrowserTestUtils.withNewTab(url, async () => {
|
||||
// Open the panel.
|
||||
await promisePageActionPanelOpen();
|
||||
EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
|
||||
await promisePageActionPanelHidden();
|
||||
|
||||
// The action should not be present.
|
||||
let actions = PageActions.actionsInPanel(window);
|
||||
Assert.ok(
|
||||
!actions.some(a => a.id == "addSearchEngine"),
|
||||
"Action should not be present in panel"
|
||||
);
|
||||
let button = BrowserPageActions.panelButtonNodeForActionID(
|
||||
"addSearchEngine"
|
||||
);
|
||||
Assert.ok(!button, "Action button should not be in panel");
|
||||
});
|
||||
});
|
||||
|
||||
// Checks the panel button with a page that offers one engine.
|
||||
add_task(async function one() {
|
||||
let url =
|
||||
getRootDirectory(gTestPath) + "page_action_menu_add_search_engine_one.html";
|
||||
await BrowserTestUtils.withNewTab(url, async () => {
|
||||
// Open the panel.
|
||||
await promisePageActionPanelOpen();
|
||||
|
||||
// The action should be present.
|
||||
let actions = PageActions.actionsInPanel(window);
|
||||
let action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in panel");
|
||||
let expectedTitle = "Add Search Engine";
|
||||
Assert.equal(action.getTitle(window), expectedTitle, "Action title");
|
||||
let button = BrowserPageActions.panelButtonNodeForActionID(
|
||||
"addSearchEngine"
|
||||
);
|
||||
Assert.ok(button, "Button should be in panel");
|
||||
Assert.equal(button.label, expectedTitle, "Button label");
|
||||
Assert.equal(
|
||||
button.classList.contains("subviewbutton-nav"),
|
||||
false,
|
||||
"Button should not expand into a subview"
|
||||
);
|
||||
|
||||
// Click the action's button.
|
||||
let enginePromise = promiseEngine(
|
||||
"engine-added",
|
||||
"page_action_menu_add_search_engine_0"
|
||||
);
|
||||
let hiddenPromise = promisePageActionPanelHidden();
|
||||
let feedbackPromise = promiseFeedbackPanelShownAndHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
await hiddenPromise;
|
||||
let engine = await enginePromise;
|
||||
let feedbackText = await feedbackPromise;
|
||||
Assert.equal(feedbackText, "Search engine added!");
|
||||
|
||||
// Open the panel again.
|
||||
await promisePageActionPanelOpen();
|
||||
EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
|
||||
await promisePageActionPanelHidden();
|
||||
|
||||
// The action should be gone.
|
||||
actions = PageActions.actionsInPanel(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(!action, "Action should not be present in panel");
|
||||
button = BrowserPageActions.panelButtonNodeForActionID("addSearchEngine");
|
||||
Assert.ok(!button, "Action button should not be in panel");
|
||||
|
||||
// Remove the engine.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-removed",
|
||||
"page_action_menu_add_search_engine_0"
|
||||
);
|
||||
await Services.search.removeEngine(engine);
|
||||
await enginePromise;
|
||||
|
||||
// Open the panel again.
|
||||
await promisePageActionPanelOpen();
|
||||
EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
|
||||
await promisePageActionPanelHidden();
|
||||
|
||||
// The action should be present again.
|
||||
actions = PageActions.actionsInPanel(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in panel");
|
||||
Assert.equal(action.getTitle(window), expectedTitle, "Action title");
|
||||
button = BrowserPageActions.panelButtonNodeForActionID("addSearchEngine");
|
||||
Assert.ok(button, "Action button should be in panel");
|
||||
Assert.equal(button.label, expectedTitle, "Button label");
|
||||
Assert.equal(
|
||||
button.classList.contains("subviewbutton-nav"),
|
||||
false,
|
||||
"Button should not expand into a subview"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Checks the panel button with a page that offers an invalid engine.
|
||||
add_task(async function invalid() {
|
||||
let url =
|
||||
getRootDirectory(gTestPath) +
|
||||
"page_action_menu_add_search_engine_invalid.html";
|
||||
await BrowserTestUtils.withNewTab(url, async tab => {
|
||||
// Open the panel.
|
||||
await promisePageActionPanelOpen();
|
||||
|
||||
// The action should be present.
|
||||
let actions = PageActions.actionsInPanel(window);
|
||||
let action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in panel");
|
||||
let expectedTitle = "Add Search Engine";
|
||||
Assert.equal(action.getTitle(window), expectedTitle, "Action title");
|
||||
let button = BrowserPageActions.panelButtonNodeForActionID(
|
||||
"addSearchEngine"
|
||||
);
|
||||
Assert.ok(button, "Button should be in panel");
|
||||
Assert.equal(button.label, expectedTitle, "Button label");
|
||||
Assert.equal(
|
||||
button.classList.contains("subviewbutton-nav"),
|
||||
false,
|
||||
"Button should not expand into a subview"
|
||||
);
|
||||
|
||||
// Click the action's button.
|
||||
let hiddenPromise = promisePageActionPanelHidden();
|
||||
let promptPromise = PromptTestUtils.waitForPrompt(tab.linkedBrowser, {
|
||||
modalType: Ci.nsIPromptService.MODAL_TYPE_CONTENT,
|
||||
promptType: "alert",
|
||||
});
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
await hiddenPromise;
|
||||
let prompt = await promptPromise;
|
||||
|
||||
Assert.ok(
|
||||
prompt.ui.infoBody.textContent.includes(
|
||||
"http://mochi.test:8888/browser/browser/base/content/test/pageActions/page_action_menu_add_search_engine_404.xml"
|
||||
),
|
||||
"Should have included the url in the prompt body"
|
||||
);
|
||||
|
||||
await PromptTestUtils.handlePrompt(prompt);
|
||||
});
|
||||
});
|
||||
|
||||
// Checks the panel button with a page that offers many engines.
|
||||
add_task(async function many() {
|
||||
let url =
|
||||
getRootDirectory(gTestPath) +
|
||||
"page_action_menu_add_search_engine_many.html";
|
||||
await BrowserTestUtils.withNewTab(url, async () => {
|
||||
// Open the panel.
|
||||
await promisePageActionPanelOpen();
|
||||
|
||||
// The action should be present.
|
||||
let actions = PageActions.actionsInPanel(window);
|
||||
let action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in panel");
|
||||
let expectedTitle = "Add Search Engine";
|
||||
Assert.equal(action.getTitle(window), expectedTitle, "Action title");
|
||||
let button = BrowserPageActions.panelButtonNodeForActionID(
|
||||
"addSearchEngine"
|
||||
);
|
||||
Assert.ok(button, "Action button should be in panel");
|
||||
Assert.equal(button.label, expectedTitle, "Button label");
|
||||
Assert.equal(
|
||||
button.classList.contains("subviewbutton-nav"),
|
||||
true,
|
||||
"Button should expand into a subview"
|
||||
);
|
||||
|
||||
// Click the action's button. The subview should be shown.
|
||||
let viewPromise = promisePageActionViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
let view = await viewPromise;
|
||||
let viewID = BrowserPageActions._panelViewNodeIDForActionID(
|
||||
"addSearchEngine",
|
||||
false
|
||||
);
|
||||
Assert.equal(view.id, viewID, "View ID");
|
||||
let bodyID = viewID + "-body";
|
||||
let body = document.getElementById(bodyID);
|
||||
Assert.deepEqual(
|
||||
Array.from(body.children, n => n.label),
|
||||
[
|
||||
"page_action_menu_add_search_engine_0",
|
||||
"page_action_menu_add_search_engine_1",
|
||||
"page_action_menu_add_search_engine_2",
|
||||
],
|
||||
"Subview children"
|
||||
);
|
||||
|
||||
// Click the first engine to install it.
|
||||
let enginePromise = promiseEngine(
|
||||
"engine-added",
|
||||
"page_action_menu_add_search_engine_0"
|
||||
);
|
||||
let hiddenPromise = promisePageActionPanelHidden();
|
||||
let feedbackPromise = promiseFeedbackPanelShownAndHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(body.children[0], {});
|
||||
await hiddenPromise;
|
||||
let engines = [];
|
||||
let engine = await enginePromise;
|
||||
engines.push(engine);
|
||||
let feedbackText = await feedbackPromise;
|
||||
Assert.equal(feedbackText, "Search engine added!", "Feedback text");
|
||||
|
||||
// Open the panel and show the subview again. The installed engine should
|
||||
// be gone.
|
||||
await promisePageActionPanelOpen();
|
||||
viewPromise = promisePageActionViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
await viewPromise;
|
||||
Assert.deepEqual(
|
||||
Array.from(body.children, n => n.label),
|
||||
[
|
||||
"page_action_menu_add_search_engine_1",
|
||||
"page_action_menu_add_search_engine_2",
|
||||
],
|
||||
"Subview children"
|
||||
);
|
||||
|
||||
// Click the next engine to install it.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-added",
|
||||
"page_action_menu_add_search_engine_1"
|
||||
);
|
||||
hiddenPromise = promisePageActionPanelHidden();
|
||||
feedbackPromise = promiseFeedbackPanelShownAndHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(body.children[0], {});
|
||||
await hiddenPromise;
|
||||
engine = await enginePromise;
|
||||
engines.push(engine);
|
||||
feedbackText = await feedbackPromise;
|
||||
Assert.equal(feedbackText, "Search engine added!", "Feedback text");
|
||||
|
||||
// Open the panel again. This time the action button should show the one
|
||||
// remaining engine.
|
||||
await promisePageActionPanelOpen();
|
||||
actions = PageActions.actionsInPanel(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in panel");
|
||||
expectedTitle = "Add Search Engine";
|
||||
Assert.equal(action.getTitle(window), expectedTitle, "Action title");
|
||||
button = BrowserPageActions.panelButtonNodeForActionID("addSearchEngine");
|
||||
Assert.ok(button, "Button should be present in panel");
|
||||
Assert.equal(button.label, expectedTitle, "Button label");
|
||||
Assert.equal(
|
||||
button.classList.contains("subviewbutton-nav"),
|
||||
false,
|
||||
"Button should not expand into a subview"
|
||||
);
|
||||
|
||||
// Click the button.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-added",
|
||||
"page_action_menu_add_search_engine_2"
|
||||
);
|
||||
hiddenPromise = promisePageActionPanelHidden();
|
||||
feedbackPromise = promiseFeedbackPanelShownAndHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
await hiddenPromise;
|
||||
engine = await enginePromise;
|
||||
engines.push(engine);
|
||||
feedbackText = await feedbackPromise;
|
||||
Assert.equal(feedbackText, "Search engine added!", "Feedback text");
|
||||
|
||||
// All engines are installed at this point. Open the panel and make sure
|
||||
// the action is gone.
|
||||
await promisePageActionPanelOpen();
|
||||
EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
|
||||
await promisePageActionPanelHidden();
|
||||
actions = PageActions.actionsInPanel(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(!action, "Action should be gone");
|
||||
button = BrowserPageActions.panelButtonNodeForActionID("addSearchEngine");
|
||||
Assert.ok(!button, "Button should not be in panel");
|
||||
|
||||
// Remove the first engine.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-removed",
|
||||
"page_action_menu_add_search_engine_0"
|
||||
);
|
||||
await Services.search.removeEngine(engines.shift());
|
||||
await enginePromise;
|
||||
|
||||
// Open the panel again. The action should be present and showing the first
|
||||
// engine.
|
||||
await promisePageActionPanelOpen();
|
||||
EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
|
||||
await promisePageActionPanelHidden();
|
||||
actions = PageActions.actionsInPanel(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in panel");
|
||||
expectedTitle = "Add Search Engine";
|
||||
Assert.equal(action.getTitle(window), expectedTitle, "Action title");
|
||||
button = BrowserPageActions.panelButtonNodeForActionID("addSearchEngine");
|
||||
Assert.ok(button, "Button should be present in panel");
|
||||
Assert.equal(button.label, expectedTitle, "Button label");
|
||||
Assert.equal(
|
||||
button.classList.contains("subviewbutton-nav"),
|
||||
false,
|
||||
"Button should not expand into a subview"
|
||||
);
|
||||
|
||||
// Remove the second engine.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-removed",
|
||||
"page_action_menu_add_search_engine_1"
|
||||
);
|
||||
await Services.search.removeEngine(engines.shift());
|
||||
await enginePromise;
|
||||
|
||||
// Open the panel again and check the subview. The subview should be
|
||||
// present now that there are two offered engines again.
|
||||
await promisePageActionPanelOpen();
|
||||
actions = PageActions.actionsInPanel(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in panel");
|
||||
expectedTitle = "Add Search Engine";
|
||||
Assert.equal(action.getTitle(window), expectedTitle, "Action title");
|
||||
button = BrowserPageActions.panelButtonNodeForActionID("addSearchEngine");
|
||||
Assert.ok(button, "Button should be in panel");
|
||||
Assert.equal(button.label, expectedTitle, "Button label");
|
||||
Assert.equal(
|
||||
button.classList.contains("subviewbutton-nav"),
|
||||
true,
|
||||
"Button should expand into a subview"
|
||||
);
|
||||
viewPromise = promisePageActionViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
await viewPromise;
|
||||
body = document.getElementById(bodyID);
|
||||
Assert.deepEqual(
|
||||
Array.from(body.children, n => n.label),
|
||||
[
|
||||
"page_action_menu_add_search_engine_0",
|
||||
"page_action_menu_add_search_engine_1",
|
||||
],
|
||||
"Subview children"
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
|
||||
await promisePageActionPanelHidden();
|
||||
|
||||
// Remove the third engine.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-removed",
|
||||
"page_action_menu_add_search_engine_2"
|
||||
);
|
||||
await Services.search.removeEngine(engines.shift());
|
||||
await enginePromise;
|
||||
|
||||
// Open the panel again and check the subview.
|
||||
await promisePageActionPanelOpen();
|
||||
viewPromise = promisePageActionViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
await viewPromise;
|
||||
Assert.deepEqual(
|
||||
Array.from(body.children, n => n.label),
|
||||
[
|
||||
"page_action_menu_add_search_engine_0",
|
||||
"page_action_menu_add_search_engine_1",
|
||||
"page_action_menu_add_search_engine_2",
|
||||
],
|
||||
"Subview children"
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
|
||||
await promisePageActionPanelHidden();
|
||||
});
|
||||
});
|
||||
|
||||
// Checks the urlbar button with a page that offers one engine.
|
||||
add_task(async function urlbarOne() {
|
||||
let url =
|
||||
getRootDirectory(gTestPath) + "page_action_menu_add_search_engine_one.html";
|
||||
await BrowserTestUtils.withNewTab(url, async () => {
|
||||
await promiseNodeVisible(BrowserPageActions.mainButtonNode);
|
||||
|
||||
// Pin the action to the urlbar.
|
||||
let placedPromise = promisePlacedInUrlbar();
|
||||
PageActions.actionForID("addSearchEngine").pinnedToUrlbar = true;
|
||||
|
||||
// It should be placed.
|
||||
let button = await placedPromise;
|
||||
let actions = PageActions.actionsInUrlbar(window);
|
||||
let action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in urlbar");
|
||||
Assert.ok(button, "Action button should be in urlbar");
|
||||
|
||||
// Click the action's button.
|
||||
let enginePromise = promiseEngine(
|
||||
"engine-added",
|
||||
"page_action_menu_add_search_engine_0"
|
||||
);
|
||||
let feedbackPromise = promiseFeedbackPanelShownAndHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
let engine = await enginePromise;
|
||||
let feedbackText = await feedbackPromise;
|
||||
Assert.equal(feedbackText, "Search engine added!");
|
||||
|
||||
// The action should be gone.
|
||||
actions = PageActions.actionsInUrlbar(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(!action, "Action should not be present in urlbar");
|
||||
button = BrowserPageActions.urlbarButtonNodeForActionID("addSearchEngine");
|
||||
Assert.ok(!button, "Action button should not be in urlbar");
|
||||
|
||||
// Remove the engine.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-removed",
|
||||
"page_action_menu_add_search_engine_0"
|
||||
);
|
||||
placedPromise = promisePlacedInUrlbar();
|
||||
await Services.search.removeEngine(engine);
|
||||
await enginePromise;
|
||||
|
||||
// The action should be present again.
|
||||
button = await placedPromise;
|
||||
actions = PageActions.actionsInUrlbar(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in urlbar");
|
||||
Assert.ok(button, "Action button should be in urlbar");
|
||||
|
||||
// Clean up.
|
||||
PageActions.actionForID("addSearchEngine").pinnedToUrlbar = false;
|
||||
await TestUtils.waitForCondition(() => {
|
||||
return !BrowserPageActions.urlbarButtonNodeForActionID("addSearchEngine");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Checks the urlbar button with a page that offers many engines.
|
||||
add_task(async function urlbarMany() {
|
||||
let url =
|
||||
getRootDirectory(gTestPath) +
|
||||
"page_action_menu_add_search_engine_many.html";
|
||||
await BrowserTestUtils.withNewTab(url, async () => {
|
||||
await promiseNodeVisible(BrowserPageActions.mainButtonNode);
|
||||
|
||||
// Pin the action to the urlbar.
|
||||
let placedPromise = promisePlacedInUrlbar();
|
||||
PageActions.actionForID("addSearchEngine").pinnedToUrlbar = true;
|
||||
|
||||
// It should be placed.
|
||||
let button = await placedPromise;
|
||||
let actions = PageActions.actionsInUrlbar(window);
|
||||
let action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in urlbar");
|
||||
Assert.ok(button, "Action button should be in urlbar");
|
||||
|
||||
// Click the action's button. The activated-action panel should open, and
|
||||
// it should contain the addSearchEngine subview.
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
let view = await waitForActivatedActionPanel();
|
||||
let viewID = BrowserPageActions._panelViewNodeIDForActionID(
|
||||
"addSearchEngine",
|
||||
true
|
||||
);
|
||||
Assert.equal(view.id, viewID, "View ID");
|
||||
let body = view.firstElementChild;
|
||||
Assert.deepEqual(
|
||||
Array.from(body.children, n => n.label),
|
||||
[
|
||||
"page_action_menu_add_search_engine_0",
|
||||
"page_action_menu_add_search_engine_1",
|
||||
"page_action_menu_add_search_engine_2",
|
||||
],
|
||||
"Subview children"
|
||||
);
|
||||
|
||||
// Click the first engine to install it.
|
||||
let enginePromise = promiseEngine(
|
||||
"engine-added",
|
||||
"page_action_menu_add_search_engine_0"
|
||||
);
|
||||
let hiddenPromise = promisePanelHidden(
|
||||
BrowserPageActions.activatedActionPanelNode
|
||||
);
|
||||
let feedbackPromise = promiseFeedbackPanelShownAndHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(body.children[0], {});
|
||||
await hiddenPromise;
|
||||
let engines = [];
|
||||
let engine = await enginePromise;
|
||||
engines.push(engine);
|
||||
let feedbackText = await feedbackPromise;
|
||||
Assert.equal(feedbackText, "Search engine added!", "Feedback text");
|
||||
|
||||
// Open the panel again. The installed engine should be gone.
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
view = await waitForActivatedActionPanel();
|
||||
body = view.firstElementChild;
|
||||
Assert.deepEqual(
|
||||
Array.from(body.children, n => n.label),
|
||||
[
|
||||
"page_action_menu_add_search_engine_1",
|
||||
"page_action_menu_add_search_engine_2",
|
||||
],
|
||||
"Subview children"
|
||||
);
|
||||
|
||||
// Click the next engine to install it.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-added",
|
||||
"page_action_menu_add_search_engine_1"
|
||||
);
|
||||
hiddenPromise = promisePanelHidden(
|
||||
BrowserPageActions.activatedActionPanelNode
|
||||
);
|
||||
feedbackPromise = promiseFeedbackPanelShownAndHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(body.children[0], {});
|
||||
await hiddenPromise;
|
||||
engine = await enginePromise;
|
||||
engines.push(engine);
|
||||
feedbackText = await feedbackPromise;
|
||||
Assert.equal(feedbackText, "Search engine added!", "Feedback text");
|
||||
|
||||
// Now there's only one engine left, so clicking the button should simply
|
||||
// install it instead of opening the activated-action panel.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-added",
|
||||
"page_action_menu_add_search_engine_2"
|
||||
);
|
||||
feedbackPromise = promiseFeedbackPanelShownAndHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
engine = await enginePromise;
|
||||
engines.push(engine);
|
||||
feedbackText = await feedbackPromise;
|
||||
Assert.equal(feedbackText, "Search engine added!", "Feedback text");
|
||||
|
||||
// All engines are installed at this point. The action should be gone.
|
||||
actions = PageActions.actionsInUrlbar(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(!action, "Action should be gone");
|
||||
button = BrowserPageActions.urlbarButtonNodeForActionID("addSearchEngine");
|
||||
Assert.ok(!button, "Button should not be in urlbar");
|
||||
|
||||
// Remove the first engine.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-removed",
|
||||
"page_action_menu_add_search_engine_0"
|
||||
);
|
||||
placedPromise = promisePlacedInUrlbar();
|
||||
await Services.search.removeEngine(engines.shift());
|
||||
await enginePromise;
|
||||
|
||||
// The action should be placed again.
|
||||
button = await placedPromise;
|
||||
actions = PageActions.actionsInUrlbar(window);
|
||||
action = actions.find(a => a.id == "addSearchEngine");
|
||||
Assert.ok(action, "Action should be present in urlbar");
|
||||
Assert.ok(button, "Button should be in urlbar");
|
||||
|
||||
// Remove the second engine.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-removed",
|
||||
"page_action_menu_add_search_engine_1"
|
||||
);
|
||||
await Services.search.removeEngine(engines.shift());
|
||||
await enginePromise;
|
||||
|
||||
// Open the panel again and check the subview. The subview should be
|
||||
// present now that there are two offered engines again.
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
view = await waitForActivatedActionPanel();
|
||||
body = view.firstElementChild;
|
||||
Assert.deepEqual(
|
||||
Array.from(body.children, n => n.label),
|
||||
[
|
||||
"page_action_menu_add_search_engine_0",
|
||||
"page_action_menu_add_search_engine_1",
|
||||
],
|
||||
"Subview children"
|
||||
);
|
||||
|
||||
// Hide the panel.
|
||||
hiddenPromise = promisePanelHidden(
|
||||
BrowserPageActions.activatedActionPanelNode
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
await hiddenPromise;
|
||||
|
||||
// Remove the third engine.
|
||||
enginePromise = promiseEngine(
|
||||
"engine-removed",
|
||||
"page_action_menu_add_search_engine_2"
|
||||
);
|
||||
await Services.search.removeEngine(engines.shift());
|
||||
await enginePromise;
|
||||
|
||||
// Open the panel again and check the subview.
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
view = await waitForActivatedActionPanel();
|
||||
body = view.firstElementChild;
|
||||
Assert.deepEqual(
|
||||
Array.from(body.children, n => n.label),
|
||||
[
|
||||
"page_action_menu_add_search_engine_0",
|
||||
"page_action_menu_add_search_engine_1",
|
||||
"page_action_menu_add_search_engine_2",
|
||||
],
|
||||
"Subview children"
|
||||
);
|
||||
|
||||
// Hide the panel.
|
||||
hiddenPromise = promisePanelHidden(
|
||||
BrowserPageActions.activatedActionPanelNode
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
await hiddenPromise;
|
||||
|
||||
// Clean up.
|
||||
PageActions.actionForID("addSearchEngine").pinnedToUrlbar = false;
|
||||
await TestUtils.waitForCondition(() => {
|
||||
return !BrowserPageActions.urlbarButtonNodeForActionID("addSearchEngine");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function promiseEngine(expectedData, expectedEngineName) {
|
||||
info(`Waiting for engine ${expectedData}`);
|
||||
return TestUtils.topicObserved(
|
||||
"browser-search-engine-modified",
|
||||
(engine, data) => {
|
||||
info(`Got engine ${engine.wrappedJSObject.name} ${data}`);
|
||||
return (
|
||||
expectedData == data &&
|
||||
expectedEngineName == engine.wrappedJSObject.name
|
||||
);
|
||||
}
|
||||
).then(([engine, data]) => engine);
|
||||
}
|
||||
|
||||
function promiseFeedbackPanelShownAndHidden() {
|
||||
info("Waiting for feedback panel popupshown");
|
||||
return BrowserTestUtils.waitForEvent(
|
||||
ConfirmationHint._panel,
|
||||
"popupshown"
|
||||
).then(() => {
|
||||
info("Got feedback panel popupshown. Now waiting for popuphidden");
|
||||
return BrowserTestUtils.waitForEvent(
|
||||
ConfirmationHint._panel,
|
||||
"popuphidden"
|
||||
).then(() => ConfirmationHint._message.textContent);
|
||||
});
|
||||
}
|
||||
|
||||
function promisePlacedInUrlbar() {
|
||||
let action = PageActions.actionForID("addSearchEngine");
|
||||
return new Promise(resolve => {
|
||||
let onPlaced = action._onPlacedInUrlbar;
|
||||
action._onPlacedInUrlbar = button => {
|
||||
action._onPlacedInUrlbar = onPlaced;
|
||||
if (action._onPlacedInUrlbar) {
|
||||
action._onPlacedInUrlbar(button);
|
||||
}
|
||||
promiseNodeVisible(button).then(() => resolve(button));
|
||||
};
|
||||
});
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const mockRemoteClients = [
|
||||
{ id: "0", name: "foo", type: "mobile" },
|
||||
{ id: "1", name: "bar", type: "desktop" },
|
||||
{ id: "2", name: "baz", type: "mobile" },
|
||||
];
|
||||
|
||||
add_task(async function copyURL() {
|
||||
// Open an actionable page so that the main page action button appears. (It
|
||||
// does not appear on about:blank for example.)
|
||||
let url = "http://example.com/";
|
||||
await BrowserTestUtils.withNewTab(url, async () => {
|
||||
// Open the panel.
|
||||
await promisePageActionPanelOpen();
|
||||
|
||||
// Click Copy URL.
|
||||
let copyURLButton = document.getElementById("pageAction-panel-copyURL");
|
||||
let hiddenPromise = promisePageActionPanelHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(copyURLButton, {});
|
||||
await hiddenPromise;
|
||||
|
||||
// Check the clipboard.
|
||||
let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(
|
||||
Ci.nsITransferable
|
||||
);
|
||||
transferable.init(null);
|
||||
let flavor = "text/unicode";
|
||||
transferable.addDataFlavor(flavor);
|
||||
Services.clipboard.getData(
|
||||
transferable,
|
||||
Services.clipboard.kGlobalClipboard
|
||||
);
|
||||
let strObj = {};
|
||||
transferable.getTransferData(flavor, strObj);
|
||||
Assert.ok(!!strObj.value);
|
||||
strObj.value.QueryInterface(Ci.nsISupportsString);
|
||||
Assert.equal(strObj.value.data, gBrowser.selectedBrowser.currentURI.spec);
|
||||
});
|
||||
});
|
|
@ -1,119 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { sinon } = ChromeUtils.import("resource://testing-common/Sinon.jsm");
|
||||
|
||||
const URL = "http://example.org/";
|
||||
|
||||
// Keep track of title of service we chose to share with
|
||||
let serviceName, sharedUrl, sharedTitle;
|
||||
let sharingPreferencesCalled = false;
|
||||
|
||||
let mockShareData = [
|
||||
{
|
||||
name: "NSA",
|
||||
menuItemTitle: "National Security Agency",
|
||||
image:
|
||||
"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEA" +
|
||||
"LAAAAAABAAEAAAICTAEAOw==",
|
||||
},
|
||||
];
|
||||
|
||||
let stub = sinon
|
||||
.stub(BrowserPageActions.shareURL, "_sharingService")
|
||||
.get(() => {
|
||||
return {
|
||||
getSharingProviders(url) {
|
||||
return mockShareData;
|
||||
},
|
||||
shareUrl(name, url, title) {
|
||||
serviceName = name;
|
||||
sharedUrl = url;
|
||||
sharedTitle = title;
|
||||
},
|
||||
openSharingPreferences() {
|
||||
sharingPreferencesCalled = true;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
registerCleanupFunction(async function() {
|
||||
stub.restore();
|
||||
EventUtils.synthesizeNativeMouseEvent({
|
||||
type: "mousemove",
|
||||
target: document.documentElement,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
});
|
||||
await PlacesUtils.history.clear();
|
||||
});
|
||||
|
||||
add_task(async function shareURL() {
|
||||
await BrowserTestUtils.withNewTab(URL, async () => {
|
||||
// Open the panel.
|
||||
await promisePageActionPanelOpen();
|
||||
|
||||
// Click Share URL.
|
||||
let shareURLButton = document.getElementById("pageAction-panel-shareURL");
|
||||
let viewPromise = promisePageActionViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(shareURLButton, {});
|
||||
|
||||
let view = await viewPromise;
|
||||
let body = document.getElementById(view.id + "-body");
|
||||
|
||||
// We should see 1 receiver and one extra node for the "More..." button
|
||||
Assert.equal(body.children.length, 2, "Has correct share receivers");
|
||||
let shareButton = body.children[0];
|
||||
Assert.equal(shareButton.label, mockShareData[0].menuItemTitle);
|
||||
let hiddenPromise = promisePageActionPanelHidden();
|
||||
// Click on share, panel should hide and sharingService should be
|
||||
// given the title of service to share with
|
||||
EventUtils.synthesizeMouseAtCenter(shareButton, {});
|
||||
await hiddenPromise;
|
||||
|
||||
Assert.equal(
|
||||
serviceName,
|
||||
mockShareData[0].name,
|
||||
"Shared the correct service name"
|
||||
);
|
||||
Assert.equal(sharedUrl, "http://example.org/", "Shared correct URL");
|
||||
Assert.equal(
|
||||
sharedTitle,
|
||||
"mochitest index /",
|
||||
"Shared with the correct title"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function openSharingPreferences() {
|
||||
await BrowserTestUtils.withNewTab(URL, async () => {
|
||||
// Open the panel.
|
||||
await promisePageActionPanelOpen();
|
||||
|
||||
// Click Share URL.
|
||||
let shareURLButton = document.getElementById("pageAction-panel-shareURL");
|
||||
let viewPromise = promisePageActionViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(shareURLButton, {});
|
||||
|
||||
let view = await viewPromise;
|
||||
let body = document.getElementById(view.id + "-body");
|
||||
|
||||
// We should see 1 receiver and one extra node for the "More..." button
|
||||
Assert.equal(body.children.length, 2, "Has correct share receivers");
|
||||
let moreButton = body.children[1];
|
||||
let hiddenPromise = promisePageActionPanelHidden();
|
||||
// Click on the "more" button, panel should hide and we should call
|
||||
// the sharingService function to open preferences
|
||||
EventUtils.synthesizeMouseAtCenter(moreButton, {});
|
||||
await hiddenPromise;
|
||||
|
||||
Assert.equal(
|
||||
sharingPreferencesCalled,
|
||||
true,
|
||||
"We called openSharingPreferences"
|
||||
);
|
||||
});
|
||||
});
|
|
@ -1,2 +0,0 @@
|
|||
<!doctype html>
|
||||
<title>Windows Sharing</title>
|
|
@ -1,53 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { sinon } = ChromeUtils.import("resource://testing-common/Sinon.jsm");
|
||||
|
||||
const TEST_URL =
|
||||
getRootDirectory(gTestPath) + "browser_page_action_menu_share_win.html";
|
||||
|
||||
// Keep track of site details we are sharing
|
||||
let sharedUrl, sharedTitle;
|
||||
|
||||
let stub = sinon
|
||||
.stub(BrowserPageActions.shareURL, "_windowsUIUtils")
|
||||
.get(() => {
|
||||
return {
|
||||
shareUrl(url, title) {
|
||||
sharedUrl = url;
|
||||
sharedTitle = title;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
registerCleanupFunction(async function() {
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
add_task(async function shareURL() {
|
||||
if (!AppConstants.isPlatformAndVersionAtLeast("win", "6.4")) {
|
||||
Assert.ok(true, "We only expose share on windows 10 and above");
|
||||
return;
|
||||
}
|
||||
|
||||
await BrowserTestUtils.withNewTab(TEST_URL, async () => {
|
||||
// Open the panel.
|
||||
await promisePageActionPanelOpen();
|
||||
|
||||
// Click Share URL.
|
||||
let shareURLButton = document.getElementById("pageAction-panel-shareURL");
|
||||
let hiddenPromise = promisePageActionPanelHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(shareURLButton, {});
|
||||
|
||||
await hiddenPromise;
|
||||
|
||||
Assert.equal(sharedUrl, TEST_URL, "Shared correct URL");
|
||||
Assert.equal(
|
||||
sharedTitle,
|
||||
"Windows Sharing",
|
||||
"Shared with the correct title"
|
||||
);
|
||||
});
|
||||
});
|
|
@ -1,147 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const { PlacesTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/PlacesTestUtils.jsm"
|
||||
);
|
||||
|
||||
function promisePageActionPanelOpen(eventDict = {}) {
|
||||
let dwu = window.windowUtils;
|
||||
return TestUtils.waitForCondition(() => {
|
||||
// Wait for the main page action button to become visible. It's hidden for
|
||||
// some URIs, so depending on when this is called, it may not yet be quite
|
||||
// visible. It's up to the caller to make sure it will be visible.
|
||||
info("Waiting for main page action button to have non-0 size");
|
||||
let bounds = dwu.getBoundsWithoutFlushing(
|
||||
BrowserPageActions.mainButtonNode
|
||||
);
|
||||
return bounds.width > 0 && bounds.height > 0;
|
||||
})
|
||||
.then(() => {
|
||||
// Wait for the panel to become open, by clicking the button if necessary.
|
||||
info("Waiting for main page action panel to be open");
|
||||
if (BrowserPageActions.panelNode.state == "open") {
|
||||
return Promise.resolve();
|
||||
}
|
||||
let shownPromise = promisePageActionPanelShown();
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
BrowserPageActions.mainButtonNode,
|
||||
eventDict
|
||||
);
|
||||
return shownPromise;
|
||||
})
|
||||
.then(() => {
|
||||
// Wait for items in the panel to become visible.
|
||||
return promisePageActionViewChildrenVisible(
|
||||
BrowserPageActions.mainViewNode
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForActivatedActionPanel() {
|
||||
if (!BrowserPageActions.activatedActionPanelNode) {
|
||||
info("Waiting for activated-action panel to be added to mainPopupSet");
|
||||
await new Promise(resolve => {
|
||||
let observer = new MutationObserver(mutations => {
|
||||
if (BrowserPageActions.activatedActionPanelNode) {
|
||||
observer.disconnect();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
let popupSet = document.getElementById("mainPopupSet");
|
||||
observer.observe(popupSet, { childList: true });
|
||||
});
|
||||
info("Activated-action panel added to mainPopupSet");
|
||||
}
|
||||
if (!BrowserPageActions.activatedActionPanelNode.state == "open") {
|
||||
info("Waiting for activated-action panel popupshown");
|
||||
await promisePanelShown(BrowserPageActions.activatedActionPanelNode);
|
||||
info("Got activated-action panel popupshown");
|
||||
}
|
||||
let panelView = BrowserPageActions.activatedActionPanelNode.querySelector(
|
||||
"panelview"
|
||||
);
|
||||
if (panelView) {
|
||||
await BrowserTestUtils.waitForEvent(
|
||||
BrowserPageActions.activatedActionPanelNode,
|
||||
"ViewShown"
|
||||
);
|
||||
await promisePageActionViewChildrenVisible(panelView);
|
||||
}
|
||||
return panelView;
|
||||
}
|
||||
|
||||
function promisePageActionPanelShown() {
|
||||
return promisePanelShown(BrowserPageActions.panelNode);
|
||||
}
|
||||
|
||||
function promisePageActionPanelHidden() {
|
||||
return promisePanelHidden(BrowserPageActions.panelNode);
|
||||
}
|
||||
|
||||
function promisePanelShown(panelIDOrNode) {
|
||||
return promisePanelEvent(panelIDOrNode, "popupshown");
|
||||
}
|
||||
|
||||
function promisePanelHidden(panelIDOrNode) {
|
||||
return promisePanelEvent(panelIDOrNode, "popuphidden");
|
||||
}
|
||||
|
||||
function promisePanelEvent(panelIDOrNode, eventType) {
|
||||
return new Promise(resolve => {
|
||||
let panel = panelIDOrNode;
|
||||
if (typeof panel == "string") {
|
||||
panel = document.getElementById(panelIDOrNode);
|
||||
if (!panel) {
|
||||
throw new Error(`Panel with ID "${panelIDOrNode}" does not exist.`);
|
||||
}
|
||||
}
|
||||
if (
|
||||
(eventType == "popupshown" && panel.state == "open") ||
|
||||
(eventType == "popuphidden" && panel.state == "closed")
|
||||
) {
|
||||
executeSoon(() => resolve(panel));
|
||||
return;
|
||||
}
|
||||
panel.addEventListener(
|
||||
eventType,
|
||||
() => {
|
||||
executeSoon(() => resolve(panel));
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function promisePageActionViewShown() {
|
||||
info("promisePageActionViewShown waiting for ViewShown");
|
||||
return BrowserTestUtils.waitForEvent(
|
||||
BrowserPageActions.panelNode,
|
||||
"ViewShown"
|
||||
).then(async event => {
|
||||
let panelViewNode = event.originalTarget;
|
||||
await promisePageActionViewChildrenVisible(panelViewNode);
|
||||
return panelViewNode;
|
||||
});
|
||||
}
|
||||
|
||||
function promisePageActionViewChildrenVisible(panelViewNode) {
|
||||
return promiseNodeVisible(panelViewNode.firstElementChild.firstElementChild);
|
||||
}
|
||||
|
||||
function promiseNodeVisible(node) {
|
||||
info(
|
||||
`promiseNodeVisible waiting, node.id=${node.id} node.localeName=${node.localName}\n`
|
||||
);
|
||||
let dwu = window.windowUtils;
|
||||
return TestUtils.waitForCondition(() => {
|
||||
let bounds = dwu.getBoundsWithoutFlushing(node);
|
||||
if (bounds.width > 0 && bounds.height > 0) {
|
||||
info(
|
||||
`promiseNodeVisible OK, node.id=${node.id} node.localeName=${node.localName}\n`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>page_action_menu_add_search_engine_0</ShortName>
|
||||
<Url type="text/html" method="GET" template="http://mochi.test:8888/" rel="searchform">
|
||||
<Param name="terms" value="{searchTerms}"/>
|
||||
</Url>
|
||||
</SearchPlugin>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>page_action_menu_add_search_engine_1</ShortName>
|
||||
<Url type="text/html" method="GET" template="http://mochi.test:8888/" rel="searchform">
|
||||
<Param name="terms" value="{searchTerms}"/>
|
||||
</Url>
|
||||
</SearchPlugin>
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>page_action_menu_add_search_engine_2</ShortName>
|
||||
<Url type="text/html" method="GET" template="http://mochi.test:8888/" rel="searchform">
|
||||
<Param name="terms" value="{searchTerms}"/>
|
||||
</Url>
|
||||
</SearchPlugin>
|
|
@ -1,8 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="search" type="application/opensearchdescription+xml" title="page_action_menu_add_search_engine_0" href="http://mochi.test:8888/browser/browser/base/content/test/pageActions/page_action_menu_add_search_engine_404.xml">
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
|
@ -1,10 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="search" type="application/opensearchdescription+xml" title="page_action_menu_add_search_engine_0" href="http://mochi.test:8888/browser/browser/base/content/test/pageActions/page_action_menu_add_search_engine_0.xml">
|
||||
<link rel="search" type="application/opensearchdescription+xml" title="page_action_menu_add_search_engine_1" href="http://mochi.test:8888/browser/browser/base/content/test/pageActions/page_action_menu_add_search_engine_1.xml">
|
||||
<link rel="search" type="application/opensearchdescription+xml" title="page_action_menu_add_search_engine_2" href="http://mochi.test:8888/browser/browser/base/content/test/pageActions/page_action_menu_add_search_engine_2.xml">
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
|
@ -1,8 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="search" type="application/opensearchdescription+xml" title="page_action_menu_add_search_engine_0" href="http://mochi.test:8888/browser/browser/base/content/test/pageActions/page_action_menu_add_search_engine_0.xml">
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
|
@ -1,9 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="search" type="application/opensearchdescription+xml" title="page_action_menu_add_search_engine_0" href="http://mochi.test:8888/browser/browser/base/content/test/pageActions/page_action_menu_add_search_engine_0.xml">
|
||||
<link rel="search" type="application/opensearchdescription+xml" title="page_action_menu_add_search_engine_1" href="http://mochi.test:8888/browser/browser/base/content/test/pageActions/page_action_menu_add_search_engine_0.xml">
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
|
@ -4,9 +4,6 @@
|
|||
"use strict";
|
||||
|
||||
add_task(async function test_pip_label_changes_tab() {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", true]],
|
||||
});
|
||||
let newWin = await BrowserTestUtils.openNewWindowWithFlushedXULCacheForMozSupports();
|
||||
|
||||
let pipTab = newWin.document.querySelector(".tabbrowser-tab[selected]");
|
||||
|
|
|
@ -36,7 +36,6 @@ BROWSER_CHROME_MANIFESTS += [
|
|||
"content/test/notificationbox/browser.ini",
|
||||
"content/test/outOfProcess/browser.ini",
|
||||
"content/test/pageActions-proton/browser.ini",
|
||||
"content/test/pageActions/browser.ini",
|
||||
"content/test/pageinfo/browser.ini",
|
||||
"content/test/pageStyle/browser.ini",
|
||||
"content/test/performance/browser.ini",
|
||||
|
|
|
@ -15,7 +15,6 @@ ChromeUtils.defineModuleGetter(
|
|||
"resource:///modules/HomePage.jsm"
|
||||
);
|
||||
|
||||
const kPrefProtonToolbarEnabled = "browser.proton.enabled";
|
||||
const kPrefProtonToolbarVersion = "browser.proton.toolbar.version";
|
||||
const kPrefHomeButtonUsed = "browser.engagement.home-button.has-used";
|
||||
const kPrefLibraryButtonUsed = "browser.engagement.library-button.has-used";
|
||||
|
@ -112,7 +111,7 @@ add_task(async function testButtonRemoval() {
|
|||
let tests = [
|
||||
// Proton enabled without home and library engagement
|
||||
{
|
||||
prefs: [[kPrefProtonToolbarEnabled, true]],
|
||||
prefs: [],
|
||||
actions: {
|
||||
shouldRemoveHomeButton: true,
|
||||
shouldRemoveLibraryButton: true,
|
||||
|
@ -122,10 +121,7 @@ add_task(async function testButtonRemoval() {
|
|||
},
|
||||
// Proton enabled with home engagement
|
||||
{
|
||||
prefs: [
|
||||
[kPrefProtonToolbarEnabled, true],
|
||||
[kPrefHomeButtonUsed, true],
|
||||
],
|
||||
prefs: [[kPrefHomeButtonUsed, true]],
|
||||
actions: {
|
||||
shouldRemoveHomeButton: false,
|
||||
shouldRemoveLibraryButton: true,
|
||||
|
@ -133,19 +129,9 @@ add_task(async function testButtonRemoval() {
|
|||
shouldUpdateVersion: true,
|
||||
},
|
||||
},
|
||||
// Proton disabled
|
||||
{
|
||||
prefs: [[kPrefProtonToolbarEnabled, false]],
|
||||
actions: {
|
||||
shouldRemoveHomeButton: false,
|
||||
shouldRemoveLibraryButton: false,
|
||||
shouldRemoveSidebarButton: false,
|
||||
shouldUpdateVersion: false,
|
||||
},
|
||||
},
|
||||
// Proton enabled with custom homepage
|
||||
{
|
||||
prefs: [[kPrefProtonToolbarEnabled, true]],
|
||||
prefs: [],
|
||||
actions: {
|
||||
shouldRemoveHomeButton: false,
|
||||
shouldRemoveLibraryButton: true,
|
||||
|
@ -158,10 +144,7 @@ add_task(async function testButtonRemoval() {
|
|||
},
|
||||
// Proton enabled with library engagement
|
||||
{
|
||||
prefs: [
|
||||
[kPrefProtonToolbarEnabled, true],
|
||||
[kPrefLibraryButtonUsed, true],
|
||||
],
|
||||
prefs: [[kPrefLibraryButtonUsed, true]],
|
||||
actions: {
|
||||
shouldRemoveHomeButton: true,
|
||||
shouldRemoveLibraryButton: false,
|
||||
|
@ -171,10 +154,7 @@ add_task(async function testButtonRemoval() {
|
|||
},
|
||||
// Proton enabled with sidebar engagement
|
||||
{
|
||||
prefs: [
|
||||
[kPrefProtonToolbarEnabled, true],
|
||||
[kPrefSidebarButtonUsed, true],
|
||||
],
|
||||
prefs: [[kPrefSidebarButtonUsed, true]],
|
||||
actions: {
|
||||
shouldRemoveHomeButton: true,
|
||||
shouldRemoveLibraryButton: true,
|
||||
|
@ -202,10 +182,7 @@ add_task(async function testButtonRemoval() {
|
|||
*/
|
||||
add_task(async function testNullSavedState() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[kPrefProtonToolbarVersion, 0],
|
||||
[kPrefProtonToolbarEnabled, true],
|
||||
],
|
||||
set: [[kPrefProtonToolbarVersion, 0]],
|
||||
});
|
||||
let oldState = CustomizableUIBSPass.gSavedState;
|
||||
|
||||
|
@ -250,10 +227,7 @@ add_task(async function testNullSavedState() {
|
|||
*/
|
||||
add_task(async function testNoNavbarPlacements() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[kPrefProtonToolbarVersion, 0],
|
||||
[kPrefProtonToolbarEnabled, true],
|
||||
],
|
||||
set: [[kPrefProtonToolbarVersion, 0]],
|
||||
});
|
||||
|
||||
let oldState = CustomizableUIBSPass.gSavedState;
|
||||
|
@ -284,10 +258,7 @@ add_task(async function testNoNavbarPlacements() {
|
|||
*/
|
||||
add_task(async function testNullPlacements() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[kPrefProtonToolbarVersion, 0],
|
||||
[kPrefProtonToolbarEnabled, true],
|
||||
],
|
||||
set: [[kPrefProtonToolbarVersion, 0]],
|
||||
});
|
||||
|
||||
let oldState = CustomizableUIBSPass.gSavedState;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
[DEFAULT]
|
||||
prefs =
|
||||
browser.proton.enabled=true
|
||||
browser.policies.alternatePath='<test-root>/browser/components/enterprisepolicies/tests/browser/homepage_button/homepage_policies.json'
|
||||
support-files =
|
||||
homepage_policies.json
|
||||
|
|
|
@ -6,26 +6,6 @@
|
|||
const PAGE =
|
||||
"http://mochi.test:8888/browser/browser/components/extensions/test/browser/context.html";
|
||||
|
||||
async function openContextMenuInPageActionPanel(extension, win = window) {
|
||||
win.gURLBar.setPageProxyState("valid");
|
||||
await promiseAnimationFrame(win);
|
||||
const mainPanelshown = BrowserTestUtils.waitForEvent(
|
||||
BrowserPageActions.panelNode,
|
||||
"popupshown"
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
BrowserPageActions.mainButtonNode,
|
||||
{},
|
||||
win
|
||||
);
|
||||
await mainPanelshown;
|
||||
let buttonID =
|
||||
"#" +
|
||||
BrowserPageActions.panelButtonNodeIDForActionID(makeWidgetId(extension.id));
|
||||
let menuID = "pageActionContextMenu";
|
||||
return openChromeContextMenu(menuID, buttonID, win);
|
||||
}
|
||||
|
||||
add_task(async function test_permissions() {
|
||||
function background() {
|
||||
browser.test.sendMessage("apis", {
|
||||
|
@ -172,67 +152,6 @@ add_task(async function test_actionContextMenus() {
|
|||
await extension.unload();
|
||||
});
|
||||
|
||||
add_task(async function test_hiddenPageActionContextMenu() {
|
||||
// In Proton the disabled pageAction are hidden in the urlbar
|
||||
// and in the overflow menu, and so the pageAction context menu
|
||||
// cannot be triggered on a disabled pageACtion.
|
||||
//
|
||||
// When we will sunset the proton about:config pref, this test
|
||||
// won't be necessary anymore since the user won't be able to
|
||||
// open the context menu on disabled actions.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", false]],
|
||||
});
|
||||
const manifest = {
|
||||
page_action: {},
|
||||
permissions: ["menus"],
|
||||
};
|
||||
|
||||
async function background() {
|
||||
const contexts = ["page_action"];
|
||||
|
||||
const parentId = browser.menus.create({ contexts, title: "parent" });
|
||||
browser.menus.create({ parentId, title: "click A" });
|
||||
browser.menus.create({ parentId, title: "click B" });
|
||||
|
||||
for (let i = 1; i < 9; i++) {
|
||||
browser.menus.create({ contexts, id: `${i}`, title: `click ${i}` });
|
||||
}
|
||||
|
||||
const [tab] = await browser.tabs.query({ active: true });
|
||||
await browser.pageAction.hide(tab.id);
|
||||
browser.test.sendMessage("ready", tab.id);
|
||||
}
|
||||
|
||||
const extension = ExtensionTestUtils.loadExtension({ manifest, background });
|
||||
const tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
"http://example.com/"
|
||||
);
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
const menu = await openContextMenuInPageActionPanel(extension);
|
||||
const menuItems = Array.prototype.filter.call(menu.children, node => {
|
||||
return window.getComputedStyle(node).visibility == "visible";
|
||||
});
|
||||
|
||||
is(menuItems.length, 2, "Correct number of children");
|
||||
const [manageItem, removeItem] = menuItems;
|
||||
|
||||
is(manageItem.label, "Manage Extension\u2026", "Correct first child");
|
||||
is(removeItem.label, "Remove Extension", "Correct second child");
|
||||
|
||||
await closeChromeContextMenu(menu.id);
|
||||
await closeChromeContextMenu(BrowserPageActions.panelNode.id);
|
||||
|
||||
// Undo the Proton pref change.
|
||||
await SpecialPowers.popPrefEnv();
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
add_task(async function test_bookmarkContextMenu() {
|
||||
const ext = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
|
|
|
@ -166,79 +166,3 @@ add_task(async function test_clickData_reset() {
|
|||
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
add_task(async function test_click_disabled() {
|
||||
// In Proton the disabled pageAction are hidden in the urlbar
|
||||
// and in the overflow menu, and so the pageAction context menu
|
||||
// cannot be triggered on a disabled pageACtion.
|
||||
//
|
||||
// When we will sunset the proton about:config pref, this test
|
||||
// won't be necessary anymore since the user won't be able to
|
||||
// open the context menu on disabled actions.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", false]],
|
||||
});
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
page_action: {},
|
||||
},
|
||||
|
||||
background() {
|
||||
let expectClick = false;
|
||||
function onClicked(tab, info) {
|
||||
if (expectClick) {
|
||||
browser.test.sendMessage("onClick");
|
||||
} else {
|
||||
browser.test.fail(
|
||||
`Unexpected click on disabled page action, button=${info.button}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function onMessage(msg, toggle) {
|
||||
if (msg == "hide" || msg == "show") {
|
||||
expectClick = msg == "show";
|
||||
|
||||
let [tab] = await browser.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true,
|
||||
});
|
||||
if (expectClick) {
|
||||
await browser.pageAction.show(tab.id);
|
||||
} else {
|
||||
await browser.pageAction.hide(tab.id);
|
||||
}
|
||||
browser.test.sendMessage("visibilitySet");
|
||||
} else {
|
||||
browser.test.fail("Unexpected message");
|
||||
}
|
||||
}
|
||||
|
||||
browser.pageAction.onClicked.addListener(onClicked);
|
||||
browser.test.onMessage.addListener(onMessage);
|
||||
browser.test.sendMessage("ready");
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("ready");
|
||||
|
||||
extension.sendMessage("hide");
|
||||
await extension.awaitMessage("visibilitySet");
|
||||
|
||||
await clickPageActionInPanel(extension, window, { button: 0 });
|
||||
await clickPageActionInPanel(extension, window, { button: 1 });
|
||||
|
||||
extension.sendMessage("show");
|
||||
await extension.awaitMessage("visibilitySet");
|
||||
|
||||
await clickPageActionInPanel(extension, window, { button: 0 });
|
||||
await extension.awaitMessage("onClick");
|
||||
await clickPageActionInPanel(extension, window, { button: 1 });
|
||||
await extension.awaitMessage("onClick");
|
||||
|
||||
// Undo the Proton pref change.
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await extension.unload();
|
||||
});
|
||||
|
|
|
@ -77,14 +77,8 @@ add_task(async function testAppShutdown() {
|
|||
await promiseStartupManager();
|
||||
await extension.awaitStartup();
|
||||
|
||||
// Get the action. In non-proton its pinnedToUrlbar should remain false.
|
||||
// In Proton there is no meatball menu, thus page actions are directly pinned
|
||||
// to the urlbar.
|
||||
action = PageActions.actionForID(actionID);
|
||||
Assert.equal(
|
||||
action.pinnedToUrlbar,
|
||||
Services.prefs.getBoolPref("browser.proton.enabled", false)
|
||||
);
|
||||
Assert.equal(action.pinnedToUrlbar, true);
|
||||
|
||||
// Now unload the extension and quit the app.
|
||||
await extension.unload();
|
||||
|
|
|
@ -155,7 +155,6 @@ async function openMultiStageWithUserAgentAttribution() {
|
|||
const TEST_PROTON_JSON = JSON.stringify(TEST_PROTON_CONTENT);
|
||||
|
||||
await setAboutWelcomePref(true);
|
||||
await setProton(true);
|
||||
await pushPrefs(["browser.aboutwelcome.screens", TEST_PROTON_JSON]);
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
|
|
|
@ -10,12 +10,6 @@ const { ASRouter } = ChromeUtils.import(
|
|||
const { BrowserWindowTracker } = ChromeUtils.import(
|
||||
"resource:///modules/BrowserWindowTracker.jsm"
|
||||
);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"PROTON_ENABLED",
|
||||
"browser.proton.enabled",
|
||||
false
|
||||
);
|
||||
|
||||
add_task(async function show_and_send_telemetry() {
|
||||
let message = (await CFRMessageProvider.getMessages()).find(
|
||||
|
@ -105,9 +99,7 @@ add_task(async function react_to_trigger() {
|
|||
"Notification id should match"
|
||||
);
|
||||
|
||||
let defaultPriority = PROTON_ENABLED
|
||||
? notificationStack.PRIORITY_SYSTEM
|
||||
: notificationStack.PRIORITY_INFO_MEDIUM;
|
||||
let defaultPriority = notificationStack.PRIORITY_SYSTEM;
|
||||
Assert.ok(
|
||||
notificationStack.currentNotification.priority === defaultPriority,
|
||||
"Notification has default priority"
|
||||
|
|
|
@ -36,7 +36,6 @@ add_task(async function proton_shows_prompt() {
|
|||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[CHECK_PREF, true],
|
||||
["browser.proton.enabled", true],
|
||||
["browser.shell.didSkipDefaultBrowserCheckOnFirstRun", true],
|
||||
],
|
||||
});
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
[DEFAULT]
|
||||
prefs =
|
||||
browser.proton.enabled=true
|
||||
support-files =
|
||||
head.js
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ skip-if =
|
|||
[browser_PageActions.js]
|
||||
[browser_PageActions_contextMenus.js]
|
||||
[browser_PageActions_newWindow.js]
|
||||
[browser_PageActions_proton.js]
|
||||
[browser_PartnerLinkAttribution.js]
|
||||
support-files =
|
||||
search-engines/basic/manifest.json
|
||||
|
|
|
@ -12,17 +12,16 @@ ChromeUtils.defineModuleGetter(
|
|||
const kPrefHomePage = "browser.startup.homepage";
|
||||
const kPrefExtensionControlled =
|
||||
"browser.startup.homepage_override.extensionControlled";
|
||||
const kPrefProtonToolbarEnabled = "browser.proton.enabled";
|
||||
const kPrefHomeButtonRemoved = "browser.engagement.home-button.has-removed";
|
||||
const kHomeButtonId = "home-button";
|
||||
const kUrlbarWidgetId = "urlbar-container";
|
||||
|
||||
async function withTestSetup({ protonEnabled = true } = {}, testFn) {
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
async function withTestSetup({} = {}, testFn) {
|
||||
CustomizableUI.removeWidgetFromArea(kHomeButtonId);
|
||||
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[kPrefProtonToolbarEnabled, protonEnabled],
|
||||
[kPrefHomeButtonRemoved, false],
|
||||
[kPrefHomePage, "about:home"],
|
||||
[kPrefExtensionControlled, false],
|
||||
|
@ -59,26 +58,19 @@ function assertHasRemovedPref(val) {
|
|||
);
|
||||
}
|
||||
|
||||
async function runAddButtonTest(protonEnabled) {
|
||||
async function runAddButtonTest() {
|
||||
await withTestSetup({}, async () => {
|
||||
Services.prefs.setBoolPref(kPrefProtonToolbarEnabled, protonEnabled);
|
||||
|
||||
// Setting the homepage once should add to the toolbar.
|
||||
assertHasRemovedPref(false);
|
||||
assertHomeButtonNotPlaced();
|
||||
|
||||
await HomePage.set("https://example.com/");
|
||||
|
||||
if (protonEnabled) {
|
||||
assertHomeButtonInArea("nav-bar");
|
||||
} else {
|
||||
assertHomeButtonNotPlaced();
|
||||
}
|
||||
assertHomeButtonInArea("nav-bar");
|
||||
assertHasRemovedPref(false);
|
||||
|
||||
// After removing the home button, a new homepage shouldn't add it.
|
||||
CustomizableUI.removeWidgetFromArea(kHomeButtonId);
|
||||
assertHasRemovedPref(protonEnabled);
|
||||
|
||||
await HomePage.set("https://mozilla.org/");
|
||||
assertHomeButtonNotPlaced();
|
||||
|
@ -86,11 +78,7 @@ async function runAddButtonTest(protonEnabled) {
|
|||
}
|
||||
|
||||
add_task(async function testAddHomeButtonOnSet() {
|
||||
await runAddButtonTest(true);
|
||||
});
|
||||
|
||||
add_task(async function testHomeButtonOnSetProtonOff() {
|
||||
await runAddButtonTest(false);
|
||||
await runAddButtonTest();
|
||||
});
|
||||
|
||||
add_task(async function testHomeButtonDoesNotMove() {
|
||||
|
|
|
@ -1,410 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests PageActions.jsm with regard to Proton.
|
||||
|
||||
"use strict";
|
||||
|
||||
const PROTON_PREF = "browser.proton.enabled";
|
||||
const PERSISTED_ACTIONS_PREF = "browser.pageActions.persistedActions";
|
||||
const TEST_ACTION_ID = "browser_PageActions_proton";
|
||||
|
||||
// Set of action IDs to ignore during this test.
|
||||
//
|
||||
// Screenshots is problematic for two reasons: (1) It's going
|
||||
// away in Proton, (2) It's built-in actions but adds itself
|
||||
// dynamically outside of PageActions, which is a problem for this test since it
|
||||
// simulates app restart by removing all actions and adding them back. So just
|
||||
// don't make any assertions about it.
|
||||
//
|
||||
// addSearchEngine gets in the way of the test when it assumes for simplicity
|
||||
// that all actions are pinned when Proton is enabled, but addSearchEngine still
|
||||
// disables itself when the current page doesn't offer a search engine. Bug
|
||||
// 1697191 removes addSearchEngine and most of the other built-in actions, but
|
||||
// until it lands, just ignore addSearchEngine.
|
||||
const IGNORED_ACTION_IDS = new Set([
|
||||
"addSearchEngine",
|
||||
"screenshots_mozilla_org",
|
||||
]);
|
||||
|
||||
// This test opens and closes lots of windows and can often cause TV tests to
|
||||
// time out for no good reason. Request a ridiculously long timeout.
|
||||
requestLongerTimeout(10);
|
||||
|
||||
add_task(async function init() {
|
||||
await disableNonReleaseActions();
|
||||
|
||||
// This test toggles Proton and simulates restart a bunch of times. We need
|
||||
// to leave PageActions in its initial state with its initial actions when the
|
||||
// test is done.
|
||||
let initialActions = PageActions.actions;
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(PERSISTED_ACTIONS_PREF);
|
||||
PageActions.init(false);
|
||||
for (let action of initialActions) {
|
||||
if (!PageActions.actionForID(action.id)) {
|
||||
PageActions.addAction(action);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// New profile without Proton -> enable Proton -> disable Proton
|
||||
add_task(async function newProfile_noProton_proton_noProton() {
|
||||
// Simulate restart with a new profile and Proton disabled.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PROTON_PREF, false]],
|
||||
});
|
||||
simulateRestart({ newProfile: true });
|
||||
Assert.deepEqual(
|
||||
ids(PageActions._persistedActions.ids),
|
||||
ids(PageActions.actions),
|
||||
"Initial PageActions._persistedActions.ids"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
ids(PageActions._persistedActions.idsInUrlbar, false),
|
||||
ids([PageActions.ACTION_ID_BOOKMARK], false),
|
||||
"Inital PageActions._persistedActions.idsInUrlbar"
|
||||
);
|
||||
Assert.ok(
|
||||
!PageActions._persistedActions.idsInUrlbarPreProton,
|
||||
"Initial PageActions._persistedActions.idsInUrlbarPreProton"
|
||||
);
|
||||
|
||||
// Get the built-in copyURL action and pin it.
|
||||
let copyURLAction = PageActions.actionForID("copyURL");
|
||||
Assert.ok(copyURLAction, "copyURL action exists when Proton is disabled");
|
||||
copyURLAction.pinnedToUrlbar = true;
|
||||
|
||||
// Add a pinned non-built-in action.
|
||||
let testAction = new PageActions.Action({
|
||||
id: TEST_ACTION_ID,
|
||||
pinnedToUrlbar: true,
|
||||
});
|
||||
PageActions.addAction(testAction);
|
||||
|
||||
// Restart again, nothing should change.
|
||||
simulateRestart({ restoringActions: [testAction] });
|
||||
let idsInUrlbar = [
|
||||
copyURLAction.id,
|
||||
testAction.id,
|
||||
PageActions.ACTION_ID_BOOKMARK,
|
||||
];
|
||||
await assertProtonNotApplied({ idsInUrlbar });
|
||||
|
||||
// Enable Proton. Nothing should change before restart.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PROTON_PREF, true]],
|
||||
});
|
||||
await assertProtonNotApplied({ idsInUrlbar });
|
||||
|
||||
// Restart. idsInUrlbarPreProton should be the old idsInUrlbar. copyURL will
|
||||
// remain in the new idsInUrlbar until the next restart since it wasn't
|
||||
// missing at the time of the previous restart and therefore wasn't purged,
|
||||
// even though it doesn't exist anymore.
|
||||
simulateRestart({ restoringActions: [testAction] });
|
||||
await assertProtonApplied({
|
||||
idsInUrlbarPreProton: idsInUrlbar,
|
||||
idsInUrlbarExtra: [copyURLAction.id],
|
||||
});
|
||||
|
||||
// Restart again, nothing should change except copyURL is purged from
|
||||
// idsInUrlbar.
|
||||
simulateRestart({ restoringActions: [testAction] });
|
||||
await assertProtonApplied({ idsInUrlbarPreProton: idsInUrlbar });
|
||||
|
||||
// Re-disable Proton. Nothing should change before restart.
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await assertProtonApplied({ idsInUrlbarPreProton: idsInUrlbar });
|
||||
|
||||
// Restart. The original idsInUrlbar should be restored, including copURL.
|
||||
simulateRestart({ restoringActions: [testAction] });
|
||||
await assertProtonNotApplied({ idsInUrlbar });
|
||||
|
||||
testAction.remove();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
// New profile with Proton -> disable Proton -> re-enable Proton
|
||||
add_task(async function newProfile_proton_noProton_proton() {
|
||||
// Simulate restart with a new profile and Proton enabled.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PROTON_PREF, true]],
|
||||
});
|
||||
simulateRestart({ newProfile: true });
|
||||
Assert.deepEqual(
|
||||
ids(PageActions._persistedActions.ids),
|
||||
ids(PageActions.actions),
|
||||
"Initial PageActions._persistedActions.ids"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
ids(PageActions._persistedActions.idsInUrlbar),
|
||||
ids(PageActions.actions.filter(a => !a.__isSeparator)),
|
||||
"Inital PageActions._persistedActions.idsInUrlbar"
|
||||
);
|
||||
Assert.equal(
|
||||
PageActions._persistedActions.idsInUrlbar[
|
||||
PageActions._persistedActions.idsInUrlbar.length - 1
|
||||
],
|
||||
PageActions.ACTION_ID_BOOKMARK,
|
||||
"Inital PageActions._persistedActions.idsInUrlbar has bookmark action last"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
PageActions._persistedActions.idsInUrlbarPreProton,
|
||||
[],
|
||||
"Initial PageActions._persistedActions.idsInUrlbarPreProton"
|
||||
);
|
||||
|
||||
// Add a pinned non-built-in action.
|
||||
let testAction = new PageActions.Action({
|
||||
id: TEST_ACTION_ID,
|
||||
pinnedToUrlbar: true,
|
||||
});
|
||||
PageActions.addAction(testAction);
|
||||
|
||||
// Restart again, nothing should change.
|
||||
simulateRestart({ restoringActions: [testAction] });
|
||||
await assertProtonApplied({ idsInUrlbarPreProton: [] });
|
||||
|
||||
// Disable Proton. Nothing should change before restart.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PROTON_PREF, false]],
|
||||
});
|
||||
await assertProtonApplied({ idsInUrlbarPreProton: [] });
|
||||
|
||||
// Restart. The built-in actions that are pinned by default should be pinned.
|
||||
// The test action will not be pinned because idsInUrlbarPreProton is empty.
|
||||
simulateRestart({ restoringActions: [testAction] });
|
||||
let idsInUrlbar = [PageActions.ACTION_ID_BOOKMARK];
|
||||
await assertProtonNotApplied({ idsInUrlbar });
|
||||
|
||||
testAction.pinnedToUrlbar = true;
|
||||
|
||||
// Restart again. The test action should be pinned.
|
||||
simulateRestart({ restoringActions: [testAction] });
|
||||
idsInUrlbar.splice(idsInUrlbar.length - 1, 0, testAction.id);
|
||||
await assertProtonNotApplied({ idsInUrlbar });
|
||||
|
||||
// Re-enable Proton. Nothing should change before restart.
|
||||
await SpecialPowers.popPrefEnv();
|
||||
await assertProtonNotApplied({ idsInUrlbar });
|
||||
|
||||
// Restart.
|
||||
simulateRestart({ restoringActions: [testAction] });
|
||||
await assertProtonApplied({ idsInUrlbarPreProton: idsInUrlbar });
|
||||
|
||||
testAction.remove();
|
||||
await SpecialPowers.popPrefEnv();
|
||||
});
|
||||
|
||||
/**
|
||||
* Simulates an app restart by purging unregistered actions, storing persisted
|
||||
* actions, removing all actions, and then re-initializing PageActions.
|
||||
*
|
||||
* @param {boolean} newProfile
|
||||
* Pass true to simulate a new profile as far as PageActions is concerned by
|
||||
* clearing PERSISTED_ACTIONS_PREF before calling init(). Pass false to
|
||||
* simulate a usual restart.
|
||||
* @param {array} restoringActions
|
||||
* Any actions that should be added back after the simulated restart.
|
||||
* PageActions automatically adds built-in actions on init, but any other
|
||||
* actions must be added back manually.
|
||||
*/
|
||||
function simulateRestart({ newProfile = false, restoringActions = [] } = {}) {
|
||||
info("Simulating restart...");
|
||||
|
||||
// shutdown phase
|
||||
// _purgeUnregisteredPersistedActions also stores the persisted actions.
|
||||
PageActions._purgeUnregisteredPersistedActions();
|
||||
for (let action of PageActions.actions) {
|
||||
action.remove();
|
||||
}
|
||||
|
||||
// startup phase
|
||||
if (newProfile) {
|
||||
Services.prefs.clearUserPref(PERSISTED_ACTIONS_PREF);
|
||||
}
|
||||
PageActions.init(false);
|
||||
for (let action of restoringActions) {
|
||||
if (!PageActions.actionForID(action.id)) {
|
||||
PageActions.addAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
info(
|
||||
"Simulating restart done, PageActions._persistedActions=" +
|
||||
JSON.stringify(PageActions._persistedActions)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that PageActions recognizes Proton is enabled. This isn't the same
|
||||
* as whether Proton is actually enabled because PageActions responds to changes
|
||||
* in the Proton pref only at the time it's initialized.
|
||||
*
|
||||
* @param {array} idsInUrlbarPreProton
|
||||
* The expected value of PageActions._persistedActions.idsInUrlbarPreProton.
|
||||
* @param {array} idsInUrlbarExtra
|
||||
* IDs that are expected to be in idsInUrlbar even though their actions are
|
||||
* not registered.
|
||||
*/
|
||||
async function assertProtonApplied({
|
||||
idsInUrlbarPreProton,
|
||||
idsInUrlbarExtra = [],
|
||||
}) {
|
||||
info("Asserting Proton is applied...");
|
||||
|
||||
Assert.deepEqual(
|
||||
ids(PageActions._persistedActions.idsInUrlbar),
|
||||
ids(
|
||||
PageActions.actions.filter(a => !a.__isSeparator).concat(idsInUrlbarExtra)
|
||||
),
|
||||
"idsInUrlbar when Proton applied"
|
||||
);
|
||||
|
||||
if (!idsInUrlbarPreProton) {
|
||||
Assert.ok(
|
||||
!PageActions._persistedActions.idsInUrlbarPreProton,
|
||||
"idsInUrlbarPreProton does not exist when Proton applied"
|
||||
);
|
||||
} else {
|
||||
Assert.deepEqual(
|
||||
ids(PageActions._persistedActions.idsInUrlbarPreProton),
|
||||
ids(idsInUrlbarPreProton),
|
||||
"idsInUrlbarPreProton when Proton applied"
|
||||
);
|
||||
}
|
||||
|
||||
assertCommonState({ idsInUrlbarExtra });
|
||||
await checkNewWindow({ idsInUrlbarExtra });
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that PageActions recognizes Proton is disabled. This isn't the same
|
||||
* as whether Proton is actually disabled because PageActions responds to
|
||||
* changes in the Proton pref only at the time it's initialized.
|
||||
*
|
||||
* @param {array} idsInUrlbar
|
||||
* The expected value of PageActions._persistedActions.idsInUrlbar.
|
||||
*/
|
||||
async function assertProtonNotApplied({ idsInUrlbar }) {
|
||||
info("Asserting Proton is not applied...");
|
||||
Assert.deepEqual(
|
||||
ids(PageActions._persistedActions.idsInUrlbar, false),
|
||||
ids(idsInUrlbar, false),
|
||||
"idsInUrlbar when Proton not applied"
|
||||
);
|
||||
Assert.ok(
|
||||
!PageActions._persistedActions.idsInUrlbarPreProton,
|
||||
"idsInUrlbarPreProton does not exist when Proton not applied"
|
||||
);
|
||||
assertCommonState();
|
||||
await checkNewWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes some assertions about PageActions state during this test that should be
|
||||
* the same regardless of whether Proton is enabled or disabled.
|
||||
*
|
||||
* @param {array} idsInUrlbarExtra
|
||||
* IDs that are expected to be in idsInUrlbar even though their actions are
|
||||
* not registered.
|
||||
*/
|
||||
function assertCommonState({ idsInUrlbarExtra = [] } = {}) {
|
||||
Assert.equal(
|
||||
PageActions._persistedActions.idsInUrlbar[
|
||||
PageActions._persistedActions.idsInUrlbar.length - 1
|
||||
],
|
||||
PageActions.ACTION_ID_BOOKMARK,
|
||||
"Bookmark action is last in idsInUrlbar"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
ids(PageActions.actionsInUrlbar(window), false),
|
||||
ids(
|
||||
PageActions._persistedActions.idsInUrlbar.filter(
|
||||
id => !idsInUrlbarExtra.includes(id)
|
||||
),
|
||||
false
|
||||
),
|
||||
"actionsInUrlbar matches idsInUrlbar"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new window and asserts that its state is correct for the current
|
||||
* PageActions and Proton states.
|
||||
*
|
||||
* @param {array} idsInUrlbarExtra
|
||||
* IDs that are expected to be in idsInUrlbar even though their actions are
|
||||
* not registered.
|
||||
*/
|
||||
async function checkNewWindow({ idsInUrlbarExtra = [] } = {}) {
|
||||
if (AppConstants.platform == "macosx" && AppConstants.DEBUG) {
|
||||
// Even with a bigger timeout than the one requested above, opening all
|
||||
// these windows still causes a timeout in Mac debug WebRender TV. Just
|
||||
// skip this part of the test on Mac debug.
|
||||
info("Skipping checkNewWindow on Mac debug due to TV failures");
|
||||
return;
|
||||
}
|
||||
|
||||
info("Checking a new window...");
|
||||
|
||||
// Open a new window.
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser: win.gBrowser,
|
||||
url: "http://example.com/",
|
||||
});
|
||||
|
||||
let ignoredElementIDs = Array.from(IGNORED_ACTION_IDS).map(id =>
|
||||
win.BrowserPageActions.urlbarButtonNodeIDForActionID(id)
|
||||
);
|
||||
|
||||
// Collect its urlbar element IDs.
|
||||
let elementIDs = [];
|
||||
for (
|
||||
let element = win.BrowserPageActions.mainButtonNode.nextElementSibling;
|
||||
element;
|
||||
element = element.nextElementSibling
|
||||
) {
|
||||
if (!ignoredElementIDs.includes(element.id)) {
|
||||
elementIDs.push(element.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that they match idsInUrlbar.
|
||||
Assert.deepEqual(
|
||||
elementIDs,
|
||||
ids(
|
||||
PageActions._persistedActions.idsInUrlbar.filter(
|
||||
id => !idsInUrlbarExtra.includes(id)
|
||||
),
|
||||
false
|
||||
).map(id => win.BrowserPageActions.urlbarButtonNodeIDForActionID(id)),
|
||||
"Actions in new window's urlbar"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function that returns action IDs with IGNORED_ACTION_IDS removed
|
||||
* and optionally sorted. See the IGNORED_ACTION_IDS comment for info on
|
||||
* ignored IDs.
|
||||
*
|
||||
* @param {array} idsOrActions
|
||||
* Array of action IDs or actions.
|
||||
* @param {boolean} sort
|
||||
* Pass true if the ordering of the IDs isn't important and you want to
|
||||
* deepEqual() two arrays of IDs as if they were sets. Pass false to preserve
|
||||
* the current ordering.
|
||||
*/
|
||||
function ids(idsOrActions, sort = true) {
|
||||
let array = idsOrActions
|
||||
.map(obj => (typeof obj == "string" ? obj : obj.id))
|
||||
.filter(id => !IGNORED_ACTION_IDS.has(id));
|
||||
if (sort) {
|
||||
array = array.sort();
|
||||
}
|
||||
return array;
|
||||
}
|
|
@ -101,21 +101,16 @@ class TestSafeBrowsingNotificationBar(WindowManagerMixin, MarionetteTestCase):
|
|||
|
||||
def check_get_me_out_of_here_button(self):
|
||||
with self.marionette.using_context("chrome"):
|
||||
if self.marionette.get_pref("browser.proton.enabled"):
|
||||
notification_box = self.marionette.find_element(
|
||||
By.CSS_SELECTOR, 'vbox.notificationbox-stack[slot="selected"]'
|
||||
)
|
||||
message = notification_box.find_element(
|
||||
By.CSS_SELECTOR, "notification-message"
|
||||
)
|
||||
button_container = message.get_property("buttonContainer")
|
||||
button = button_container.find_element(
|
||||
By.CSS_SELECTOR, 'button[label="Get me out of here!"]'
|
||||
)
|
||||
else:
|
||||
button = self.marionette.find_element(
|
||||
By.ID, "tabbrowser-tabbox"
|
||||
).find_element(By.CSS_SELECTOR, 'button[label="Get me out of here!"]')
|
||||
notification_box = self.marionette.find_element(
|
||||
By.CSS_SELECTOR, 'vbox.notificationbox-stack[slot="selected"]'
|
||||
)
|
||||
message = notification_box.find_element(
|
||||
By.CSS_SELECTOR, "notification-message"
|
||||
)
|
||||
button_container = message.get_property("buttonContainer")
|
||||
button = button_container.find_element(
|
||||
By.CSS_SELECTOR, 'button[label="Get me out of here!"]'
|
||||
)
|
||||
button.click()
|
||||
|
||||
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
|
||||
|
@ -125,22 +120,13 @@ class TestSafeBrowsingNotificationBar(WindowManagerMixin, MarionetteTestCase):
|
|||
|
||||
def check_x_button(self):
|
||||
with self.marionette.using_context("chrome"):
|
||||
if self.marionette.get_pref("browser.proton.enabled"):
|
||||
notification_box = self.marionette.find_element(
|
||||
By.CSS_SELECTOR, 'vbox.notificationbox-stack[slot="selected"]'
|
||||
)
|
||||
message = notification_box.find_element(
|
||||
By.CSS_SELECTOR, "notification-message[value=blocked-badware-page]"
|
||||
)
|
||||
button = message.get_property("closeButton")
|
||||
else:
|
||||
button = (
|
||||
self.marionette.find_element(By.ID, "tabbrowser-tabbox")
|
||||
.find_element(
|
||||
By.CSS_SELECTOR, "notification[value=blocked-badware-page]"
|
||||
)
|
||||
.find_element(By.CSS_SELECTOR, ".messageCloseButton")
|
||||
)
|
||||
notification_box = self.marionette.find_element(
|
||||
By.CSS_SELECTOR, 'vbox.notificationbox-stack[slot="selected"]'
|
||||
)
|
||||
message = notification_box.find_element(
|
||||
By.CSS_SELECTOR, "notification-message[value=blocked-badware-page]"
|
||||
)
|
||||
button = message.get_property("closeButton")
|
||||
button.click()
|
||||
|
||||
Wait(self.marionette, timeout=self.marionette.timeout.page_load).until(
|
||||
|
|
|
@ -4,51 +4,35 @@
|
|||
// the color of the tab line are applied properly.
|
||||
|
||||
add_task(async function test_support_tab_line() {
|
||||
for (let protonTabsEnabled of [true, false]) {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", protonTabsEnabled]],
|
||||
});
|
||||
let newWin = await BrowserTestUtils.openNewWindowWithFlushedXULCacheForMozSupports();
|
||||
let newWin = await BrowserTestUtils.openNewWindowWithFlushedXULCacheForMozSupports();
|
||||
|
||||
const TAB_LINE_COLOR = "#ff0000";
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
theme: {
|
||||
colors: {
|
||||
frame: ACCENT_COLOR,
|
||||
tab_background_text: "#000",
|
||||
tab_line: TAB_LINE_COLOR,
|
||||
},
|
||||
const TAB_LINE_COLOR = "#ff0000";
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
theme: {
|
||||
colors: {
|
||||
frame: ACCENT_COLOR,
|
||||
tab_background_text: "#000",
|
||||
tab_line: TAB_LINE_COLOR,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
await extension.startup();
|
||||
|
||||
info("Checking selected tab line color");
|
||||
let selectedTab = newWin.document.querySelector(
|
||||
".tabbrowser-tab[selected]"
|
||||
);
|
||||
let line = selectedTab.querySelector(".tab-line");
|
||||
let tab = selectedTab.querySelector(".tab-background");
|
||||
let element = protonTabsEnabled ? tab : line;
|
||||
let property = protonTabsEnabled ? "boxShadow" : "backgroundColor";
|
||||
let computedValue = newWin.getComputedStyle(element)[property];
|
||||
let expectedColor = `rgb(${hexToRGB(TAB_LINE_COLOR).join(", ")})`;
|
||||
if (protonTabsEnabled) {
|
||||
Assert.ok(
|
||||
computedValue.includes(expectedColor),
|
||||
`Tab line should be displayed in the box shadow of the tab when Proton is enabled: ${computedValue}`
|
||||
);
|
||||
} else {
|
||||
Assert.equal(
|
||||
computedValue,
|
||||
expectedColor,
|
||||
"Tab line should have theme color"
|
||||
);
|
||||
}
|
||||
info("Checking selected tab line color");
|
||||
let selectedTab = newWin.document.querySelector(".tabbrowser-tab[selected]");
|
||||
let tab = selectedTab.querySelector(".tab-background");
|
||||
let element = tab;
|
||||
let property = "boxShadow";
|
||||
let computedValue = newWin.getComputedStyle(element)[property];
|
||||
let expectedColor = `rgb(${hexToRGB(TAB_LINE_COLOR).join(", ")})`;
|
||||
Assert.ok(
|
||||
computedValue.includes(expectedColor),
|
||||
`Tab line should be displayed in the box shadow of the tab: ${computedValue}`
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
await BrowserTestUtils.closeWindow(newWin);
|
||||
}
|
||||
await extension.unload();
|
||||
await BrowserTestUtils.closeWindow(newWin);
|
||||
});
|
||||
|
|
|
@ -78,201 +78,185 @@ function assertTelemetrySent(hb, eventNames) {
|
|||
});
|
||||
}
|
||||
|
||||
function getStars(notice, protonEnabled) {
|
||||
if (protonEnabled) {
|
||||
return notice.buttonContainer.querySelectorAll(".star-x");
|
||||
}
|
||||
return notice.messageDetails.querySelectorAll(".star-x");
|
||||
function getStars(notice) {
|
||||
return notice.buttonContainer.querySelectorAll(".star-x");
|
||||
}
|
||||
|
||||
for (let protonEnabled of [true, false]) {
|
||||
add_task(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["browser.proton.enabled", protonEnabled]],
|
||||
});
|
||||
let win = await BrowserTestUtils.openNewWindowWithFlushedXULCacheForMozSupports();
|
||||
// Open a new tab to keep the window open.
|
||||
await BrowserTestUtils.openNewForegroundTab(
|
||||
win.gBrowser,
|
||||
"https://example.com"
|
||||
);
|
||||
add_task(async function setup() {
|
||||
let win = await BrowserTestUtils.openNewWindowWithFlushedXULCacheForMozSupports();
|
||||
// Open a new tab to keep the window open.
|
||||
await BrowserTestUtils.openNewForegroundTab(
|
||||
win.gBrowser,
|
||||
"https://example.com"
|
||||
);
|
||||
});
|
||||
|
||||
// Several of the behaviors of heartbeat prompt are mutually exclusive, so checks are broken up
|
||||
// into three batches.
|
||||
|
||||
/* Batch #1 - General UI, Stars, and telemetry data */
|
||||
add_task(async function() {
|
||||
const targetWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
const notificationBox = targetWindow.gHighPriorityNotificationBox;
|
||||
|
||||
const preCount = notificationBox.allNotifications.length;
|
||||
const hb = new Heartbeat(targetWindow, {
|
||||
testing: true,
|
||||
flowId: "test",
|
||||
message: "test",
|
||||
engagementButtonLabel: undefined,
|
||||
learnMoreMessage: "Learn More",
|
||||
learnMoreUrl: "https://example.org/learnmore",
|
||||
});
|
||||
|
||||
// Several of the behaviors of heartbeat prompt are mutually exclusive, so checks are broken up
|
||||
// into three batches.
|
||||
// Check UI
|
||||
const learnMoreEl = hb.notice.messageText.querySelector(".text-link");
|
||||
Assert.equal(
|
||||
notificationBox.allNotifications.length,
|
||||
preCount + 1,
|
||||
"Correct number of notifications open"
|
||||
);
|
||||
Assert.equal(getStars(hb.notice).length, 5, "Correct number of stars");
|
||||
Assert.equal(
|
||||
hb.notice.buttonContainer.querySelectorAll(".notification-button").length,
|
||||
0,
|
||||
"Engagement button not shown"
|
||||
);
|
||||
Assert.equal(
|
||||
learnMoreEl.href,
|
||||
"https://example.org/learnmore",
|
||||
"Learn more url correct"
|
||||
);
|
||||
Assert.equal(learnMoreEl.value, "Learn More", "Learn more label correct");
|
||||
// There's a space included before the learn more link in proton.
|
||||
Assert.equal(
|
||||
hb.notice.messageText.textContent,
|
||||
"test ",
|
||||
"Message is correct"
|
||||
);
|
||||
|
||||
/* Batch #1 - General UI, Stars, and telemetry data */
|
||||
add_task(async function() {
|
||||
const targetWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
const notificationBox = targetWindow.gHighPriorityNotificationBox;
|
||||
// Check that when clicking the learn more link, a tab opens with the right URL
|
||||
let loadedPromise;
|
||||
const tabOpenPromise = new Promise(resolve => {
|
||||
targetWindow.gBrowser.tabContainer.addEventListener(
|
||||
"TabOpen",
|
||||
event => {
|
||||
let tab = event.target;
|
||||
loadedPromise = BrowserTestUtils.browserLoaded(
|
||||
tab.linkedBrowser,
|
||||
true,
|
||||
url => url && url !== "about:blank"
|
||||
);
|
||||
resolve(tab);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
learnMoreEl.click();
|
||||
const tab = await tabOpenPromise;
|
||||
const tabUrl = await loadedPromise;
|
||||
|
||||
const preCount = notificationBox.allNotifications.length;
|
||||
const hb = new Heartbeat(targetWindow, {
|
||||
testing: true,
|
||||
flowId: "test",
|
||||
message: "test",
|
||||
engagementButtonLabel: undefined,
|
||||
learnMoreMessage: "Learn More",
|
||||
learnMoreUrl: "https://example.org/learnmore",
|
||||
});
|
||||
Assert.equal(
|
||||
tabUrl,
|
||||
"https://example.org/learnmore",
|
||||
"Learn more link opened the right url"
|
||||
);
|
||||
|
||||
// Check UI
|
||||
const learnMoreEl = hb.notice.messageText.querySelector(".text-link");
|
||||
Assert.equal(
|
||||
notificationBox.allNotifications.length,
|
||||
preCount + 1,
|
||||
"Correct number of notifications open"
|
||||
);
|
||||
Assert.equal(
|
||||
getStars(hb.notice, protonEnabled).length,
|
||||
5,
|
||||
"Correct number of stars"
|
||||
);
|
||||
Assert.equal(
|
||||
hb.notice.buttonContainer.querySelectorAll(".notification-button").length,
|
||||
0,
|
||||
"Engagement button not shown"
|
||||
);
|
||||
Assert.equal(
|
||||
learnMoreEl.href,
|
||||
"https://example.org/learnmore",
|
||||
"Learn more url correct"
|
||||
);
|
||||
Assert.equal(learnMoreEl.value, "Learn More", "Learn more label correct");
|
||||
// There's a space included before the learn more link in proton.
|
||||
Assert.equal(
|
||||
hb.notice.messageText.textContent,
|
||||
"test" + (protonEnabled ? " " : ""),
|
||||
"Message is correct"
|
||||
);
|
||||
const telemetrySentPromise = assertTelemetrySent(hb, [
|
||||
"offeredTS",
|
||||
"learnMoreTS",
|
||||
"closedTS",
|
||||
]);
|
||||
// Close notification to trigger telemetry to be sent
|
||||
await closeAllNotifications(targetWindow, notificationBox);
|
||||
await telemetrySentPromise;
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
// Check that when clicking the learn more link, a tab opens with the right URL
|
||||
let loadedPromise;
|
||||
const tabOpenPromise = new Promise(resolve => {
|
||||
targetWindow.gBrowser.tabContainer.addEventListener(
|
||||
"TabOpen",
|
||||
event => {
|
||||
let tab = event.target;
|
||||
loadedPromise = BrowserTestUtils.browserLoaded(
|
||||
tab.linkedBrowser,
|
||||
true,
|
||||
url => url && url !== "about:blank"
|
||||
);
|
||||
resolve(tab);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
learnMoreEl.click();
|
||||
const tab = await tabOpenPromise;
|
||||
const tabUrl = await loadedPromise;
|
||||
// Batch #2 - Engagement buttons
|
||||
add_task(async function() {
|
||||
const targetWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
const notificationBox = targetWindow.gHighPriorityNotificationBox;
|
||||
const hb = new Heartbeat(targetWindow, {
|
||||
testing: true,
|
||||
flowId: "test",
|
||||
message: "test",
|
||||
engagementButtonLabel: "Click me!",
|
||||
postAnswerUrl: "https://example.org/postAnswer",
|
||||
learnMoreMessage: "Learn More",
|
||||
learnMoreUrl: "https://example.org/learnMore",
|
||||
});
|
||||
const engagementButton = hb.notice.buttonContainer.querySelector(
|
||||
".notification-button"
|
||||
);
|
||||
|
||||
Assert.equal(
|
||||
tabUrl,
|
||||
"https://example.org/learnmore",
|
||||
"Learn more link opened the right url"
|
||||
Assert.equal(getStars(hb.notice).length, 0, "Stars not shown");
|
||||
Assert.ok(engagementButton, "Engagement button added");
|
||||
Assert.equal(
|
||||
engagementButton.label,
|
||||
"Click me!",
|
||||
"Engagement button has correct label"
|
||||
);
|
||||
|
||||
const engagementEl = hb.notice.buttonContainer.querySelector(
|
||||
".notification-button"
|
||||
);
|
||||
let loadedPromise;
|
||||
const tabOpenPromise = new Promise(resolve => {
|
||||
targetWindow.gBrowser.tabContainer.addEventListener(
|
||||
"TabOpen",
|
||||
event => {
|
||||
let tab = event.target;
|
||||
loadedPromise = BrowserTestUtils.browserLoaded(
|
||||
tab.linkedBrowser,
|
||||
true,
|
||||
url => url && url !== "about:blank"
|
||||
);
|
||||
resolve(tab);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
engagementEl.click();
|
||||
const tab = await tabOpenPromise;
|
||||
const tabUrl = await loadedPromise;
|
||||
// the postAnswer url gets query parameters appended onto the end, so use Assert.startsWith instead of Assert.equal
|
||||
Assert.ok(
|
||||
tabUrl.startsWith("https://example.org/postAnswer"),
|
||||
"Engagement button opened the right url"
|
||||
);
|
||||
|
||||
const telemetrySentPromise = assertTelemetrySent(hb, [
|
||||
"offeredTS",
|
||||
"learnMoreTS",
|
||||
"closedTS",
|
||||
]);
|
||||
// Close notification to trigger telemetry to be sent
|
||||
await closeAllNotifications(targetWindow, notificationBox);
|
||||
await telemetrySentPromise;
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
const telemetrySentPromise = assertTelemetrySent(hb, [
|
||||
"offeredTS",
|
||||
"engagedTS",
|
||||
"closedTS",
|
||||
]);
|
||||
// Close notification to trigger telemetry to be sent
|
||||
await closeAllNotifications(targetWindow, notificationBox);
|
||||
await telemetrySentPromise;
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
// Batch 3 - Closing the window while heartbeat is open
|
||||
add_task(async function() {
|
||||
const targetWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||
|
||||
const hb = new Heartbeat(targetWindow, {
|
||||
testing: true,
|
||||
flowId: "test",
|
||||
message: "test",
|
||||
});
|
||||
|
||||
// Batch #2 - Engagement buttons
|
||||
add_task(async function() {
|
||||
const targetWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
const notificationBox = targetWindow.gHighPriorityNotificationBox;
|
||||
const hb = new Heartbeat(targetWindow, {
|
||||
testing: true,
|
||||
flowId: "test",
|
||||
message: "test",
|
||||
engagementButtonLabel: "Click me!",
|
||||
postAnswerUrl: "https://example.org/postAnswer",
|
||||
learnMoreMessage: "Learn More",
|
||||
learnMoreUrl: "https://example.org/learnMore",
|
||||
});
|
||||
const engagementButton = hb.notice.buttonContainer.querySelector(
|
||||
".notification-button"
|
||||
);
|
||||
const telemetrySentPromise = assertTelemetrySent(hb, [
|
||||
"offeredTS",
|
||||
"windowClosedTS",
|
||||
]);
|
||||
// triggers sending ping to normandy
|
||||
await BrowserTestUtils.closeWindow(targetWindow);
|
||||
await telemetrySentPromise;
|
||||
});
|
||||
|
||||
Assert.equal(
|
||||
getStars(hb.notice, protonEnabled).length,
|
||||
0,
|
||||
"Stars not shown"
|
||||
);
|
||||
Assert.ok(engagementButton, "Engagement button added");
|
||||
Assert.equal(
|
||||
engagementButton.label,
|
||||
"Click me!",
|
||||
"Engagement button has correct label"
|
||||
);
|
||||
|
||||
const engagementEl = hb.notice.buttonContainer.querySelector(
|
||||
".notification-button"
|
||||
);
|
||||
let loadedPromise;
|
||||
const tabOpenPromise = new Promise(resolve => {
|
||||
targetWindow.gBrowser.tabContainer.addEventListener(
|
||||
"TabOpen",
|
||||
event => {
|
||||
let tab = event.target;
|
||||
loadedPromise = BrowserTestUtils.browserLoaded(
|
||||
tab.linkedBrowser,
|
||||
true,
|
||||
url => url && url !== "about:blank"
|
||||
);
|
||||
resolve(tab);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
});
|
||||
engagementEl.click();
|
||||
const tab = await tabOpenPromise;
|
||||
const tabUrl = await loadedPromise;
|
||||
// the postAnswer url gets query parameters appended onto the end, so use Assert.startsWith instead of Assert.equal
|
||||
Assert.ok(
|
||||
tabUrl.startsWith("https://example.org/postAnswer"),
|
||||
"Engagement button opened the right url"
|
||||
);
|
||||
|
||||
const telemetrySentPromise = assertTelemetrySent(hb, [
|
||||
"offeredTS",
|
||||
"engagedTS",
|
||||
"closedTS",
|
||||
]);
|
||||
// Close notification to trigger telemetry to be sent
|
||||
await closeAllNotifications(targetWindow, notificationBox);
|
||||
await telemetrySentPromise;
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
// Batch 3 - Closing the window while heartbeat is open
|
||||
add_task(async function() {
|
||||
const targetWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||
|
||||
const hb = new Heartbeat(targetWindow, {
|
||||
testing: true,
|
||||
flowId: "test",
|
||||
message: "test",
|
||||
});
|
||||
|
||||
const telemetrySentPromise = assertTelemetrySent(hb, [
|
||||
"offeredTS",
|
||||
"windowClosedTS",
|
||||
]);
|
||||
// triggers sending ping to normandy
|
||||
await BrowserTestUtils.closeWindow(targetWindow);
|
||||
await telemetrySentPromise;
|
||||
});
|
||||
|
||||
add_task(async function cleanup() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
}
|
||||
add_task(async function cleanup() {
|
||||
const win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const PROTON_ENABLED = Services.prefs.getBoolPref("browser.proton.enabled", false);
|
||||
const NOTIFICATION_LOCAL_NAME = PROTON_ENABLED ? "notification-message" : "notification";
|
||||
const NOTIFICATION_LOCAL_NAME = "notification-message"
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var testtag_notificationbox_buttons = [
|
||||
|
@ -336,7 +335,7 @@ var tests =
|
|||
result(nb, ntf) {
|
||||
testtag_notificationbox_State(nb, "append link with callback", ntf, 1);
|
||||
|
||||
let buttonContainer = PROTON_ENABLED ? ntf.buttonContainer : ntf.messageDetails;
|
||||
let buttonContainer = ntf.buttonContainer;
|
||||
let button = buttonContainer.lastElementChild;
|
||||
SimpleTest.is(button.localName, "button", "button is a button");
|
||||
SimpleTest.ok(!button.href, "button href is not set");
|
||||
|
@ -385,9 +384,7 @@ var tests =
|
|||
result(nb, ntf) {
|
||||
testtag_notificationbox_State(nb, "append link with callback", ntf, 1);
|
||||
|
||||
let link = PROTON_ENABLED
|
||||
? ntf.messageText.lastElementChild.previousSibling.previousSibling
|
||||
: ntf.messageText.lastElementChild.previousSibling;
|
||||
let link = ntf.messageText.lastElementChild.previousSibling.previousSibling;
|
||||
SimpleTest.is(link.localName, "label", "link 1 is a label");
|
||||
SimpleTest.ok(link.value != "", "link 1 label is set");
|
||||
SimpleTest.ok(link.href.endsWith("/test1"), "link 1 href is set");
|
||||
|
@ -416,11 +413,8 @@ var tests =
|
|||
return ntf;
|
||||
},
|
||||
result(nb, ntf) {
|
||||
let expectedValue = "10";
|
||||
if (PROTON_ENABLED) {
|
||||
expectedValue = "3";
|
||||
ntf = nb.getNotificationWithValue(expectedValue);
|
||||
}
|
||||
let expectedValue = "3";
|
||||
ntf = nb.getNotificationWithValue(expectedValue);
|
||||
is(nb.currentNotification, ntf, "appendNotification last notification");
|
||||
is(nb.currentNotification.getAttribute("value"), expectedValue, "appendNotification order");
|
||||
return 1;
|
||||
|
@ -430,35 +424,10 @@ var tests =
|
|||
// test closing notifications to make sure that the current notification is still set properly
|
||||
repeat: true,
|
||||
test(nb, testidx) {
|
||||
if (PROTON_ENABLED) {
|
||||
this.repeat = false;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
switch (testidx) {
|
||||
case 1:
|
||||
nb.getNotificationWithValue("10").close();
|
||||
return [1, 9];
|
||||
case 2:
|
||||
nb.removeNotification(nb.getNotificationWithValue("9"));
|
||||
return [2, 8];
|
||||
case 3:
|
||||
nb.removeCurrentNotification();
|
||||
return [3, 7];
|
||||
case 4:
|
||||
nb.getNotificationWithValue("6").close();
|
||||
return [4, 7];
|
||||
case 5:
|
||||
nb.removeNotification(nb.getNotificationWithValue("5"));
|
||||
return [5, 7];
|
||||
case 6:
|
||||
nb.removeCurrentNotification();
|
||||
return [6, 4];
|
||||
}
|
||||
return testidx;
|
||||
this.repeat = false;
|
||||
return undefined;
|
||||
},
|
||||
result(nb, arr) {
|
||||
if (PROTON_ENABLED) {
|
||||
let notificationOrder = [4, 7, 2, 8, 5, 6, 1, 9, 10, 3];
|
||||
let allNotificationValues = [...nb.stack.children].map(n => n.getAttribute("value"));
|
||||
is(allNotificationValues.length, notificationOrder.length, "Expected number of notifications");
|
||||
|
@ -470,13 +439,6 @@ var tests =
|
|||
);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
// arr is [testindex, expectedvalue]
|
||||
is(nb.currentNotification.getAttribute("value"), "" + arr[1], "close order " + arr[0]);
|
||||
is(nb.allNotifications.length, 10 - arr[0], "close order " + arr[0] + " count");
|
||||
if (arr[0] == 6)
|
||||
this.repeat = false;
|
||||
return ++arr[0];
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -564,17 +526,13 @@ function testtag_notification_State(nb, ntf, testid, label, value, image, priori
|
|||
|
||||
is(ntf.getAttribute("type"), type, testid + " notification type");
|
||||
|
||||
if (PROTON_ENABLED) {
|
||||
let icons = {
|
||||
info: "chrome://global/skin/icons/info-filled.svg",
|
||||
warning: "chrome://global/skin/icons/warning.svg",
|
||||
critical: "chrome://global/skin/icons/error.svg",
|
||||
};
|
||||
let icon = icons[type];
|
||||
is(getComputedStyle(ntf.messageImage, "::after").content, `url("${icon}")`, "notification image is set");
|
||||
} else {
|
||||
is(ntf.messageImage.getAttribute("src"), image, testid + " notification image");
|
||||
}
|
||||
let icons = {
|
||||
info: "chrome://global/skin/icons/info-filled.svg",
|
||||
warning: "chrome://global/skin/icons/warning.svg",
|
||||
critical: "chrome://global/skin/icons/error.svg",
|
||||
};
|
||||
let icon = icons[type];
|
||||
is(getComputedStyle(ntf.messageImage, "::after").content, `url("${icon}")`, "notification image is set");
|
||||
}
|
||||
|
||||
function checkPopupTest(nb, ntf)
|
||||
|
@ -585,11 +543,7 @@ function checkPopupTest(nb, ntf)
|
|||
var evt = new Event("");
|
||||
ntf.dispatchEvent(evt);
|
||||
evt.target.buttonInfo = testtag_notificationbox_buttons[0];
|
||||
if (PROTON_ENABLED) {
|
||||
ntf.handleEvent(evt);
|
||||
} else {
|
||||
ntf._doButtonCommand(evt);
|
||||
}
|
||||
ntf.handleEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче