summaryrefslogtreecommitdiffstats
path: root/browser/components/urlbar/tests/browser/browser_engagement.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/urlbar/tests/browser/browser_engagement.js')
-rw-r--r--browser/components/urlbar/tests/browser/browser_engagement.js206
1 files changed, 206 insertions, 0 deletions
diff --git a/browser/components/urlbar/tests/browser/browser_engagement.js b/browser/components/urlbar/tests/browser/browser_engagement.js
new file mode 100644
index 0000000000..b964a61a75
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/browser_engagement.js
@@ -0,0 +1,206 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests the UrlbarProvider.onEngagement() method.
+
+"use strict";
+
+add_task(async function abandonment() {
+ await doTest({
+ expectedEndState: "abandonment",
+ endEngagement: async () => {
+ await UrlbarTestUtils.promisePopupClose(window, () => gURLBar.blur());
+ },
+ });
+});
+
+add_task(async function engagement() {
+ await BrowserTestUtils.withNewTab("about:blank", async () => {
+ await doTest({
+ expectedEndState: "engagement",
+ endEngagement: async () => {
+ let result, element;
+ await UrlbarTestUtils.promisePopupClose(window, () => {
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ result = gURLBar.view.selectedResult;
+ element = gURLBar.view.selectedElement;
+ EventUtils.synthesizeKey("KEY_Enter");
+ });
+ return { result, element };
+ },
+ expectedEndDetails: {
+ selIndex: 0,
+ selType: "history",
+ provider: "",
+ searchSource: "urlbar",
+ isSessionOngoing: false,
+ },
+ });
+ });
+});
+
+add_task(async function privateWindow_abandonment() {
+ let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
+ await doTest({
+ win,
+ expectedEndState: "abandonment",
+ expectedIsPrivate: true,
+ endEngagement: async () => {
+ await UrlbarTestUtils.promisePopupClose(win, () => win.gURLBar.blur());
+ },
+ });
+ await BrowserTestUtils.closeWindow(win);
+});
+
+add_task(async function privateWindow_engagement() {
+ let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
+ await doTest({
+ win,
+ expectedEndState: "engagement",
+ expectedIsPrivate: true,
+ endEngagement: async () => {
+ let result, element;
+ await UrlbarTestUtils.promisePopupClose(win, () => {
+ EventUtils.synthesizeKey("KEY_ArrowDown", {}, win);
+ result = win.gURLBar.view.selectedResult;
+ element = win.gURLBar.view.selectedElement;
+ EventUtils.synthesizeKey("KEY_Enter", {}, win);
+ });
+ return { result, element };
+ },
+ expectedEndDetails: {
+ selIndex: 0,
+ selType: "history",
+ provider: "",
+ searchSource: "urlbar",
+ isSessionOngoing: false,
+ },
+ });
+ await BrowserTestUtils.closeWindow(win);
+});
+
+/**
+ * Performs an engagement test.
+ *
+ * @param {object} options
+ * Options object.
+ * @param {string} options.expectedEndState
+ * The expected state at the end of the engagement.
+ * @param {Function} options.endEngagement
+ * A function that should end the engagement. If the expected end state is
+ * "engagement", the function should return `{ result, element }` with the
+ * expected engaged result and element.
+ * @param {window} [options.win]
+ * The window to perform the test in.
+ * @param {boolean} [options.expectedIsPrivate]
+ * Whether the engagement and query context are expected to be private.
+ * @param {object} [options.expectedEndDetails]
+ * The expected `details` at the end of the engagement. `searchString` is
+ * automatically included since it's always present. If `provider` is
+ * expected, then include it and set it to any value; this function will
+ * replace it with the name of the test provider.
+ */
+async function doTest({
+ expectedEndState,
+ endEngagement,
+ win = window,
+ expectedIsPrivate = false,
+ expectedEndDetails = {},
+}) {
+ let provider = new TestProvider();
+ UrlbarProvidersManager.registerProvider(provider);
+
+ let startPromise = provider.promiseEngagement();
+ await UrlbarTestUtils.promiseAutocompleteResultPopup({
+ window: win,
+ value: "test",
+ fireInputEvent: true,
+ });
+
+ let [isPrivate, state, queryContext, details] = await startPromise;
+ Assert.equal(isPrivate, expectedIsPrivate, "Start isPrivate");
+ Assert.equal(state, "start", "Start state");
+
+ // `queryContext` isn't always defined for `start`, and `onEngagement`
+ // shouldn't rely on it being defined on start, but there's no good reason to
+ // assert that it's not defined here.
+
+ // Similarly, `details` is never defined for `start`, but there's no good
+ // reason to assert that it's not defined.
+
+ let endPromise = provider.promiseEngagement();
+ let { result, element } = (await endEngagement()) ?? {};
+
+ [isPrivate, state, queryContext, details] = await endPromise;
+ Assert.equal(isPrivate, expectedIsPrivate, "End isPrivate");
+ Assert.equal(state, expectedEndState, "End state");
+ Assert.ok(queryContext, "End queryContext");
+ Assert.equal(
+ queryContext.isPrivate,
+ expectedIsPrivate,
+ "End queryContext.isPrivate"
+ );
+
+ let detailsDefaults = {
+ searchString: "test",
+ searchSource: "urlbar",
+ provider: undefined,
+ selIndex: -1,
+ };
+ if ("provider" in expectedEndDetails) {
+ detailsDefaults.provider = provider.name;
+ delete expectedEndDetails.provider;
+ }
+
+ if (expectedEndState == "engagement") {
+ Assert.ok(
+ result,
+ "endEngagement() should have returned the expected engaged result"
+ );
+ Assert.ok(
+ element,
+ "endEngagement() should have returned the expected engaged element"
+ );
+ expectedEndDetails.result = result;
+ expectedEndDetails.element = element;
+ }
+
+ Assert.deepEqual(
+ details,
+ Object.assign(detailsDefaults, expectedEndDetails),
+ "End details"
+ );
+
+ UrlbarProvidersManager.unregisterProvider(provider);
+}
+
+/**
+ * Test provider that resolves promises when onEngagement is called.
+ */
+class TestProvider extends UrlbarTestUtils.TestProvider {
+ _resolves = [];
+
+ constructor() {
+ super({
+ priority: Infinity,
+ results: [
+ new UrlbarResult(
+ UrlbarUtils.RESULT_TYPE.URL,
+ UrlbarUtils.RESULT_SOURCE.HISTORY,
+ { url: "http://example.com/" }
+ ),
+ ],
+ });
+ }
+
+ onEngagement(...args) {
+ let resolve = this._resolves.shift();
+ if (resolve) {
+ resolve(args);
+ }
+ }
+
+ promiseEngagement() {
+ return new Promise(resolve => this._resolves.push(resolve));
+ }
+}