diff options
Diffstat (limited to '')
-rw-r--r-- | browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js b/browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js new file mode 100644 index 0000000000..cc1ed29ceb --- /dev/null +++ b/browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js @@ -0,0 +1,304 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests feedback and dismissal acknowledgments in the view. + */ + +"use strict"; + +// The name of this command must be one that's recognized as not ending the +// urlbar session. See `isSessionOngoing` comments for details. +const FEEDBACK_COMMAND = "show_less_frequently"; + +let gTestProvider; + +add_setup(async function () { + gTestProvider = new TestProvider({ + results: [ + new UrlbarResult( + UrlbarUtils.RESULT_TYPE.URL, + UrlbarUtils.RESULT_SOURCE.OTHER_LOCAL, + { + url: "https://example.com/", + isBlockable: true, + blockL10n: { + id: "urlbar-result-menu-dismiss-firefox-suggest", + }, + } + ), + ], + }); + + gTestProvider.commandCount = {}; + UrlbarProvidersManager.registerProvider(gTestProvider); + + // Add a visit so that there's one result above the test result (the + // heuristic) and one below (the visit) just to make sure removing the test + // result doesn't mess up adjacent results. + await PlacesUtils.history.clear(); + await PlacesUtils.bookmarks.eraseEverything(); + await UrlbarTestUtils.formHistory.clear(); + await PlacesTestUtils.addVisits("https://example.com/aaa"); + + registerCleanupFunction(() => { + UrlbarProvidersManager.unregisterProvider(gTestProvider); + }); +}); + +// Tests dismissal acknowledgment when the dismissed row is not selected. +add_task(async function acknowledgeDismissal_rowNotSelected() { + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test", + }); + await doDismissTest({ shouldBeSelected: false }); +}); + +// Tests dismissal acknowledgment when the dismissed row is selected. +add_task(async function acknowledgeDismissal_rowSelected() { + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test", + }); + + // Select the row. + let resultIndex = await getTestResultIndex(); + while (gURLBar.view.selectedRowIndex != resultIndex) { + this.EventUtils.synthesizeKey("KEY_ArrowDown"); + } + + await doDismissTest({ resultIndex, shouldBeSelected: true }); +}); + +// Tests a feedback acknowledgment command immediately followed by a dismissal +// acknowledgment command. This makes sure that both feedback acknowledgment +// works and a subsequent dismissal command works while the urlbar session +// remains ongoing. +add_task(async function acknowledgeFeedbackAndDismissal() { + // Trigger the suggestion. + await UrlbarTestUtils.promiseAutocompleteResultPopup({ + window, + value: "test", + }); + + let resultIndex = await getTestResultIndex(); + let details = await UrlbarTestUtils.getDetailsOfResultAt(window, resultIndex); + + // Click the feedback command. + await UrlbarTestUtils.openResultMenuAndClickItem(window, FEEDBACK_COMMAND, { + resultIndex, + }); + + Assert.equal( + gTestProvider.commandCount[FEEDBACK_COMMAND], + 1, + "One feedback command should have happened" + ); + gTestProvider.commandCount[FEEDBACK_COMMAND] = 0; + + Assert.ok( + gURLBar.view.isOpen, + "The view should remain open clicking the command" + ); + Assert.ok( + details.element.row.hasAttribute("feedback-acknowledgment"), + "Row should have feedback acknowledgment after clicking command" + ); + + info("Doing dismissal"); + await doDismissTest({ resultIndex, shouldBeSelected: true }); +}); + +/** + * Does a dismissal test: + * + * 1. Clicks the dismiss command in the test result + * 2. Verifies a dismissal acknowledgment tip replaces the result + * 3. Clicks the "Got it" button in the tip + * 4. Verifies the tip is dismissed + * + * @param {object} options + * Options object + * @param {boolean} options.shouldBeSelected + * True if the test result is expected to be selected initially. If true, this + * function verifies the "Got it" button in the dismissal acknowledgment tip + * also becomes selected. + * @param {number} options.resultIndex + * The index of the test result, if known beforehand. Leave -1 to find it + * automatically. + */ +async function doDismissTest({ shouldBeSelected, resultIndex = -1 }) { + if (resultIndex < 0) { + resultIndex = await getTestResultIndex(); + } + + let selectedElement = gURLBar.view.selectedElement; + Assert.ok(selectedElement, "There should be an initially selected element"); + + if (shouldBeSelected) { + Assert.equal( + gURLBar.view.selectedRowIndex, + resultIndex, + "The test result should be selected" + ); + } else { + Assert.notEqual( + gURLBar.view.selectedRowIndex, + resultIndex, + "The test result should not be selected" + ); + } + + let resultCount = UrlbarTestUtils.getResultCount(window); + + // Click the dismiss command. + await UrlbarTestUtils.openResultMenuAndClickItem(window, "dismiss", { + resultIndex, + openByMouse: true, + }); + + Assert.equal( + gTestProvider.commandCount.dismiss, + 1, + "One dismissal should have happened" + ); + gTestProvider.commandCount.dismiss = 0; + + // The row should be a tip now. + Assert.ok(gURLBar.view.isOpen, "The view should remain open after dismissal"); + Assert.equal( + UrlbarTestUtils.getResultCount(window), + resultCount, + "The result count should not haved changed after dismissal" + ); + + let details = await UrlbarTestUtils.getDetailsOfResultAt(window, resultIndex); + Assert.equal( + details.type, + UrlbarUtils.RESULT_TYPE.TIP, + "Row should be a tip after dismissal" + ); + Assert.equal( + details.result.payload.type, + "dismissalAcknowledgment", + "Tip type should be dismissalAcknowledgment" + ); + Assert.ok( + !details.element.row.hasAttribute("selected"), + "Row should not have 'selected' attribute" + ); + Assert.ok( + !details.element.row._content.hasAttribute("selected"), + "Row-inner should not have 'selected' attribute" + ); + Assert.ok( + !details.element.row.hasAttribute("feedback-acknowledgment"), + "Row should not have feedback acknowledgment after dismissal" + ); + + // Get the dismissal acknowledgment's "Got it" button. + let gotItButton = UrlbarTestUtils.getButtonForResultIndex( + window, + "0", + resultIndex + ); + Assert.ok(gotItButton, "Row should have a 'Got it' button"); + + if (shouldBeSelected) { + Assert.equal( + gURLBar.view.selectedElement, + gotItButton, + "The 'Got it' button should be selected" + ); + } else { + Assert.notEqual( + gURLBar.view.selectedElement, + gotItButton, + "The 'Got it' button should not be selected" + ); + Assert.equal( + gURLBar.view.selectedElement, + selectedElement, + "The initially selected element should remain selected" + ); + } + + // Click it. + EventUtils.synthesizeMouseAtCenter(gotItButton, {}, window); + + // The view should remain open and the tip row should be gone. + Assert.ok( + gURLBar.view.isOpen, + "The view should remain open clicking the 'Got it' button" + ); + Assert.equal( + UrlbarTestUtils.getResultCount(window), + resultCount - 1, + "The result count should be one less after clicking 'Got it' button" + ); + for (let i = 0; i < UrlbarTestUtils.getResultCount(window); i++) { + details = await UrlbarTestUtils.getDetailsOfResultAt(window, i); + Assert.ok( + details.type != UrlbarUtils.RESULT_TYPE.TIP && + details.result.providerName != gTestProvider.name, + "Tip result and test result should not be present" + ); + } + + await UrlbarTestUtils.promisePopupClose(window); +} + +/** + * A provider that acknowledges feedback and dismissals. + */ +class TestProvider extends UrlbarTestUtils.TestProvider { + getResultCommands(result) { + return [ + { + name: FEEDBACK_COMMAND, + l10n: { + id: "firefox-suggest-weather-command-inaccurate-location", + }, + }, + { + name: "dismiss", + l10n: { + id: "firefox-suggest-weather-command-not-interested", + }, + }, + ]; + } + + onEngagement(isPrivate, state, queryContext, details) { + if (details.result?.providerName == this.name) { + let { selType } = details; + + info(`onEngagement called, selType=` + selType); + + if (!this.commandCount.hasOwnProperty(selType)) { + this.commandCount[selType] = 0; + } + this.commandCount[selType]++; + + if (selType == FEEDBACK_COMMAND) { + queryContext.view.acknowledgeFeedback(details.result); + } else if (selType == "dismiss") { + queryContext.view.acknowledgeDismissal(details.result); + } + } + } +} + +async function getTestResultIndex() { + let index = 0; + let resultCount = UrlbarTestUtils.getResultCount(window); + for (; index < resultCount; index++) { + let details = await UrlbarTestUtils.getDetailsOfResultAt(window, index); + if (details.result.providerName == gTestProvider.name) { + break; + } + } + Assert.less(index, resultCount, "The test result should be present"); + return index; +} |