michael@0: /** michael@0: * Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ michael@0: */ michael@0: michael@0: gBrowser.selectedTab = gBrowser.addTab(); michael@0: michael@0: function finishAndCleanUp() michael@0: { michael@0: gBrowser.removeCurrentTab(); michael@0: promiseClearHistory().then(finish); michael@0: } michael@0: michael@0: /** michael@0: * One-time DOMContentLoaded callback. michael@0: */ michael@0: function load(href, callback) michael@0: { michael@0: content.location.href = href; michael@0: gBrowser.addEventListener("load", function() { michael@0: if (content.location.href == href) { michael@0: gBrowser.removeEventListener("load", arguments.callee, true); michael@0: if (callback) michael@0: callback(); michael@0: } michael@0: }, true); michael@0: } michael@0: michael@0: var conn = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection; michael@0: michael@0: /** michael@0: * Gets a single column value from either the places or historyvisits table. michael@0: */ michael@0: function getColumn(table, column, fromColumnName, fromColumnValue) michael@0: { michael@0: var stmt = conn.createStatement( michael@0: "SELECT " + column + " FROM " + table + " WHERE " + fromColumnName + "=:val " + michael@0: "LIMIT 1"); michael@0: try { michael@0: stmt.params.val = fromColumnValue; michael@0: stmt.executeStep(); michael@0: return stmt.row[column]; michael@0: } michael@0: finally { michael@0: stmt.finalize(); michael@0: } michael@0: } michael@0: michael@0: function test() michael@0: { michael@0: // Make sure titles are correctly saved for a URI with the proper michael@0: // notifications. michael@0: michael@0: waitForExplicitFinish(); michael@0: michael@0: // Create and add history observer. michael@0: var historyObserver = { michael@0: data: [], michael@0: onBeginUpdateBatch: function() {}, michael@0: onEndUpdateBatch: function() {}, michael@0: onVisit: function(aURI, aVisitID, aTime, aSessionID, aReferringID, michael@0: aTransitionType) { michael@0: }, michael@0: onTitleChanged: function(aURI, aPageTitle, aGUID) { michael@0: this.data.push({ uri: aURI, title: aPageTitle, guid: aGUID }); michael@0: michael@0: // We only expect one title change. michael@0: // michael@0: // Although we are loading two different pages, the first page does not michael@0: // have a title. Since the title starts out as empty and then is set michael@0: // to empty, there is no title change notification. michael@0: michael@0: PlacesUtils.history.removeObserver(this); michael@0: confirmResults(this.data); michael@0: }, michael@0: onDeleteURI: function() {}, michael@0: onClearHistory: function() {}, michael@0: onPageChanged: function() {}, michael@0: onDeleteVisits: function() {}, michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver]) michael@0: }; michael@0: PlacesUtils.history.addObserver(historyObserver, false); michael@0: michael@0: load("http://example.com/tests/toolkit/components/places/tests/browser/title1.html", function() { michael@0: load("http://example.com/tests/toolkit/components/places/tests/browser/title2.html"); michael@0: }); michael@0: michael@0: function confirmResults(data) { michael@0: is(data[0].uri.spec, "http://example.com/tests/toolkit/components/places/tests/browser/title2.html"); michael@0: is(data[0].title, "Some title"); michael@0: is(data[0].guid, getColumn("moz_places", "guid", "url", data[0].uri.spec)); michael@0: michael@0: data.forEach(function(item) { michael@0: var title = getColumn("moz_places", "title", "url", data[0].uri.spec); michael@0: is(title, item.title); michael@0: }); michael@0: michael@0: finishAndCleanUp(); michael@0: } michael@0: }