forked from mirrors/gecko-dev
Wikipedia suggestions from Rust don't have an `advertiser` property, unlike suggestions from the JS backend [1]. That causes an exception to be thrown when `UrlbarProviderQuickSuggest` tries to convert the advertister to lower case for telemetry. The result is that telemetry isn't properly recorded for Rust Wikipedia suggestions, and anything that happens after telemetry is supposed to be recorded doesn't actually happen, which means dismissals aren't handled. I fixed this by adding `advertiser` to Rust Wikipedia suggestions, and I modified the telemetry tests for sponsored and nonsponsored suggestions so they also run with Rust enabled. This tests the code path where the error was thrown. Running the telemetry tests with Rust enabled revealed some more problems that I also fixed: * Rust Wikipedia suggestions also don't have `iab_category`, so I added that to them too. * `_assertGleanPing()` in head.js wasn't checking a few properties, so I added them. Now it checks them all. * URLs in the Glean ping are declared with type `url`, which means our tests need to use valid URLs in their dummy data. The mock Merino server and some related tests are using invalid URL values like `"url"`, so I fixed that. [1] The suggestions data in remote settings does include an `advertiser`, so it's possible to consider this a bug in the Rust implementation, but IMO it makes sense for nonsponsored suggestions to lack an advertiser, and it's always set to `"Wikipedia"` anyway. Differential Revision: https://phabricator.services.mozilla.com/D191795
643 lines
20 KiB
JavaScript
643 lines
20 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
/* import-globals-from ../../unit/head.js */
|
|
/* eslint-disable jsdoc/require-param */
|
|
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
QuickSuggest: "resource:///modules/QuickSuggest.sys.mjs",
|
|
TelemetryTestUtils: "resource://testing-common/TelemetryTestUtils.sys.mjs",
|
|
UrlbarProviderAutofill: "resource:///modules/UrlbarProviderAutofill.sys.mjs",
|
|
UrlbarProviderQuickSuggest:
|
|
"resource:///modules/UrlbarProviderQuickSuggest.sys.mjs",
|
|
});
|
|
|
|
add_setup(async function setUpQuickSuggestXpcshellTest() {
|
|
// Initializing TelemetryEnvironment in an xpcshell environment requires
|
|
// jumping through a bunch of hoops. Suggest's use of TelemetryEnvironment is
|
|
// tested in browser tests, and there's no other necessary reason to wait for
|
|
// TelemetryEnvironment initialization in xpcshell tests, so just skip it.
|
|
UrlbarPrefs._testSkipTelemetryEnvironmentInit = true;
|
|
});
|
|
|
|
/**
|
|
* Adds two tasks: One with the Rust backend disabled and one with it enabled.
|
|
* The names of the task functions will be the name of the passed-in task
|
|
* function appended with "_rustDisabled" and "_rustEnabled" respectively. Call
|
|
* with the usual `add_task()` arguments.
|
|
*/
|
|
function add_tasks_with_rust(...args) {
|
|
let taskFnIndex = args.findIndex(a => typeof a == "function");
|
|
let taskFn = args[taskFnIndex];
|
|
|
|
for (let rustEnabled of [false, true]) {
|
|
let newTaskFn = async (...taskFnArgs) => {
|
|
info("Setting rustEnabled: " + rustEnabled);
|
|
UrlbarPrefs.set("quicksuggest.rustEnabled", rustEnabled);
|
|
info("Done setting rustEnabled: " + rustEnabled);
|
|
|
|
let rv;
|
|
try {
|
|
info("Calling original task function: " + taskFn.name);
|
|
rv = await taskFn(...taskFnArgs);
|
|
} finally {
|
|
info("Done calling original task function: " + taskFn.name);
|
|
info("Clearing rustEnabled");
|
|
UrlbarPrefs.clear("quicksuggest.rustEnabled");
|
|
info("Done clearing rustEnabled");
|
|
}
|
|
return rv;
|
|
};
|
|
|
|
Object.defineProperty(newTaskFn, "name", {
|
|
value: taskFn.name + (rustEnabled ? "_rustEnabled" : "_rustDisabled"),
|
|
});
|
|
let addTaskArgs = [...args];
|
|
addTaskArgs[taskFnIndex] = newTaskFn;
|
|
add_task(...addTaskArgs);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns an expected Wikipedia (non-sponsored) result that can be passed to
|
|
* `check_results()` regardless of whether the Rust backend is enabled.
|
|
*
|
|
* @returns {object}
|
|
* An object that can be passed to `check_results()`.
|
|
*/
|
|
function makeWikipediaResult({
|
|
source,
|
|
provider,
|
|
keyword = "wikipedia",
|
|
title = "Wikipedia Suggestion",
|
|
url = "http://example.com/wikipedia",
|
|
originalUrl = "http://example.com/wikipedia",
|
|
icon = null,
|
|
iconBlob = new Blob([new Uint8Array([])]),
|
|
impressionUrl = "http://example.com/wikipedia-impression",
|
|
clickUrl = "http://example.com/wikipedia-click",
|
|
blockId = 1,
|
|
advertiser = "Wikipedia",
|
|
iabCategory = "5 - Education",
|
|
suggestedIndex = -1,
|
|
isSuggestedIndexRelativeToGroup = true,
|
|
}) {
|
|
let result = {
|
|
suggestedIndex,
|
|
isSuggestedIndexRelativeToGroup,
|
|
type: UrlbarUtils.RESULT_TYPE.URL,
|
|
source: UrlbarUtils.RESULT_SOURCE.SEARCH,
|
|
heuristic: false,
|
|
payload: {
|
|
title,
|
|
url,
|
|
originalUrl,
|
|
displayUrl: url.replace(/^https:\/\//, ""),
|
|
isSponsored: false,
|
|
qsSuggestion: keyword,
|
|
sponsoredAdvertiser: "Wikipedia",
|
|
sponsoredIabCategory: "5 - Education",
|
|
helpUrl: QuickSuggest.HELP_URL,
|
|
helpL10n: {
|
|
id: "urlbar-result-menu-learn-more-about-firefox-suggest",
|
|
},
|
|
isBlockable: true,
|
|
blockL10n: {
|
|
id: "urlbar-result-menu-dismiss-firefox-suggest",
|
|
},
|
|
telemetryType: "adm_nonsponsored",
|
|
},
|
|
};
|
|
|
|
if (UrlbarPrefs.get("quickSuggestRustEnabled")) {
|
|
result.payload.source = source || "rust";
|
|
result.payload.provider = provider || "Wikipedia";
|
|
result.payload.iconBlob = iconBlob;
|
|
} else {
|
|
result.payload.source = source || "remote-settings";
|
|
result.payload.provider = provider || "AdmWikipedia";
|
|
result.payload.icon = icon;
|
|
result.payload.sponsoredImpressionUrl = impressionUrl;
|
|
result.payload.sponsoredClickUrl = clickUrl;
|
|
result.payload.sponsoredBlockId = blockId;
|
|
result.payload.sponsoredAdvertiser = advertiser;
|
|
result.payload.sponsoredIabCategory = iabCategory;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Returns an expected AMP (sponsored) result that can be passed to
|
|
* `check_results()` regardless of whether the Rust backend is enabled.
|
|
*
|
|
* @returns {object}
|
|
* An object that can be passed to `check_results()`.
|
|
*/
|
|
function makeAmpResult({
|
|
source,
|
|
provider,
|
|
keyword = "amp",
|
|
title = "AMP Suggestion",
|
|
url = "http://example.com/amp",
|
|
originalUrl = "http://example.com/amp",
|
|
icon = null,
|
|
iconBlob = new Blob([new Uint8Array([])]),
|
|
impressionUrl = "http://example.com/amp-impression",
|
|
clickUrl = "http://example.com/amp-click",
|
|
blockId = 1,
|
|
advertiser = "Amp",
|
|
iabCategory = "22 - Shopping",
|
|
suggestedIndex = -1,
|
|
isSuggestedIndexRelativeToGroup = true,
|
|
} = {}) {
|
|
let result = {
|
|
suggestedIndex,
|
|
isSuggestedIndexRelativeToGroup,
|
|
type: UrlbarUtils.RESULT_TYPE.URL,
|
|
source: UrlbarUtils.RESULT_SOURCE.SEARCH,
|
|
heuristic: false,
|
|
payload: {
|
|
title,
|
|
url,
|
|
originalUrl,
|
|
displayUrl: url.replace(/^https:\/\//, ""),
|
|
isSponsored: true,
|
|
qsSuggestion: keyword,
|
|
sponsoredImpressionUrl: impressionUrl,
|
|
sponsoredClickUrl: clickUrl,
|
|
sponsoredBlockId: blockId,
|
|
sponsoredAdvertiser: advertiser,
|
|
sponsoredIabCategory: iabCategory,
|
|
helpUrl: QuickSuggest.HELP_URL,
|
|
helpL10n: {
|
|
id: "urlbar-result-menu-learn-more-about-firefox-suggest",
|
|
},
|
|
isBlockable: true,
|
|
blockL10n: {
|
|
id: "urlbar-result-menu-dismiss-firefox-suggest",
|
|
},
|
|
telemetryType: "adm_sponsored",
|
|
descriptionL10n: { id: "urlbar-result-action-sponsored" },
|
|
},
|
|
};
|
|
|
|
if (UrlbarPrefs.get("quickSuggestRustEnabled")) {
|
|
result.payload.source = source || "rust";
|
|
result.payload.provider = provider || "Amp";
|
|
result.payload.iconBlob = iconBlob;
|
|
} else {
|
|
result.payload.source = source || "remote-settings";
|
|
result.payload.provider = provider || "AdmWikipedia";
|
|
result.payload.icon = icon;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Tests quick suggest prefs migrations.
|
|
*
|
|
* @param {object} options
|
|
* The options object.
|
|
* @param {object} options.testOverrides
|
|
* An object that modifies how migration is performed. It has the following
|
|
* properties, and all are optional:
|
|
*
|
|
* {number} migrationVersion
|
|
* Migration will stop at this version, so for example you can test
|
|
* migration only up to version 1 even when the current actual version is
|
|
* larger than 1.
|
|
* {object} defaultPrefs
|
|
* An object that maps pref names (relative to `browser.urlbar`) to
|
|
* default-branch values. These should be the default prefs for the given
|
|
* `migrationVersion` and will be set as defaults before migration occurs.
|
|
*
|
|
* @param {string} options.scenario
|
|
* The scenario to set at the time migration occurs.
|
|
* @param {object} options.expectedPrefs
|
|
* The expected prefs after migration: `{ defaultBranch, userBranch }`
|
|
* Pref names should be relative to `browser.urlbar`.
|
|
* @param {object} [options.initialUserBranch]
|
|
* Prefs to set on the user branch before migration ocurs. Use these to
|
|
* simulate user actions like disabling prefs or opting in or out of the
|
|
* online modal. Pref names should be relative to `browser.urlbar`.
|
|
*/
|
|
async function doMigrateTest({
|
|
testOverrides,
|
|
scenario,
|
|
expectedPrefs,
|
|
initialUserBranch = {},
|
|
}) {
|
|
info(
|
|
"Testing migration: " +
|
|
JSON.stringify({
|
|
testOverrides,
|
|
initialUserBranch,
|
|
scenario,
|
|
expectedPrefs,
|
|
})
|
|
);
|
|
|
|
function setPref(branch, name, value) {
|
|
switch (typeof value) {
|
|
case "boolean":
|
|
branch.setBoolPref(name, value);
|
|
break;
|
|
case "number":
|
|
branch.setIntPref(name, value);
|
|
break;
|
|
case "string":
|
|
branch.setCharPref(name, value);
|
|
break;
|
|
default:
|
|
Assert.ok(
|
|
false,
|
|
`Pref type not handled for setPref: ${name} = ${value}`
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
|
|
function getPref(branch, name) {
|
|
let type = typeof UrlbarPrefs.get(name);
|
|
switch (type) {
|
|
case "boolean":
|
|
return branch.getBoolPref(name);
|
|
case "number":
|
|
return branch.getIntPref(name);
|
|
case "string":
|
|
return branch.getCharPref(name);
|
|
default:
|
|
Assert.ok(false, `Pref type not handled for getPref: ${name} ${type}`);
|
|
break;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
let defaultBranch = Services.prefs.getDefaultBranch("browser.urlbar.");
|
|
let userBranch = Services.prefs.getBranch("browser.urlbar.");
|
|
|
|
// Set initial prefs. `initialDefaultBranch` are firefox.js values, i.e.,
|
|
// defaults immediately after startup and before any scenario update and
|
|
// migration happens.
|
|
UrlbarPrefs._updatingFirefoxSuggestScenario = true;
|
|
UrlbarPrefs.clear("quicksuggest.migrationVersion");
|
|
let initialDefaultBranch = {
|
|
"suggest.quicksuggest.nonsponsored": false,
|
|
"suggest.quicksuggest.sponsored": false,
|
|
"quicksuggest.dataCollection.enabled": false,
|
|
};
|
|
for (let name of Object.keys(initialDefaultBranch)) {
|
|
userBranch.clearUserPref(name);
|
|
}
|
|
for (let [branch, prefs] of [
|
|
[defaultBranch, initialDefaultBranch],
|
|
[userBranch, initialUserBranch],
|
|
]) {
|
|
for (let [name, value] of Object.entries(prefs)) {
|
|
if (value !== undefined) {
|
|
setPref(branch, name, value);
|
|
}
|
|
}
|
|
}
|
|
UrlbarPrefs._updatingFirefoxSuggestScenario = false;
|
|
|
|
// Update the scenario and check prefs twice. The first time the migration
|
|
// should happen, and the second time the migration should not happen and
|
|
// all the prefs should stay the same.
|
|
for (let i = 0; i < 2; i++) {
|
|
info(`Calling updateFirefoxSuggestScenario, i=${i}`);
|
|
|
|
// Do the scenario update and set `isStartup` to simulate startup.
|
|
await UrlbarPrefs.updateFirefoxSuggestScenario({
|
|
...testOverrides,
|
|
scenario,
|
|
isStartup: true,
|
|
});
|
|
|
|
// Check expected pref values. Store expected effective values as we go so
|
|
// we can check them afterward. For a given pref, the expected effective
|
|
// value is the user value, or if there's not a user value, the default
|
|
// value.
|
|
let expectedEffectivePrefs = {};
|
|
let {
|
|
defaultBranch: expectedDefaultBranch,
|
|
userBranch: expectedUserBranch,
|
|
} = expectedPrefs;
|
|
expectedDefaultBranch = expectedDefaultBranch || {};
|
|
expectedUserBranch = expectedUserBranch || {};
|
|
for (let [branch, prefs, branchType] of [
|
|
[defaultBranch, expectedDefaultBranch, "default"],
|
|
[userBranch, expectedUserBranch, "user"],
|
|
]) {
|
|
let entries = Object.entries(prefs);
|
|
if (!entries.length) {
|
|
continue;
|
|
}
|
|
|
|
info(
|
|
`Checking expected prefs on ${branchType} branch after updating scenario`
|
|
);
|
|
for (let [name, value] of entries) {
|
|
expectedEffectivePrefs[name] = value;
|
|
if (branch == userBranch) {
|
|
Assert.ok(
|
|
userBranch.prefHasUserValue(name),
|
|
`Pref ${name} is on user branch`
|
|
);
|
|
}
|
|
Assert.equal(
|
|
getPref(branch, name),
|
|
value,
|
|
`Pref ${name} value on ${branchType} branch`
|
|
);
|
|
}
|
|
}
|
|
|
|
info(
|
|
`Making sure prefs on the default branch without expected user-branch values are not on the user branch`
|
|
);
|
|
for (let name of Object.keys(initialDefaultBranch)) {
|
|
if (!expectedUserBranch.hasOwnProperty(name)) {
|
|
Assert.ok(
|
|
!userBranch.prefHasUserValue(name),
|
|
`Pref ${name} is not on user branch`
|
|
);
|
|
}
|
|
}
|
|
|
|
info(`Checking expected effective prefs`);
|
|
for (let [name, value] of Object.entries(expectedEffectivePrefs)) {
|
|
Assert.equal(
|
|
UrlbarPrefs.get(name),
|
|
value,
|
|
`Pref ${name} effective value`
|
|
);
|
|
}
|
|
|
|
let currentVersion =
|
|
testOverrides?.migrationVersion === undefined
|
|
? UrlbarPrefs.FIREFOX_SUGGEST_MIGRATION_VERSION
|
|
: testOverrides.migrationVersion;
|
|
Assert.equal(
|
|
UrlbarPrefs.get("quicksuggest.migrationVersion"),
|
|
currentVersion,
|
|
"quicksuggest.migrationVersion is correct after migration"
|
|
);
|
|
}
|
|
|
|
// Clean up.
|
|
UrlbarPrefs._updatingFirefoxSuggestScenario = true;
|
|
UrlbarPrefs.clear("quicksuggest.migrationVersion");
|
|
let userBranchNames = [
|
|
...Object.keys(initialUserBranch),
|
|
...Object.keys(expectedPrefs.userBranch || {}),
|
|
];
|
|
for (let name of userBranchNames) {
|
|
userBranch.clearUserPref(name);
|
|
}
|
|
UrlbarPrefs._updatingFirefoxSuggestScenario = false;
|
|
}
|
|
|
|
/**
|
|
* Does some "show less frequently" tests where the cap is set in remote
|
|
* settings and Nimbus. See `doOneShowLessFrequentlyTest()`. This function
|
|
* assumes the matching behavior implemented by the given `BaseFeature` is based
|
|
* on matching prefixes of the given keyword starting at the first word. It
|
|
* also assumes the `BaseFeature` provides suggestions in remote settings.
|
|
*
|
|
* @param {object} options
|
|
* Options object.
|
|
* @param {BaseFeature} options.feature
|
|
* The feature that provides the suggestion matched by the searches.
|
|
* @param {*} options.expectedResult
|
|
* The expected result that should be matched, for searches that are expected
|
|
* to match a result. Can also be a function; it's passed the current search
|
|
* string and it should return the expected result.
|
|
* @param {string} options.showLessFrequentlyCountPref
|
|
* The name of the pref that stores the "show less frequently" count being
|
|
* tested.
|
|
* @param {string} options.nimbusCapVariable
|
|
* The name of the Nimbus variable that stores the "show less frequently" cap
|
|
* being tested.
|
|
* @param {object} options.keyword
|
|
* The primary keyword to use during the test. It must contain more than one
|
|
* word, and it must have at least two chars after the first space.
|
|
*/
|
|
async function doShowLessFrequentlyTests({
|
|
feature,
|
|
expectedResult,
|
|
showLessFrequentlyCountPref,
|
|
nimbusCapVariable,
|
|
keyword,
|
|
}) {
|
|
// Do some sanity checks on the keyword. Any checks that fail are errors in
|
|
// the test. This function assumes
|
|
let spaceIndex = keyword.indexOf(" ");
|
|
if (spaceIndex < 0) {
|
|
throw new Error("keyword must contain a space");
|
|
}
|
|
if (spaceIndex == 0) {
|
|
throw new Error("keyword must not start with a space");
|
|
}
|
|
if (keyword.length < spaceIndex + 3) {
|
|
throw new Error("keyword must have at least two chars after the space");
|
|
}
|
|
|
|
let tests = [
|
|
{
|
|
showLessFrequentlyCount: 0,
|
|
canShowLessFrequently: true,
|
|
newSearches: {
|
|
[keyword.substring(0, spaceIndex - 1)]: false,
|
|
[keyword.substring(0, spaceIndex)]: true,
|
|
[keyword.substring(0, spaceIndex + 1)]: true,
|
|
[keyword.substring(0, spaceIndex + 2)]: true,
|
|
[keyword.substring(0, spaceIndex + 3)]: true,
|
|
},
|
|
},
|
|
{
|
|
showLessFrequentlyCount: 1,
|
|
canShowLessFrequently: true,
|
|
newSearches: {
|
|
[keyword.substring(0, spaceIndex)]: false,
|
|
},
|
|
},
|
|
{
|
|
showLessFrequentlyCount: 2,
|
|
canShowLessFrequently: true,
|
|
newSearches: {
|
|
[keyword.substring(0, spaceIndex + 1)]: false,
|
|
},
|
|
},
|
|
{
|
|
showLessFrequentlyCount: 3,
|
|
canShowLessFrequently: false,
|
|
newSearches: {
|
|
[keyword.substring(0, spaceIndex + 2)]: false,
|
|
},
|
|
},
|
|
{
|
|
showLessFrequentlyCount: 3,
|
|
canShowLessFrequently: false,
|
|
newSearches: {},
|
|
},
|
|
];
|
|
|
|
info("Testing 'show less frequently' with cap in remote settings");
|
|
await doOneShowLessFrequentlyTest({
|
|
tests,
|
|
feature,
|
|
expectedResult,
|
|
showLessFrequentlyCountPref,
|
|
rs: {
|
|
show_less_frequently_cap: 3,
|
|
},
|
|
});
|
|
|
|
// Nimbus should override remote settings.
|
|
info("Testing 'show less frequently' with cap in Nimbus and remote settings");
|
|
await doOneShowLessFrequentlyTest({
|
|
tests,
|
|
feature,
|
|
expectedResult,
|
|
showLessFrequentlyCountPref,
|
|
rs: {
|
|
show_less_frequently_cap: 10,
|
|
},
|
|
nimbus: {
|
|
[nimbusCapVariable]: 3,
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Does a group of searches, increments the "show less frequently" count, and
|
|
* repeats until all groups are done. The cap can be set by remote settings
|
|
* config and/or Nimbus.
|
|
*
|
|
* @param {object} options
|
|
* Options object.
|
|
* @param {BaseFeature} options.feature
|
|
* The feature that provides the suggestion matched by the searches.
|
|
* @param {*} options.expectedResult
|
|
* The expected result that should be matched, for searches that are expected
|
|
* to match a result. Can also be a function; it's passed the current search
|
|
* string and it should return the expected result.
|
|
* @param {string} options.showLessFrequentlyCountPref
|
|
* The name of the pref that stores the "show less frequently" count being
|
|
* tested.
|
|
* @param {object} options.tests
|
|
* An array where each item describes a group of new searches to perform and
|
|
* expected state. Each item should look like this:
|
|
* `{ showLessFrequentlyCount, canShowLessFrequently, newSearches }`
|
|
*
|
|
* {number} showLessFrequentlyCount
|
|
* The expected value of `showLessFrequentlyCount` before the group of
|
|
* searches is performed.
|
|
* {boolean} canShowLessFrequently
|
|
* The expected value of `canShowLessFrequently` before the group of
|
|
* searches is performed.
|
|
* {object} newSearches
|
|
* An object that maps each search string to a boolean that indicates
|
|
* whether the first remote settings suggestion should be triggered by the
|
|
* search string. Searches are cumulative: The intended use is to pass a
|
|
* large initial group of searches in the first search group, and then each
|
|
* following `newSearches` is a diff against the previous.
|
|
* @param {object} options.rs
|
|
* The remote settings config to set.
|
|
* @param {object} options.nimbus
|
|
* The Nimbus variables to set.
|
|
*/
|
|
async function doOneShowLessFrequentlyTest({
|
|
feature,
|
|
expectedResult,
|
|
showLessFrequentlyCountPref,
|
|
tests,
|
|
rs = {},
|
|
nimbus = {},
|
|
}) {
|
|
// Disable Merino so we trigger only remote settings suggestions. The
|
|
// `BaseFeature` is expected to add remote settings suggestions using keywords
|
|
// start starting with the first word in each full keyword, but the mock
|
|
// Merino server will always return whatever suggestion it's told to return
|
|
// regardless of the search string. That means Merino will return a suggestion
|
|
// for a keyword that's smaller than the first full word.
|
|
UrlbarPrefs.set("quicksuggest.dataCollection.enabled", false);
|
|
|
|
// Set Nimbus variables and RS config.
|
|
let cleanUpNimbus = await UrlbarTestUtils.initNimbusFeature(nimbus);
|
|
await QuickSuggestTestUtils.withConfig({
|
|
config: rs,
|
|
callback: async () => {
|
|
let cumulativeSearches = {};
|
|
|
|
for (let {
|
|
showLessFrequentlyCount,
|
|
canShowLessFrequently,
|
|
newSearches,
|
|
} of tests) {
|
|
info(
|
|
"Starting subtest: " +
|
|
JSON.stringify({
|
|
showLessFrequentlyCount,
|
|
canShowLessFrequently,
|
|
newSearches,
|
|
})
|
|
);
|
|
|
|
Assert.equal(
|
|
feature.showLessFrequentlyCount,
|
|
showLessFrequentlyCount,
|
|
"showLessFrequentlyCount should be correct initially"
|
|
);
|
|
Assert.equal(
|
|
UrlbarPrefs.get(showLessFrequentlyCountPref),
|
|
showLessFrequentlyCount,
|
|
"Pref should be correct initially"
|
|
);
|
|
Assert.equal(
|
|
feature.canShowLessFrequently,
|
|
canShowLessFrequently,
|
|
"canShowLessFrequently should be correct initially"
|
|
);
|
|
|
|
// Merge the current `newSearches` object into the cumulative object.
|
|
cumulativeSearches = {
|
|
...cumulativeSearches,
|
|
...newSearches,
|
|
};
|
|
|
|
for (let [searchString, isExpected] of Object.entries(
|
|
cumulativeSearches
|
|
)) {
|
|
info("Doing search: " + JSON.stringify({ searchString, isExpected }));
|
|
|
|
let results = [];
|
|
if (isExpected) {
|
|
results.push(
|
|
typeof expectedResult == "function"
|
|
? expectedResult(searchString)
|
|
: expectedResult
|
|
);
|
|
}
|
|
|
|
await check_results({
|
|
context: createContext(searchString, {
|
|
providers: [UrlbarProviderQuickSuggest.name],
|
|
isPrivate: false,
|
|
}),
|
|
matches: results,
|
|
});
|
|
}
|
|
|
|
feature.incrementShowLessFrequentlyCount();
|
|
}
|
|
},
|
|
});
|
|
|
|
await cleanUpNimbus();
|
|
UrlbarPrefs.clear(showLessFrequentlyCountPref);
|
|
UrlbarPrefs.set("quicksuggest.dataCollection.enabled", true);
|
|
}
|