diff options
Diffstat (limited to 'browser/components/places/tests/chrome')
15 files changed, 1392 insertions, 0 deletions
diff --git a/browser/components/places/tests/chrome/.eslintrc.js b/browser/components/places/tests/chrome/.eslintrc.js new file mode 100644 index 000000000..8c0f4f574 --- /dev/null +++ b/browser/components/places/tests/chrome/.eslintrc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + "extends": [ + "../../../../../testing/mochitest/chrome.eslintrc.js" + ] +}; diff --git a/browser/components/places/tests/chrome/chrome.ini b/browser/components/places/tests/chrome/chrome.ini new file mode 100644 index 000000000..d7b4a55c8 --- /dev/null +++ b/browser/components/places/tests/chrome/chrome.ini @@ -0,0 +1,15 @@ +[DEFAULT] +support-files = head.js + +[test_0_bug510634.xul] +[test_0_multiple_left_pane.xul] +[test_bug1163447_selectItems_through_shortcut.xul] +[test_bug427633_no_newfolder_if_noip.xul] +[test_bug485100-change-case-loses-tag.xul] +[test_bug549192.xul] +[test_bug549491.xul] +[test_bug631374_tags_selector_scroll.xul] +[test_editBookmarkOverlay_keywords.xul] +[test_editBookmarkOverlay_tags_liveUpdate.xul] +[test_selectItems_on_nested_tree.xul] +[test_treeview_date.xul] diff --git a/browser/components/places/tests/chrome/head.js b/browser/components/places/tests/chrome/head.js new file mode 100644 index 000000000..26b97f6d7 --- /dev/null +++ b/browser/components/places/tests/chrome/head.js @@ -0,0 +1,7 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils", + "resource://testing-common/PlacesTestUtils.jsm"); diff --git a/browser/components/places/tests/chrome/test_0_bug510634.xul b/browser/components/places/tests/chrome/test_0_bug510634.xul new file mode 100644 index 000000000..86e102180 --- /dev/null +++ b/browser/components/places/tests/chrome/test_0_bug510634.xul @@ -0,0 +1,99 @@ +<?xml version="1.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/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="510634: Wrong icons on bookmarks sidebar" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <tree id="tree" + type="places" + flex="1"> + <treecols> + <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/> + </treecols> + <treechildren flex="1"/> + </tree> + + <script type="application/javascript"> + <![CDATA[ + + /** + * Bug 510634 - Wrong icons on bookmarks sidebar + * https://bugzilla.mozilla.org/show_bug.cgi?id=510634 + * + * Ensures that properties for special queries are set on their tree nodes, + * even if PlacesUIUtils.leftPaneFolderId was not initialized. + */ + + SimpleTest.waitForExplicitFinish(); + + function runTest() { + // We need to cache and restore this getter in order to simulate + // Bug 510634 + let cachedLeftPaneFolderIdGetter = + PlacesUIUtils.__lookupGetter__("leftPaneFolderId"); + // Must also cache and restore this getter as it is affected by + // leftPaneFolderId, from bug 564900. + let cachedAllBookmarksFolderIdGetter = + PlacesUIUtils.__lookupGetter__("allBookmarksFolderId"); + + let leftPaneFolderId = PlacesUIUtils.leftPaneFolderId; + + // restore the getter + PlacesUIUtils.__defineGetter__("leftPaneFolderId", cachedLeftPaneFolderIdGetter); + + // Setup the places tree contents. + let tree = document.getElementById("tree"); + tree.place = "place:queryType=1&folder=" + leftPaneFolderId; + + // The query-property is set on the title column for each row. + let titleColumn = tree.treeBoxObject.columns.getColumnAt(0); + + // Open All Bookmarks + tree.selectItems([PlacesUIUtils.leftPaneQueries["AllBookmarks"]]); + PlacesUtils.asContainer(tree.selectedNode).containerOpen = true; + is(PlacesUIUtils.allBookmarksFolderId, tree.selectedNode.itemId, + "Opened All Bookmarks"); + + ["History", "Downloads", "Tags", "AllBookmarks", "BookmarksToolbar", + "BookmarksMenu", "UnfiledBookmarks"].forEach( + function(aQueryName, aRow) { + let found = false; + for (let i = 0; i < tree.view.rowCount && !found; i++) { + rowProperties = tree.view.getCellProperties(i, titleColumn).split(" "); + found = rowProperties.includes("OrganizerQuery_" + aQueryName); + } + ok(found, "OrganizerQuery_" + aQueryName + " is set"); + } + ); + + // Close the root node + tree.result.root.containerOpen = false; + + // Restore the getters for the next test. + PlacesUIUtils.__defineGetter__("leftPaneFolderId", cachedLeftPaneFolderIdGetter); + PlacesUIUtils.__defineGetter__("allBookmarksFolderId", + cachedAllBookmarksFolderIdGetter); + + SimpleTest.finish(); + } + + ]]> + </script> +</window> diff --git a/browser/components/places/tests/chrome/test_0_multiple_left_pane.xul b/browser/components/places/tests/chrome/test_0_multiple_left_pane.xul new file mode 100644 index 000000000..09a4d2054 --- /dev/null +++ b/browser/components/places/tests/chrome/test_0_multiple_left_pane.xul @@ -0,0 +1,85 @@ +<?xml version="1.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/. --> + +<!-- Bug 466422: + - Check that we replace the left pane with a correct one if it gets corrupted + - and we end up having more than one. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> + +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Test handling of multiple left pane folders" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + + <body xmlns="http://www.w3.org/1999/xhtml"> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"></pre> + </body> + + <script type="application/javascript"> + <![CDATA[ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + // Sanity checks. + ok(PlacesUtils, "PlacesUtils is running in chrome context"); + ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context"); + ok(PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION > 0, + "Left pane version in chrome context, " + + "current version is: " + PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION ); + + let fakeLeftPanes = []; + // We need 2 left pane folders to simulate a corrupt profile. + do { + let leftPaneItems = PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO); + + // Create a fake left pane folder. + let folder = yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.rootGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_FOLDER + }); + + let fakeLeftPaneRoot = yield PlacesUtils.promiseItemId(folder.guid); + PlacesUtils.annotations.setItemAnnotation(fakeLeftPaneRoot, PlacesUIUtils.ORGANIZER_FOLDER_ANNO, + PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION, 0, + PlacesUtils.annotations.EXPIRE_NEVER); + fakeLeftPanes.push(folder.guid); + } while (fakeLeftPanes.length < 2); + + // Initialize the left pane queries. + PlacesUIUtils.leftPaneFolderId; + + // Check left pane. + ok(PlacesUIUtils.leftPaneFolderId > 0, + "Left pane folder correctly created"); + let leftPaneItems = PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO); + is(leftPaneItems.length, 1, + "We correctly have only 1 left pane folder"); + + // Check that all old left pane items have been removed. + for (let guid of fakeLeftPanes) { + ok(!(yield PlacesUtils.bookmarks.fetch({guid})), "This folder should have been removed"); + } + }).then(() => SimpleTest.finish()); + } + ]]> + </script> + +</window> diff --git a/browser/components/places/tests/chrome/test_bug1163447_selectItems_through_shortcut.xul b/browser/components/places/tests/chrome/test_bug1163447_selectItems_through_shortcut.xul new file mode 100644 index 000000000..8e3a99533 --- /dev/null +++ b/browser/components/places/tests/chrome/test_bug1163447_selectItems_through_shortcut.xul @@ -0,0 +1,89 @@ +<?xml version="1.0"?> + +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/licenses/publicdomain/ + --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="1163447: selectItems in Places no longer selects items within Toolbar or Sidebar folders" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" src="head.js" /> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <tree id="tree" + type="places" + flex="1"> + <treecols> + <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/> + </treecols> + <treechildren flex="1"/> + </tree> + + <script type="application/javascript"><![CDATA[ + + /** + * Bug 1163447: places-tree should be able to select an item within the toolbar, and + * unfiled bookmarks. Yet not follow recursive folder-shortcuts infinitely. + */ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + let bmu = PlacesUtils.bookmarks; + + yield bmu.insert({ + parentGuid: bmu.toolbarGuid, + index: bmu.DEFAULT_INDEX, + type: bmu.TYPE_BOOKMARK, + url: "place:folder=TOOLBAR", + title: "shortcut to self - causing infinite recursion if not handled properly" + }); + + yield bmu.insert({ + parentGuid: bmu.toolbarGuid, + index: bmu.DEFAULT_INDEX, + type: bmu.TYPE_BOOKMARK, + url: "place:folder=UNFILED_BOOKMARKS", + title: "shortcut to unfiled, within toolbar" + }); + + let folder = yield bmu.insert({ + parentGuid: bmu.unfiledGuid, + index: bmu.DEFAULT_INDEX, + type: bmu.TYPE_FOLDER, + title: "folder within unfiled" + }); + + // Setup the places tree contents. + let tree = document.getElementById("tree"); + tree.place = "place:folder=TOOLBAR"; + + // Select the folder via the selectItems(itemId) API being tested + let itemId = yield PlacesUtils.promiseItemId(folder.guid); + tree.selectItems([itemId]); + + is(tree.selectedNode && tree.selectedNode.itemId, itemId, "The node was selected through the shortcut"); + + // Cleanup + yield bmu.eraseEverything(); + + }).catch(err => { + ok(false, `Uncaught error: ${err}`); + }).then(SimpleTest.finish); + } + ]]></script> +</window> diff --git a/browser/components/places/tests/chrome/test_bug427633_no_newfolder_if_noip.xul b/browser/components/places/tests/chrome/test_bug427633_no_newfolder_if_noip.xul new file mode 100644 index 000000000..b659b2b46 --- /dev/null +++ b/browser/components/places/tests/chrome/test_bug427633_no_newfolder_if_noip.xul @@ -0,0 +1,91 @@ +<?xml version="1.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/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?> +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> + +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> +<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?> + +<!DOCTYPE window [ + <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd"> + %editBookmarkOverlayDTD; +]> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Bug 427633 - Disable creating a New Folder in the bookmarks dialogs if insertionPoint is invalid" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" + src="chrome://browser/content/places/editBookmarkOverlay.js"/> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <vbox id="editBookmarkPanelContent"/> + + <script type="application/javascript"> + <![CDATA[ + + /** + * Bug 427633 - Disable creating a New Folder in the bookmarks dialogs if + * insertionPoint is invalid. + */ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + // Add a bookmark. + let bm = yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + url: "http://www.example.com/", + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + title: "mozilla" + }); + + // Init panel. + ok(gEditItemOverlay, "gEditItemOverlay is in context"); + let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm); + gEditItemOverlay.initPanel({ node }); + ok(gEditItemOverlay.initialized, "gEditItemOverlay is initialized"); + + let tree = gEditItemOverlay._element("folderTree"); + yield openFolderTree(tree); + + tree.view.selection.clearSelection(); + ok(document.getElementById("editBMPanel_newFolderButton").disabled, + "New folder button is disabled if there's no selection"); + + // Cleanup. + yield PlacesUtils.bookmarks.remove(bm.guid); + }).then(() => SimpleTest.finish()); + } + + function openFolderTree(tree) { + return new Promise(resolve => { + tree.addEventListener("DOMAttrModified", function onAttrModified(event) { + if (event.attrName == "place") { + tree.removeEventListener("DOMAttrModified", onAttrModified); + resolve(); + } + }); + + // Open the folder tree. + document.getElementById("editBMPanel_foldersExpander").doCommand(); + }); + } + ]]> + </script> + +</window> diff --git a/browser/components/places/tests/chrome/test_bug485100-change-case-loses-tag.xul b/browser/components/places/tests/chrome/test_bug485100-change-case-loses-tag.xul new file mode 100644 index 000000000..afad950cb --- /dev/null +++ b/browser/components/places/tests/chrome/test_bug485100-change-case-loses-tag.xul @@ -0,0 +1,83 @@ +<?xml version="1.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/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?> +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> + +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> +<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?> + +<!DOCTYPE window [ + <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd"> + %editBookmarkOverlayDTD; +]> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="485100: Exchanging a letter of a tag name with its big/small equivalent removes tag from bookmark" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" + src="chrome://browser/content/places/editBookmarkOverlay.js"/> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <vbox id="editBookmarkPanelContent"/> + + <script type="application/javascript"> + <![CDATA[ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + let testTag = "foo"; + let testTagUpper = "Foo"; + let testURI = Services.io.newURI("http://www.example.com/", null, null); + + // Add a bookmark. + let bm = yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + title: "mozilla", + url: testURI + }); + + // Init panel + ok(gEditItemOverlay, "gEditItemOverlay is in context"); + let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm); + gEditItemOverlay.initPanel({ node }); + + // add a tag + document.getElementById("editBMPanel_tagsField").value = testTag; + gEditItemOverlay.onTagsFieldChange(); + + // test that the tag has been added in the backend + is(PlacesUtils.tagging.getTagsForURI(testURI)[0], testTag, "tags match"); + + // change the tag + document.getElementById("editBMPanel_tagsField").value = testTagUpper; + gEditItemOverlay.onTagsFieldChange(); + + // test that the tag has been added in the backend + is(PlacesUtils.tagging.getTagsForURI(testURI)[0], testTagUpper, "tags match"); + + // Cleanup. + PlacesUtils.tagging.untagURI(testURI, [testTag]); + yield PlacesUtils.bookmarks.remove(bm.guid); + }).then(() => SimpleTest.finish()); + } + ]]> + </script> + +</window> diff --git a/browser/components/places/tests/chrome/test_bug549192.xul b/browser/components/places/tests/chrome/test_bug549192.xul new file mode 100644 index 000000000..4e6a89bb1 --- /dev/null +++ b/browser/components/places/tests/chrome/test_bug549192.xul @@ -0,0 +1,120 @@ +<?xml version="1.0"?> + +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/licenses/publicdomain/ + --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="549192: History view not updated after deleting entry" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" src="head.js" /> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <tree id="tree" + type="places" + flatList="true" + flex="1"> + <treecols> + <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/> + </treecols> + <treechildren flex="1"/> + </tree> + + <script type="application/javascript"><![CDATA[ + /** + * Bug 874407 + * Ensures that history views are updated properly after visits. + * Bug 549192 + * Ensures that history views are updated after deleting entries. + */ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + yield PlacesTestUtils.clearHistory(); + + // Add some visits. + let timeInMicroseconds = PlacesUtils.toPRTime(Date.now() - 10000); + + function newTimeInMicroseconds() { + timeInMicroseconds = timeInMicroseconds + 1000; + return timeInMicroseconds; + } + + let vtime = Date.now() * 1000; + const ttype = PlacesUtils.history.TRANSITION_TYPED; + let places = + [{ uri: Services.io.newURI("http://example.tld/", null, null), + visitDate: newTimeInMicroseconds(), transition: ttype }, + { uri: Services.io.newURI("http://example2.tld/", null, null), + visitDate: newTimeInMicroseconds(), transition: ttype }, + { uri: Services.io.newURI("http://example3.tld/", null, null), + visitDate: newTimeInMicroseconds(), transition: ttype }]; + + yield PlacesTestUtils.addVisits(places); + + // Make a history query. + let query = PlacesUtils.history.getNewQuery(); + let opts = PlacesUtils.history.getNewQueryOptions(); + opts.sortingMode = opts.SORT_BY_DATE_DESCENDING; + let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts); + + // Setup the places tree contents. + var tree = document.getElementById("tree"); + tree.place = queryURI; + + // loop through the rows and check them. + let treeView = tree.view; + let selection = treeView.selection; + let rc = treeView.rowCount; + + for (let i = 0; i < rc; i++) { + selection.select(i); + let node = tree.selectedNode; + is(node.uri, places[rc - i - 1].uri.spec, + "Found expected node at position " + i + "."); + } + + is(rc, 3, "Found expected number of rows."); + + // First check live-update of the view when adding visits. + places.forEach(place => place.visitDate = newTimeInMicroseconds()); + yield PlacesTestUtils.addVisits(places); + + for (let i = 0; i < rc; i++) { + selection.select(i); + let node = tree.selectedNode; + is(node.uri, places[rc - i - 1].uri.spec, + "Found expected node at position " + i + "."); + } + + // Now remove the pages and verify live-update again. + for (let i = 0; i < rc; i++) { + selection.select(0); + let node = tree.selectedNode; + tree.controller.remove("Removing page"); + ok(treeView.treeIndexForNode(node) == Ci.nsINavHistoryResultTreeViewer.INDEX_INVISIBLE, + node.uri + " removed."); + ok(treeView.rowCount == rc - i - 1, "Rows count decreased"); + } + + // Cleanup. + yield PlacesTestUtils.clearHistory(); + }).then(() => SimpleTest.finish()); + } + ]]></script> +</window> diff --git a/browser/components/places/tests/chrome/test_bug549491.xul b/browser/components/places/tests/chrome/test_bug549491.xul new file mode 100644 index 000000000..5ec7a765a --- /dev/null +++ b/browser/components/places/tests/chrome/test_bug549491.xul @@ -0,0 +1,78 @@ +<?xml version="1.0"?> + +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/licenses/publicdomain/ + --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="549491: 'The root node is never visible' exception when details of the root node are modified " + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" src="head.js" /> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <tree id="tree" + type="places" + flatList="true" + flex="1"> + <treecols> + <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/> + <splitter class="tree-splitter"/> + <treecol label="Date" anonid="date" flex="1"/> + </treecols> + <treechildren flex="1"/> + </tree> + + <script type="application/javascript"><![CDATA[ + /** + * Bug 549491 + * https://bugzilla.mozilla.org/show_bug.cgi?id=549491 + * + * Ensures that changing the details of places tree's root-node doesn't + * throw. + */ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + yield PlacesTestUtils.clearHistory(); + + yield PlacesTestUtils.addVisits({ + uri: Services.io.newURI("http://example.tld/", null, null), + transition: PlacesUtils.history.TRANSITION_TYPED + }); + + // Make a history query. + let query = PlacesUtils.history.getNewQuery(); + let opts = PlacesUtils.history.getNewQueryOptions(); + let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts); + + // Setup the places tree contents. + let tree = document.getElementById("tree"); + tree.place = queryURI; + + let rootNode = tree.result.root; + let obs = tree.view.QueryInterface(Ci.nsINavHistoryResultObserver); + obs.nodeHistoryDetailsChanged(rootNode, rootNode.time, rootNode.accessCount); + obs.nodeTitleChanged(rootNode, rootNode.title); + ok(true, "No exceptions thrown"); + + // Cleanup. + yield PlacesTestUtils.clearHistory(); + }).then(SimpleTest.finish); + } + ]]></script> +</window> diff --git a/browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul b/browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul new file mode 100644 index 000000000..b1d73017f --- /dev/null +++ b/browser/components/places/tests/chrome/test_bug631374_tags_selector_scroll.xul @@ -0,0 +1,170 @@ +<?xml version="1.0"?> + +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?> +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> + +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> +<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?> + +<!DOCTYPE window [ + <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd"> + %editBookmarkOverlayDTD; +]> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Bug 631374 - Editing tags in the selector scrolls up the listbox" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" + src="chrome://browser/content/places/editBookmarkOverlay.js"/> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <vbox id="editBookmarkPanelContent"/> + + <script type="application/javascript"> + <![CDATA[ + + /** + * This test checks that editing tags doesn't scroll the tags selector + * listbox to wrong positions. + */ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + let bs = PlacesUtils.bookmarks; + + let tags = ["a", "b", "c", "d", "e", "f", "g", + "h", "i", "l", "m", "n", "o", "p"]; + + // Add a bookmark and tag it. + let uri1 = Services.io.newURI("http://www1.mozilla.org/", null, null); + let bm1 = yield bs.insert({ + parentGuid: bs.toolbarGuid, + index: bs.DEFAULT_INDEX, + type: bs.TYPE_BOOKMARK, + title: "mozilla", + url: uri1.spec + }); + PlacesUtils.tagging.tagURI(uri1, tags); + + // Add a second bookmark so that tags won't disappear when unchecked. + let uri2 = Services.io.newURI("http://www2.mozilla.org/", null, null); + let bm2 = yield bs.insert({ + parentGuid: bs.toolbarGuid, + index: bs.DEFAULT_INDEX, + type: bs.TYPE_BOOKMARK, + title: "mozilla", + url: uri2.spec + }); + PlacesUtils.tagging.tagURI(uri2, tags); + + // Init panel. + ok(gEditItemOverlay, "gEditItemOverlay is in context"); + let node1 = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm1); + gEditItemOverlay.initPanel({ node: node1 }); + ok(gEditItemOverlay.initialized, "gEditItemOverlay is initialized"); + + yield openTagSelector(); + let tagsSelector = document.getElementById("editBMPanel_tagsSelector"); + + // Go by two so there is some untouched tag in the middle. + for (let i = 8; i < tags.length; i += 2) { + tagsSelector.selectedIndex = i; + let listItem = tagsSelector.selectedItem; + isnot(listItem, null, "Valid listItem found"); + + tagsSelector.ensureElementIsVisible(listItem); + let visibleIndex = tagsSelector.getIndexOfFirstVisibleRow(); + + ok(listItem.checked, "Item is checked " + i); + let selectedTag = listItem.label; + + // Uncheck the tag. + listItem.checked = false; + is(visibleIndex, tagsSelector.getIndexOfFirstVisibleRow(), + "Scroll position did not change"); + + // The listbox is rebuilt, so we have to get the new element. + let newItem = tagsSelector.selectedItem; + isnot(newItem, null, "Valid new listItem found"); + ok(!newItem.checked, "New listItem is unchecked " + i); + is(newItem.label, selectedTag, "Correct tag is still selected"); + + // Check the tag. + newItem.checked = true; + is(visibleIndex, tagsSelector.getIndexOfFirstVisibleRow(), + "Scroll position did not change"); + } + + // Remove the second bookmark, then nuke some of the tags. + yield bs.remove(bm2.guid); + + // Doing this backwords tests more interesting paths. + for (let i = tags.length - 1; i >= 0 ; i -= 2) { + tagsSelector.selectedIndex = i; + let listItem = tagsSelector.selectedItem; + isnot(listItem, null, "Valid listItem found"); + + tagsSelector.ensureElementIsVisible(listItem); + let firstVisibleTag = tags[tagsSelector.getIndexOfFirstVisibleRow()]; + + ok(listItem.checked, "Item is checked " + i); + let selectedTag = listItem.label; + + // Uncheck the tag. + listItem.checked = false; + + // Ensure the first visible tag is still visible in the list. + let firstVisibleIndex = tagsSelector.getIndexOfFirstVisibleRow(); + let lastVisibleIndex = firstVisibleIndex + tagsSelector.getNumberOfVisibleRows() -1; + let expectedTagIndex = tags.indexOf(firstVisibleTag); + ok(expectedTagIndex >= firstVisibleIndex && + expectedTagIndex <= lastVisibleIndex, + "Scroll position is correct"); + + // The listbox is rebuilt, so we have to get the new element. + let newItem = tagsSelector.selectedItem; + isnot(newItem, null, "Valid new listItem found"); + ok(newItem.checked, "New listItem is checked " + i); + is(tagsSelector.selectedItem.label, + tags[Math.min(i + 1, tags.length - 2)], + "The next tag is now selected"); + } + + // Cleanup. + yield bs.remove(bm1.guid); + }).then(SimpleTest.finish).catch(alert); + } + + function openTagSelector() { + // Wait for the tags selector to be open. + let promise = new Promise(resolve => { + let row = document.getElementById("editBMPanel_tagsSelectorRow"); + row.addEventListener("DOMAttrModified", function onAttrModified() { + row.removeEventListener("DOMAttrModified", onAttrModified); + resolve(); + }); + }); + + // Open the tags selector. + document.getElementById("editBMPanel_tagsSelectorExpander").doCommand(); + + return promise; + } + ]]> + </script> + +</window> diff --git a/browser/components/places/tests/chrome/test_editBookmarkOverlay_keywords.xul b/browser/components/places/tests/chrome/test_editBookmarkOverlay_keywords.xul new file mode 100644 index 000000000..f553d018b --- /dev/null +++ b/browser/components/places/tests/chrome/test_editBookmarkOverlay_keywords.xul @@ -0,0 +1,99 @@ +<?xml version="1.0"?> + +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?> +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> + +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> +<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?> + +<!DOCTYPE window [ + <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd"> + %editBookmarkOverlayDTD; +]> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="Bug 1343256 - Bookmark keywords disappear from one bookmark when adding a keyword to another bookmark" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/> + <script type="application/javascript" + src="chrome://browser/content/places/editBookmarkOverlay.js"/> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <vbox id="editBookmarkPanelContent"/> + + <script type="application/javascript"> + <![CDATA[ + function runTest() { + SimpleTest.waitForExplicitFinish(); + Task.spawn(test.bind(this)) + .catch(ex => ok(false, ex)) + .then(() => PlacesUtils.bookmarks.eraseEverything()) + .then(SimpleTest.finish); + } + + function promiseOnItemChanged() { + return new Promise(resolve => { + PlacesUtils.bookmarks.addObserver({ + onBeginUpdateBatch() {}, + onEndUpdateBatch() {}, + onItemAdded() {}, + onItemRemoved() {}, + onItemVisited() {}, + onItemMoved() {}, + onItemChanged(id, property, isAnno, value) { + PlacesUtils.bookmarks.removeObserver(this); + resolve({ property, value }); + }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]) + }, false); + }); + } + + function* test() { + ok(gEditItemOverlay, "Sanity check: gEditItemOverlay is in context"); + let keywordField = document.getElementById("editBMPanel_keywordField"); + + for (let i = 0; i < 2; ++i) { + let bm = yield PlacesUtils.bookmarks.insert({ + url: `http://www.test${i}.me/`, + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + }); + info(`Init panel on bookmark #${i+1}`); + let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm); + gEditItemOverlay.initPanel({ node }); + is(document.getElementById("editBMPanel_keywordField").value, "", + "The keyword field should be empty"); + info("Add a keyword to the bookmark"); + let promise = promiseOnItemChanged(); + keywordField.focus(); + keywordField.value = "kw"; + synthesizeKey(i.toString(), {}); + synthesizeKey("VK_RETURN", {}); + keywordField.blur(); + let {property, value} = yield promise; + is(property, "keyword", "The keyword should have been changed"); + is(value, `kw${i}`, "The new keyword value is correct"); + } + + for (let i = 0; i < 2; ++i) { + let entry = yield PlacesUtils.keywords.fetch({ url: `http://www.test${i}.me/` }); + is(entry.keyword, `kw${i}`, `The keyword for http://www.test${i}.me/ is correct`); + } + }; + ]]> + </script> + +</window> diff --git a/browser/components/places/tests/chrome/test_editBookmarkOverlay_tags_liveUpdate.xul b/browser/components/places/tests/chrome/test_editBookmarkOverlay_tags_liveUpdate.xul new file mode 100644 index 000000000..1b1cc6473 --- /dev/null +++ b/browser/components/places/tests/chrome/test_editBookmarkOverlay_tags_liveUpdate.xul @@ -0,0 +1,204 @@ +<?xml version="1.0"?> + +<!-- Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/skin/places/editBookmarkOverlay.css"?> +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> + +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> +<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?> + +<!DOCTYPE window [ + <!ENTITY % editBookmarkOverlayDTD SYSTEM "chrome://browser/locale/places/editBookmarkOverlay.dtd"> + %editBookmarkOverlayDTD; +]> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="485100: Exchanging a letter of a tag name with its big/small equivalent removes tag from bookmark" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" + src="chrome://browser/content/places/editBookmarkOverlay.js"/> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <vbox id="editBookmarkPanelContent"/> + + <script type="application/javascript"> + <![CDATA[ + function checkTagsSelector(aAvailableTags, aCheckedTags) { + is(PlacesUtils.tagging.allTags.length, aAvailableTags.length, + "tagging service is in sync."); + let tagsSelector = document.getElementById("editBMPanel_tagsSelector"); + let children = tagsSelector.childNodes; + is(children.length, aAvailableTags.length, + "Found expected number of tags in the tags selector"); + + Array.prototype.forEach.call(children, function (aChild) { + let tag = aChild.getAttribute("label"); + ok(true, "Found tag '" + tag + "' in the selector"); + ok(aAvailableTags.includes(tag), "Found expected tag"); + let checked = aChild.getAttribute("checked") == "true"; + is(checked, aCheckedTags.includes(tag), + "Tag is correctly marked"); + }); + } + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + const TEST_URI = Services.io.newURI("http://www.test.me/", null, null); + const TEST_URI2 = Services.io.newURI("http://www.test.again.me/", null, null); + const TEST_TAG = "test-tag"; + + ok(gEditItemOverlay, "Sanity check: gEditItemOverlay is in context"); + + // Open the tags selector. + document.getElementById("editBMPanel_tagsSelectorRow").collapsed = false; + + // Add a bookmark. + let bm = yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: TEST_URI.spec, + title: "test.me" + }); + + // Init panel. + let node = yield PlacesUIUtils.promiseNodeLikeFromFetchInfo(bm); + gEditItemOverlay.initPanel({ node }); + + // Add a tag. + PlacesUtils.tagging.tagURI(TEST_URI, [TEST_TAG]); + + is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], TEST_TAG, + "Correctly added tag to a single bookmark"); + is(document.getElementById("editBMPanel_tagsField").value, TEST_TAG, + "Editing a single bookmark shows the added tag"); + checkTagsSelector([TEST_TAG], [TEST_TAG]); + + // Remove tag. + PlacesUtils.tagging.untagURI(TEST_URI, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], undefined, + "The tag has been removed"); + is(document.getElementById("editBMPanel_tagsField").value, "", + "Editing a single bookmark should not show any tag"); + checkTagsSelector([], []); + + // Add a second bookmark. + let bm2 = yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + title: "test.again.me", + url: TEST_URI2.spec + }); + + // Init panel with multiple uris. + gEditItemOverlay.initPanel({ uris: [TEST_URI, TEST_URI2] }); + + // Add a tag to the first uri. + PlacesUtils.tagging.tagURI(TEST_URI, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], TEST_TAG, + "Correctly added a tag to the first bookmark."); + is(document.getElementById("editBMPanel_tagsField").value, "", + "Editing multiple bookmarks without matching tags should not show any tag."); + checkTagsSelector([TEST_TAG], []); + + // Add a tag to the second uri. + PlacesUtils.tagging.tagURI(TEST_URI2, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI2)[0], TEST_TAG, + "Correctly added a tag to the second bookmark."); + is(document.getElementById("editBMPanel_tagsField").value, TEST_TAG, + "Editing multiple bookmarks should show matching tags."); + checkTagsSelector([TEST_TAG], [TEST_TAG]); + + // Remove tag from the first bookmark. + PlacesUtils.tagging.untagURI(TEST_URI, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], undefined, + "Correctly removed tag from the first bookmark."); + is(document.getElementById("editBMPanel_tagsField").value, "", + "Editing multiple bookmarks without matching tags should not show any tag."); + checkTagsSelector([TEST_TAG], []); + + // Remove tag from the second bookmark. + PlacesUtils.tagging.untagURI(TEST_URI2, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI2)[0], undefined, + "Correctly removed tag from the second bookmark."); + is(document.getElementById("editBMPanel_tagsField").value, "", + "Editing multiple bookmarks without matching tags should not show any tag."); + checkTagsSelector([], []); + + // Init panel with a nsIURI entry. + gEditItemOverlay.initPanel({ uris: [TEST_URI] }); + + // Add a tag. + PlacesUtils.tagging.tagURI(TEST_URI, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], TEST_TAG, + "Correctly added tag to the first entry."); + is(document.getElementById("editBMPanel_tagsField").value, TEST_TAG, + "Editing a single nsIURI entry shows the added tag"); + checkTagsSelector([TEST_TAG], [TEST_TAG]); + + // Remove tag. + PlacesUtils.tagging.untagURI(TEST_URI, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], undefined, + "Correctly removed tag from the nsIURI entry."); + is(document.getElementById("editBMPanel_tagsField").value, "", + "Editing a single nsIURI entry should not show any tag"); + checkTagsSelector([], []); + + // Init panel with multiple nsIURI entries. + gEditItemOverlay.initPanel({ uris: [TEST_URI, TEST_URI2] }); + + // Add a tag to the first entry. + PlacesUtils.tagging.tagURI(TEST_URI, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], TEST_TAG, + "Tag correctly added."); + is(document.getElementById("editBMPanel_tagsField").value, "", + "Editing multiple nsIURIs without matching tags should not show any tag."); + checkTagsSelector([TEST_TAG], []); + + // Add a tag to the second entry. + PlacesUtils.tagging.tagURI(TEST_URI2, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI2)[0], TEST_TAG, + "Tag correctly added."); + is(document.getElementById("editBMPanel_tagsField").value, TEST_TAG, + "Editing multiple nsIURIs should show matching tags"); + checkTagsSelector([TEST_TAG], [TEST_TAG]); + + // Remove tag from the first entry. + PlacesUtils.tagging.untagURI(TEST_URI, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI)[0], undefined, + "Correctly removed tag from the first entry."); + is(document.getElementById("editBMPanel_tagsField").value, "", + "Editing multiple nsIURIs without matching tags should not show any tag."); + checkTagsSelector([TEST_TAG], []); + + // Remove tag from the second entry. + PlacesUtils.tagging.untagURI(TEST_URI2, [TEST_TAG]); + is(PlacesUtils.tagging.getTagsForURI(TEST_URI2)[0], undefined, + "Correctly removed tag from the second entry."); + is(document.getElementById("editBMPanel_tagsField").value, "", + "Editing multiple nsIURIs without matching tags should not show any tag."); + checkTagsSelector([], []); + + // Cleanup. + yield PlacesUtils.bookmarks.remove(bm.guid); + yield PlacesUtils.bookmarks.remove(bm2.guid); + }).then(SimpleTest.finish); + } + ]]> + </script> + +</window> diff --git a/browser/components/places/tests/chrome/test_selectItems_on_nested_tree.xul b/browser/components/places/tests/chrome/test_selectItems_on_nested_tree.xul new file mode 100644 index 000000000..032c7a258 --- /dev/null +++ b/browser/components/places/tests/chrome/test_selectItems_on_nested_tree.xul @@ -0,0 +1,86 @@ +<?xml version="1.0"?> + +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/licenses/publicdomain/ + --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="549192: History view not updated after deleting entry" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" src="head.js" /> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <tree id="tree" + type="places" + flex="1"> + <treecols> + <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/> + </treecols> + <treechildren flex="1"/> + </tree> + + <script type="application/javascript"><![CDATA[ + /** + * Ensure that selectItems doesn't recurse infinitely in nested trees. + */ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + Task.spawn(function* () { + yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "place:folder=UNFILED_BOOKMARKS", + title: "shortcut" + }); + + yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "place:folder=UNFILED_BOOKMARKS&maxResults=10", + title: "query" + }); + + let folder = yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_FOLDER, + title: "folder" + }); + + let bm = yield PlacesUtils.bookmarks.insert({ + parentGuid: folder.guid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "http://www.mozilla.org/", + title: "bookmark" + }); + + // Setup the places tree contents. + let tree = document.getElementById("tree"); + tree.place = "place:folder=UNFILED_BOOKMARKS"; + + // Select the last bookmark. + let itemId = yield PlacesUtils.promiseItemId(bm.guid); + tree.selectItems([itemId]); + is (tree.selectedNode.itemId, itemId, "The right node was selected"); + }).then(SimpleTest.finish); + } + ]]></script> +</window> diff --git a/browser/components/places/tests/chrome/test_treeview_date.xul b/browser/components/places/tests/chrome/test_treeview_date.xul new file mode 100644 index 000000000..559232611 --- /dev/null +++ b/browser/components/places/tests/chrome/test_treeview_date.xul @@ -0,0 +1,159 @@ +<?xml version="1.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/. --> + +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> + +<?xml-stylesheet href="chrome://browser/content/places/places.css"?> +<?xml-stylesheet href="chrome://browser/skin/places/places.css"?> +<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?> + +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="435322: Places tree view's formatting" + onload="runTest();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> + <script type="application/javascript" src="head.js" /> + + <body xmlns="http://www.w3.org/1999/xhtml" /> + + <tree id="tree" + type="places" + flatList="true" + flex="1"> + <treecols> + <treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/> + <splitter class="tree-splitter"/> + <treecol label="Tags" id="tags" anonid="tags" flex="1"/> + <splitter class="tree-splitter"/> + <treecol label="Url" id="url" anonid="url" flex="1"/> + <splitter class="tree-splitter"/> + <treecol label="Visit Date" id="date" anonid="date" flex="1"/> + <splitter class="tree-splitter"/> + <treecol label="Visit Count" id="visitCount" anonid="visitCount" flex="1"/> + </treecols> + <treechildren flex="1"/> + </tree> + + <script type="application/javascript"> + <![CDATA[ + + /** + * Bug 435322 + * https://bugzilla.mozilla.org/show_bug.cgi?id=435322 + * + * Ensures that date in places treeviews is correctly formatted. + */ + + function runTest() { + SimpleTest.waitForExplicitFinish(); + + function uri(spec) { + return Services.io.newURI(spec, null, null); + } + + Task.spawn(function* () { + yield PlacesTestUtils.clearHistory(); + + let midnight = new Date(); + midnight.setHours(0); + midnight.setMinutes(0); + midnight.setSeconds(0); + midnight.setMilliseconds(0); + + // Add a visit 1ms before midnight, a visit at midnight, and + // a visit 1ms after midnight. + yield PlacesTestUtils.addVisits([ + {uri: uri("http://before.midnight.com/"), + visitDate: (midnight.getTime() - 1) * 1000, + transition: PlacesUtils.history.TRANSITION_TYPED}, + {uri: uri("http://at.midnight.com/"), + visitDate: (midnight.getTime()) * 1000, + transition: PlacesUtils.history.TRANSITION_TYPED}, + {uri: uri("http://after.midnight.com/"), + visitDate: (midnight.getTime() + 1) * 1000, + transition: PlacesUtils.history.TRANSITION_TYPED} + ]); + + // add a bookmark to the midnight visit + let bm = yield PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + url: "http://at.midnight.com/", + title: "A bookmark at midnight", + type: PlacesUtils.bookmarks.TYPE_BOOKMARK + }); + + // Make a history query. + let query = PlacesUtils.history.getNewQuery(); + let opts = PlacesUtils.history.getNewQueryOptions(); + let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts); + + // Setup the places tree contents. + let tree = document.getElementById("tree"); + tree.place = queryURI; + + // loop through the rows and check formatting + let treeView = tree.view; + let rc = treeView.rowCount; + ok(rc >= 3, "Rows found"); + let columns = tree.columns; + ok(columns.count > 0, "Columns found"); + const locale = Cc["@mozilla.org/chrome/chrome-registry;1"] + .getService(Ci.nsIXULChromeRegistry) + .getSelectedLocale("global", true); + for (let r = 0; r < rc; r++) { + let node = treeView.nodeForTreeIndex(r); + ok(node, "Places node found"); + for (let ci = 0; ci < columns.count; ci++) { + let c = columns.getColumnAt(ci); + let text = treeView.getCellText(r, c); + switch (c.element.getAttribute("anonid")) { + case "title": + // The title can differ, we did not set any title so we would + // expect null, but in such a case the view will generate a title + // through PlacesUIUtils.getBestTitle. + if (node.title) + is(text, node.title, "Title is correct"); + break; + case "url": + is(text, node.uri, "Uri is correct"); + break; + case "date": + let timeObj = new Date(node.time / 1000); + // Default is short date format. + let dtOptions = { year: 'numeric', month: 'numeric', day: 'numeric', + hour: 'numeric', minute: 'numeric' }; + // For today's visits we don't show date portion. + if (node.uri == "http://at.midnight.com/" || + node.uri == "http://after.midnight.com/") { + dtOptions = { hour: 'numeric', minute: 'numeric' }; + } else if (node.uri != "http://before.midnight.com/") { + // Avoid to test spurious uris, due to how the test works + // a redirecting uri could be put in the tree while we test. + break; + } + let timeStr = timeObj.toLocaleString(locale, dtOptions); + + is(text, timeStr, "Date format is correct"); + break; + case "visitCount": + is(text, 1, "Visit count is correct"); + break; + } + } + } + + // Cleanup. + yield PlacesUtils.bookmarks.remove(bm.guid); + yield PlacesTestUtils.clearHistory(); + }).then(SimpleTest.finish); + } + ]]> + </script> +</window> |