commit 18e78b9083d2caea7b47c53ff5e583c1e07b59be parent c46798b2217a5331061230224c19c0826154d5ef Author: James Teow <jteow@mozilla.com> Date: Tue, 11 Nov 2025 02:37:14 +0000 Bug 1986285 - Part 5: Fix tests in browser/components/urlbar - r=urlbar-reviewers,daisuke Differential Revision: https://phabricator.services.mozilla.com/D264739 Diffstat:
11 files changed, 432 insertions(+), 322 deletions(-)
diff --git a/browser/components/urlbar/tests/browser/browser_urlbar_annotation.js b/browser/components/urlbar/tests/browser/browser_urlbar_annotation.js @@ -14,13 +14,6 @@ if (AppConstants.platform === "macosx") { requestLongerTimeout(2); } -const FRECENCY = { - ORGANIC: 2000, - SPONSORED: -1, - BOOKMARKED: 2075, - SEARCHED: 100, -}; - const { VISIT_SOURCE_ORGANIC, VISIT_SOURCE_SPONSORED, @@ -40,14 +33,7 @@ async function waitForVisitNotification(href) { ); } -async function assertDatabase({ targetURL, expected }) { - const frecency = await PlacesTestUtils.getDatabaseValue( - "moz_places", - "frecency", - { url: targetURL } - ); - Assert.equal(frecency, expected.frecency, "Frecency is correct"); - +async function assertDatabaseAndGetFrecency({ targetURL, expected }) { const placesId = await PlacesTestUtils.getDatabaseValue("moz_places", "id", { url: targetURL, }); @@ -70,6 +56,13 @@ async function assertDatabase({ targetURL, expected }) { expectedTriggeringPlaceId, `The triggeringPlaceId in database is correct for ${targetURL}` ); + const frecency = await PlacesTestUtils.getDatabaseValue( + "moz_places", + "frecency", + { url: targetURL } + ); + Assert.greater(frecency, 0, "Frecency is non-zero "); + return frecency; } function registerProvider(payload) { @@ -131,7 +124,6 @@ add_task(async function basic() { }, expected: { source: VISIT_SOURCE_SPONSORED, - frecency: FRECENCY.SPONSORED, }, }, { @@ -149,7 +141,6 @@ add_task(async function basic() { ], expected: { source: VISIT_SOURCE_BOOKMARKED, - frecency: FRECENCY.BOOKMARKED, }, }, { @@ -168,7 +159,6 @@ add_task(async function basic() { ], expected: { source: VISIT_SOURCE_SPONSORED, - frecency: FRECENCY.BOOKMARKED, }, }, { @@ -179,11 +169,11 @@ add_task(async function basic() { }, expected: { source: VISIT_SOURCE_ORGANIC, - frecency: FRECENCY.ORGANIC, }, }, ]; + const databaseResults = []; for (const { description, input, payload, bookmarks, expected } of testData) { info(description); const provider = registerProvider(payload); @@ -198,7 +188,11 @@ add_task(async function basic() { await pickResult({ input, payloadURL: payload.url }); await promiseVisited; info("Check database"); - await assertDatabase({ targetURL: payload.url, expected }); + let frecency = await assertDatabaseAndGetFrecency({ + targetURL: payload.url, + expected, + }); + databaseResults.push({ description, frecency }); Assert.ok( !SponsorProtection.isProtectedBrowser(browser), "Navigations from the URL bar do not cause sponsor protection at this time." @@ -209,6 +203,34 @@ add_task(async function basic() { await PlacesUtils.history.clear(); await PlacesUtils.bookmarks.eraseEverything(); } + + // Since the bookmark and organic result are typed, they are in a higher + // bucket. Sponsored results belong to a lower bucket. + databaseResults.sort((a, b) => b.frecency - a.frecency); + Assert.equal(databaseResults[0].description, "Bookmarked result"); + Assert.equal(databaseResults[1].description, "Organic result"); + Assert.equal( + databaseResults[0].frecency, + databaseResults[1].frecency, + "Organic and bookmarked results should have the same frecency." + ); + + Assert.equal(databaseResults[2].description, "Sponsored result"); + Assert.equal( + databaseResults[3].description, + "Sponsored and bookmarked result" + ); + Assert.equal( + databaseResults[2].frecency, + databaseResults[3].frecency, + "Sponsored results should have the same frecency." + ); + + Assert.greater( + databaseResults[1].frecency, + databaseResults[2].frecency, + "Non-sponsored results should have a higher frecency than sponsored results." + ); }); add_task(async function redirection() { @@ -230,21 +252,24 @@ add_task(async function redirection() { await Promise.all(promises); info("Check database"); - await assertDatabase({ + let frecency1 = await assertDatabaseAndGetFrecency({ targetURL: payload.url, expected: { source: VISIT_SOURCE_SPONSORED, - frecency: FRECENCY.SPONSORED, }, }); - await assertDatabase({ + let frecency2 = await assertDatabaseAndGetFrecency({ targetURL: redirectTo, expected: { source: VISIT_SOURCE_SPONSORED, triggerURL: payload.url, - frecency: FRECENCY.SPONSORED, }, }); + Assert.equal( + frecency1, + frecency2, + "Sponsored visits should have the same frecency." + ); }); await PlacesUtils.history.clear(); @@ -266,7 +291,6 @@ add_task(async function search() { resultURL: "https://example.com/?q=abc", expected: { source: VISIT_SOURCE_SEARCHED, - frecency: FRECENCY.SEARCHED, }, }, { @@ -282,7 +306,6 @@ add_task(async function search() { ], expected: { source: VISIT_SOURCE_BOOKMARKED, - frecency: FRECENCY.BOOKMARKED, }, }, ]; @@ -313,7 +336,10 @@ add_task(async function search() { EventUtils.synthesizeKey("KEY_Enter"); await onLoad; await promiseVisited; - await assertDatabase({ targetURL: resultURL, expected }); + let frecency1 = await assertDatabaseAndGetFrecency({ + targetURL: resultURL, + expected, + }); // Open another URL to check whther the source is not inherited. const payload = { url: "https://example.com/" }; @@ -321,13 +347,27 @@ add_task(async function search() { promiseVisited = waitForVisitNotification(payload.url); await pickResult({ input, payloadURL: payload.url }); await promiseVisited; - await assertDatabase({ + let frecency2 = await assertDatabaseAndGetFrecency({ targetURL: payload.url, expected: { source: VISIT_SOURCE_ORGANIC, - frecency: FRECENCY.ORGANIC, }, }); + + if (expected.source === VISIT_SOURCE_SEARCHED) { + Assert.less( + frecency1, + frecency2, + "Frecency of searched result is less than organic result." + ); + } else if (expected.source === VISIT_SOURCE_BOOKMARKED) { + Assert.equal( + frecency1, + frecency2, + "Frecency of bookmarked result is equal to organic result." + ); + } + UrlbarProvidersManager.unregisterProvider(provider); await PlacesUtils.history.clear(); diff --git a/browser/components/urlbar/tests/unit/test_000_frecency.js b/browser/components/urlbar/tests/unit/test_000_frecency.js @@ -6,178 +6,123 @@ Autocomplete Frecency Tests -- add a visit for each score permutation +- adds a visit for each transition type (recent and old) - search - test number of matches - test each item's location in results +- verify recent visits rank higher than older visits */ testEngine_setup(); -try { - var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].getService( - Ci.nsINavHistoryService - ); -} catch (ex) { - do_throw("Could not get services\n"); -} +// A visit will be added for each transition. +const TRANSITIONS = { + link: PlacesUtils.history.TRANSITION_LINK, + redirectPermanent: PlacesUtils.history.TRANSITION_REDIRECT_PERMANENT, + redirectTemporary: PlacesUtils.history.TRANSITION_REDIRECT_TEMPORARY, + typed: PlacesUtils.history.TRANSITION_TYPED, + bookmark: PlacesUtils.history.TRANSITION_BOOKMARK, + embed: PlacesUtils.history.TRANSITION_EMBED, + download: PlacesUtils.history.TRANSITION_DOWNLOAD, + framedLink: PlacesUtils.history.TRANSITION_FRAMED_LINK, + reload: PlacesUtils.history.TRANSITION_RELOAD, +}; -var bucketPrefs = [ - ["firstBucketCutoff", "firstBucketWeight"], - ["secondBucketCutoff", "secondBucketWeight"], - ["thirdBucketCutoff", "thirdBucketWeight"], - ["fourthBucketCutoff", "fourthBucketWeight"], - [null, "defaultBucketWeight"], +// Despite visits being added for EMBED, DOWNLOAD, FRAMED_LINK, and RELOAD, +// we don't actually expect them to show up in results. +const EXPECTED_TRANSITION_ORDER = [ + // High bucket. + PlacesUtils.history.TRANSITION_BOOKMARK, + PlacesUtils.history.TRANSITION_TYPED, + // Medium bucket. + PlacesUtils.history.TRANSITION_REDIRECT_TEMPORARY, + PlacesUtils.history.TRANSITION_REDIRECT_PERMANENT, + PlacesUtils.history.TRANSITION_LINK, ]; -var bonusPrefs = { - embedVisitBonus: PlacesUtils.history.TRANSITION_EMBED, - framedLinkVisitBonus: PlacesUtils.history.TRANSITION_FRAMED_LINK, - linkVisitBonus: PlacesUtils.history.TRANSITION_LINK, - typedVisitBonus: PlacesUtils.history.TRANSITION_TYPED, - bookmarkVisitBonus: PlacesUtils.history.TRANSITION_BOOKMARK, - downloadVisitBonus: PlacesUtils.history.TRANSITION_DOWNLOAD, - permRedirectVisitBonus: PlacesUtils.history.TRANSITION_REDIRECT_PERMANENT, - tempRedirectVisitBonus: PlacesUtils.history.TRANSITION_REDIRECT_TEMPORARY, - reloadVisitBonus: PlacesUtils.history.TRANSITION_RELOAD, -}; +async function createTestEntries(searchTerm) { + const testEntries = []; -// create test data -var searchTerm = "frecency"; -var results = []; -var now = Date.now(); -var prefPrefix = "places.frecency."; - -async function task_initializeBucket(bucket) { - let [cutoffName, weightName] = bucket; - // get pref values - let weight = Services.prefs.getIntPref(prefPrefix + weightName, 0); - let cutoff = Services.prefs.getIntPref(prefPrefix + cutoffName, 0); - if (cutoff < 1) { - return; - } + for (let [transitionName, transitionType] of Object.entries(TRANSITIONS)) { + let uri = Services.io.newURI( + `https://${searchTerm}.com/${transitionName}/` + ); - // generate a date within the cutoff period - let dateInPeriod = (now - (cutoff - 1) * 86400 * 1000) * 1000; - - for (let [bonusName, visitType] of Object.entries(bonusPrefs)) { - let frecency = -1; - let calculatedURI = null; - let matchTitle = ""; - let bonusValue = Services.prefs.getIntPref(prefPrefix + bonusName); - // unvisited (only for first cutoff date bucket) - if ( - bonusName == "unvisitedBookmarkBonus" || - bonusName == "unvisitedTypedBonus" - ) { - if (cutoffName == "firstBucketCutoff") { - let points = Math.ceil((bonusValue / parseFloat(100.0)) * weight); - let visitCount = 1; // bonusName == "unvisitedBookmarkBonus" ? 1 : 0; - frecency = Math.ceil(visitCount * points); - calculatedURI = Services.io.newURI( - "http://" + - searchTerm + - ".com/" + - bonusName + - ":" + - bonusValue + - "/cutoff:" + - cutoff + - "/weight:" + - weight + - "/frecency:" + - frecency - ); - if (bonusName == "unvisitedBookmarkBonus") { - matchTitle = searchTerm + "UnvisitedBookmark"; - await PlacesUtils.bookmarks.insert({ - parentGuid: PlacesUtils.bookmarks.unfiledGuid, - url: calculatedURI, - title: matchTitle, - }); - } else { - matchTitle = searchTerm + "UnvisitedTyped"; - await PlacesTestUtils.addVisits({ - uri: calculatedURI, - title: matchTitle, - transition: visitType, - visitDate: now, - }); - histsvc.markPageAsTyped(calculatedURI); - } - } - } else { - // visited - // visited bookmarks get the visited bookmark bonus twice - if (visitType == Ci.nsINavHistoryService.TRANSITION_BOOKMARK) { - bonusValue = bonusValue * 2; - } - - let points = Math.ceil( - (1 * ((bonusValue / parseFloat(100.0)).toFixed(6) * weight)) / 1 - ); - if (!points) { - if ( - visitType == Ci.nsINavHistoryService.TRANSITION_EMBED || - visitType == Ci.nsINavHistoryService.TRANSITION_FRAMED_LINK || - visitType == Ci.nsINavHistoryService.TRANSITION_DOWNLOAD || - visitType == Ci.nsINavHistoryService.TRANSITION_RELOAD || - bonusName == "defaultVisitBonus" - ) { - frecency = 0; - } else { - frecency = -1; - } - } else { - frecency = points; - } - calculatedURI = Services.io.newURI( - "http://" + - searchTerm + - ".com/" + - bonusName + - ":" + - bonusValue + - "/cutoff:" + - cutoff + - "/weight:" + - weight + - "/frecency:" + - frecency - ); - if (visitType == Ci.nsINavHistoryService.TRANSITION_BOOKMARK) { - matchTitle = searchTerm + "Bookmarked"; - await PlacesUtils.bookmarks.insert({ - parentGuid: PlacesUtils.bookmarks.unfiledGuid, - url: calculatedURI, - title: matchTitle, - }); - } else { - matchTitle = calculatedURI.spec.substr( - calculatedURI.spec.lastIndexOf("/") + 1 - ); - } - await PlacesTestUtils.addVisits({ - uri: calculatedURI, - transition: visitType, - visitDate: dateInPeriod, + let title = `${searchTerm} ${transitionName} test`; + + if (transitionType === PlacesUtils.history.TRANSITION_BOOKMARK) { + await PlacesTestUtils.addBookmarkWithDetails({ + uri, + title, }); } - if (calculatedURI && frecency) { - results.push([calculatedURI, frecency, matchTitle]); - await PlacesTestUtils.addVisits({ - uri: calculatedURI, - title: matchTitle, - transition: visitType, - visitDate: dateInPeriod, + await PlacesTestUtils.addVisits({ + uri, + title, + transition: transitionType, + }); + + if (transitionType === PlacesUtils.history.TRANSITION_TYPED) { + PlacesUtils.history.markPageAsTyped(uri); + } + + testEntries.push({ + uri, + title, + transitionType, + transitionName, + age: "recent", + }); + } + + // 180 days ago in microseconds. + // This number was chosen because we want a safe value that is so old, even + // a higher bucket wouldn't allow it to remain higher than a more recent + // visit that was in a lower non-zero bucket. + const OLD_TIME = (Date.now() - 180 * 24 * 60 * 60 * 1000) * 1000; + for (let [transitionName, transitionType] of Object.entries(TRANSITIONS)) { + let uri = Services.io.newURI( + `https://${searchTerm}.com/old/${transitionName}/` + ); + + let title = `${searchTerm} ${transitionName} test`; + + if (transitionType === PlacesUtils.history.TRANSITION_BOOKMARK) { + await PlacesTestUtils.addBookmarkWithDetails({ + uri, + title, }); } + + await PlacesTestUtils.addVisits({ + uri, + title, + transition: transitionType, + visitDate: OLD_TIME, + }); + + if (transitionType === PlacesUtils.history.TRANSITION_TYPED) { + PlacesUtils.history.markPageAsTyped(uri); + } + + testEntries.push({ + uri, + title, + transitionType, + transitionName, + age: "old", + }); } + + return testEntries; } add_task(async function test_frecency() { + const searchTerm = "frecency"; + const testEntries = await createTestEntries(searchTerm); + // Disable autoFill for this test. Services.prefs.setBoolPref("browser.urlbar.autoFill", false); Services.prefs.setBoolPref("browser.urlbar.suggest.searches", false); @@ -195,56 +140,62 @@ add_task(async function test_frecency() { Services.prefs.clearUserPref("browser.urlbar.suggest.searches"); Services.prefs.clearUserPref("browser.urlbar.scotchBonnet.enableOverride"); }); - for (let bucket of bucketPrefs) { - await task_initializeBucket(bucket); - } - - // Sort results by frecency. Break ties by alphabetical URL. - results.sort((a, b) => { - let frecencyDiff = b[1] - a[1]; - if (frecencyDiff == 0) { - return a[0].spec.localeCompare(b[0].spec); - } - return frecencyDiff; - }); // Make sure there's enough results returned Services.prefs.setIntPref( "browser.urlbar.maxRichResults", // +1 for the heuristic search result. - results.length + 1 + testEntries.length + 1 ); await PlacesTestUtils.promiseAsyncUpdates(); + + // Perform the search. let context = createContext(searchTerm, { isPrivate: false }); - let urlbarResults = []; - for (let result of results) { - let url = result[0].spec; - if (url.toLowerCase().includes("bookmark")) { - urlbarResults.push( - makeBookmarkResult(context, { - uri: url, - title: result[2], - }) + + let expectedResults = [ + makeSearchResult(context, { + engineName: SUGGESTIONS_ENGINE_NAME, + heuristic: true, + }), + ]; + + // Add entries in expected recent frecency order. + for (let expectedTransition of EXPECTED_TRANSITION_ORDER) { + let entry = testEntries.find( + e => e.transitionType == expectedTransition && e.age == "recent" + ); + + if (expectedTransition === PlacesUtils.history.TRANSITION_BOOKMARK) { + expectedResults.push( + makeBookmarkResult(context, { uri: entry.uri.spec, title: entry.title }) + ); + } else { + expectedResults.push( + makeVisitResult(context, { uri: entry.uri.spec, title: entry.title }) + ); + } + } + + // Add entries in expected recent frecency order. + for (let expectedTransition of EXPECTED_TRANSITION_ORDER) { + let entry = testEntries.find( + e => e.transitionType == expectedTransition && e.age == "old" + ); + + if (expectedTransition === PlacesUtils.history.TRANSITION_BOOKMARK) { + expectedResults.push( + makeBookmarkResult(context, { uri: entry.uri.spec, title: entry.title }) ); } else { - urlbarResults.push( - makeVisitResult(context, { - uri: url, - title: result[2], - }) + expectedResults.push( + makeVisitResult(context, { uri: entry.uri.spec, title: entry.title }) ); } } await check_results({ context, - matches: [ - makeSearchResult(context, { - engineName: SUGGESTIONS_ENGINE_NAME, - heuristic: true, - }), - ...urlbarResults, - ], + matches: expectedResults, }); }); diff --git a/browser/components/urlbar/tests/unit/test_autofill_bookmarked.js b/browser/components/urlbar/tests/unit/test_autofill_bookmarked.js @@ -21,12 +21,20 @@ add_task(async function () { url: `http://${host}`, parentGuid: PlacesUtils.bookmarks.unfiledGuid, }); + // Add one visit to http to give it a realistic origin frecency score instead + // of the default value of 1. This ensures the threshold test doesn't use an + // artificially low baseline. + await PlacesTestUtils.addVisits(`http://${host}`); + for (let i = 0; i < 3; i++) { await PlacesTestUtils.addVisits(`https://${host}`); } // ensure both fall below the threshold. for (let i = 0; i < 15; i++) { - await PlacesTestUtils.addVisits(`https://not-${host}`); + await PlacesTestUtils.addVisits({ + url: `https://not-${host}`, + transition: PlacesUtils.history.TRANSITION_TYPED, + }); } async function check_autofill() { @@ -78,10 +86,19 @@ add_task(async function () { await checkOriginsOrder(host, ["http://", "https://"]); await PlacesUtils.bookmarks.remove(bookmark); await PlacesUtils.withConnectionWrapper("removeOrphans", async db => { - db.execute(`DELETE FROM moz_places WHERE url = :url`, { + // Delete the visit. + await db.execute( + ` + DELETE FROM moz_historyvisits + WHERE place_id = (SELECT id FROM moz_places WHERE url = :url)`, + { url: `http://${host}/` } + ); + + await db.execute(`DELETE FROM moz_places WHERE url = :url`, { url: `http://${host}/`, }); - db.execute( + + await db.execute( `DELETE FROM moz_origins WHERE prefix = "http://" AND host = :host`, { host } ); @@ -90,6 +107,8 @@ add_task(async function () { url: `http://${host}`, parentGuid: PlacesUtils.bookmarks.unfiledGuid, }); + // Add a visit to prevent origin frecency from being too low. + await PlacesTestUtils.addVisits(`http://${host}`); await checkOriginsOrder(host, ["https://", "http://"]); diff --git a/browser/components/urlbar/tests/unit/test_autofill_origins.js b/browser/components/urlbar/tests/unit/test_autofill_origins.js @@ -336,10 +336,22 @@ add_task(async function groupByHost() { { uri: "https://example.com/" }, { uri: "https://example.com/" }, - { uri: "https://mozilla.org/" }, - { uri: "https://mozilla.org/" }, - { uri: "https://mozilla.org/" }, - { uri: "https://mozilla.org/" }, + { + uri: "https://mozilla.org/", + transition: PlacesUtils.history.TRANSITION_TYPED, + }, + { + uri: "https://mozilla.org/", + transition: PlacesUtils.history.TRANSITION_TYPED, + }, + { + uri: "https://mozilla.org/", + transition: PlacesUtils.history.TRANSITION_TYPED, + }, + { + uri: "https://mozilla.org/", + transition: PlacesUtils.history.TRANSITION_TYPED, + }, ]); let httpFrec = await PlacesTestUtils.getDatabaseValue( @@ -920,17 +932,17 @@ add_task(async function nullTitle() { // Set title of visits data to an empty string causes // the title to be null in the database. title: "", - frecency: 100, + frecencyBucket: "high", }, { uri: "https://www.example.com/", - title: "high frecency", - frecency: 50, + title: "medium frecency", + frecencyBucket: "medium", }, { uri: "http://www.example.com/", title: "low frecency", - frecency: 1, + frecencyBucket: "low", }, ], input: "example.com", @@ -940,12 +952,12 @@ add_task(async function nullTitle() { matches: context => [ makeVisitResult(context, { uri: "http://example.com/", - title: "high frecency", + title: "medium frecency", heuristic: true, }), makeVisitResult(context, { uri: "https://www.example.com/", - title: "high frecency", + title: "medium frecency", }), ], }, @@ -958,17 +970,17 @@ add_task(async function domainTitle() { { uri: "http://example.com/", title: "example.com", - frecency: 100, + frecencyBucket: "high", }, { uri: "https://www.example.com/", title: "", - frecency: 50, + frecencyBucket: "medium", }, { uri: "http://www.example.com/", title: "lowest frecency but has title", - frecency: 1, + frecencyBucket: "low", }, ], input: "example.com", @@ -996,12 +1008,12 @@ add_task(async function exactMatchedTitle() { { uri: "http://example.com/", title: "exact match", - frecency: 50, + frecencyBucket: "medium", }, { uri: "https://www.example.com/", title: "high frecency uri", - frecency: 100, + frecencyBucket: "high", }, ], input: "http://example.com/", @@ -1024,21 +1036,56 @@ add_task(async function exactMatchedTitle() { }); async function doTitleTest({ visits, input, expected }) { - await PlacesTestUtils.addVisits(visits); - for (const { uri, frecency } of visits) { - // Prepare data. - await PlacesUtils.withConnectionWrapper("test::doTitleTest", async db => { - await db.execute( - `UPDATE moz_places SET frecency = :frecency, recalc_frecency=0 WHERE url = :url`, - { - frecency, - url: uri, - } - ); - await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); - }); + for (let visit of visits) { + switch (visit.frecencyBucket) { + case "high": { + await PlacesTestUtils.addVisits({ + title: visit.title, + uri: visit.uri, + transition: PlacesUtils.history.TRANSITION_TYPED, + }); + break; + } + case "medium": { + await PlacesTestUtils.addVisits({ title: visit.title, uri: visit.uri }); + break; + } + case "low": { + // Non-bookmarked sponsors are categorized as low. + await PlacesTestUtils.addVisits({ + title: visit.title, + uri: visit.uri, + }); + // Add visits doesn't allow you to set the visit source. + await PlacesUtils.withConnectionWrapper("setVisitSource", async db => { + await db.execute( + ` + UPDATE moz_historyvisits + SET source = :source + WHERE place_id = (SELECT id FROM moz_places WHERE url = :url)`, + { + url: visit.uri, + source: PlacesUtils.history.VISIT_SOURCE_SPONSORED, + } + ); + await db.execute( + ` + UPDATE moz_places + SET recalc_frecency = 1 + WHERE id = (SELECT id FROM moz_places WHERE url = :url)`, + { + url: visit.uri, + } + ); + }); + await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); + break; + } + } } + await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); + const context = createContext(input, { isPrivate: false }); await check_results({ context, diff --git a/browser/components/urlbar/tests/unit/test_autofill_originsAndQueries.js b/browser/components/urlbar/tests/unit/test_autofill_originsAndQueries.js @@ -848,6 +848,21 @@ add_autofill_task(async function bookmarkBelowThreshold() { await PlacesTestUtils.addBookmarkWithDetails({ uri: "http://" + url, }); + + // Bookmarks without a visit are given a frecency boost. To reduce its + // frecency (and thus, make it lower than the origin autofill threshold), + // set its creation date to a long time ago. + let thirtyYearsAgoMicroseconds = + (Date.now() - 30 * 365 * 24 * 60 * 60 * 1000) * 1000; + await PlacesUtils.withConnectionWrapper( + "test_autofill_originsAndQueries::add_autofill_task", + async db => { + await db.execute("UPDATE moz_bookmarks SET dateAdded = :dateAdded", { + dateAdded: thirtyYearsAgoMicroseconds, + }); + } + ); + await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); // Make sure the bookmarked origin and place frecencies are below the diff --git a/browser/components/urlbar/tests/unit/test_empty_search.js b/browser/components/urlbar/tests/unit/test_empty_search.js @@ -25,20 +25,32 @@ add_task(async function test_empty_search() { let uri6 = Services.io.newURI("http://t.foo/6"); let uri7 = Services.io.newURI("http://t.foo/7"); - await PlacesTestUtils.addVisits([ - { uri: uri7, title: "title" }, - { uri: uri6, title: "title" }, - { uri: uri4, title: "title" }, - { uri: uri3, title: "title" }, - { uri: uri2, title: "title" }, - { uri: uri1, title: "title" }, - ]); - await PlacesTestUtils.addBookmarkWithDetails({ uri: uri6, title: "title" }); await PlacesTestUtils.addBookmarkWithDetails({ uri: uri5, title: "title" }); await PlacesTestUtils.addBookmarkWithDetails({ uri: uri4, title: "title" }); await PlacesTestUtils.addBookmarkWithDetails({ uri: uri2, title: "title" }); + await PlacesTestUtils.addVisits([ + { + uri: uri7, + title: "title", + }, + { + uri: uri6, + title: "title", + }, + { + uri: uri4, + title: "title", + }, + { uri: uri3, title: "title" }, + { + uri: uri2, + title: "title", + }, + { uri: uri1, title: "title" }, + ]); + await addOpenPages(uri7, 1); // Now remove page 6 from history, so it is an unvisited bookmark. @@ -46,6 +58,10 @@ add_task(async function test_empty_search() { await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); + // With the changes above, the sites have the same frecency: + // Group 1: http://t.foo/6, http://t.foo/5, http://t.foo/4, http://t.foo/2 + // Group 2: http://t.foo/7, http://t.foo/3, http://t.foo/1 + // With the changes above, the sites in descending order of frecency are: // uri2 // uri4 diff --git a/browser/components/urlbar/tests/unit/test_multi_word_search.js b/browser/components/urlbar/tests/unit/test_multi_word_search.js @@ -24,12 +24,6 @@ add_task(async function test_match_beginning() { let uri2 = Services.io.newURI("http://d.e.f/g-h_i/h/t/p"); let uri3 = Services.io.newURI("http://g.h.i/j-k_l/h/t/p"); let uri4 = Services.io.newURI("http://j.k.l/m-n_o/h/t/p"); - await PlacesTestUtils.addVisits([ - { uri: uri4, title: "f(o)o b<a>r" }, - { uri: uri3, title: "f(o)o b<a>r" }, - { uri: uri2, title: "b(a)r b<a>z" }, - { uri: uri1, title: "f(o)o b<a>r" }, - ]); await PlacesTestUtils.addBookmarkWithDetails({ uri: uri3, title: "f(o)o b<a>r", @@ -38,6 +32,12 @@ add_task(async function test_match_beginning() { uri: uri4, title: "b(a)r b<a>z", }); + await PlacesTestUtils.addVisits([ + { uri: uri4, title: "f(o)o b<a>r" }, + { uri: uri3, title: "f(o)o b<a>r" }, + { uri: uri2, title: "b(a)r b<a>z" }, + { uri: uri1, title: "f(o)o b<a>r" }, + ]); await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); diff --git a/browser/components/urlbar/tests/unit/test_providerTabToSearch.js b/browser/components/urlbar/tests/unit/test_providerTabToSearch.js @@ -349,7 +349,7 @@ add_task(async function multipleEnginesForHostname() { // results. let otherVisitResults = []; for (let i = 0; i < maxResultCount; i++) { - let url = "https://mochi.test:8888/example/" + i; + let url = `https://mochi${i}.test:8888/example/` + i; await PlacesTestUtils.addVisits(url); otherVisitResults.unshift( makeVisitResult(context, { diff --git a/browser/components/urlbar/tests/unit/test_special_search.js b/browser/components/urlbar/tests/unit/test_special_search.js @@ -20,26 +20,30 @@ function setSuggestPrefsToFalse() { const TRANSITION_TYPED = PlacesUtils.history.TRANSITION_TYPED; add_task(async function test_special_searches() { + // High weight - Typed visit. let uri1 = Services.io.newURI("http://url/"); + // Medium weight - Regular visit. let uri2 = Services.io.newURI("http://url/2"); + // Medium weight - Regular visit. let uri3 = Services.io.newURI("http://foo.bar/"); + // High weight - Typed visit. let uri4 = Services.io.newURI("http://foo.bar/2"); + // High weight - Bookmark. let uri5 = Services.io.newURI("http://url/star"); + // High weight - Bookmark, regular visit. let uri6 = Services.io.newURI("http://url/star/2"); + // High weight - Bookmark, no visit. let uri7 = Services.io.newURI("http://foo.bar/star"); + // High weight - Bookmark. let uri8 = Services.io.newURI("http://foo.bar/star/2"); + // High weight - Bookmark, no visit. let uri9 = Services.io.newURI("http://url/tag"); + // High weight - Bookmark, no visit. let uri10 = Services.io.newURI("http://url/tag/2"); + // High weight - Bookmark, typed visit. let uri11 = Services.io.newURI("http://foo.bar/tag"); + // High weight - Bookmark, 0 visits. let uri12 = Services.io.newURI("http://foo.bar/tag/2"); - await PlacesTestUtils.addVisits([ - { uri: uri11, title: "title", transition: TRANSITION_TYPED }, - { uri: uri6, title: "foo.bar" }, - { uri: uri4, title: "foo.bar", transition: TRANSITION_TYPED }, - { uri: uri3, title: "title" }, - { uri: uri2, title: "foo.bar" }, - { uri: uri1, title: "title", transition: TRANSITION_TYPED }, - ]); await PlacesTestUtils.addBookmarkWithDetails({ uri: uri12, @@ -66,21 +70,32 @@ add_task(async function test_special_searches() { await PlacesTestUtils.addBookmarkWithDetails({ uri: uri6, title: "foo.bar" }); await PlacesTestUtils.addBookmarkWithDetails({ uri: uri5, title: "title" }); + await PlacesTestUtils.addVisits([ + { uri: uri11, title: "title", transition: TRANSITION_TYPED }, + { uri: uri6, title: "foo.bar" }, + { uri: uri4, title: "foo.bar", transition: TRANSITION_TYPED }, + { uri: uri3, title: "title" }, + { uri: uri2, title: "foo.bar" }, + { uri: uri1, title: "title", transition: TRANSITION_TYPED }, + ]); + await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); // Order of frecency when not restricting, descending: - // uri11 // uri1 // uri4 - // uri6 // uri5 + // uri6 // uri7 // uri8 // uri9 // uri10 + // uri11 // uri12 // uri2 // uri3 + // Because there are a lot of ties, the ordering is influenced by order in + // which they were inserted. // Test restricting searches. @@ -95,10 +110,10 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri1.spec, title: "title" }), makeVisitResult(context, { uri: uri4.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri6.spec, title: "foo.bar" }), + makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri2.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri3.spec, title: "title" }), ], @@ -115,12 +130,8 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeBookmarkResult(context, { - uri: uri11.spec, - title: "title", - }), - makeBookmarkResult(context, { uri: uri6.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri5.spec, title: "title" }), + makeBookmarkResult(context, { uri: uri6.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri7.spec, title: "title" }), makeBookmarkResult(context, { uri: uri8.spec, title: "foo.bar" }), makeBookmarkResult(context, { @@ -132,6 +143,10 @@ add_task(async function test_special_searches() { title: "foo.bar", }), makeBookmarkResult(context, { + uri: uri11.spec, + title: "title", + }), + makeBookmarkResult(context, { uri: uri12.spec, title: "foo.bar", }), @@ -148,10 +163,6 @@ add_task(async function test_special_searches() { heuristic: true, }), makeBookmarkResult(context, { - uri: uri11.spec, - title: "title", - }), - makeBookmarkResult(context, { uri: uri9.spec, title: "title", }), @@ -160,6 +171,10 @@ add_task(async function test_special_searches() { title: "foo.bar", }), makeBookmarkResult(context, { + uri: uri11.spec, + title: "title", + }), + makeBookmarkResult(context, { uri: uri12.spec, title: "foo.bar", }), @@ -179,9 +194,9 @@ add_task(async function test_special_searches() { source: UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL, heuristic: true, }), - makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri4.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri6.spec, title: "foo.bar" }), + makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri2.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri3.spec, title: "title" }), ], @@ -198,9 +213,9 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri4.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri6.spec, title: "foo.bar" }), + makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri2.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri3.spec, title: "title" }), ], @@ -219,9 +234,9 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri4.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri6.spec, title: "foo.bar" }), + makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri2.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri3.spec, title: "title" }), ], @@ -238,11 +253,6 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeBookmarkResult(context, { - uri: uri11.spec, - title: "title", - tags: ["foo.bar"], - }), makeBookmarkResult(context, { uri: uri6.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri7.spec, title: "title" }), makeBookmarkResult(context, { uri: uri8.spec, title: "foo.bar" }), @@ -257,6 +267,11 @@ add_task(async function test_special_searches() { tags: ["foo.bar"], }), makeBookmarkResult(context, { + uri: uri11.spec, + title: "title", + tags: ["foo.bar"], + }), + makeBookmarkResult(context, { uri: uri12.spec, title: "foo.bar", tags: ["foo.bar"], @@ -275,12 +290,12 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri4.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri6.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri8.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri9.spec, title: "title" }), makeVisitResult(context, { uri: uri10.spec, title: "foo.bar" }), + makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri12.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri2.spec, title: "foo.bar" }), ], @@ -297,10 +312,10 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri4.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri7.spec, title: "title" }), makeBookmarkResult(context, { uri: uri8.spec, title: "foo.bar" }), + makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri12.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri3.spec, title: "title" }), ], @@ -318,11 +333,6 @@ add_task(async function test_special_searches() { heuristic: true, }), makeBookmarkResult(context, { - uri: uri11.spec, - title: "title", - tags: ["foo.bar"], - }), - makeBookmarkResult(context, { uri: uri9.spec, title: "title", tags: ["foo.bar"], @@ -333,6 +343,11 @@ add_task(async function test_special_searches() { tags: ["foo.bar"], }), makeBookmarkResult(context, { + uri: uri11.spec, + title: "title", + tags: ["foo.bar"], + }), + makeBookmarkResult(context, { uri: uri12.spec, title: "foo.bar", tags: ["foo.bar"], @@ -446,9 +461,9 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri4.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri6.spec, title: "foo.bar" }), + makeVisitResult(context, { uri: uri11.spec, title: "title" }), makeVisitResult(context, { uri: uri2.spec, title: "foo.bar" }), makeVisitResult(context, { uri: uri3.spec, title: "title" }), ], @@ -471,11 +486,6 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeBookmarkResult(context, { - uri: uri11.spec, - title: "title", - tags: ["foo.bar"], - }), makeVisitResult(context, { uri: uri4.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri6.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri7.spec, title: "title" }), @@ -491,6 +501,11 @@ add_task(async function test_special_searches() { tags: ["foo.bar"], }), makeBookmarkResult(context, { + uri: uri11.spec, + title: "title", + tags: ["foo.bar"], + }), + makeBookmarkResult(context, { uri: uri12.spec, title: "foo.bar", tags: ["foo.bar"], @@ -513,11 +528,6 @@ add_task(async function test_special_searches() { engineName: SUGGESTIONS_ENGINE_NAME, heuristic: true, }), - makeBookmarkResult(context, { - uri: uri11.spec, - title: "title", - tags: ["foo.bar"], - }), makeBookmarkResult(context, { uri: uri6.spec, title: "foo.bar" }), makeBookmarkResult(context, { uri: uri7.spec, title: "title" }), makeBookmarkResult(context, { uri: uri8.spec, title: "foo.bar" }), @@ -532,6 +542,11 @@ add_task(async function test_special_searches() { tags: ["foo.bar"], }), makeBookmarkResult(context, { + uri: uri11.spec, + title: "title", + tags: ["foo.bar"], + }), + makeBookmarkResult(context, { uri: uri12.spec, title: "foo.bar", tags: ["foo.bar"], diff --git a/browser/components/urlbar/tests/unit/test_tab_matches.js b/browser/components/urlbar/tests/unit/test_tab_matches.js @@ -321,6 +321,10 @@ add_task(async function test_tab_matches() { heuristic: true, }), makeTabSwitchResult(context, { + uri: "http://abc.com/", + title: "ABC rocks", + }), + makeTabSwitchResult(context, { uri: "data:text/html,test", title: "data:text/html,test", iconUri: UrlbarUtils.ICON.DEFAULT, @@ -329,10 +333,6 @@ add_task(async function test_tab_matches() { uri: "about:mozilla", title: "about:mozilla", }), - makeTabSwitchResult(context, { - uri: "http://abc.com/", - title: "ABC rocks", - }), ], }); diff --git a/browser/components/urlbar/tests/unit/test_word_boundary_search.js b/browser/components/urlbar/tests/unit/test_word_boundary_search.js @@ -26,18 +26,6 @@ add_task(async function test_escape() { Services.prefs.clearUserPref("browser.urlbar.autoFill"); }); - await PlacesTestUtils.addVisits([ - { uri: "http://matchme/", title: "title1" }, - { uri: "http://dontmatchme/", title: "title1" }, - { uri: "http://title/1", title: "matchme2" }, - { uri: "http://title/2", title: "dontmatchme3" }, - { uri: "http://tag/1", title: "title1" }, - { uri: "http://tag/2", title: "title1" }, - { uri: "http://crazytitle/", title: "!@#$%^&*()_+{}|:<>?word" }, - { uri: "http://katakana/", title: katakana.join("") }, - { uri: "http://ideograph/", title: ideograph.join("") }, - { uri: "http://camel/pleaseMatchMe/", title: "title1" }, - ]); await PlacesTestUtils.addBookmarkWithDetails({ uri: "http://tag/1", title: "title1", @@ -48,6 +36,25 @@ add_task(async function test_escape() { title: "title1", tags: ["dontmatchme3"], }); + + await PlacesTestUtils.addVisits([ + { uri: "http://matchme/", title: "title1" }, + { uri: "http://dontmatchme/", title: "title1" }, + { uri: "http://title/1", title: "matchme2" }, + { uri: "http://title/2", title: "dontmatchme3" }, + { + uri: "http://tag/1", + title: "title1", + }, + { + uri: "http://tag/2", + title: "title1", + }, + { uri: "http://crazytitle/", title: "!@#$%^&*()_+{}|:<>?word" }, + { uri: "http://katakana/", title: katakana.join("") }, + { uri: "http://ideograph/", title: ideograph.join("") }, + { uri: "http://camel/pleaseMatchMe/", title: "title1" }, + ]); await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies(); info("Match 'match' at the beginning or after / or on a CamelCase");