1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/places/tests/inline/head_autocomplete.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,199 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Ci = Components.interfaces; 1.9 +const Cc = Components.classes; 1.10 +const Cr = Components.results; 1.11 +const Cu = Components.utils; 1.12 + 1.13 +Cu.import("resource://gre/modules/Services.jsm"); 1.14 + 1.15 +// Import common head. 1.16 +let (commonFile = do_get_file("../head_common.js", false)) { 1.17 + let uri = Services.io.newFileURI(commonFile); 1.18 + Services.scriptloader.loadSubScript(uri.spec, this); 1.19 +} 1.20 + 1.21 +// Put any other stuff relative to this test folder below. 1.22 + 1.23 +XPCOMUtils.defineLazyServiceGetter(this, "gHistory", 1.24 + "@mozilla.org/browser/history;1", 1.25 + "mozIAsyncHistory"); 1.26 + 1.27 +/** 1.28 + * @param aSearches 1.29 + * Array of AutoCompleteSearch names. 1.30 + */ 1.31 +function AutoCompleteInput(aSearches) { 1.32 + this.searches = aSearches; 1.33 +} 1.34 +AutoCompleteInput.prototype = { 1.35 + searches: null, 1.36 + minResultsForPopup: 0, 1.37 + timeout: 10, 1.38 + searchParam: "", 1.39 + textValue: "", 1.40 + disableAutoComplete: false, 1.41 + 1.42 + completeDefaultIndex: true, 1.43 + defaultIndex: 0, 1.44 + 1.45 + // Text selection range 1.46 + _selStart: 0, 1.47 + _selEnd: 0, 1.48 + get selectionStart() { 1.49 + return this._selStart; 1.50 + }, 1.51 + get selectionEnd() { 1.52 + return this._selEnd; 1.53 + }, 1.54 + selectTextRange: function(aStart, aEnd) { 1.55 + this._selStart = aStart; 1.56 + this._selEnd = aEnd; 1.57 + }, 1.58 + 1.59 + onTextEntered: function() false, 1.60 + onTextReverted: function() false, 1.61 + 1.62 + get searchCount() { 1.63 + return this.searches.length; 1.64 + }, 1.65 + getSearchAt: function(aIndex) { 1.66 + return this.searches[aIndex]; 1.67 + }, 1.68 + 1.69 + onSearchBegin: function () {}, 1.70 + onSearchComplete: function () {}, 1.71 + 1.72 + popupOpen: false, 1.73 + 1.74 + popup: { 1.75 + selectedIndex: -1, 1.76 + invalidate: function () {}, 1.77 + 1.78 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompletePopup]) 1.79 + }, 1.80 + 1.81 + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput]) 1.82 +} 1.83 + 1.84 +/** 1.85 + * @param aSearchString 1.86 + * String to search. 1.87 + * @param aExpectedValue 1.88 + * Expected value returned by autoFill. 1.89 + * May be a string, or an object like 1.90 + * { 1.91 + * autoFilled: the value suggested by autofill, 1.92 + * completed: the value completed on user's confirmation 1.93 + * } 1.94 + * In the latter case this will also check that on user's confirmation 1.95 + * the result's casing is correctly applied. 1.96 + */ 1.97 +function ensure_results(aSearchString, aExpectedValue) { 1.98 + let autoFilledValue, completedValue; 1.99 + if (typeof(aExpectedValue) == "string") { 1.100 + autoFilledValue = aExpectedValue; 1.101 + } 1.102 + else { 1.103 + autoFilledValue = aExpectedValue.autoFilled; 1.104 + completedValue = aExpectedValue.completed; 1.105 + } 1.106 + 1.107 + // Make an AutoCompleteInput that uses our searches and confirms results. 1.108 + let input = new AutoCompleteInput(["urlinline"]); 1.109 + input.textValue = aSearchString; 1.110 + 1.111 + // Caret must be at the end for autoFill to happen. 1.112 + let strLen = aSearchString.length; 1.113 + input.selectTextRange(strLen, strLen); 1.114 + do_check_eq(input.selectionStart, strLen); 1.115 + do_check_eq(input.selectionEnd, strLen); 1.116 + 1.117 + let controller = Cc["@mozilla.org/autocomplete/controller;1"]. 1.118 + getService(Ci.nsIAutoCompleteController); 1.119 + controller.input = input; 1.120 + 1.121 + let numSearchesStarted = 0; 1.122 + input.onSearchBegin = function() { 1.123 + numSearchesStarted++; 1.124 + do_check_eq(numSearchesStarted, 1); 1.125 + }; 1.126 + 1.127 + input.onSearchComplete = function() { 1.128 + // We should be running only one query. 1.129 + do_check_eq(numSearchesStarted, 1); 1.130 + 1.131 + // Check the autoFilled result. 1.132 + do_check_eq(input.textValue, autoFilledValue); 1.133 + 1.134 + if (completedValue) { 1.135 + // Now force completion and check correct casing of the result. 1.136 + // This ensures the controller is able to do its magic case-preserving 1.137 + // stuff and correct replacement of the user's casing with result's one. 1.138 + controller.handleEnter(false); 1.139 + do_check_eq(input.textValue, completedValue); 1.140 + } 1.141 + 1.142 + waitForCleanup(run_next_test); 1.143 + }; 1.144 + 1.145 + do_log_info("Searching for: '" + aSearchString + "'"); 1.146 + controller.startSearch(aSearchString); 1.147 +} 1.148 + 1.149 +function run_test() { 1.150 + do_register_cleanup(function () { 1.151 + Services.prefs.clearUserPref("browser.urlbar.autocomplete.enabled"); 1.152 + Services.prefs.clearUserPref("browser.urlbar.autoFill"); 1.153 + Services.prefs.clearUserPref("browser.urlbar.autoFill.typed"); 1.154 + }); 1.155 + 1.156 + gAutoCompleteTests.forEach(function (testData) { 1.157 + let [description, searchString, expectedValue, setupFunc] = testData; 1.158 + add_test(function () { 1.159 + do_log_info(description); 1.160 + Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", true); 1.161 + Services.prefs.setBoolPref("browser.urlbar.autoFill", true); 1.162 + Services.prefs.setBoolPref("browser.urlbar.autoFill.typed", false); 1.163 + 1.164 + if (setupFunc) { 1.165 + setupFunc(); 1.166 + } 1.167 + 1.168 + // At this point frecency could still be updating due to latest pages 1.169 + // updates. 1.170 + // This is not a problem in real life, but autocomplete tests should 1.171 + // return reliable resultsets, thus we have to wait. 1.172 + promiseAsyncUpdates().then(function () ensure_results(searchString, 1.173 + expectedValue)); 1.174 + }) 1.175 + }, this); 1.176 + 1.177 + run_next_test(); 1.178 +} 1.179 + 1.180 +let gAutoCompleteTests = []; 1.181 +function add_autocomplete_test(aTestData) { 1.182 + gAutoCompleteTests.push(aTestData); 1.183 +} 1.184 + 1.185 +function waitForCleanup(aCallback) { 1.186 + remove_all_bookmarks(); 1.187 + promiseClearHistory().then(aCallback); 1.188 +} 1.189 + 1.190 +function addBookmark(aBookmarkObj) { 1.191 + do_check_true(!!aBookmarkObj.url); 1.192 + let parentId = aBookmarkObj.parentId ? aBookmarkObj.parentId 1.193 + : PlacesUtils.unfiledBookmarksFolderId; 1.194 + let itemId = PlacesUtils.bookmarks 1.195 + .insertBookmark(parentId, 1.196 + NetUtil.newURI(aBookmarkObj.url), 1.197 + PlacesUtils.bookmarks.DEFAULT_INDEX, 1.198 + "A bookmark"); 1.199 + if (aBookmarkObj.keyword) { 1.200 + PlacesUtils.bookmarks.setKeywordForBookmark(itemId, aBookmarkObj.keyword); 1.201 + } 1.202 +}