summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js')
-rw-r--r--browser/components/urlbar/tests/browser/browser_acknowledgeFeedbackAndDismissal.js304
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;
+}