diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
commit | fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch) | |
tree | 4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure_edge_cases.js | |
parent | Releasing progress-linux version 124.0.1-1~progress7.99u1. (diff) | |
download | firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip |
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure_edge_cases.js')
-rw-r--r-- | browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure_edge_cases.js | 626 |
1 files changed, 584 insertions, 42 deletions
diff --git a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure_edge_cases.js b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure_edge_cases.js index d28352b417..725240c9b1 100644 --- a/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure_edge_cases.js +++ b/browser/components/urlbar/tests/engagementTelemetry/browser/browser_glean_telemetry_exposure_edge_cases.js @@ -38,8 +38,12 @@ add_setup(async function () { gProvider = new TestProvider(); UrlbarProvidersManager.registerProvider(gProvider); - // Increase the timeout of the stale-rows timer so it doesn't interfere with - // this test, which specifically tests what happens before the timer fires. + // This test specifically checks the view's behavior before and after it + // removes stale rows, so it needs to control when that occurs. There are two + // times the view removes stale rows: (1) when the stale-rows timer fires, (2) + // when a query finishes. We prevent (1) from occuring by increasing the + // timer's timeout so it never fires during the test. We'll rely on (2) to + // trigger stale rows removal. let originalRemoveStaleRowsTimeout = UrlbarView.removeStaleRowsTimeout; UrlbarView.removeStaleRowsTimeout = 30000; @@ -49,11 +53,17 @@ add_setup(async function () { }); }); -// Does one query that fills up the view with search suggestions, starts a -// second query that returns a history result, and cancels it before it can -// finish but after the view is updated. Regardless of `showExposureResults`, -// the history result should not trigger an exposure since it never had a chance -// to be visible in the view. +// Does the following: +// +// 1. Starts and finishes a query that fills up the view +// 2. Starts a second query with results that cannot replace rows from the first +// query and that therefore must be appended and hidden +// 3. Cancels the second query before it finishes (so that stale rows are not +// removed) +// +// Results in the second query should not trigger an exposure. They can never be +// visible in the view since the second query is canceled before stale rows are +// removed. add_task(async function noExposure() { for (let showExposureResults of [true, false]) { await do_noExposure(showExposureResults); @@ -116,7 +126,7 @@ async function do_noExposure(showExposureResults) { // When the provider's `startQuery()` is called, let it add its results but // don't let it return. That will cause the view to be updated with the new // results but prevent it from showing hidden rows since the query won't - // finish. + // finish (so stale rows won't be removed). let queryResolver = Promise.withResolvers(); gProvider.finishQueryPromise = queryResolver.promise; @@ -147,14 +157,24 @@ async function do_noExposure(showExposureResults) { // Make sure the view is full of visible rows as expected, plus the one or two // hidden rows for the history and/or bookmark results. - let rows = UrlbarTestUtils.getResultsContainer(window); - let expectedCount = MAX_RESULT_COUNT + 1; + let expected = [ + { + source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS, + type: UrlbarUtils.RESULT_TYPE.URL, + url: bookmarkUrl, + }, + ]; if (showExposureResults) { - expectedCount++; + expected.unshift({ + source: UrlbarUtils.RESULT_SOURCE.HISTORY, + type: UrlbarUtils.RESULT_TYPE.URL, + url: historyUrl, + }); } + let rows = UrlbarTestUtils.getResultsContainer(window); Assert.equal( rows.children.length, - expectedCount, + MAX_RESULT_COUNT + expected.length, "The view has the expected number of rows" ); @@ -176,24 +196,15 @@ async function do_noExposure(showExposureResults) { } // Check the hidden history and/or bookmark rows. - let expected = [ - { source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS, url: bookmarkUrl }, - ]; - if (showExposureResults) { - expected.unshift({ - source: UrlbarUtils.RESULT_SOURCE.HISTORY, - url: historyUrl, - }); - } for (let i = 0; i < expected.length; i++) { - let { source, url } = expected[i]; + let { source, type, url } = expected[i]; let row = rows.children[MAX_RESULT_COUNT + i]; Assert.ok(row, `rows[${i}] should exist`); Assert.ok(BrowserTestUtils.isHidden(row), `rows[${i}] should be hidden`); Assert.equal( row.result.type, - UrlbarUtils.RESULT_TYPE.URL, - `rows[${i}].result.type should be URL` + type, + `rows[${i}].result.type should be as expected` ); Assert.equal( row.result.source, @@ -212,8 +223,8 @@ async function do_noExposure(showExposureResults) { await UrlbarTestUtils.promisePopupClose(window); gURLBar.blur(); - // No exposure should have been recorded since the history result was never - // visible. + // No exposure should have been recorded since the history result could never + // be visible. assertExposureTelemetry([]); // Clean up. @@ -221,17 +232,24 @@ async function do_noExposure(showExposureResults) { await queryPromise; await SpecialPowers.popPrefEnv(); Services.fog.testResetFOG(); + gProvider.finishQueryPromise = null; } -// Does one query that underfills the view and then a second query that returns -// a search suggestion. The search suggestion should be appended and trigger an -// exposure. When `showExposureResults` is true, it should also be shown. After -// the view is updated, it shouldn't matter whether or not the second query is -// canceled. -add_task(async function exposure_append() { +// Does the following: +// +// 1. Starts and finishes a query that underfills the view +// 2. Starts a second query +// 3. Waits for rows from the second query to be appended. They will be +// immediately visible since the first query underfilled the view. +// 4. Either cancels the second query (so stale rows are not removed) or waits +// for it to finish (so stale rows are removed) +// +// Results in the second query should trigger an exposure since they are made +// visible in step 3. Step 4 should not actually matter. +add_task(async function exposure_append_underfilled() { for (let showExposureResults of [true, false]) { for (let cancelSecondQuery of [true, false]) { - await do_exposure_append({ + await do_exposure_append_underfilled({ showExposureResults, cancelSecondQuery, }); @@ -239,7 +257,10 @@ add_task(async function exposure_append() { } }); -async function do_exposure_append({ showExposureResults, cancelSecondQuery }) { +async function do_exposure_append_underfilled({ + showExposureResults, + cancelSecondQuery, +}) { info( "Starting do_exposure_append: " + JSON.stringify({ showExposureResults, cancelSecondQuery }) @@ -287,7 +308,8 @@ async function do_exposure_append({ showExposureResults, cancelSecondQuery }) { // When the provider's `startQuery()` is called, let it add its results but // don't let it return. That will cause the view to be updated with the new - // results but let us test the specific case where the query doesn't finish. + // results but let us test the specific case where the query doesn't finish + // (so stale rows are not removed). let queryResolver = Promise.withResolvers(); gProvider.finishQueryPromise = queryResolver.promise; @@ -357,13 +379,19 @@ async function do_exposure_append({ showExposureResults, cancelSecondQuery }) { await queryPromise; await SpecialPowers.popPrefEnv(); Services.fog.testResetFOG(); + gProvider.finishQueryPromise = null; } -// Does one query that returns a search suggestion and then a second query that -// returns a new search suggestion. The new search suggestion can replace the -// old one, so it should trigger an exposure. When `showExposureResults` is -// true, it should actually replace it. After the view is updated, it shouldn't -// matter whether or not the second query is canceled. +// Does the following: +// +// 1. Starts and finishes a query +// 2. Starts a second query with a result that can replace an existing row from +// the previous query +// 3. Either cancels the second query (so stale rows are not removed) or waits +// for it to finish (so stale rows are removed) +// +// The result in the second query should trigger an exposure since it's made +// visible in step 2. Step 3 should not actually matter. add_task(async function exposure_replace() { for (let showExposureResults of [true, false]) { for (let cancelSecondQuery of [true, false]) { @@ -433,7 +461,8 @@ async function do_exposure_replace({ showExposureResults, cancelSecondQuery }) { // When the provider's `startQuery()` is called, let it add its results but // don't let it return. That will cause the view to be updated with the new - // results but let us test the specific case where the query doesn't finish. + // results but let us test the specific case where the query doesn't finish + // (so stale rows are not removed). let queryResolver = Promise.withResolvers(); gProvider.finishQueryPromise = queryResolver.promise; @@ -503,6 +532,519 @@ async function do_exposure_replace({ showExposureResults, cancelSecondQuery }) { await queryPromise; await SpecialPowers.popPrefEnv(); Services.fog.testResetFOG(); + gProvider.finishQueryPromise = null; +} + +// Does the following: +// +// 1. Starts and finishes a query that fills up the view +// 2. Starts a second query with a result that cannot replace any rows from the +// first query and that therefore must be appended and hidden +// 3. Finishes the second query +// +// The result in the second query should trigger an exposure since it's made +// visible in step 3. +add_task(async function exposure_append_full() { + for (let showExposureResults of [true, false]) { + await do_exposure_append_full(showExposureResults); + } +}); + +async function do_exposure_append_full(showExposureResults) { + info( + "Starting do_exposure_append_full: " + + JSON.stringify({ showExposureResults }) + ); + + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.urlbar.exposureResults", "history"], + ["browser.urlbar.showExposureResults", showExposureResults], + ], + }); + + // Make the provider return enough search suggestions to fill the view. + gProvider.results = []; + for (let i = 0; i < MAX_RESULT_COUNT; i++) { + gProvider.results.push( + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.SEARCH, + UrlbarUtils.RESULT_SOURCE.SEARCH, + { + suggestion: "suggestion " + i, + engine: Services.search.defaultEngine.name, + } + ) + ); + } + + // Do the first query to fill the view with search suggestions. + info("Doing first query"); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test 1", + }); + + // Now make the provider return a history result and bookmark. If + // `showExposureResults` is true, the history result will be added to the view + // but it should be hidden since the view is already full. If it's false, it + // shouldn't be added at all. The bookmark will always be added, which will + // tell us when the view has been updated either way. (It also will be hidden + // since the view is already full.) + let historyUrl = "https://example.com/history"; + let bookmarkUrl = "https://example.com/bookmark"; + gProvider.results = [ + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.HISTORY, + { url: historyUrl } + ), + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.BOOKMARKS, + { url: bookmarkUrl } + ), + ]; + + // When the provider's `startQuery()` is called, let it add its results but + // don't let it return. That will cause the view to be updated with the new + // results but prevent it from showing hidden rows since the query won't + // finish (so stale rows won't be removed). + let queryResolver = Promise.withResolvers(); + gProvider.finishQueryPromise = queryResolver.promise; + + // Observe when the view appends the bookmark row. This will tell us when the + // view has been updated with the provider's new results. The bookmark row + // will be hidden since the view is already full with search suggestions. + let lastRowPromise = promiseLastRowAppended( + row => row.result.payload.url == bookmarkUrl + ); + + // Now start the second query but don't await it. + info("Starting second query"); + let queryPromise = UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test 2", + reopenOnBlur: false, + }); + + // Wait for the view to be updated. + info("Waiting for last row"); + let lastRow = await lastRowPromise; + info("Done waiting for last row"); + + Assert.ok( + BrowserTestUtils.isHidden(lastRow), + "The new bookmark row should be hidden since the view is full" + ); + + // Make sure the view is full of visible rows as expected, plus the one or two + // hidden rows for the history and bookmark results. + let expected = [ + { + source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS, + type: UrlbarUtils.RESULT_TYPE.URL, + url: bookmarkUrl, + }, + ]; + if (showExposureResults) { + expected.unshift({ + source: UrlbarUtils.RESULT_SOURCE.HISTORY, + type: UrlbarUtils.RESULT_TYPE.URL, + url: historyUrl, + }); + } + let rows = UrlbarTestUtils.getResultsContainer(window); + Assert.equal( + rows.children.length, + MAX_RESULT_COUNT + expected.length, + "The view has the expected number of rows" + ); + + // Check the visible rows. + for (let i = 0; i < MAX_RESULT_COUNT; i++) { + let row = rows.children[i]; + Assert.ok(BrowserTestUtils.isVisible(row), `rows[${i}] should be visible`); + Assert.ok( + row.result.type == UrlbarUtils.RESULT_TYPE.SEARCH, + `rows[${i}].result.type should be SEARCH` + ); + // The heuristic won't have a suggestion so skip it. + if (i > 0) { + Assert.ok( + row.result.payload.suggestion, + `rows[${i}] should have a suggestion` + ); + } + } + + // Check the hidden history and bookmark rows. + for (let i = 0; i < expected.length; i++) { + let { source, type, url } = expected[i]; + let row = rows.children[MAX_RESULT_COUNT + i]; + Assert.ok(row, `rows[${i}] should exist`); + Assert.ok(BrowserTestUtils.isHidden(row), `rows[${i}] should be hidden`); + Assert.equal( + row.result.type, + type, + `rows[${i}].result.type should be as expected` + ); + Assert.equal( + row.result.source, + source, + `rows[${i}].result.source should be as expected` + ); + Assert.equal( + row.result.payload.url, + url, + `rows[${i}] URL should be as expected` + ); + } + + // Now let the query finish (so stale rows are removed). + queryResolver.resolve(); + info("Waiting for second query to finish"); + await queryPromise; + info("Second query finished"); + + rows = UrlbarTestUtils.getResultsContainer(window); + Assert.equal( + rows.children.length, + // + 1 for the heurustic. + 1 + expected.length, + "The view has the expected number of rows" + ); + + // Check the visible rows (except the heuristic). + for (let i = 0; i < expected.length; i++) { + let { source, type, url } = expected[i]; + let index = i + 1; + let row = rows.children[index]; + Assert.ok(row, `rows[${index}] should exist`); + Assert.ok( + BrowserTestUtils.isVisible(row), + `rows[${index}] should be visible` + ); + Assert.equal( + row.result.type, + type, + `rows[${index}].result.type should be as expected` + ); + Assert.equal( + row.result.source, + source, + `rows[${index}].result.source should be as expected` + ); + Assert.equal( + row.result.payload.url, + url, + `rows[${index}] URL should be as expected` + ); + } + + // Close the view. Blur the urlbar to end the session. + info("Closing view and blurring"); + await UrlbarTestUtils.promisePopupClose(window); + gURLBar.blur(); + + // An exposure for the history result should have been recorded. + assertExposureTelemetry([{ results: "history" }]); + + // Clean up. + await SpecialPowers.popPrefEnv(); + Services.fog.testResetFOG(); + gProvider.finishQueryPromise = null; +} + +// Does the following: +// +// 1. Starts and finishes a query that fills up the view +// 2. Starts a second query with results that cannot replace rows from the first +// query and that therefore must be appended and hidden +// 3. Before the second query finishes (i.e., before stale rows are removed), +// starts and finishes a third query (after which stale rows are removed) +// +// Results in the third query should trigger an exposure since they become +// visible when the query finishes (and stale rows are removed) in step 3. +// Results in the second query should not trigger an exposure since they could +// never be visible since the query is canceled before stale rows are removed. +add_task(async function exposure_append_full_twice() { + for (let showExposureResults of [true, false]) { + await do_exposure_append_full_twice(showExposureResults); + } +}); + +async function do_exposure_append_full_twice(showExposureResults) { + info( + "Starting do_exposure_append_full_twice: " + + JSON.stringify({ showExposureResults }) + ); + + // Exposure results are history and tab. + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.urlbar.exposureResults", "history,tab"], + ["browser.urlbar.showExposureResults", showExposureResults], + ], + }); + + // Make the provider return enough search suggestions to fill the view. + gProvider.results = []; + for (let i = 0; i < MAX_RESULT_COUNT; i++) { + gProvider.results.push( + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.SEARCH, + UrlbarUtils.RESULT_SOURCE.SEARCH, + { + suggestion: "suggestion " + i, + engine: Services.search.defaultEngine.name, + } + ) + ); + } + + // Do the first query to fill the view with search suggestions. + info("Doing first query"); + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test 1", + }); + + // Now make the provider return a history result, tab, and bookmark. If + // `showExposureResults` is true, the history and tab results will be added to + // the view but they should be hidden since the view is already full. If it's + // false, they shouldn't be added at all. The bookmark will always be added, + // which will tell us when the view has been updated either way. (It also will + // be hidden since the view is already full.) + let historyUrl = "https://example.com/history"; + let tabUrl = "https://example.com/tab"; + let bookmarkUrl = "https://example.com/bookmark"; + gProvider.results = [ + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.HISTORY, + { url: historyUrl } + ), + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.TAB_SWITCH, + UrlbarUtils.RESULT_SOURCE.TABS, + { url: tabUrl } + ), + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.BOOKMARKS, + { url: bookmarkUrl } + ), + ]; + + // When the provider's `startQuery()` is called, let it add its results but + // don't let it return. That will cause the view to be updated with the new + // results but prevent it from showing hidden rows since the query won't + // finish (so stale rows won't be removed). + let secondQueryResolver = Promise.withResolvers(); + gProvider.finishQueryPromise = secondQueryResolver.promise; + + // Observe when the view appends the bookmark row. This will tell us when the + // view has been updated with the provider's new results. The bookmark row + // will be hidden since the view is already full with search suggestions. + let lastRowPromise = promiseLastRowAppended( + row => row.result.payload.url == bookmarkUrl + ); + + // Now start the second query but don't await it. + info("Starting second query"); + let secondQueryPromise = UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test 2", + reopenOnBlur: false, + }); + + // Wait for the view to be updated. + info("Waiting for last row"); + let lastRow = await lastRowPromise; + info("Done waiting for last row"); + + Assert.ok( + BrowserTestUtils.isHidden(lastRow), + "The new bookmark row should be hidden since the view is full" + ); + + // Make sure the view is full of visible rows as expected, plus the one or + // three hidden rows for the history, tab, and bookmark results. + let expected = [ + { + source: UrlbarUtils.RESULT_SOURCE.BOOKMARKS, + type: UrlbarUtils.RESULT_TYPE.URL, + url: bookmarkUrl, + }, + ]; + if (showExposureResults) { + expected.unshift( + { + source: UrlbarUtils.RESULT_SOURCE.HISTORY, + type: UrlbarUtils.RESULT_TYPE.URL, + url: historyUrl, + }, + { + source: UrlbarUtils.RESULT_SOURCE.TABS, + type: UrlbarUtils.RESULT_TYPE.TAB_SWITCH, + url: tabUrl, + } + ); + } + let rows = UrlbarTestUtils.getResultsContainer(window); + Assert.equal( + rows.children.length, + MAX_RESULT_COUNT + expected.length, + "The view has the expected number of rows" + ); + + // Check the visible rows. + for (let i = 0; i < MAX_RESULT_COUNT; i++) { + let row = rows.children[i]; + Assert.ok(BrowserTestUtils.isVisible(row), `rows[${i}] should be visible`); + Assert.ok( + row.result.type == UrlbarUtils.RESULT_TYPE.SEARCH, + `rows[${i}].result.type should be SEARCH` + ); + // The heuristic won't have a suggestion so skip it. + if (i > 0) { + Assert.ok( + row.result.payload.suggestion, + `rows[${i}] should have a suggestion` + ); + } + } + + // Check the hidden history, tab, and bookmark rows. + for (let i = 0; i < expected.length; i++) { + let { source, type, url } = expected[i]; + let row = rows.children[MAX_RESULT_COUNT + i]; + Assert.ok(row, `rows[${i}] should exist`); + Assert.ok(BrowserTestUtils.isHidden(row), `rows[${i}] should be hidden`); + Assert.equal( + row.result.type, + type, + `rows[${i}].result.type should be as expected` + ); + Assert.equal( + row.result.source, + source, + `rows[${i}].result.source should be as expected` + ); + Assert.equal( + row.result.payload.url, + url, + `rows[${i}] URL should be as expected` + ); + } + + // Now make the provider return only a history result. + gProvider.results = [ + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.HISTORY, + { url: historyUrl } + ), + ]; + + // Without waiting for the second query to finish (i.e., before stale rows are + // removed), do a third query and allow it to finish (so stale rows are + // removed). An exposure should be recorded for the history result since it's + // present in the third query. An exposure should not be recorded for the tab + // result because it could not have been visible since the second query did + // not finish. + + let thirdQueryStartedPromise = new Promise(resolve => { + let queryListener = { + onQueryStarted: () => { + gURLBar.controller.removeQueryListener(queryListener); + resolve(); + }, + }; + gURLBar.controller.addQueryListener(queryListener); + }); + + info("Starting third query"); + let thirdQueryPromise = UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test 3", + reopenOnBlur: false, + }); + + // The test provider's `startQuery()` is still awaiting its + // `finishQueryPromise`, so we need to resolve it so the provider can respond + // to the third query. But before we do that, we need to make sure the third + // query has started and canceled the second query because otherwise the + // second query could finish and cause stale rows to be removed. + info("Waiting for third query to start"); + await thirdQueryStartedPromise; + info("Resolving provider's finishQueryPromise"); + secondQueryResolver.resolve(); + + // Now wait for the third query to finish. + info("Waiting for third query to finish"); + await thirdQueryPromise; + + expected = []; + if (showExposureResults) { + expected.unshift({ + source: UrlbarUtils.RESULT_SOURCE.HISTORY, + type: UrlbarUtils.RESULT_TYPE.URL, + url: historyUrl, + }); + } + + rows = UrlbarTestUtils.getResultsContainer(window); + Assert.equal( + rows.children.length, + // + 1 for the heurustic. + 1 + expected.length, + "The view has the expected number of rows" + ); + + // Check the history row. + for (let i = 0; i < expected.length; i++) { + let { source, type, url } = expected[i]; + let index = i + 1; + let row = rows.children[index]; + Assert.ok(row, `rows[${index}] should exist`); + Assert.ok( + BrowserTestUtils.isVisible(row), + `rows[${index}] should be visible` + ); + Assert.equal( + row.result.type, + type, + `rows[${index}].result.type should be as expected` + ); + Assert.equal( + row.result.source, + source, + `rows[${index}].result.source should be as expected` + ); + Assert.equal( + row.result.payload.url, + url, + `rows[${index}] URL should be as expected` + ); + } + + // Close the view. Blur the urlbar to end the session. + info("Closing view and blurring"); + await UrlbarTestUtils.promisePopupClose(window); + gURLBar.blur(); + + // An exposure only for the history result should have been recorded. If an + // exposure was also incorrectly recorded for the tab result, this will fail + // with "history,tab" instead of only "history". + assertExposureTelemetry([{ results: "history" }]); + + // Clean up. + await secondQueryPromise; + await SpecialPowers.popPrefEnv(); + Services.fog.testResetFOG(); + gProvider.finishQueryPromise = null; } /** @@ -523,7 +1065,7 @@ class TestProvider extends UrlbarTestUtils.TestProvider { function promiseLastRowAppended(predicate) { return new Promise(resolve => { let rows = UrlbarTestUtils.getResultsContainer(window); - let observer = new MutationObserver(mutations => { + let observer = new MutationObserver(() => { let lastRow = rows.children[rows.children.length - 1]; info( "Observed mutation, lastRow.result is: " + |