summaryrefslogtreecommitdiffstats
path: root/browser/components/places/tests/browser/browser_bookmark_popup.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/places/tests/browser/browser_bookmark_popup.js')
-rw-r--r--browser/components/places/tests/browser/browser_bookmark_popup.js712
1 files changed, 712 insertions, 0 deletions
diff --git a/browser/components/places/tests/browser/browser_bookmark_popup.js b/browser/components/places/tests/browser/browser_bookmark_popup.js
new file mode 100644
index 0000000000..b5385e3a08
--- /dev/null
+++ b/browser/components/places/tests/browser/browser_bookmark_popup.js
@@ -0,0 +1,712 @@
+/* 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/. */
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+
+"use strict";
+requestLongerTimeout(2);
+
+/**
+ * Test opening and closing the bookmarks panel.
+ */
+let win;
+let bookmarkPanel;
+let bookmarkStar;
+let bookmarkPanelTitle;
+let bookmarkRemoveButton;
+let editBookmarkPanelRemoveButtonRect;
+
+const TEST_URL = "data:text/html,<html><body></body></html>";
+
+add_setup(async function () {
+ win = await BrowserTestUtils.openNewBrowserWindow();
+
+ win.StarUI._createPanelIfNeeded();
+ win.StarUI._closePanelQuickForTesting = true;
+ bookmarkPanel = win.document.getElementById("editBookmarkPanel");
+ bookmarkPanel.setAttribute("animate", false);
+ bookmarkStar = win.BookmarkingUI.star;
+ bookmarkPanelTitle = win.document.getElementById("editBookmarkPanelTitle");
+ bookmarkRemoveButton = win.document.getElementById(
+ "editBookmarkPanelRemoveButton"
+ );
+
+ registerCleanupFunction(async () => {
+ delete win.StarUI._closePanelQuickForTesting;
+ await BrowserTestUtils.closeWindow(win);
+ });
+});
+
+function mouseout() {
+ let mouseOutPromise = BrowserTestUtils.waitForEvent(
+ bookmarkPanel,
+ "mouseout"
+ );
+ EventUtils.synthesizeNativeMouseEvent({
+ type: "mousemove",
+ target: win.gURLBar.textbox,
+ offsetX: 0,
+ offsetY: 0,
+ win,
+ });
+ EventUtils.synthesizeMouse(bookmarkPanel, 0, 0, { type: "mouseout" }, win);
+ info("Waiting for mouseout event");
+ return mouseOutPromise;
+}
+
+async function test_bookmarks_popup({
+ isNewBookmark,
+ popupShowFn,
+ popupEditFn,
+ shouldAutoClose,
+ popupHideFn,
+ isBookmarkRemoved,
+}) {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser: win.gBrowser, url: TEST_URL },
+ async function (browser) {
+ try {
+ if (!isNewBookmark) {
+ await PlacesUtils.bookmarks.insert({
+ parentGuid: await PlacesUIUtils.defaultParentGuid,
+ url: TEST_URL,
+ title: "Home Page",
+ });
+ }
+
+ info(`BookmarkingUI.status is ${win.BookmarkingUI.status}`);
+ await TestUtils.waitForCondition(
+ () => win.BookmarkingUI.status != win.BookmarkingUI.STATUS_UPDATING,
+ "BookmarkingUI should not be updating"
+ );
+
+ Assert.equal(
+ bookmarkStar.hasAttribute("starred"),
+ !isNewBookmark,
+ "Page should only be starred prior to popupshown if editing bookmark"
+ );
+ Assert.equal(
+ bookmarkPanel.state,
+ "closed",
+ "Panel should be 'closed' to start test"
+ );
+ let shownPromise = promisePopupShown(bookmarkPanel);
+ await popupShowFn(browser);
+ await shownPromise;
+ Assert.equal(
+ bookmarkPanel.state,
+ "open",
+ "Panel should be 'open' after shownPromise is resolved"
+ );
+
+ editBookmarkPanelRemoveButtonRect =
+ bookmarkRemoveButton.getBoundingClientRect();
+
+ if (popupEditFn) {
+ await popupEditFn();
+ }
+ Assert.equal(
+ bookmarkStar.getAttribute("starred"),
+ "true",
+ "Page is starred"
+ );
+ Assert.equal(
+ bookmarkPanelTitle.dataset.l10nId,
+ isNewBookmark ? "bookmarks-add-bookmark" : "bookmarks-edit-bookmark",
+ "title should match isEditingBookmark state"
+ );
+ Assert.equal(
+ bookmarkRemoveButton.dataset.l10nId,
+ isNewBookmark ? "bookmark-panel-cancel" : "bookmark-panel-remove",
+ "remove/cancel button label should match isEditingBookmark state"
+ );
+
+ if (!shouldAutoClose) {
+ await new Promise(resolve => setTimeout(resolve, 400));
+ Assert.equal(
+ bookmarkPanel.state,
+ "open",
+ "Panel should still be 'open' for non-autoclose"
+ );
+ }
+
+ let defaultLocation = await PlacesUIUtils.defaultParentGuid;
+ const promises = [];
+ if (isNewBookmark && !isBookmarkRemoved) {
+ // Expect new bookmark to be created.
+ promises.push(
+ PlacesTestUtils.waitForNotification("bookmark-added", events =>
+ events.some(
+ ({ parentGuid, url }) =>
+ parentGuid == defaultLocation && TEST_URL == url
+ )
+ )
+ );
+ }
+ if (!isNewBookmark && isBookmarkRemoved) {
+ // Expect existing bookmark to be removed.
+ promises.push(
+ PlacesTestUtils.waitForNotification("bookmark-removed", events =>
+ events.some(
+ ({ parentGuid, url }) =>
+ parentGuid == defaultLocation && TEST_URL == url
+ )
+ )
+ );
+ }
+
+ promises.push(promisePopupHidden(bookmarkPanel));
+ if (popupHideFn) {
+ await popupHideFn();
+ } else {
+ // Move the mouse out of the way so that the panel will auto-close.
+ await mouseout();
+ }
+ await Promise.all(promises);
+
+ Assert.equal(
+ bookmarkStar.hasAttribute("starred"),
+ !isBookmarkRemoved,
+ "Page is starred after closing"
+ );
+
+ // Count number of bookmarks.
+ let count = 0;
+ await PlacesUtils.bookmarks.fetch({ url: TEST_URL }, () => count++);
+ const message = isBookmarkRemoved
+ ? "No bookmark should exist"
+ : "Only one bookmark should exist";
+ Assert.equal(count, isBookmarkRemoved ? 0 : 1, message);
+ } finally {
+ let bookmark = await PlacesUtils.bookmarks.fetch({ url: TEST_URL });
+ Assert.equal(
+ !!bookmark,
+ !isBookmarkRemoved,
+ "bookmark should not be present if a panel action should've removed it"
+ );
+ if (bookmark) {
+ await PlacesUtils.bookmarks.remove(bookmark);
+ }
+ }
+ }
+ );
+}
+
+add_task(async function panel_shown_for_new_bookmarks_and_autocloses() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(
+ async function panel_shown_once_for_doubleclick_on_new_bookmark_star_and_autocloses() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ EventUtils.synthesizeMouse(
+ bookmarkStar,
+ 10,
+ 10,
+ { clickCount: 2 },
+ win
+ );
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+ }
+);
+
+add_task(
+ async function panel_shown_once_for_slow_doubleclick_on_new_bookmark_star_and_autocloses() {
+ todo(
+ false,
+ "bug 1250267, may need to add some tracking state to " +
+ "browser-places.js for this."
+ );
+
+ /*
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ *popupShowFn() {
+ EventUtils.synthesizeMouse(bookmarkStar, 10, 10, window);
+ await new Promise(resolve => setTimeout(resolve, 300));
+ EventUtils.synthesizeMouse(bookmarkStar, 10, 10, window);
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+ */
+ }
+);
+
+add_task(
+ async function panel_shown_for_keyboardshortcut_on_new_bookmark_star_and_autocloses() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ EventUtils.synthesizeKey("D", { accelKey: true }, win);
+ },
+ shouldAutoClose: true,
+ isBookmarkRemoved: false,
+ });
+ }
+);
+
+add_task(async function panel_shown_for_new_bookmarks_mousemove_mouseout() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ async popupEditFn() {
+ let mouseMovePromise = BrowserTestUtils.waitForEvent(
+ bookmarkPanel,
+ "mousemove"
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ bookmarkPanel,
+ { type: "mousemove" },
+ win
+ );
+ info("Waiting for mousemove event");
+ await mouseMovePromise;
+ info("Got mousemove event");
+
+ await new Promise(resolve => setTimeout(resolve, 400));
+ is(
+ bookmarkPanel.state,
+ "open",
+ "Panel should still be open on mousemove"
+ );
+ },
+ async popupHideFn() {
+ await mouseout();
+ info("Got mouseout event, should autoclose now");
+ },
+ shouldAutoClose: false,
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(async function panel_shown_for_new_bookmark_close_with_ESC() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ shouldAutoClose: true,
+ popupHideFn() {
+ EventUtils.synthesizeKey("VK_ESCAPE", { accelKey: true }, win);
+ },
+ isBookmarkRemoved: true,
+ });
+});
+
+add_task(async function panel_shown_for_editing_no_autoclose_close_with_ESC() {
+ await test_bookmarks_popup({
+ isNewBookmark: false,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ EventUtils.synthesizeKey("VK_ESCAPE", { accelKey: true }, win);
+ },
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(async function panel_shown_for_new_bookmark_keypress_no_autoclose() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ popupEditFn() {
+ EventUtils.sendChar("VK_TAB", win);
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ bookmarkPanel.hidePopup();
+ },
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(async function bookmark_with_invalid_default_folder() {
+ await createAndRemoveDefaultFolder();
+
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ shouldAutoClose: true,
+ async popupShowFn(browser) {
+ EventUtils.synthesizeKey("d", { accelKey: true }, win);
+ },
+ });
+});
+
+add_task(
+ async function panel_shown_for_new_bookmark_compositionstart_no_autoclose() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ async popupEditFn() {
+ let compositionStartPromise = BrowserTestUtils.waitForEvent(
+ bookmarkPanel,
+ "compositionstart"
+ );
+ EventUtils.synthesizeComposition({ type: "compositionstart" }, win);
+ info("Waiting for compositionstart event");
+ await compositionStartPromise;
+ info("Got compositionstart event");
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ EventUtils.synthesizeComposition(
+ { type: "compositioncommitasis" },
+ win
+ );
+ bookmarkPanel.hidePopup();
+ },
+ isBookmarkRemoved: false,
+ });
+ }
+);
+
+add_task(
+ async function panel_shown_for_new_bookmark_compositionstart_mouseout_no_autoclose() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ async popupEditFn() {
+ let mouseMovePromise = BrowserTestUtils.waitForEvent(
+ bookmarkPanel,
+ "mousemove"
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ bookmarkPanel,
+ {
+ type: "mousemove",
+ },
+ win
+ );
+ info("Waiting for mousemove event");
+ await mouseMovePromise;
+ info("Got mousemove event");
+
+ let compositionStartPromise = BrowserTestUtils.waitForEvent(
+ bookmarkPanel,
+ "compositionstart"
+ );
+ EventUtils.synthesizeComposition({ type: "compositionstart" }, win);
+ info("Waiting for compositionstart event");
+ await compositionStartPromise;
+ info("Got compositionstart event");
+
+ await mouseout();
+ info("Got mouseout event, but shouldn't run autoclose");
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ EventUtils.synthesizeComposition(
+ { type: "compositioncommitasis" },
+ win
+ );
+ bookmarkPanel.hidePopup();
+ },
+ isBookmarkRemoved: false,
+ });
+ }
+);
+
+add_task(
+ async function panel_shown_for_new_bookmark_compositionend_no_autoclose() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn() {
+ bookmarkStar.click();
+ },
+ async popupEditFn() {
+ let mouseMovePromise = BrowserTestUtils.waitForEvent(
+ bookmarkPanel,
+ "mousemove"
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ bookmarkPanel,
+ {
+ type: "mousemove",
+ },
+ win
+ );
+ info("Waiting for mousemove event");
+ await mouseMovePromise;
+ info("Got mousemove event");
+
+ EventUtils.synthesizeComposition(
+ {
+ type: "compositioncommit",
+ data: "committed text",
+ },
+ win
+ );
+ },
+ popupHideFn() {
+ bookmarkPanel.hidePopup();
+ },
+ shouldAutoClose: false,
+ isBookmarkRemoved: false,
+ });
+ }
+);
+
+add_task(async function contextmenu_new_bookmark_keypress_no_autoclose() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ async popupShowFn(browser) {
+ let contextMenu = win.document.getElementById("contentAreaContextMenu");
+ let awaitPopupShown = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popupshown"
+ );
+ let awaitPopupHidden = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popuphidden"
+ );
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "body",
+ {
+ type: "contextmenu",
+ button: 2,
+ },
+ browser
+ );
+ await awaitPopupShown;
+ contextMenu.activateItem(
+ win.document.getElementById("context-bookmarkpage")
+ );
+ await awaitPopupHidden;
+ },
+ popupEditFn() {
+ EventUtils.sendChar("VK_TAB", win);
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ bookmarkPanel.hidePopup();
+ },
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(async function bookmarks_menu_new_bookmark_remove_bookmark() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn(browser) {
+ win.document.getElementById("menu_bookmarkThisPage").doCommand();
+ },
+ shouldAutoClose: true,
+ popupHideFn() {
+ win.document.getElementById("editBookmarkPanelRemoveButton").click();
+ },
+ isBookmarkRemoved: true,
+ });
+});
+
+add_task(async function ctrl_d_edit_bookmark_remove_bookmark() {
+ await test_bookmarks_popup({
+ isNewBookmark: false,
+ popupShowFn(browser) {
+ EventUtils.synthesizeKey("D", { accelKey: true }, win);
+ },
+ shouldAutoClose: true,
+ popupHideFn() {
+ win.document.getElementById("editBookmarkPanelRemoveButton").click();
+ },
+ isBookmarkRemoved: true,
+ });
+});
+
+add_task(async function enter_on_remove_bookmark_should_remove_bookmark() {
+ if (AppConstants.platform == "macosx") {
+ // "Full Keyboard Access" is disabled by default, and thus doesn't allow
+ // keyboard navigation to the "Remove Bookmarks" button by default.
+ return;
+ }
+
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn(browser) {
+ EventUtils.synthesizeKey("D", { accelKey: true }, win);
+ },
+ shouldAutoClose: true,
+ popupHideFn() {
+ while (
+ !win.document.activeElement ||
+ win.document.activeElement.id != "editBookmarkPanelRemoveButton"
+ ) {
+ EventUtils.sendChar("VK_TAB", win);
+ }
+ EventUtils.sendChar("VK_RETURN", win);
+ },
+ isBookmarkRemoved: true,
+ });
+});
+
+add_task(async function mouse_hovering_panel_should_prevent_autoclose() {
+ if (AppConstants.platform != "win") {
+ // This test requires synthesizing native mouse movement which is
+ // best supported on Windows.
+ return;
+ }
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ async popupShowFn() {
+ await EventUtils.promiseNativeMouseEvent({
+ type: "mousemove",
+ target: win.document.documentElement,
+ offsetX: editBookmarkPanelRemoveButtonRect.left,
+ offsetY: editBookmarkPanelRemoveButtonRect.top,
+ });
+ EventUtils.synthesizeKey("D", { accelKey: true }, win);
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ win.document.getElementById("editBookmarkPanelRemoveButton").click();
+ },
+ isBookmarkRemoved: true,
+ });
+});
+
+add_task(async function ctrl_d_new_bookmark_mousedown_mouseout_no_autoclose() {
+ await test_bookmarks_popup({
+ isNewBookmark: true,
+ popupShowFn(browser) {
+ EventUtils.synthesizeKey("D", { accelKey: true }, win);
+ },
+ async popupEditFn() {
+ let mouseMovePromise = BrowserTestUtils.waitForEvent(
+ bookmarkPanel,
+ "mousemove"
+ );
+ EventUtils.synthesizeMouseAtCenter(
+ bookmarkPanel,
+ { type: "mousemove" },
+ win
+ );
+ info("Waiting for mousemove event");
+ await mouseMovePromise;
+ info("Got mousemove event");
+
+ await new Promise(resolve => setTimeout(resolve, 400));
+ is(
+ bookmarkPanel.state,
+ "open",
+ "Panel should still be open on mousemove"
+ );
+
+ EventUtils.synthesizeMouseAtCenter(
+ bookmarkPanelTitle,
+ {
+ button: 1,
+ type: "mousedown",
+ },
+ win
+ );
+
+ await mouseout();
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ win.document.getElementById("editBookmarkPanelRemoveButton").click();
+ },
+ isBookmarkRemoved: true,
+ });
+});
+
+add_task(async function enter_during_autocomplete_should_prevent_autoclose() {
+ await test_bookmarks_popup({
+ isNewBookmark: false,
+ async popupShowFn(browser) {
+ PlacesUtils.tagging.tagURI(makeURI(TEST_URL), ["Abc"]);
+ EventUtils.synthesizeKey("d", { accelKey: true }, win);
+ },
+ async popupEditFn() {
+ // Start autocomplete with the registered tag.
+ let tagsField = win.document.getElementById("editBMPanel_tagsField");
+ tagsField.value = "";
+ let popup = win.document.getElementById("editBMPanel_tagsAutocomplete");
+ let promiseShown = BrowserTestUtils.waitForEvent(popup, "popupshown");
+ tagsField.focus();
+ EventUtils.sendString("a", win);
+ await promiseShown;
+ ok(promiseShown, "autocomplete shown");
+
+ // Select first candidate.
+ EventUtils.synthesizeKey("KEY_ArrowDown", {}, win);
+
+ // Type Enter key to choose the item.
+ EventUtils.synthesizeKey("KEY_Enter", {}, win);
+
+ Assert.equal(
+ tagsField.value,
+ "Abc",
+ "Autocomplete should've inserted the selected item"
+ );
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ EventUtils.synthesizeKey("KEY_Escape", {}, win);
+ },
+ isBookmarkRemoved: false,
+ });
+});
+
+add_task(async function escape_during_autocomplete_should_prevent_autoclose() {
+ await test_bookmarks_popup({
+ isNewBookmark: false,
+ async popupShowFn(browser) {
+ PlacesUtils.tagging.tagURI(makeURI(TEST_URL), ["Abc"]);
+ EventUtils.synthesizeKey("d", { accelKey: true }, win);
+ },
+ async popupEditFn() {
+ // Start autocomplete with the registered tag.
+ let tagsField = win.document.getElementById("editBMPanel_tagsField");
+ tagsField.value = "";
+ let popup = win.document.getElementById("editBMPanel_tagsAutocomplete");
+ let promiseShown = BrowserTestUtils.waitForEvent(popup, "popupshown");
+ tagsField.focus();
+ EventUtils.sendString("a", win);
+ await promiseShown;
+ ok(promiseShown, "autocomplete shown");
+
+ // Select first candidate.
+ EventUtils.synthesizeKey("KEY_ArrowDown", {}, win);
+
+ // Type Escape key to close autocomplete.
+ EventUtils.synthesizeKey("KEY_Escape", {}, win);
+
+ // The text reverts to what was typed.
+ // Note, it's important that this is different from the previously
+ // inserted tag, since it will test an untag/tag undo condition.
+ Assert.equal(
+ tagsField.value,
+ "a",
+ "Autocomplete should revert to what was typed"
+ );
+ },
+ shouldAutoClose: false,
+ popupHideFn() {
+ EventUtils.synthesizeKey("KEY_Escape", {}, win);
+ },
+ isBookmarkRemoved: false,
+ });
+});