toolkit/mozapps/extensions/test/browser/browser_searching.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:503a16aae34e
1 /* Any copyright is dedicated to the Public Domain.
2 * http://creativecommons.org/publicdomain/zero/1.0/
3 */
4
5 // Tests that searching for add-ons works correctly
6
7 const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url";
8 const SEARCH_URL = TESTROOT + "browser_searching.xml";
9 const NO_MATCH_URL = TESTROOT + "browser_searching_empty.xml";
10
11 const QUERY = "SEARCH";
12 const NO_MATCH_QUERY = "NOMATCHQUERY";
13 const REMOTE_TO_INSTALL = "remote1";
14 const REMOTE_INSTALL_URL = TESTROOT + "addons/browser_searching.xpi";
15
16 var gManagerWindow;
17 var gCategoryUtilities;
18 var gProvider;
19 var gServer;
20 var gAddonInstalled = false;
21
22 function test() {
23 requestLongerTimeout(2);
24 // Turn on searching for this test
25 Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
26 Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
27
28 waitForExplicitFinish();
29
30 gProvider = new MockProvider();
31
32 gProvider.createAddons([{
33 id: "addon1@tests.mozilla.org",
34 name: "PASS - f",
35 description: "Test description - SEARCH",
36 size: 3,
37 version: "1.0",
38 updateDate: new Date(2010, 4, 2, 0, 0, 1)
39 }, {
40 id: "fail-addon1@tests.mozilla.org",
41 name: "FAIL",
42 description: "Does not match query"
43 }, {
44 id: "addon2@tests.mozilla.org",
45 name: "PASS - c",
46 description: "Test description - reSEARCHing SEARCH SEARCH",
47 size: 6,
48 version: "2.0",
49 updateDate: new Date(2010, 4, 2, 0, 0, 0)
50 }]);
51
52 var installs = gProvider.createInstalls([{
53 name: "PASS - a - SEARCHing",
54 sourceURI: "http://example.com/install1.xpi"
55 }, {
56 name: "PASS - g - reSEARCHing SEARCH",
57 sourceURI: "http://example.com/install2.xpi"
58 }, {
59 // Does not match query
60 name: "FAIL",
61 sourceURI: "http://example.com/fail-install1.xpi"
62 }]);
63
64 for (let install of installs )
65 install.install();
66
67 open_manager("addons://list/extension", function(aWindow) {
68 gManagerWindow = aWindow;
69 gCategoryUtilities = new CategoryUtilities(gManagerWindow);
70 run_next_test();
71 });
72 }
73
74 function end_test() {
75 close_manager(gManagerWindow, function() {
76 var installedAddon = get_addon_item(REMOTE_TO_INSTALL).mAddon;
77 installedAddon.uninstall();
78
79 AddonManager.getAllInstalls(function(aInstallsList) {
80 for (var install of aInstallsList) {
81 var sourceURI = install.sourceURI.spec;
82 if (sourceURI == REMOTE_INSTALL_URL ||
83 sourceURI.match(/^http:\/\/example\.com\/(.+)\.xpi$/) != null)
84 install.cancel();
85 }
86
87 finish();
88 });
89 });
90 }
91
92 function getAnonymousElementByAttribute(aElement, aName, aValue) {
93 return gManagerWindow.document.getAnonymousElementByAttribute(aElement,
94 aName,
95 aValue);
96 }
97
98 /*
99 * Checks whether or not the Add-ons Manager is currently searching
100 *
101 * @param aExpectedSearching
102 * The expected isSearching state
103 */
104 function check_is_searching(aExpectedSearching) {
105 var loading = gManagerWindow.document.getElementById("search-loading");
106 is(!is_hidden(loading), aExpectedSearching,
107 "Search throbber should be showing iff currently searching");
108 }
109
110 /*
111 * Completes a search
112 *
113 * @param aQuery
114 * The query to search for
115 * @param aFinishImmediately
116 * Boolean representing whether or not the search is expected to
117 * finish immediately
118 * @param aCallback
119 * The callback to call when the search is done
120 * @param aCategoryType
121 * The expected selected category after the search is done.
122 * Optional and defaults to "search"
123 */
124 function search(aQuery, aFinishImmediately, aCallback, aCategoryType) {
125 // Point search to the correct xml test file
126 var url = (aQuery == NO_MATCH_QUERY) ? NO_MATCH_URL : SEARCH_URL;
127 Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, url);
128
129 aCategoryType = aCategoryType ? aCategoryType : "search";
130
131 var searchBox = gManagerWindow.document.getElementById("header-search");
132 searchBox.value = aQuery;
133
134 EventUtils.synthesizeMouseAtCenter(searchBox, { }, gManagerWindow);
135 EventUtils.synthesizeKey("VK_RETURN", { }, gManagerWindow);
136
137 var finishImmediately = true;
138 wait_for_view_load(gManagerWindow, function() {
139 is(gCategoryUtilities.selectedCategory, aCategoryType, "Expected category view should be selected");
140 is(gCategoryUtilities.isTypeVisible("search"), aCategoryType == "search",
141 "Search category should only be visible if it is the current view");
142 check_is_searching(false);
143 is(finishImmediately, aFinishImmediately, "Search should finish immediately only if expected");
144
145 aCallback();
146 });
147
148 finishImmediately = false
149 if (!aFinishImmediately)
150 check_is_searching(true);
151 }
152
153 /*
154 * Return results of a search
155 *
156 * @return Array of objects, each containing the name and item of a specific
157 * result
158 */
159 function get_actual_results() {
160 var list = gManagerWindow.document.getElementById("search-list");
161 var rows = list.getElementsByTagName("richlistitem");
162
163 var results = [];
164 for (var item of rows) {
165
166 // Only consider items that are currently showing
167 var style = gManagerWindow.document.defaultView.getComputedStyle(item, "");
168 if (style.display == "none" || style.visibility != "visible")
169 continue;
170
171 if (item.mInstall || item.isPending("install")) {
172 var sourceURI = item.mInstall.sourceURI.spec;
173 if (sourceURI == REMOTE_INSTALL_URL) {
174 results.push({name: REMOTE_TO_INSTALL, item: item});
175 continue;
176 }
177
178 var result = sourceURI.match(/^http:\/\/example\.com\/(.+)\.xpi$/);
179 if (result != null) {
180 is(item.mInstall.name.indexOf("PASS"), 0, "Install name should start with PASS");
181 results.push({name: result[1], item: item});
182 continue;
183 }
184 }
185 else if (item.mAddon) {
186 var result = item.mAddon.id.match(/^(.+)@tests\.mozilla\.org$/);
187 if (result != null) {
188 is(item.mAddon.name.indexOf("PASS"), 0, "Addon name should start with PASS");
189 results.push({name: result[1], item: item});
190 continue;
191 }
192 }
193 else {
194 ok(false, "Found an item in the list that was neither installing or installed");
195 }
196 }
197
198 return results;
199 }
200
201 /*
202 * Returns expected results when searching for QUERY with default ordering
203 *
204 * @param aSortBy
205 * How the results are sorted (e.g. "name")
206 * @param aLocalExpected
207 * Boolean representing if local results are expected
208 * @return A pair: [array of results with an expected order,
209 * array of results with unknown order]
210 */
211 function get_expected_results(aSortBy, aLocalExpected) {
212 var expectedOrder = null, unknownOrder = null;
213 switch (aSortBy) {
214 case "relevancescore":
215 expectedOrder = [ "addon2" , "remote1", "install2", "addon1",
216 "install1", "remote2", "remote3" , "remote4" ];
217 unknownOrder = [];
218 break;
219 case "name":
220 // Defaults to ascending order
221 expectedOrder = [ "install1", "remote1", "addon2" , "remote2",
222 "remote3" , "addon1" , "install2", "remote4" ];
223 unknownOrder = [];
224 break;
225 case "dateUpdated":
226 expectedOrder = [ "addon1", "addon2" ];
227 // Updated date not available for installs and remote add-ons
228 unknownOrder = [ "install1", "install2", "remote1",
229 "remote2" , "remote3" , "remote4" ];
230 break;
231 default:
232 ok(false, "Should recognize sortBy when checking the order of items");
233 }
234
235 // Only keep expected results
236 function filterResults(aId) {
237 // Include REMOTE_TO_INSTALL as a local add-on if it has been installed
238 if (gAddonInstalled && aId == REMOTE_TO_INSTALL)
239 return aLocalExpected;
240
241 if (aId.indexOf("addon") == 0 || aId.indexOf("install") == 0)
242 return aLocalExpected;
243 if (aId.indexOf("remote") == 0)
244 return !aLocalExpected;
245
246 return false;
247 }
248
249
250 return [expectedOrder.filter(filterResults),
251 unknownOrder.filter(filterResults)]
252 }
253
254 /*
255 * Check that the actual and expected results are the same
256 *
257 * @param aQuery
258 * The search query used
259 * @param aSortBy
260 * How the results are sorted (e.g. "name")
261 * @param aReverseOrder
262 * Boolean representing if the results are in reverse default order
263 * @param aShowLocal
264 * Boolean representing if local results are being shown
265 */
266 function check_results(aQuery, aSortBy, aReverseOrder, aShowLocal) {
267
268 var xpinstall_enabled = true;
269 try {
270 xpinstall_enabled = Services.prefs.getBoolPref(PREF_XPI_ENABLED);
271 }
272 catch (e) {};
273
274 // When XPI Instalation is disabled, those buttons are hidden and unused
275 if (xpinstall_enabled) {
276 var localFilterSelected = gManagerWindow.document.getElementById("search-filter-local").selected;
277 var remoteFilterSelected = gManagerWindow.document.getElementById("search-filter-remote").selected;
278 is(localFilterSelected, aShowLocal, "Local filter should be selected if showing local items");
279 is(remoteFilterSelected, !aShowLocal, "Remote filter should be selected if showing remote items");
280 }
281
282 // Get expected order assuming default order
283 var expectedOrder = [], unknownOrder = [];
284 if (aQuery == QUERY)
285 [expectedOrder, unknownOrder] = get_expected_results(aSortBy, aShowLocal);
286
287 // Get actual order of results
288 var actualResults = get_actual_results();
289 var actualOrder = [result.name for each(result in actualResults)];
290
291 // Reverse array of actual results if supposed to be in reverse order.
292 // Reverse actualOrder instead of expectedOrder so can always check
293 // expectedOrder before unknownOrder
294 if (aReverseOrder)
295 actualOrder.reverse();
296
297 // Check actual vs. expected list of results
298 var totalExpectedResults = expectedOrder.length + unknownOrder.length;
299 is(actualOrder.length, totalExpectedResults, "Should get correct number of results");
300
301 // Check the "first" and "last" attributes are set correctly
302 for (let i = 0; i < actualResults.length; i++) {
303 if (i == 0) {
304 is(actualResults[0].item.hasAttribute("first"), true,
305 "First item should have 'first' attribute set");
306 is(actualResults[0].item.hasAttribute("last"), false,
307 "First item should not have 'last' attribute set");
308 } else if (i == (actualResults.length - 1)) {
309 is(actualResults[actualResults.length - 1].item.hasAttribute("first"), false,
310 "Last item should not have 'first' attribute set");
311 is(actualResults[actualResults.length - 1].item.hasAttribute("last"), true,
312 "Last item should have 'last' attribute set");
313 } else {
314 is(actualResults[i].item.hasAttribute("first"), false,
315 "Item " + i + " should not have 'first' attribute set");
316 is(actualResults[i].item.hasAttribute("last"), false,
317 "Item " + i + " should not have 'last' attribute set");
318 }
319 }
320
321 var i = 0;
322 for (; i < expectedOrder.length; i++)
323 is(actualOrder[i], expectedOrder[i], "Should have seen expected item");
324
325 // Items with data that is unknown can appear in any order among themselves,
326 // so just check that these items exist
327 for (; i < actualOrder.length; i++) {
328 var unknownOrderIndex = unknownOrder.indexOf(actualOrder[i]);
329 ok(unknownOrderIndex >= 0, "Should expect to see item with data that is unknown");
330 unknownOrder[unknownOrderIndex] = null;
331 }
332
333 // Check status of empty notice
334 var emptyNotice = gManagerWindow.document.getElementById("search-list-empty");
335 is(emptyNotice.hidden, totalExpectedResults > 0,
336 "Empty notice should be hidden only if expecting shown items");
337 }
338
339 /*
340 * Check results of a search with different filterings
341 *
342 * @param aQuery
343 * The search query used
344 * @param aSortBy
345 * How the results are sorted (e.g. "name")
346 * @param aReverseOrder
347 * Boolean representing if the results are in reverse default order
348 * @param aLocalOnly
349 * Boolean representing if the results are local only, can be undefined
350 */
351 function check_filtered_results(aQuery, aSortBy, aReverseOrder, aLocalOnly) {
352 var localFilter = gManagerWindow.document.getElementById("search-filter-local");
353 var remoteFilter = gManagerWindow.document.getElementById("search-filter-remote");
354
355 var list = gManagerWindow.document.getElementById("search-list");
356 list.ensureElementIsVisible(localFilter);
357
358 // Check with showing local add-ons
359 EventUtils.synthesizeMouseAtCenter(localFilter, { }, gManagerWindow);
360 check_results(aQuery, aSortBy, aReverseOrder, true);
361
362 // Check with showing remote add-ons
363 aLocalOnly = aLocalOnly || false;
364 EventUtils.synthesizeMouseAtCenter(remoteFilter, { }, gManagerWindow);
365 check_results(aQuery, aSortBy, aReverseOrder, aLocalOnly);
366 }
367
368 /*
369 * Get item for a specific add-on by name
370 *
371 * @param aName
372 * The name of the add-on to search for
373 * @return Row of add-on if found, null otherwise
374 */
375 function get_addon_item(aName) {
376 var id = aName + "@tests.mozilla.org";
377 var list = gManagerWindow.document.getElementById("search-list");
378 var rows = list.getElementsByTagName("richlistitem");
379 for (var row of rows) {
380 if (row.mAddon && row.mAddon.id == id)
381 return row;
382 }
383
384 return null;
385 }
386
387 /*
388 * Get item for a specific install by name
389 *
390 * @param aName
391 * The name of the install to search for
392 * @return Row of install if found, null otherwise
393 */
394 function get_install_item(aName) {
395 var sourceURI = "http://example.com/" + aName + ".xpi";
396 var list = gManagerWindow.document.getElementById("search-list");
397 var rows = list.getElementsByTagName("richlistitem");
398 for (var row of rows) {
399 if (row.mInstall && row.mInstall.sourceURI.spec == sourceURI)
400 return row;
401 }
402
403 return null;
404 }
405
406 /*
407 * Gets the install button for a specific item
408 *
409 * @param aItem
410 * The item to get the install button for
411 * @return The install button for aItem
412 */
413 function get_install_button(aItem) {
414 isnot(aItem, null, "Item should not be null when checking state of install button");
415 var installStatus = getAnonymousElementByAttribute(aItem, "anonid", "install-status");
416 return getAnonymousElementByAttribute(installStatus, "anonid", "install-remote-btn");
417 }
418
419
420 // Tests that searching for the empty string does nothing when not in the search view
421 add_test(function() {
422 is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should initially be hidden");
423
424 var selectedCategory = gCategoryUtilities.selectedCategory;
425 isnot(selectedCategory, "search", "Selected type should not initially be the search view");
426 search("", true, run_next_test, selectedCategory);
427 });
428
429 // Tests that the results from a query are sorted by relevancescore in descending order.
430 // Also test that double clicking non-install items goes to the detail view, and that
431 // only remote items have install buttons showing
432 add_test(function() {
433 search(QUERY, false, function() {
434 check_filtered_results(QUERY, "relevancescore", false);
435
436 var list = gManagerWindow.document.getElementById("search-list");
437 var results = get_actual_results();
438 for (var result of results) {
439 var installBtn = get_install_button(result.item);
440 is(installBtn.hidden, result.name.indexOf("remote") != 0,
441 "Install button should only be showing for remote items");
442 }
443
444 var currentIndex = -1;
445 function run_next_double_click_test() {
446 currentIndex++;
447 if (currentIndex >= results.length) {
448 run_next_test();
449 return;
450 }
451
452 var result = results[currentIndex];
453 if (result.name.indexOf("install") == 0) {
454 run_next_double_click_test();
455 return;
456 }
457
458 var item = result.item;
459 list.ensureElementIsVisible(item);
460 EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, gManagerWindow);
461 EventUtils.synthesizeMouseAtCenter(item, { clickCount: 2 }, gManagerWindow);
462 wait_for_view_load(gManagerWindow, function() {
463 var name = gManagerWindow.document.getElementById("detail-name").textContent;
464 is(name, item.mAddon.name, "Name in detail view should be correct");
465 var version = gManagerWindow.document.getElementById("detail-version").value;
466 is(version, item.mAddon.version, "Version in detail view should be correct");
467
468 EventUtils.synthesizeMouseAtCenter(gManagerWindow.document.getElementById("category-search"),
469 { }, gManagerWindow);
470 wait_for_view_load(gManagerWindow, run_next_double_click_test);
471 });
472 }
473
474 run_next_double_click_test();
475 });
476 });
477
478 // Tests that the sorters and filters correctly manipulate the results
479 add_test(function() {
480 var sorters = gManagerWindow.document.getElementById("search-sorters");
481 var originalHandler = sorters.handler;
482
483 var sorterNames = ["name", "dateUpdated"];
484 var buttonIds = ["name-btn", "date-btn"];
485 var currentIndex = 0;
486 var currentReversed = false;
487
488 function run_sort_test() {
489 if (currentIndex >= sorterNames.length) {
490 sorters.handler = originalHandler;
491 run_next_test();
492 return;
493 }
494
495 // Simulate clicking on a specific sorter
496 var buttonId = buttonIds[currentIndex];
497 var sorter = getAnonymousElementByAttribute(sorters, "anonid", buttonId);
498 is_element_visible(sorter);
499 EventUtils.synthesizeMouseAtCenter(sorter, { }, gManagerWindow);
500 }
501
502 sorters.handler = {
503 onSortChanged: function(aSortBy, aAscending) {
504 if (originalHandler && "onSortChanged" in originalHandler)
505 originalHandler.onSortChanged(aSortBy, aAscending);
506
507 check_filtered_results(QUERY, sorterNames[currentIndex], currentReversed);
508
509 if (currentReversed)
510 currentIndex++;
511 currentReversed = !currentReversed;
512
513 run_sort_test();
514 }
515 };
516
517 check_filtered_results(QUERY, "relevancescore", false);
518 run_sort_test();
519 });
520
521 // Tests that searching for the empty string does nothing when in search view
522 add_test(function() {
523 search("", true, function() {
524 check_filtered_results(QUERY, "dateUpdated", true);
525 run_next_test();
526 });
527 });
528
529 // Tests that clicking a different category hides the search query
530 add_test(function() {
531 gCategoryUtilities.openType("extension", function() {
532 is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should be hidden");
533 is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension");
534 run_next_test();
535 });
536 });
537
538 // Tests that re-searching for query doesn't actually complete a new search,
539 // and the last sort is still used
540 add_test(function() {
541 search(QUERY, true, function() {
542 check_filtered_results(QUERY, "dateUpdated", true);
543 run_next_test();
544 });
545 });
546
547 // Tests that getting zero results works correctly
548 add_test(function() {
549 search(NO_MATCH_QUERY, false, function() {
550 check_filtered_results(NO_MATCH_QUERY, "relevancescore", false);
551 run_next_test();
552 });
553 });
554
555 // Tests that installing a remote add-on works
556 add_test(function() {
557 var installBtn = null;
558
559 var listener = {
560 onInstallEnded: function(aInstall, aAddon) {
561 // Don't immediately consider the installed add-on as local because
562 // if the user was filtering out local add-ons, the installed add-on
563 // would vanish. Only consider add-on as local on new searches.
564
565 aInstall.removeListener(this);
566
567 is(installBtn.hidden, true, "Install button should be hidden after install ended");
568 check_filtered_results(QUERY, "relevancescore", false);
569 run_next_test();
570 }
571 }
572
573 search(QUERY, false, function() {
574 var list = gManagerWindow.document.getElementById("search-list");
575 var remoteItem = get_addon_item(REMOTE_TO_INSTALL);
576 list.ensureElementIsVisible(remoteItem);
577
578 installBtn = get_install_button(remoteItem);
579 is(installBtn.hidden, false, "Install button should be showing before install");
580 remoteItem.mAddon.install.addListener(listener);
581 EventUtils.synthesizeMouseAtCenter(installBtn, { }, gManagerWindow);
582 });
583 });
584
585 // Tests that re-searching for query results in correct results
586 add_test(function() {
587 // Select a different category
588 gCategoryUtilities.openType("extension", function() {
589 is(gCategoryUtilities.isTypeVisible("search"), false, "Search category should be hidden");
590 is(gCategoryUtilities.selectedCategory, "extension", "View should have changed to extension");
591
592 var installBtn = get_install_button(get_addon_item(REMOTE_TO_INSTALL));
593 is(installBtn.hidden, true, "Install button should be hidden for installed item");
594
595 search(QUERY, true, function() {
596 check_filtered_results(QUERY, "relevancescore", false);
597 run_next_test();
598 });
599 });
600 });
601
602 // Tests that incompatible add-ons are shown with a warning if compatibility checking is disabled
603 add_test(function() {
604 AddonManager.checkCompatibility = false;
605 search("incompatible", false, function() {
606 var item = get_addon_item("remote5");
607 is_element_visible(item, "Incompatible addon should be visible");
608 is(item.getAttribute("notification"), "warning", "Compatibility warning should be shown");
609
610 item = get_addon_item("remote6");
611 is(item, null, "Addon incompatible with the product should not be visible");
612
613 AddonManager.checkCompatibility = true;
614 run_next_test();
615 });
616 });
617
618 // Tests that compatible-by-default addons are shown if strict compatibility checking is disabled
619 add_test(function() {
620 restart_manager(gManagerWindow, null, function(aWindow) {
621 gManagerWindow = aWindow;
622 gCategoryUtilities = new CategoryUtilities(gManagerWindow);
623
624 Services.prefs.setBoolPref(PREF_STRICT_COMPAT, false);
625 search("incompatible", false, function() {
626 var item = get_addon_item("remote5");
627 is_element_visible(item, "Incompatible addon should be visible");
628 isnot(item.getAttribute("notification"), "warning", "Compatibility warning should not be shown");
629
630 var item = get_addon_item("remote6");
631 is(item, null, "Addon incompatible with the product should not be visible");
632
633 Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
634 run_next_test();
635 });
636 });
637 });
638
639
640 // Tests that restarting the manager doesn't change search results
641 add_test(function() {
642 restart_manager(gManagerWindow, null, function(aWindow) {
643 gManagerWindow = aWindow;
644 gCategoryUtilities = new CategoryUtilities(gManagerWindow);
645
646 // We never restore to the search pane
647 is(gCategoryUtilities.selectedCategory, "discover", "View should have changed to discover");
648
649 // Installed add-on is considered local on new search
650 gAddonInstalled = true;
651
652 search(QUERY, false, function() {
653 check_filtered_results(QUERY, "relevancescore", false);
654
655 var installBtn = get_install_button(get_addon_item(REMOTE_TO_INSTALL));
656 is(installBtn.hidden, true, "Install button should be hidden for installed item");
657
658 run_next_test();
659 });
660 });
661 });
662
663 function bug_815120_test_search(aLocalOnly) {
664 restart_manager(gManagerWindow, "addons://list/extension", function(aWindow) {
665 gManagerWindow = aWindow;
666 gCategoryUtilities = new CategoryUtilities(gManagerWindow);
667
668 // Installed add-on is considered local on new search
669 gAddonInstalled = true;
670
671 // The search buttons should be hidden in the LocalOnly setup
672 var localFilterButton = aWindow.document.getElementById("search-filter-local");
673 is(aLocalOnly, is_hidden(localFilterButton), "Local filter button visibility does not match, aLocalOnly = " + aLocalOnly);
674
675 var remoteFilterButton = aWindow.document.getElementById("search-filter-remote");
676 is(aLocalOnly, is_hidden(remoteFilterButton), "Remote filter button visibility does not match, aLocalOnly = " + aLocalOnly);
677
678 search(QUERY, false, function() {
679 check_filtered_results(QUERY, "relevancescore", false, aLocalOnly);
680 run_next_test();
681 });
682 });
683 }
684
685 // Tests for Bug 815120
686 add_test(function() {
687 Services.prefs.setBoolPref(PREF_XPI_ENABLED, false);
688 bug_815120_test_search(true);
689 });
690
691 add_test(function() {
692 Services.prefs.setBoolPref(PREF_XPI_ENABLED, true);
693 bug_815120_test_search(false);
694 });
695

mercurial