summaryrefslogtreecommitdiffstats
path: root/browser/components/places/tests/browser/browser_bookmarksProperties.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/places/tests/browser/browser_bookmarksProperties.js')
-rw-r--r--browser/components/places/tests/browser/browser_bookmarksProperties.js526
1 files changed, 526 insertions, 0 deletions
diff --git a/browser/components/places/tests/browser/browser_bookmarksProperties.js b/browser/components/places/tests/browser/browser_bookmarksProperties.js
new file mode 100644
index 0000000000..c493a21a62
--- /dev/null
+++ b/browser/components/places/tests/browser/browser_bookmarksProperties.js
@@ -0,0 +1,526 @@
+/* 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/. */
+
+/**
+ * Tests the bookmarks Properties dialog.
+ */
+
+// DOM ids of Places sidebar trees.
+const SIDEBAR_HISTORY_TREE_ID = "historyTree";
+const SIDEBAR_BOOKMARKS_TREE_ID = "bookmarks-view";
+
+const SIDEBAR_HISTORY_ID = "viewHistorySidebar";
+const SIDEBAR_BOOKMARKS_ID = "viewBookmarksSidebar";
+
+// For history sidebar.
+const SIDEBAR_HISTORY_BYLASTVISITED_VIEW = "bylastvisited";
+const SIDEBAR_HISTORY_BYMOSTVISITED_VIEW = "byvisited";
+const SIDEBAR_HISTORY_BYDATE_VIEW = "byday";
+const SIDEBAR_HISTORY_BYSITE_VIEW = "bysite";
+const SIDEBAR_HISTORY_BYDATEANDSITE_VIEW = "bydateandsite";
+
+// Action to execute on the current node.
+const ACTION_EDIT = 0;
+const ACTION_ADD = 1;
+
+// If action is ACTION_ADD, set type to one of those, to define what do you
+// want to create.
+const TYPE_FOLDER = 0;
+const TYPE_BOOKMARK = 1;
+
+const TEST_URL = "http://www.example.com/";
+
+const DIALOG_URL = "chrome://browser/content/places/bookmarkProperties.xhtml";
+
+function add_bookmark(url) {
+ return PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+ url,
+ title: `bookmark/${url}`,
+ });
+}
+
+// Each test is an obj w/ a desc property and run method.
+var gTests = [];
+
+// ------------------------------------------------------------------------------
+// Bug 462662 - Pressing Enter to select tag from autocomplete closes bookmarks properties dialog
+
+gTests.push({
+ desc: "Bug 462662 - Pressing Enter to select tag from autocomplete closes bookmarks properties dialog",
+ sidebar: SIDEBAR_BOOKMARKS_ID,
+ action: ACTION_EDIT,
+ itemType: null,
+ window: null,
+ _bookmark: null,
+ _cleanShutdown: false,
+
+ async setup() {
+ // Add a bookmark in unsorted bookmarks folder.
+ this._bookmark = await add_bookmark(TEST_URL);
+ Assert.ok(this._bookmark, "Correctly added a bookmark");
+
+ // Add a tag to this bookmark.
+ PlacesUtils.tagging.tagURI(Services.io.newURI(TEST_URL), ["testTag"]);
+ var tags = PlacesUtils.tagging.getTagsForURI(Services.io.newURI(TEST_URL));
+ Assert.equal(tags[0], "testTag", "Correctly added a tag");
+ },
+
+ selectNode(tree) {
+ tree.selectItems([PlacesUtils.bookmarks.unfiledGuid]);
+ PlacesUtils.asContainer(tree.selectedNode).containerOpen = true;
+ tree.selectItems([this._bookmark.guid]);
+ Assert.equal(
+ tree.selectedNode.bookmarkGuid,
+ this._bookmark.guid,
+ "Bookmark has been selected"
+ );
+ },
+
+ async run() {
+ // open tags autocomplete and press enter
+ var tagsField = this.window.document.getElementById(
+ "editBMPanel_tagsField"
+ );
+ var self = this;
+
+ let unloadPromise = new Promise(resolve => {
+ this.window.addEventListener(
+ "unload",
+ function (event) {
+ tagsField.popup.removeEventListener(
+ "popuphidden",
+ popupListener,
+ true
+ );
+ Assert.ok(
+ self._cleanShutdown,
+ "Dialog window should not be closed by pressing Enter on the autocomplete popup"
+ );
+ executeSoon(function () {
+ resolve();
+ });
+ },
+ { capture: true, once: true }
+ );
+ });
+
+ var popupListener = {
+ handleEvent(aEvent) {
+ switch (aEvent.type) {
+ case "popuphidden":
+ // Everything worked fine, we can stop observing the window.
+ self._cleanShutdown = true;
+ self.window.document
+ .getElementById("bookmarkpropertiesdialog")
+ .cancelDialog();
+ break;
+ case "popupshown":
+ tagsField.popup.removeEventListener("popupshown", this, true);
+ // In case this test fails the window will close, the test will fail
+ // since we didn't set _cleanShutdown.
+ let richlistbox = tagsField.popup.richlistbox;
+ // Focus and select first result.
+ Assert.equal(
+ richlistbox.itemCount,
+ 1,
+ "We have 1 autocomplete result"
+ );
+ tagsField.popup.selectedIndex = 0;
+ Assert.equal(
+ richlistbox.selectedItems.length,
+ 1,
+ "We have selected a tag from the autocomplete popup"
+ );
+ info("About to focus the autocomplete results");
+ richlistbox.focus();
+ EventUtils.synthesizeKey("VK_RETURN", {}, self.window);
+ break;
+ default:
+ Assert.ok(false, "unknown event: " + aEvent.type);
+ }
+ },
+ };
+ tagsField.popup.addEventListener("popupshown", popupListener, true);
+ tagsField.popup.addEventListener("popuphidden", popupListener, true);
+
+ // Open tags autocomplete popup.
+ info("About to focus the tagsField");
+ executeSoon(() => {
+ tagsField.focus();
+ tagsField.value = "";
+ EventUtils.synthesizeKey("t", {}, this.window);
+ });
+ await unloadPromise;
+ },
+
+ finish() {
+ SidebarUI.hide();
+ },
+
+ async cleanup() {
+ // Check tags have not changed.
+ var tags = PlacesUtils.tagging.getTagsForURI(Services.io.newURI(TEST_URL));
+ Assert.equal(tags[0], "testTag", "Tag on node has not changed");
+
+ // Cleanup.
+ PlacesUtils.tagging.untagURI(Services.io.newURI(TEST_URL), ["testTag"]);
+ await PlacesUtils.bookmarks.remove(this._bookmark);
+ let bm = await PlacesUtils.bookmarks.fetch(this._bookmark.guid);
+ Assert.ok(!bm, "should have been removed");
+ },
+});
+
+// ------------------------------------------------------------------------------
+// Bug 476020 - Pressing Esc while having the tag autocomplete open closes the bookmarks panel
+
+gTests.push({
+ desc: "Bug 476020 - Pressing Esc while having the tag autocomplete open closes the bookmarks panel",
+ sidebar: SIDEBAR_BOOKMARKS_ID,
+ action: ACTION_EDIT,
+ itemType: null,
+ window: null,
+ _bookmark: null,
+ _cleanShutdown: false,
+
+ async setup() {
+ // Add a bookmark in unsorted bookmarks folder.
+ this._bookmark = await add_bookmark(TEST_URL);
+ Assert.ok(this._bookmark, "Correctly added a bookmark");
+
+ // Add a tag to this bookmark.
+ PlacesUtils.tagging.tagURI(Services.io.newURI(TEST_URL), ["testTag"]);
+ var tags = PlacesUtils.tagging.getTagsForURI(Services.io.newURI(TEST_URL));
+ Assert.equal(tags[0], "testTag", "Correctly added a tag");
+ },
+
+ selectNode(tree) {
+ tree.selectItems([PlacesUtils.bookmarks.unfiledGuid]);
+ PlacesUtils.asContainer(tree.selectedNode).containerOpen = true;
+ tree.selectItems([this._bookmark.guid]);
+ Assert.equal(
+ tree.selectedNode.bookmarkGuid,
+ this._bookmark.guid,
+ "Bookmark has been selected"
+ );
+ },
+
+ async run() {
+ // open tags autocomplete and press enter
+ var tagsField = this.window.document.getElementById(
+ "editBMPanel_tagsField"
+ );
+ var self = this;
+
+ let hiddenPromise = new Promise(resolve => {
+ this.window.addEventListener(
+ "unload",
+ function (event) {
+ tagsField.popup.removeEventListener(
+ "popuphidden",
+ popupListener,
+ true
+ );
+ Assert.ok(
+ self._cleanShutdown,
+ "Dialog window should not be closed by pressing Escape on the autocomplete popup"
+ );
+ executeSoon(function () {
+ resolve();
+ });
+ },
+ { capture: true, once: true }
+ );
+ });
+
+ var popupListener = {
+ handleEvent(aEvent) {
+ switch (aEvent.type) {
+ case "popuphidden":
+ // Everything worked fine.
+ self._cleanShutdown = true;
+ self.window.document
+ .getElementById("bookmarkpropertiesdialog")
+ .cancelDialog();
+ break;
+ case "popupshown":
+ tagsField.popup.removeEventListener("popupshown", this, true);
+ // In case this test fails the window will close, the test will fail
+ // since we didn't set _cleanShutdown.
+ let richlistbox = tagsField.popup.richlistbox;
+ // Focus and select first result.
+ Assert.equal(
+ richlistbox.itemCount,
+ 1,
+ "We have 1 autocomplete result"
+ );
+ tagsField.popup.selectedIndex = 0;
+ Assert.equal(
+ richlistbox.selectedItems.length,
+ 1,
+ "We have selected a tag from the autocomplete popup"
+ );
+ info("About to focus the autocomplete results");
+ richlistbox.focus();
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, self.window);
+ break;
+ default:
+ Assert.ok(false, "unknown event: " + aEvent.type);
+ }
+ },
+ };
+ tagsField.popup.addEventListener("popupshown", popupListener, true);
+ tagsField.popup.addEventListener("popuphidden", popupListener, true);
+
+ // Open tags autocomplete popup.
+ info("About to focus the tagsField");
+ tagsField.focus();
+ tagsField.value = "";
+ EventUtils.synthesizeKey("t", {}, this.window);
+ await hiddenPromise;
+ },
+
+ finish() {
+ SidebarUI.hide();
+ },
+
+ async cleanup() {
+ // Check tags have not changed.
+ var tags = PlacesUtils.tagging.getTagsForURI(Services.io.newURI(TEST_URL));
+ Assert.equal(tags[0], "testTag", "Tag on node has not changed");
+
+ // Cleanup.
+ PlacesUtils.tagging.untagURI(Services.io.newURI(TEST_URL), ["testTag"]);
+ await PlacesUtils.bookmarks.remove(this._bookmark);
+ let bm = await PlacesUtils.bookmarks.fetch(this._bookmark.guid);
+ Assert.ok(!bm, "should have been removed");
+ },
+});
+
+// ------------------------------------------------------------------------------
+// Bug 491269 - Test that editing folder name in bookmarks properties dialog does not accept the dialog
+
+gTests.push({
+ desc: `Bug 491269 - Test that editing folder name in bookmarks properties dialog does not accept the dialog`,
+ sidebar: SIDEBAR_HISTORY_ID,
+ dialogUrl: DIALOG_URL,
+ action: ACTION_ADD,
+ historyView: SIDEBAR_HISTORY_BYLASTVISITED_VIEW,
+ window: null,
+
+ async setup() {
+ // Add a visit.
+ await PlacesTestUtils.addVisits(TEST_URL);
+ },
+
+ selectNode(tree) {
+ var visitNode = tree.view.nodeForTreeIndex(0);
+ tree.selectNode(visitNode);
+ Assert.equal(
+ tree.selectedNode.uri,
+ TEST_URL,
+ "The correct visit has been selected"
+ );
+ Assert.equal(
+ tree.selectedNode.itemId,
+ -1,
+ "The selected node is not bookmarked"
+ );
+ },
+
+ async run() {
+ // Open folder selector.
+ var foldersExpander = this.window.document.getElementById(
+ "editBMPanel_foldersExpander"
+ );
+ var folderTree = this.window.gEditItemOverlay._folderTree;
+ var self = this;
+
+ let unloadPromise = new Promise(resolve => {
+ this.window.addEventListener(
+ "unload",
+ event => {
+ Assert.ok(
+ self._cleanShutdown,
+ "Dialog window should not be closed by pressing ESC in folder name textbox"
+ );
+ executeSoon(() => {
+ resolve();
+ });
+ },
+ { capture: true, once: true }
+ );
+ });
+
+ folderTree.addEventListener(
+ "DOMAttrModified",
+ function onDOMAttrModified(event) {
+ if (event.attrName != "place") {
+ return;
+ }
+ folderTree.removeEventListener("DOMAttrModified", onDOMAttrModified);
+ executeSoon(async function () {
+ // Create a new folder.
+ var newFolderButton = self.window.document.getElementById(
+ "editBMPanel_newFolderButton"
+ );
+ newFolderButton.doCommand();
+
+ // Wait for the folder to be created and for editing to start.
+ await TestUtils.waitForCondition(
+ () => folderTree.hasAttribute("editing"),
+ "We are editing new folder name in folder tree"
+ );
+
+ // Press Escape to discard editing new folder name.
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, self.window);
+ Assert.ok(
+ !folderTree.hasAttribute("editing"),
+ "We have finished editing folder name in folder tree"
+ );
+
+ self._cleanShutdown = true;
+
+ self.window.document
+ .getElementById("bookmarkpropertiesdialog")
+ .cancelDialog();
+ });
+ }
+ );
+ foldersExpander.doCommand();
+ await unloadPromise;
+ },
+
+ finish() {
+ SidebarUI.hide();
+ },
+
+ async cleanup() {
+ await PlacesTestUtils.promiseAsyncUpdates();
+
+ await PlacesUtils.history.clear();
+ },
+});
+
+// ------------------------------------------------------------------------------
+
+add_task(async function test_setup() {
+ // This test can take some time, if we timeout too early it could run
+ // in the middle of other tests, or hang them.
+ requestLongerTimeout(2);
+});
+
+add_task(async function test_run() {
+ for (let test of gTests) {
+ info(`Start of test: ${test.desc}`);
+ await test.setup();
+
+ await execute_test_in_sidebar(test);
+ await test.run();
+
+ await test.cleanup();
+ await test.finish();
+
+ info(`End of test: ${test.desc}`);
+ }
+});
+
+/**
+ * Global functions to run a test in Properties dialog context.
+ */
+
+function execute_test_in_sidebar(test) {
+ return new Promise(resolve => {
+ var sidebar = document.getElementById("sidebar");
+ sidebar.addEventListener(
+ "load",
+ function () {
+ // Need to executeSoon since the tree is initialized on sidebar load.
+ executeSoon(async () => {
+ await open_properties_dialog(test);
+ resolve();
+ });
+ },
+ { capture: true, once: true }
+ );
+ SidebarUI.show(test.sidebar);
+ });
+}
+
+async function promise_properties_window(dialogUrl = DIALOG_URL) {
+ let win = await BrowserTestUtils.promiseAlertDialogOpen(null, dialogUrl, {
+ isSubDialog: true,
+ });
+ await SimpleTest.promiseFocus(win);
+ await win.document.mozSubdialogReady;
+ return win;
+}
+
+async function open_properties_dialog(test) {
+ var sidebar = document.getElementById("sidebar");
+
+ // If this is history sidebar, set the required view.
+ if (test.sidebar == SIDEBAR_HISTORY_ID) {
+ sidebar.contentDocument.getElementById(test.historyView).doCommand();
+ }
+
+ // Get sidebar's Places tree.
+ var sidebarTreeID =
+ test.sidebar == SIDEBAR_BOOKMARKS_ID
+ ? SIDEBAR_BOOKMARKS_TREE_ID
+ : SIDEBAR_HISTORY_TREE_ID;
+ var tree = sidebar.contentDocument.getElementById(sidebarTreeID);
+ // The sidebar may take a moment to open from the doCommand, therefore wait
+ // until it has opened before continuing.
+ await TestUtils.waitForCondition(() => tree, "Sidebar tree has been loaded");
+
+ // Ask current test to select the node to edit.
+ test.selectNode(tree);
+ Assert.ok(
+ tree.selectedNode,
+ "We have a places node selected: " + tree.selectedNode.title
+ );
+
+ return new Promise(resolve => {
+ var command = null;
+ switch (test.action) {
+ case ACTION_EDIT:
+ command = "placesCmd_show:info";
+ break;
+ case ACTION_ADD:
+ if (test.sidebar == SIDEBAR_BOOKMARKS_ID) {
+ if (test.itemType == TYPE_FOLDER) {
+ command = "placesCmd_new:folder";
+ } else if (test.itemType == TYPE_BOOKMARK) {
+ command = "placesCmd_new:bookmark";
+ } else {
+ Assert.ok(
+ false,
+ "You didn't set a valid itemType for adding an item"
+ );
+ }
+ } else {
+ command = "placesCmd_createBookmark";
+ }
+ break;
+ default:
+ Assert.ok(false, "You didn't set a valid action for this test");
+ }
+ // Ensure command is enabled for this node.
+ Assert.ok(
+ tree.controller.isCommandEnabled(command),
+ " command '" + command + "' on current selected node is enabled"
+ );
+
+ promise_properties_window(test.dialogUrl).then(win => {
+ test.window = win;
+ resolve();
+ });
+ // This will open the dialog. For some reason this needs to be executed
+ // later, as otherwise opening the dialog throws an exception.
+ executeSoon(() => {
+ tree.controller.doCommand(command);
+ });
+ });
+}