Index: chrome/test/data/extensions/api_test/history/test.js |
=================================================================== |
--- chrome/test/data/extensions/api_test/history/test.js (revision 0) |
+++ chrome/test/data/extensions/api_test/history/test.js (revision 0) |
@@ -0,0 +1,598 @@ |
+// History api test for Chrome. |
+// browser_tests.exe --gtest_filter=ExtensionApiTest.History |
+ |
+var pass = chrome.test.callbackPass; |
+var fail = chrome.test.callbackFail; |
+var assertEq = chrome.test.assertEq; |
+ |
+var GOOGLE_URL = 'http://www.google.com/'; |
+var PICASA_URL = 'http://www.picasa.com/'; |
+var A_RELATIVE_URL = |
+ 'http://www.a.com:1337/files/extensions/api_test/history/a.html'; |
+var B_RELATIVE_URL = |
+ 'http://www.b.com:1337/files/extensions/api_test/history/b.html'; |
+ |
+/** |
+* A helper function to flip the setTimeout arguments and make the code more |
+* readable. |
+* @param {number} seconds The number of seconds to wait. |
+* @param {function} callback Closure. |
+*/ |
+function waitAFewSeconds(seconds, callback) { |
+ setTimeout(callback, seconds * 1000); |
+}; |
+ |
+/** |
+* Object used for listening to the chrome.history.onVisited events. The global |
+* object 'itemVisited' stores the last item received. |
+*/ |
+var itemVisitedCallback = null; |
+function itemVisitedListener(visited) { |
+ if (null != itemVisitedCallback) { |
+ itemVisitedCallback(visited); |
+ }; |
+}; |
+ |
+function removeItemVisitedListener() { |
+ chrome.experimental.history.onVisited.removeListener(itemVisitedListener); |
+ itemVisitedCallback = null; |
+} |
+ |
+function setItemVisitedListener(callback) { |
+ chrome.experimental.history.onVisited.addListener(itemVisitedListener); |
+ itemVisitedCallback = callback; |
+} |
+ |
+function setNextItemVisitedListener(callback) { |
+ itemVisitedCallback = callback; |
+} |
+ |
+/** |
+* An object used for listening to the chrome.history.onVisitRemoved events. The |
+* global object 'itemRemovedInfo' stores the information from the last callback. |
+*/ |
+var itemRemovedCallback = null; |
+function itemRemovedListener(removed) { |
+ if (null != itemRemovedCallback) { |
+ itemRemovedCallback(removed); |
+ }; |
+}; |
+ |
+function removeItemRemovedListener() { |
+ chrome.experimental.history.onVisited.removeListener(itemRemovedListener); |
+ itemRemovedCallback = null; |
+} |
+ |
+function setItemRemovedListener(callback) { |
+ chrome.experimental.history.onVisitRemoved.addListener(itemRemovedListener); |
+ itemRemovedCallback = callback; |
+} |
+ |
+function setNextItemRemovedListener(callback) { |
+ itemRemovedCallback = callback; |
+} |
+ |
+/** |
+* An object used for listening to the chrome.history.onVisitRemoved events. Set |
+* 'tabCompleteCallback' to a function to add extra processing to the callback. |
+* The global object 'tabsCompleteData' contains a list of the last known state |
+* of every tab. |
+*/ |
+var tabCompleteCallback = null; |
+var tabsCompleteData = {}; |
+function tabsCompleteListener(tabId, changeInfo) { |
+ if (changeInfo && changeInfo.status) { |
+ tabsCompleteData[tabId] = changeInfo.status; |
+ }; |
+ if (null != tabCompleteCallback) { |
+ tabCompleteCallback(); |
+ }; |
+}; |
+ |
+/** |
+* Queries the entire history for items, calling the closure with an argument |
+* specifying the the number of items in the query. |
+* @param {function(number)} callback The closure. |
+*/ |
+function countItemsInHistory(callback) { |
+ var query = {'search': ''}; |
+ chrome.experimental.history.search(query, function(results) { |
+ callback(results.length); |
+ }); |
+}; |
+ |
+/** |
+* Populates the history by calling addUrl for each url in the array urls. |
+* @param {Array.<string>} urls The array of urls to populate the history. |
+* @param {function} callback Closure. |
+*/ |
+function populateHistory(urls, callback) { |
+ urls.forEach(function(url) { |
+ chrome.experimental.history.addUrl({ 'url': url }); |
+ }); |
+ callback(); |
+}; |
+ |
+chrome.test.runTests([ |
+ // All the tests require a blank state to start from. This test is run |
+ // first to insure that state can be acheived. |
+ function clearHistory() { |
+ chrome.experimental.history.deleteAll(pass(function() { |
+ countItemsInHistory(pass(function(count) { |
+ assertEq(0, count); |
+ })); |
+ })); |
+ }, |
+ |
+ function basicSearch() { |
+ // basicSearch callback. |
+ function basicSearchTestVerification() { |
+ removeItemVisitedListener(); |
+ var query = { 'search': '' }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(GOOGLE_URL, results[0].url); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ // basicSearch entry point. |
+ chrome.experimental.history.deleteAll(function() { |
+ setItemVisitedListener(basicSearchTestVerification); |
+ populateHistory([GOOGLE_URL], function() { }); |
+ }); |
+ }, |
+ |
+ function timeScopedSearch() { |
+ var startDate = {}; |
+ var endDate = {}; |
+ |
+ function timeScopedSearchTestVerification() { |
+ removeItemVisitedListener(); |
+ |
+ var query = { 'search': '', |
+ 'startTime': startDate.getTime(), |
+ 'endTime': endDate.getTime() }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(GOOGLE_URL, results[0].url); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ function onAddedItem() { |
+ // Set the next test callback. |
+ setNextItemVisitedListener(timeScopedSearchTestVerification); |
+ |
+ // Chrome has seconds resolution, so we must wait in order to search |
+ // a range. |
+ waitAFewSeconds(2, function() { |
+ endDate = new Date(); |
+ endDate.setTime(endDate.getTime() - 500); |
+ populateHistory([PICASA_URL], function() { }); |
+ }); |
+ }; |
+ |
+ // timeScopedSearch entry point. |
+ chrome.experimental.history.deleteAll(function() { |
+ // Set the test callback. |
+ setItemVisitedListener(onAddedItem); |
+ // Set the start time a few seconds in the past. |
+ startDate = new Date(); |
+ startDate.setTime(startDate.getTime() - 1000); |
+ populateHistory([GOOGLE_URL], function() { }); |
+ }); |
+ }, |
+ |
+ // Give time epochs x,y,z and history events A,B which occur in the sequence |
+ // x A y B z, this test scopes the search to the interval [y,z] to test that |
+ // [x,y) is excluded. The previous test scoped to the interval [x,y]. |
+ function timeScopedSearch2() { |
+ var startDate = {}; |
+ var endDate = {}; |
+ |
+ function timeScopedSearch2TestVerification() { |
+ removeItemVisitedListener(); |
+ |
+ endDate = new Date(); |
+ endDate.setTime(endDate.getTime() + 1000); |
+ var query = { 'search': '', |
+ 'startTime': startDate.getTime(), |
+ 'endTime': endDate.getTime() }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(PICASA_URL, results[0].url); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ function onAddedItem() { |
+ // Set the next test callback. |
+ setNextItemVisitedListener(timeScopedSearch2TestVerification); |
+ |
+ // Chrome has seconds resolution, so we must wait in order to search |
+ // a range. |
+ waitAFewSeconds(2, function() { |
+ startDate = new Date(); |
+ startDate.setTime(startDate.getTime() - 1000); |
+ populateHistory([PICASA_URL], function() { }); |
+ }); |
+ }; |
+ |
+ // timeScopedSearch entry point. |
+ chrome.experimental.history.deleteAll(function() { |
+ // Set the test callback. |
+ setItemVisitedListener(onAddedItem); |
+ populateHistory([GOOGLE_URL], function() { }); |
+ }); |
+ }, |
+ |
+ function lengthScopedSearch() { |
+ var urls = [GOOGLE_URL, PICASA_URL]; |
+ var urlsAdded = 0; |
+ |
+ function lengthScopedSearchTestVerification() { |
+ // Ensure all urls have been added. |
+ urlsAdded += 1; |
+ if (urlsAdded < urls.length) |
+ return; |
+ |
+ removeItemVisitedListener(); |
+ |
+ var query = { 'search': '', 'maxResults': 1 }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(PICASA_URL, results[0].url); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ // lengthScopedSearch entry point. |
+ chrome.experimental.history.deleteAll(function() { |
+ setItemVisitedListener(lengthScopedSearchTestVerification); |
+ populateHistory(urls, function() { }); |
+ }); |
+ }, |
+ |
+ function fullTextSearch() { |
+ chrome.experimental.history.deleteAll(function() { |
+ // The continuation of the test after the windows have been opened. |
+ var validateTest = function() { |
+ // Continue with the test. |
+ // A title search for www.a.com should find a. |
+ var query = { 'search': 'www.a.com' }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(A_RELATIVE_URL, results[0].url); |
+ |
+ // Text in the body of b.html. |
+ query = { 'search': 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(B_RELATIVE_URL, results[0].url); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }); |
+ }; |
+ |
+ // Setup a callback object for tab events. |
+ var urls = [A_RELATIVE_URL, B_RELATIVE_URL]; |
+ var tabIds = []; |
+ |
+ function listenerCallback() { |
+ if (tabIds.length < urls.length) { |
+ return; |
+ }; |
+ |
+ // Ensure both tabs have completed loading. |
+ for (var index = 0, id; id = tabIds[index]; index++) { |
+ if (!tabsCompleteData[id] || |
+ tabsCompleteData[id] != 'complete') { |
+ return; |
+ }; |
+ }; |
+ |
+ // Unhook callbacks. |
+ tabCompleteCallback = null; |
+ chrome.tabs.onUpdated.removeListener(tabsCompleteListener); |
+ |
+ // Allow indexing to occur. |
+ waitAFewSeconds(2, function() { |
+ validateTest(); |
+ }); |
+ }; |
+ |
+ tabCompleteCallback = listenerCallback; |
+ chrome.tabs.onUpdated.addListener(tabsCompleteListener); |
+ |
+ // Navigate to a few pages. |
+ urls.forEach(function(url) { |
+ chrome.tabs.create({ 'url': url }, function(tab) { |
+ tabIds.push(tab.id); |
+ }); |
+ }); |
+ }); |
+ }, |
+ |
+ function getVisits() { |
+ // getVisits callback. |
+ function getVisitsTestVerification() { |
+ removeItemVisitedListener(); |
+ |
+ // Verify that we received the url. |
+ var query = { 'search': '' }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(GOOGLE_URL, results[0].url); |
+ |
+ var id = results[0].id; |
+ chrome.experimental.history.getVisits({ 'url': GOOGLE_URL }, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(id, results[0].id); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }); |
+ }; |
+ |
+ // getVisits entry point. |
+ chrome.experimental.history.deleteAll(function() { |
+ setItemVisitedListener(getVisitsTestVerification); |
+ populateHistory([GOOGLE_URL], function() { }); |
+ }); |
+ }, |
+ |
+ function deleteUrl() { |
+ function deleteUrlTestVerification() { |
+ removeItemRemovedListener(); |
+ |
+ var query = { 'search': '' }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(0, results.length); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ function onAddedItem() { |
+ removeItemVisitedListener(); |
+ |
+ var query = { 'search': '' }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(GOOGLE_URL, results[0].url); |
+ |
+ chrome.experimental.history.deleteUrl({ 'url': GOOGLE_URL }); |
+ }); |
+ }; |
+ |
+ // deleteUrl entry point. |
+ chrome.experimental.history.deleteAll(function() { |
+ setItemVisitedListener(onAddedItem); |
+ setItemRemovedListener(deleteUrlTestVerification); |
+ populateHistory([GOOGLE_URL], function() { }); |
+ }); |
+ }, |
+ |
+ function deleteRange() { |
+ var urls = [GOOGLE_URL, PICASA_URL]; |
+ var startDate = {}; |
+ var endDate = {}; |
+ var itemsAdded = 0; |
+ |
+ function deleteRangeTestVerification() { |
+ removeItemRemovedListener(); |
+ |
+ var query = { 'search': '' }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(PICASA_URL, results[0].url); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ function onAddedItem() { |
+ itemsAdded += 1; |
+ |
+ if (itemsAdded < urls.length) { |
+ // Chrome has seconds resolution, so we must wait to search a range. |
+ waitAFewSeconds(2, function() { |
+ endDate = new Date(); |
+ endDate.setTime(endDate.getTime() - 1000); |
+ populateHistory([urls[itemsAdded]], function() { }); |
+ }); |
+ return; |
+ }; |
+ |
+ removeItemVisitedListener(); |
+ chrome.experimental.history.deleteRange({ 'startTime': startDate.getTime(), |
+ 'endTime': endDate.getTime() }, |
+ function() { }); |
+ }; |
+ |
+ // deletRange entry point. |
+ chrome.experimental.history.deleteAll(function() { |
+ setItemVisitedListener(onAddedItem); |
+ setItemRemovedListener(deleteRangeTestVerification); |
+ |
+ startDate = new Date(); |
+ startDate.setTime(startDate.getTime() - 1000); |
+ |
+ populateHistory([urls[itemsAdded]], function() { }); |
+ }); |
+ }, |
+ |
+ // Suppose we have time epochs x,y,z and history events A,B which occur in the |
+ // sequence x A y B z. The previous deleteRange test deleted the range [x,y], |
+ // this test deletes the range [y,z]. |
+ function deleteRange2() { |
+ var urls = [GOOGLE_URL, PICASA_URL]; |
+ var startDate = {}; |
+ var endDate = {}; |
+ var itemsAdded = 0; |
+ |
+ function deleteRange2TestVerification() { |
+ removeItemRemovedListener(); |
+ |
+ var query = { 'search': '' }; |
+ chrome.experimental.history.search(query, function(results) { |
+ assertEq(1, results.length); |
+ assertEq(GOOGLE_URL, results[0].url); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ function onAddedItem() { |
+ itemsAdded += 1; |
+ |
+ if (itemsAdded < urls.length) { |
+ // Chrome has seconds resolution, so we must wait to search a range. |
+ waitAFewSeconds(2, function() { |
+ startDate = new Date(); |
+ startDate.setTime(startDate.getTime() - 1000); |
+ populateHistory([urls[itemsAdded]], function() { }); |
+ }); |
+ return; |
+ }; |
+ |
+ removeItemVisitedListener(); |
+ |
+ endDate = new Date(); |
+ endDate.setTime(endDate.getTime() + 1000); |
+ chrome.experimental.history.deleteRange({ 'startTime': startDate.getTime(), |
+ 'endTime': endDate.getTime() }, |
+ function() { }); |
+ }; |
+ |
+ // deletRange entry point. |
+ chrome.experimental.history.deleteAll(function() { |
+ setItemVisitedListener(onAddedItem); |
+ setItemRemovedListener(deleteRange2TestVerification); |
+ populateHistory([urls[itemsAdded]], function() { }); |
+ }); |
+ }, |
+ |
+ // This test has the following format. From the main entry point we |
+ // attach a listener and give that listener a state to callback on. After |
+ // receipt of the first message we validate it is as excepted in |
+ // 'firsPageVisit.' We update the callback to 'secondPageVisit' and modify |
+ //the history. |
+ function listenForAdd() { |
+ function secondPageVisit(visited) { |
+ // Update state machine. |
+ itemVisitedCallback = null; |
+ chrome.experimental.history.onVisited.removeListener(itemVisitedListener); |
+ |
+ // Validate the state. |
+ countItemsInHistory(function(count) { |
+ assertEq(2, count); |
+ assertEq(PICASA_URL, visited.url); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ function firstPageVisit(visited) { |
+ // Update state machine. |
+ itemVisitedCallback = secondPageVisit; |
+ |
+ // Validate the state. |
+ countItemsInHistory(function(count) { |
+ assertEq(1, count); |
+ assertEq(GOOGLE_URL, visited.url); |
+ |
+ // Transistion to next state. |
+ populateHistory([PICASA_URL], function() { |
+ }); |
+ }); |
+ }; |
+ |
+ // Populate the history one item at a time. |
+ itemVisitedCallback = firstPageVisit; |
+ chrome.experimental.history.onVisited.addListener(itemVisitedListener); |
+ |
+ chrome.experimental.history.deleteAll(function() { |
+ populateHistory([GOOGLE_URL], function() { |
+ }); |
+ }); |
+ }, |
+ |
+ function listenForDelete() { |
+ var urls = [GOOGLE_URL, PICASA_URL]; |
+ var visited_urls = {}; |
+ |
+ // Callback for deletions. |
+ function deleteRangeCallback(removed) { |
+ // We will no longer need to listen to deletions. |
+ itemRemovedCallback = null; |
+ chrome.experimental.history.onVisitRemoved.removeListener( |
+ itemRemovedListener); |
+ |
+ // The two added urls should have been deleted together. |
+ assertEq(false, removed.allHistory); |
+ assertEq(2, removed.urls.length); |
+ |
+ // History should be empty. |
+ countItemsInHistory(function(count) { |
+ assertEq(0, count); |
+ |
+ // The test has succeeded. |
+ chrome.test.succeed(); |
+ }); |
+ }; |
+ |
+ // Callback for page visits. |
+ function historyPopulatedCallback(visited) { |
+ visited_urls[visited_urls.length] = visited.url; |
+ |
+ if (visited_urls.length < urls.length) { |
+ return; |
+ } |
+ |
+ // We will no longer need to listen to visits. |
+ itemVisitedCallback = null; |
+ chrome.experimental.history.onVisited.removeListener(itemVisitedListener); |
+ countItemsInHistory(function(count) { |
+ assertEq(2, count); |
+ |
+ var startDate = new Date(); |
+ startDate.setDate(startDate.getDate() - 1); |
+ var endDate = new Date(); |
+ chrome.experimental.history.deleteRange( |
+ { 'startTime': startDate.getTime(), 'endTime': endDate.getTime() }, |
+ function() { }); |
+ }); |
+ }; |
+ |
+ // We must be called back after the initial |
+ itemVisitedCallback = historyPopulatedCallback; |
+ chrome.experimental.history.onVisited.addListener(itemVisitedListener); |
+ |
+ chrome.experimental.history.deleteAll(function() { |
+ // Do not add the listener until after we have reset the state of history. |
+ itemRemovedCallback = deleteRangeCallback; |
+ chrome.experimental.history.onVisitRemoved.addListener( |
+ itemRemovedListener); |
+ |
+ // This call triggers the onVisited event handler. |
+ populateHistory(urls, function() { }); |
+ }); |
+ }, |
+]); |
Property changes on: chrome\test\data\extensions\api_test\history\test.js |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |