diff options
Diffstat (limited to 'toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser')
29 files changed, 1385 insertions, 0 deletions
diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser.ini b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser.ini new file mode 100644 index 0000000000..4630a86977 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser.ini @@ -0,0 +1,36 @@ +[DEFAULT] +prefs = + identity.fxaccounts.remote.root=https://example.com/ +support-files = + head.js + ../../index.md + +[browser_sma_block_message.js] +[browser_sma_open_about_page.js] +[browser_sma_open_awesome_bar.js] +[browser_sma_open_firefox_view.js] +[browser_sma_open_private_browser_window.js] +[browser_sma_open_protection_panel.js] +[browser_sma_open_protection_report.js] +[browser_sma_open_url.js] +[browser_sma_open_spotlight_dialog.js] +[browser_sma_pin_current_tab.js] +[browser_sma_pin_firefox.js] +[browser_sma_pin_private_firefox.js] +skip-if = os != "win" +[browser_sma_show_firefox_accounts.js] +[browser_sma_show_migration_wizard.js] +skip-if = + os == "mac" && os_version == "10.15" && debug # Bug 1837646 +[browser_sma.js] +[browser_sma_docs.js] +[browser_sma_accept_doh.js] +[browser_sma_disable_doh.js] +[browser_sma_cfrmessageprovider.js] +[browser_sma_configure_homepage.js] +[browser_sma_default_browser.js] +[browser_sma_default_pdf_handler.js] +[browser_sma_set_prefs.js] +[browser_sma_click_element.js] +[browser_sma_handle_multiaction.js] +[browser_sma_open_firefoxview.js] diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma.js new file mode 100644 index 0000000000..b46b3730e9 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma.js @@ -0,0 +1,21 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_unknown_event() { + let error; + try { + await SpecialMessageActions.handleAction( + { type: "UNKNOWN_EVENT_123" }, + gBrowser + ); + } catch (e) { + error = e; + } + ok(error, "should throw if an unexpected event is handled"); + Assert.equal( + error.message, + "Special message action with type UNKNOWN_EVENT_123 is unsupported." + ); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_accept_doh.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_accept_doh.js new file mode 100644 index 0000000000..f9255b17ec --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_accept_doh.js @@ -0,0 +1,17 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; +const DOH_DOORHANGER_DECISION_PREF = "doh-rollout.doorhanger-decision"; + +add_task(async function test_disable_doh() { + await SpecialPowers.pushPrefEnv({ + set: [[DOH_DOORHANGER_DECISION_PREF, ""]], + }); + await SMATestUtils.executeAndValidateAction({ type: "ACCEPT_DOH" }); + Assert.equal( + Services.prefs.getStringPref(DOH_DOORHANGER_DECISION_PREF, ""), + "UIOk", + "Pref should be set on accept" + ); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_block_message.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_block_message.js new file mode 100644 index 0000000000..0671253b43 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_block_message.js @@ -0,0 +1,23 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_block_message() { + let blockStub = sinon.stub(SpecialMessageActions, "blockMessageById"); + + await SMATestUtils.executeAndValidateAction({ + type: "BLOCK_MESSAGE", + data: { + id: "TEST_MESSAGE_ID", + }, + }); + + Assert.equal(blockStub.callCount, 1, "blockMessageById called by the action"); + Assert.equal( + blockStub.firstCall.args[0], + "TEST_MESSAGE_ID", + "Argument is message id" + ); + blockStub.restore(); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_cancel.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_cancel.js new file mode 100644 index 0000000000..ca42dac563 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_cancel.js @@ -0,0 +1,14 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_cancel_event() { + let error = null; + try { + await SMATestUtils.executeAndValidateAction({ type: "CANCEL" }); + } catch (e) { + error = e; + } + ok(!error, "should not throw for CANCEL"); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_cfrmessageprovider.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_cfrmessageprovider.js new file mode 100644 index 0000000000..d89039c007 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_cfrmessageprovider.js @@ -0,0 +1,31 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { CFRMessageProvider } = ChromeUtils.importESModule( + "resource://activity-stream/lib/CFRMessageProvider.sys.mjs" +); + +add_task(async function test_all_test_messages() { + let messagesWithButtons = (await CFRMessageProvider.getMessages()).filter( + m => m.content.buttons + ); + + for (let message of messagesWithButtons) { + info(`Testing ${message.id}`); + if (message.template === "infobar") { + for (let button of message.content.buttons) { + await SMATestUtils.validateAction(button.action); + } + } else { + let { primary, secondary } = message.content.buttons; + await SMATestUtils.validateAction(primary.action); + for (let secondaryBtn of secondary) { + if (secondaryBtn.action) { + await SMATestUtils.validateAction(secondaryBtn.action); + } + } + } + } +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_click_element.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_click_element.js new file mode 100644 index 0000000000..afc4b03722 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_click_element.js @@ -0,0 +1,108 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { ASRouter } = ChromeUtils.import( + "resource://activity-stream/lib/ASRouter.jsm" +); +const { + withFirefoxView, + assertFirefoxViewTab, + openFirefoxViewTab, + closeFirefoxViewTab, +} = ChromeUtils.importESModule( + "resource://testing-common/FirefoxViewTestUtils.sys.mjs" +); + +const TEST_MESSAGE = { + message: { + template: "feature_callout", + content: { + id: "TEST_MESSAGE", + template: "multistage", + backdrop: "transparent", + transitions: false, + screens: [ + { + id: "TEST_SCREEN_ID", + parent_selector: "#tabpickup-steps", + content: { + position: "callout", + arrow_position: "top", + title: { + string_id: "Test", + }, + subtitle: { + string_id: "Test", + }, + primary_button: { + label: { + string_id: "Test", + }, + action: { + type: "CLICK_ELEMENT", + data: { + selector: + "#tab-pickup-container button.primary:not(#error-state-button)", + }, + }, + }, + }, + }, + ], + }, + }, +}; + +let sandbox; + +add_setup(async () => { + await SpecialPowers.pushPrefEnv({ + set: [["browser.tabs.firefox-view", true]], + }); + + sandbox = sinon.createSandbox(); + + registerCleanupFunction(async () => { + await SpecialPowers.popPrefEnv(); + sandbox.restore(); + }); +}); + +add_task(async function test_CLICK_ELEMENT() { + SpecialPowers.pushPrefEnv([ + "browser.firefox-view.feature-tour", + JSON.stringify({ + screen: "", + complete: true, + }), + ]); + + const sendTriggerStub = sandbox.stub(ASRouter, "sendTriggerMessage"); + sendTriggerStub.resolves(TEST_MESSAGE); + + await withFirefoxView({ openNewWindow: true }, async browser => { + const { document } = browser.contentWindow; + const calloutSelector = "#multi-stage-message-root.featureCallout"; + + await BrowserTestUtils.waitForCondition(() => { + return document.querySelector( + `${calloutSelector}:not(.hidden) .${TEST_MESSAGE.message.content.screens[0].id}` + ); + }); + + // Clicking the CTA with the CLICK_ELEMENT action should result in the element found with the configured selector being clicked + const clickElementSelector = + TEST_MESSAGE.message.content.screens[0].content.primary_button.action.data + .selector; + const clickElement = document.querySelector(clickElementSelector); + const successClick = () => { + ok(true, "Configured element was clicked"); + clickElement.removeEventListener("click", successClick); + }; + + clickElement.addEventListener("click", successClick); + document.querySelector(`${calloutSelector} button.primary`).click(); + }); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_configure_homepage.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_configure_homepage.js new file mode 100644 index 0000000000..ac9ae3d997 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_configure_homepage.js @@ -0,0 +1,110 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const HOMEPAGE_PREF = "browser.startup.homepage"; +const NEWTAB_PREF = "browser.newtabpage.enabled"; +const HIGHLIGHTS_PREF = + "browser.newtabpage.activity-stream.feeds.section.highlights"; +const HIGHLIGHTS_ROWS_PREF = + "browser.newtabpage.activity-stream.section.highlights.rows"; +const SEARCH_PREF = "browser.newtabpage.activity-stream.showSearch"; +const TOPSITES_PREF = "browser.newtabpage.activity-stream.feeds.topsites"; +const SNIPPETS_PREF = "browser.newtabpage.activity-stream.feeds.snippets"; +const TOPSTORIES_PREF = + "browser.newtabpage.activity-stream.feeds.system.topstories"; + +add_setup(async function () { + await SpecialPowers.pushPrefEnv({ + // Highlights are preffed off by default. + set: [ + [HIGHLIGHTS_PREF, true], + [ + "browser.newtabpage.activity-stream.discoverystream.endpointSpocsClear", + "", + ], + ], + }); + + registerCleanupFunction(async () => { + await SpecialPowers.popPrefEnv(); + [ + HOMEPAGE_PREF, + NEWTAB_PREF, + HIGHLIGHTS_PREF, + HIGHLIGHTS_ROWS_PREF, + SEARCH_PREF, + TOPSITES_PREF, + SNIPPETS_PREF, + ].forEach(prefName => Services.prefs.clearUserPref(prefName)); + }); +}); + +add_task(async function test_CONFIGURE_HOMEPAGE_newtab_home_prefs() { + const action = { + type: "CONFIGURE_HOMEPAGE", + data: { homePage: "default", newtab: "default" }, + }; + await SpecialPowers.pushPrefEnv({ + set: [ + [HOMEPAGE_PREF, "about:blank"], + [NEWTAB_PREF, false], + ], + }); + + Assert.ok(Services.prefs.prefHasUserValue(HOMEPAGE_PREF), "Test setup ok"); + Assert.ok(Services.prefs.prefHasUserValue(NEWTAB_PREF), "Test setup ok"); + + await SMATestUtils.executeAndValidateAction(action); + + Assert.ok( + !Services.prefs.prefHasUserValue(HOMEPAGE_PREF), + "Homepage pref should be back to default" + ); + Assert.ok( + !Services.prefs.prefHasUserValue(NEWTAB_PREF), + "Newtab pref should be back to default" + ); +}); + +add_task(async function test_CONFIGURE_HOMEPAGE_layout_prefs() { + const action = { + type: "CONFIGURE_HOMEPAGE", + data: { + layout: { + search: true, + topsites: false, + highlights: false, + snippets: false, + topstories: false, + }, + }, + }; + await SpecialPowers.pushPrefEnv({ + set: [ + [HIGHLIGHTS_ROWS_PREF, 3], + [SEARCH_PREF, false], + ], + }); + + await SMATestUtils.executeAndValidateAction(action); + + Assert.ok(Services.prefs.getBoolPref(SEARCH_PREF), "Search is turned on"); + Assert.ok( + !Services.prefs.getBoolPref(TOPSITES_PREF), + "Topsites are turned off" + ); + Assert.ok( + Services.prefs.getBoolPref(HIGHLIGHTS_PREF), + "HIGHLIGHTS_PREF are on because they have been customized" + ); + Assert.ok( + !Services.prefs.getBoolPref(TOPSTORIES_PREF), + "Topstories are turned off" + ); + Assert.ok( + !Services.prefs.getBoolPref(SNIPPETS_PREF), + "Snippets are turned off" + ); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_default_browser.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_default_browser.js new file mode 100644 index 0000000000..2d919456cd --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_default_browser.js @@ -0,0 +1,22 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_set_default_browser() { + const sandbox = sinon.createSandbox(); + const stub = sandbox.stub(); + + await SMATestUtils.executeAndValidateAction( + { type: "SET_DEFAULT_BROWSER" }, + { + ownerGlobal: { + getShellService: () => ({ + setAsDefault: stub, + }), + }, + } + ); + + Assert.equal(stub.callCount, 1, "setAsDefault was called by the action"); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_default_pdf_handler.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_default_pdf_handler.js new file mode 100644 index 0000000000..adb77b93e2 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_default_pdf_handler.js @@ -0,0 +1,92 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_set_default_pdf_handler_no_data() { + const sandbox = sinon.createSandbox(); + const stub = sandbox.stub(); + + await SMATestUtils.executeAndValidateAction( + { type: "SET_DEFAULT_PDF_HANDLER" }, + { + ownerGlobal: { + getShellService: () => ({ + setAsDefaultPDFHandler: stub, + }), + }, + } + ); + + Assert.equal( + stub.callCount, + 1, + "setAsDefaultPDFHandler was called by the action" + ); + Assert.ok( + stub.calledWithExactly(false), + "setAsDefaultPDFHandler called with onlyIfKnownBrowser = false" + ); +}); + +add_task(async function test_set_default_pdf_handler_data_false() { + const sandbox = sinon.createSandbox(); + const stub = sandbox.stub(); + + await SMATestUtils.executeAndValidateAction( + { + type: "SET_DEFAULT_PDF_HANDLER", + data: { + onlyIfKnownBrowser: false, + }, + }, + { + ownerGlobal: { + getShellService: () => ({ + setAsDefaultPDFHandler: stub, + }), + }, + } + ); + + Assert.equal( + stub.callCount, + 1, + "setAsDefaultPDFHandler was called by the action" + ); + Assert.ok( + stub.calledWithExactly(false), + "setAsDefaultPDFHandler called with onlyIfKnownBrowser = false" + ); +}); + +add_task(async function test_set_default_pdf_handler_data_true() { + const sandbox = sinon.createSandbox(); + const stub = sandbox.stub(); + + await SMATestUtils.executeAndValidateAction( + { + type: "SET_DEFAULT_PDF_HANDLER", + data: { + onlyIfKnownBrowser: true, + }, + }, + { + ownerGlobal: { + getShellService: () => ({ + setAsDefaultPDFHandler: stub, + }), + }, + } + ); + + Assert.equal( + stub.callCount, + 1, + "setAsDefaultPDFHandler was called by the action" + ); + Assert.ok( + stub.calledWithExactly(true), + "setAsDefaultPDFHandler called with onlyIfKnownBrowser = true" + ); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_disable_doh.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_disable_doh.js new file mode 100644 index 0000000000..aa61214360 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_disable_doh.js @@ -0,0 +1,28 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; +const DOH_DOORHANGER_DECISION_PREF = "doh-rollout.doorhanger-decision"; +const NETWORK_TRR_MODE_PREF = "network.trr.mode"; + +add_task(async function test_disable_doh() { + await SpecialPowers.pushPrefEnv({ + set: [ + [DOH_DOORHANGER_DECISION_PREF, "mochitest"], + [NETWORK_TRR_MODE_PREF, 0], + ], + }); + + await SMATestUtils.executeAndValidateAction({ type: "DISABLE_DOH" }); + + Assert.equal( + Services.prefs.getStringPref(DOH_DOORHANGER_DECISION_PREF, ""), + "UIDisabled", + "Pref should be set on disabled" + ); + Assert.equal( + Services.prefs.getIntPref(NETWORK_TRR_MODE_PREF, 0), + 5, + "Pref should be set on disabled" + ); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_docs.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_docs.js new file mode 100644 index 0000000000..cf2ec2c305 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_docs.js @@ -0,0 +1,32 @@ +const TEST_URL = + "https://example.com/browser/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/index.md"; + +function getHeadingsFromDocs(docs) { + const re = /### `(\w+)`/g; + const found = []; + let match = 1; + while (match) { + match = re.exec(docs); + if (match) { + found.push(match[1]); + } + } + return found; +} + +add_task(async function test_sma_docs() { + let request = await fetch(TEST_URL); + let docs = await request.text(); + let headings = getHeadingsFromDocs(docs); + const schemaTypes = ( + await fetchSMASchema + ).definitions.SpecialMessageActionSchemas.anyOf.map( + s => s.properties.type.enum[0] + ); + for (let schemaType of schemaTypes) { + Assert.ok( + headings.includes(schemaType), + `${schemaType} not found in SpecialMessageActionSchemas/index.md` + ); + } +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_handle_multiaction.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_handle_multiaction.js new file mode 100644 index 0000000000..709f4515ad --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_handle_multiaction.js @@ -0,0 +1,72 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_handle_multi_action() { + const action = { + type: "MULTI_ACTION", + data: { + actions: [ + { + type: "DISABLE_DOH", + }, + { + type: "OPEN_AWESOME_BAR", + }, + ], + }, + }; + const DOH_DOORHANGER_DECISION_PREF = "doh-rollout.doorhanger-decision"; + const NETWORK_TRR_MODE_PREF = "network.trr.mode"; + + await SpecialPowers.pushPrefEnv({ + set: [ + [DOH_DOORHANGER_DECISION_PREF, "mochitest"], + [NETWORK_TRR_MODE_PREF, 0], + ], + }); + + await SMATestUtils.executeAndValidateAction(action); + + Assert.equal( + Services.prefs.getStringPref(DOH_DOORHANGER_DECISION_PREF, ""), + "UIDisabled", + "Pref should be set on disabled" + ); + Assert.equal( + Services.prefs.getIntPref(NETWORK_TRR_MODE_PREF, 0), + 5, + "Pref should be set on disabled" + ); + + Assert.ok(gURLBar.focused, "Focus should be on awesome bar"); +}); + +add_task(async function test_handle_multi_action_with_invalid_action() { + const action = { + type: "MULTI_ACTION", + data: { + actions: [ + { + type: "NONSENSE", + }, + ], + }, + }; + + await SMATestUtils.validateAction(action); + + let error; + try { + await SpecialMessageActions.handleAction(action, gBrowser); + } catch (e) { + error = e; + } + + ok(error, "should throw if an unexpected event is handled"); + Assert.equal( + error.message, + "Error in MULTI_ACTION event: Special message action with type NONSENSE is unsupported." + ); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_about_page.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_about_page.js new file mode 100644 index 0000000000..264646bd0e --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_about_page.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_OPEN_ABOUT_PAGE() { + const tabPromise = BrowserTestUtils.waitForNewTab( + gBrowser, + "about:logins?foo=bar" + ); + await SMATestUtils.executeAndValidateAction({ + type: "OPEN_ABOUT_PAGE", + data: { args: "logins", entrypoint: "foo=bar", where: "tabshifted" }, + }); + + const tab = await tabPromise; + ok(tab, "should open about page with entrypoint in a new tab by default"); + BrowserTestUtils.removeTab(tab); +}); + +add_task(async function test_OPEN_ABOUT_PAGE_NEW_WINDOW() { + const newWindowPromise = BrowserTestUtils.waitForNewWindow( + gBrowser, + "about:robots?foo=bar" + ); + await SMATestUtils.executeAndValidateAction({ + type: "OPEN_ABOUT_PAGE", + data: { args: "robots", entrypoint: "foo=bar", where: "window" }, + }); + + const win = await newWindowPromise; + ok(win, "should open about page in a new window"); + BrowserTestUtils.closeWindow(win); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_awesome_bar.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_awesome_bar.js new file mode 100644 index 0000000000..62f7d8bb68 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_awesome_bar.js @@ -0,0 +1,9 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_OPEN_AWESOME_BAR() { + await SMATestUtils.executeAndValidateAction({ type: "OPEN_AWESOME_BAR" }); + Assert.ok(gURLBar.focused, "Focus should be on awesome bar"); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_firefox_view.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_firefox_view.js new file mode 100644 index 0000000000..110d864121 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_firefox_view.js @@ -0,0 +1,49 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { assertFirefoxViewTab, closeFirefoxViewTab } = + ChromeUtils.importESModule( + "resource://testing-common/FirefoxViewTestUtils.sys.mjs" + ); + +add_setup(async () => { + await SpecialPowers.pushPrefEnv({ + set: [["browser.tabs.firefox-view", true]], + }); + + CustomizableUI.addWidgetToArea( + "firefox-view-button", + CustomizableUI.AREA_TABSTRIP, + 0 + ); + + registerCleanupFunction(async () => { + // If you're running mochitest with --keep-open=true, and need to + // easily tell whether the button really appeared, comment out the below + // line so that the button hangs around after the test finishes. + CustomizableUI.removeWidgetFromArea("firefox-view-button"); + await SpecialPowers.popPrefEnv(); + }); +}); + +add_task(async function test_open_firefox_view() { + // setup + let newTabOpened = BrowserTestUtils.waitForEvent( + gBrowser.tabContainer, + "TabOpen" + ); + + // execute + await SMATestUtils.executeAndValidateAction({ + type: "OPEN_FIREFOX_VIEW", + }); + + // verify + await newTabOpened; + assertFirefoxViewTab(window); + + // cleanup + closeFirefoxViewTab(window); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_firefoxview.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_firefoxview.js new file mode 100644 index 0000000000..c3b9aa884a --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_firefoxview.js @@ -0,0 +1,20 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_open_firefoxview() { + const tabPromise = BrowserTestUtils.waitForNewTab( + gBrowser, + "about:firefoxview" + ); + await SMATestUtils.executeAndValidateAction({ + type: "OPEN_FIREFOX_VIEW", + }); + + const tab = await tabPromise; + + ok(tab, "should open about:firefoxview in a new tab"); + + BrowserTestUtils.removeTab(tab); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_private_browser_window.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_private_browser_window.js new file mode 100644 index 0000000000..b6c933fbcf --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_private_browser_window.js @@ -0,0 +1,17 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_OPEN_PRIVATE_BROWSER_WINDOW() { + const newWindowPromise = BrowserTestUtils.waitForNewWindow(); + await SMATestUtils.executeAndValidateAction({ + type: "OPEN_PRIVATE_BROWSER_WINDOW", + }); + const win = await newWindowPromise; + ok( + PrivateBrowsingUtils.isWindowPrivate(win), + "should open a private browsing window" + ); + await BrowserTestUtils.closeWindow(win); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_protection_panel.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_protection_panel.js new file mode 100644 index 0000000000..c9522426a2 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_protection_panel.js @@ -0,0 +1,22 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_OPEN_PROTECTION_PANEL() { + await BrowserTestUtils.withNewTab(EXAMPLE_URL, async browser => { + const popupshown = BrowserTestUtils.waitForEvent( + window, + "popupshown", + true, + e => e.target.id == "protections-popup" + ); + + await SMATestUtils.executeAndValidateAction({ + type: "OPEN_PROTECTION_PANEL", + }); + + let { target: popupEl } = await popupshown; + Assert.equal(popupEl.state, "open", "Protections popup is open."); + }); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_protection_report.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_protection_report.js new file mode 100644 index 0000000000..3960075cd9 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_protection_report.js @@ -0,0 +1,29 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_OPEN_PROTECTION_REPORT() { + await BrowserTestUtils.withNewTab("about:blank", async browser => { + let loaded = BrowserTestUtils.browserLoaded( + browser, + false, + "about:protections" + ); + + await SMATestUtils.executeAndValidateAction({ + type: "OPEN_PROTECTION_REPORT", + }); + + await loaded; + + // When the graph is built it means any messaging has finished, + // we can close the tab. + await SpecialPowers.spawn(browser, [], async function () { + await ContentTaskUtils.waitForCondition(() => { + let bars = content.document.querySelectorAll(".graph-bar"); + return bars.length; + }, "The graph has been built"); + }); + }); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_spotlight_dialog.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_spotlight_dialog.js new file mode 100644 index 0000000000..29e72535ea --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_spotlight_dialog.js @@ -0,0 +1,38 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { OnboardingMessageProvider } = ChromeUtils.import( + "resource://activity-stream/lib/OnboardingMessageProvider.jsm" +); + +const { Spotlight } = ChromeUtils.import( + "resource://activity-stream/lib/Spotlight.jsm" +); + +add_task(async function test_OPEN_SPOTLIGHT_DIALOG() { + let pbNewTabMessage = ( + await OnboardingMessageProvider.getUntranslatedMessages() + ).filter(m => m.id === "PB_NEWTAB_FOCUS_PROMO"); + info(`Testing ${pbNewTabMessage[0].id}`); + let showSpotlightStub = sinon.stub(Spotlight, "showSpotlightDialog"); + await SMATestUtils.executeAndValidateAction({ + type: "SHOW_SPOTLIGHT", + data: { ...pbNewTabMessage[0].content.promoButton.action.data }, + }); + + Assert.equal( + showSpotlightStub.callCount, + 1, + "Should call showSpotlightDialog" + ); + + Assert.deepEqual( + showSpotlightStub.firstCall.args[1], + pbNewTabMessage[0].content.promoButton.action.data, + "Should be called with action.data" + ); + + showSpotlightStub.restore(); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_url.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_url.js new file mode 100644 index 0000000000..876193b7ad --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_open_url.js @@ -0,0 +1,33 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_OPEN_URL() { + const action = { + type: "OPEN_URL", + data: { args: EXAMPLE_URL, where: "current" }, + }; + await BrowserTestUtils.withNewTab("about:blank", async browser => { + const loaded = BrowserTestUtils.browserLoaded(browser); + await SMATestUtils.executeAndValidateAction(action); + const url = await loaded; + Assert.equal( + url, + "https://example.com/", + "should open URL in the same tab" + ); + }); +}); + +add_task(async function test_OPEN_URL_new_tab() { + const action = { + type: "OPEN_URL", + data: { args: EXAMPLE_URL, where: "tab" }, + }; + const tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, EXAMPLE_URL); + await SpecialMessageActions.handleAction(action, gBrowser); + const browser = await tabPromise; + ok(browser, "should open URL in a new tab"); + BrowserTestUtils.removeTab(browser); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_current_tab.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_current_tab.js new file mode 100644 index 0000000000..4425325526 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_current_tab.js @@ -0,0 +1,14 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_PIN_CURRENT_TAB() { + await BrowserTestUtils.withNewTab("about:blank", async browser => { + await SMATestUtils.executeAndValidateAction({ type: "PIN_CURRENT_TAB" }); + + ok(gBrowser.selectedTab.pinned, "should pin current tab"); + + gBrowser.unpinTab(gBrowser.selectedTab); + }); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_firefox.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_firefox.js new file mode 100644 index 0000000000..09714e6703 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_firefox.js @@ -0,0 +1,72 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const isWin = AppConstants.platform == "win"; +const isMac = AppConstants.platform == "macosx"; + +add_task(async function test_PIN_FIREFOX_TO_TASKBAR() { + const sandbox = sinon.createSandbox(); + let shell = { + async checkPinCurrentAppToTaskbarAsync() {}, + QueryInterface: () => shell, + get macDockSupport() { + return this; + }, + get shellService() { + return this; + }, + + ensureAppIsPinnedToDock: sandbox.stub(), + isCurrentAppPinnedToTaskbarAsync: sandbox.stub(), + pinCurrentAppToTaskbarAsync: sandbox.stub().resolves(undefined), + isAppInDock: false, + }; + + // Prefer the mocked implementation and fall back to the original version, + // which can call back into the mocked version (via this.shellService). + shell = new Proxy(shell, { + get(target, prop) { + return (prop in target ? target : ShellService)[prop]; + }, + }); + + const test = () => + SMATestUtils.executeAndValidateAction( + { type: "PIN_FIREFOX_TO_TASKBAR" }, + { + ownerGlobal: { + getShellService: () => shell, + }, + } + ); + + await test(); + + function check(count, message) { + Assert.equal( + shell.pinCurrentAppToTaskbarAsync.callCount, + count * isWin, + `pinCurrentAppToTaskbarAsync was ${message} by the action for windows` + ); + Assert.equal( + shell.ensureAppIsPinnedToDock.callCount, + count * isMac, + `ensureAppIsPinnedToDock was ${message} by the action for not windows` + ); + } + check(1, "called"); + + // Pretend the app is already pinned. + shell.isCurrentAppPinnedToTaskbarAsync.resolves(true); + shell.isAppInDock = true; + await test(); + check(1, "not called"); + + // Pretend the app became unpinned. + shell.isCurrentAppPinnedToTaskbarAsync.resolves(false); + shell.isAppInDock = false; + await test(); + check(2, "called again"); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_private_firefox.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_private_firefox.js new file mode 100644 index 0000000000..90880edd27 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_pin_private_firefox.js @@ -0,0 +1,78 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_PIN_PRIVATE_FIREFOX_TO_TASKBAR() { + const sandbox = sinon.createSandbox(); + let shell = { + async checkPinCurrentAppToTaskbarAsync() {}, + QueryInterface: () => shell, + get macDockSupport() { + return this; + }, + get shellService() { + return this; + }, + + ensureAppIsPinnedToDock: sandbox.stub(), + isCurrentAppPinnedToTaskbarAsync: sandbox.stub(), + pinCurrentAppToTaskbarAsync: sandbox.stub().resolves(undefined), + isAppInDock: false, + }; + + // Prefer the mocked implementation and fall back to the original version, + // which can call back into the mocked version (via this.shellService). + shell = new Proxy(shell, { + get(target, prop) { + return (Object.hasOwn(target, prop) ? target : ShellService)[prop]; + }, + }); + + const test = () => + SMATestUtils.executeAndValidateAction( + { + type: "PIN_FIREFOX_TO_TASKBAR", + data: { + privatePin: true, + }, + }, + { + ownerGlobal: { + getShellService: () => shell, + }, + } + ); + + await test(); + + function check(count, message, arg) { + Assert.equal( + shell.pinCurrentAppToTaskbarAsync.callCount, + count, + `pinCurrentAppToTaskbarAsync was ${message} by the action for windows` + ); + if (arg) { + Assert.equal( + shell.pinCurrentAppToTaskbarAsync.calledWith(arg), + true, + `pinCurrentAppToTaskbarAsync was ${message} with the arg: ${JSON.stringify( + arg + )}` + ); + } + } + check(1, "called", true); + + // Pretend the app is already pinned. + shell.isCurrentAppPinnedToTaskbarAsync.resolves(true); + shell.isAppInDock = true; + await test(); + check(1, "not called"); + + // Pretend the app became unpinned. + shell.isCurrentAppPinnedToTaskbarAsync.resolves(false); + shell.isAppInDock = false; + await test(); + check(2, "called again", true); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_set_prefs.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_set_prefs.js new file mode 100644 index 0000000000..3d408192b6 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_set_prefs.js @@ -0,0 +1,167 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const HOMEPAGE_PREF = "browser.startup.homepage"; +const PRIVACY_SEGMENTATION_PREF = "browser.dataFeatureRecommendations.enabled"; +const MESSAGING_ACTION_PREF = "special-message-testpref"; + +const PREFS_TO_CLEAR = [ + HOMEPAGE_PREF, + PRIVACY_SEGMENTATION_PREF, + `messaging-system-action.${MESSAGING_ACTION_PREF}`, +]; + +add_setup(async function () { + registerCleanupFunction(async () => { + PREFS_TO_CLEAR.forEach(pref => Services.prefs.clearUserPref(pref)); + }); +}); + +add_task(async function test_set_privacy_segmentation_pref() { + const action = { + type: "SET_PREF", + data: { + pref: { + name: PRIVACY_SEGMENTATION_PREF, + value: true, + }, + }, + }; + + Assert.ok( + !Services.prefs.prefHasUserValue(PRIVACY_SEGMENTATION_PREF), + "Test setup ok" + ); + + await SMATestUtils.executeAndValidateAction(action); + + Assert.ok( + Services.prefs.getBoolPref(PRIVACY_SEGMENTATION_PREF), + `${PRIVACY_SEGMENTATION_PREF} pref successfully updated` + ); +}); + +add_task(async function test_clear_privacy_segmentation_pref() { + Services.prefs.setBoolPref(PRIVACY_SEGMENTATION_PREF, true); + Assert.ok( + Services.prefs.prefHasUserValue(PRIVACY_SEGMENTATION_PREF), + "Test setup ok" + ); + + const action = { + type: "SET_PREF", + data: { + pref: { + name: PRIVACY_SEGMENTATION_PREF, + }, + }, + }; + + await SMATestUtils.executeAndValidateAction(action); + + Assert.ok( + !Services.prefs.prefHasUserValue(PRIVACY_SEGMENTATION_PREF), + `${PRIVACY_SEGMENTATION_PREF} pref successfully cleared` + ); +}); + +add_task(async function test_set_homepage_pref() { + const action = { + type: "SET_PREF", + data: { + pref: { + name: HOMEPAGE_PREF, + value: "https://foo.example.com", + }, + }, + }; + + Assert.ok(!Services.prefs.prefHasUserValue(HOMEPAGE_PREF), "Test setup ok"); + + await SMATestUtils.executeAndValidateAction(action); + + Assert.equal( + Services.prefs.getStringPref(HOMEPAGE_PREF), + "https://foo.example.com", + `${HOMEPAGE_PREF} pref successfully updated` + ); +}); + +add_task(async function test_clear_homepage_pref() { + Services.prefs.setStringPref(HOMEPAGE_PREF, "https://www.example.com"); + Assert.ok(Services.prefs.prefHasUserValue(HOMEPAGE_PREF), "Test setup ok"); + + const action = { + type: "SET_PREF", + data: { + pref: { + name: HOMEPAGE_PREF, + }, + }, + }; + + await SMATestUtils.executeAndValidateAction(action); + + Assert.ok( + !Services.prefs.prefHasUserValue(HOMEPAGE_PREF), + `${HOMEPAGE_PREF} pref successfully updated` + ); +}); + +// Set a pref not listed in "allowed prefs" +add_task(async function test_set_messaging_system_pref() { + const action = { + type: "SET_PREF", + data: { + pref: { + name: MESSAGING_ACTION_PREF, + value: true, + }, + }, + }; + + await SMATestUtils.executeAndValidateAction(action); + + Assert.equal( + Services.prefs.getBoolPref( + `messaging-system-action.${MESSAGING_ACTION_PREF}` + ), + true, + `messaging-system-action.${MESSAGING_ACTION_PREF} pref successfully updated to correct value` + ); +}); + +// Clear a pref not listed in "allowed prefs" that was initially set by +// the SET_PREF special messaging action +add_task(async function test_clear_messaging_system_pref() { + Services.prefs.setBoolPref( + `messaging-system-action.${MESSAGING_ACTION_PREF}`, + true + ); + Assert.ok( + Services.prefs.prefHasUserValue( + `messaging-system-action.${MESSAGING_ACTION_PREF}` + ), + "Test setup ok" + ); + + const action = { + type: "SET_PREF", + data: { + pref: { + name: MESSAGING_ACTION_PREF, + }, + }, + }; + + await SMATestUtils.executeAndValidateAction(action); + + Assert.ok( + !Services.prefs.prefHasUserValue( + `messaging-system-action.${MESSAGING_ACTION_PREF}` + ), + `messaging-system-action.${MESSAGING_ACTION_PREF} pref successfully cleared` + ); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_show_firefox_accounts.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_show_firefox_accounts.js new file mode 100644 index 0000000000..82bba359a3 --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_show_firefox_accounts.js @@ -0,0 +1,66 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Note: "identity.fxaccounts.remote.root" is set to https://example.com in browser.ini +add_task(async function test_SHOW_FIREFOX_ACCOUNTS() { + await BrowserTestUtils.withNewTab("about:blank", async browser => { + let loaded = BrowserTestUtils.browserLoaded(browser); + await SMATestUtils.executeAndValidateAction({ + type: "SHOW_FIREFOX_ACCOUNTS", + data: { entrypoint: "snippets" }, + }); + Assert.equal( + await loaded, + "https://example.com/?context=fx_desktop_v3&entrypoint=snippets&action=email&service=sync", + "should load fxa with endpoint=snippets" + ); + + // Open a URL + loaded = BrowserTestUtils.browserLoaded(browser); + await SMATestUtils.executeAndValidateAction({ + type: "SHOW_FIREFOX_ACCOUNTS", + data: { entrypoint: "aboutwelcome" }, + }); + + Assert.equal( + await loaded, + "https://example.com/?context=fx_desktop_v3&entrypoint=aboutwelcome&action=email&service=sync", + "should load fxa with a custom endpoint" + ); + + // Open a URL with extra parameters + loaded = BrowserTestUtils.browserLoaded(browser); + await SMATestUtils.executeAndValidateAction({ + type: "SHOW_FIREFOX_ACCOUNTS", + data: { entrypoint: "test", extraParams: { foo: "bar" } }, + }); + + Assert.equal( + await loaded, + "https://example.com/?context=fx_desktop_v3&entrypoint=test&action=email&service=sync&foo=bar", + "should load fxa with a custom endpoint and extra parameters in url" + ); + }); + + add_task(async function test_SHOW_FIREFOX_ACCOUNTS_where() { + // Open FXA with a 'where' prop + const action = { + type: "SHOW_FIREFOX_ACCOUNTS", + data: { + entrypoint: "activity-stream-firstrun", + where: "tab", + }, + }; + const tabPromise = BrowserTestUtils.waitForNewTab( + gBrowser, + "https://example.com/?context=fx_desktop_v3&entrypoint=activity-stream-firstrun&action=email&service=sync" + ); + + await SpecialMessageActions.handleAction(action, gBrowser); + const browser = await tabPromise; + ok(browser, "should open FXA in a new tab"); + BrowserTestUtils.removeTab(browser); + }); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_show_migration_wizard.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_show_migration_wizard.js new file mode 100644 index 0000000000..aea84f026a --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/browser_sma_show_migration_wizard.js @@ -0,0 +1,69 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const FORCE_LEGACY = + Services.prefs.getCharPref( + "browser.migrate.content-modal.about-welcome-behavior", + "default" + ) == "legacy"; + +add_setup(async () => { + // Load the initial tab at example.com. This makes it so that if + // we're using the new migration wizard, we'll load the about:preferences + // page in a new tab rather than overtaking the initial one. This + // makes it easier to be consistent with closing and opening + // behaviours between the two kinds of migration wizards. + let browser = gBrowser.selectedBrowser; + BrowserTestUtils.loadURIString(browser, "https://example.com"); + await BrowserTestUtils.browserLoaded(browser); +}); + +add_task(async function test_SHOW_MIGRATION_WIZARD() { + let wizardOpened = BrowserTestUtils.waitForMigrationWizard( + window, + FORCE_LEGACY + ); + + await SMATestUtils.executeAndValidateAction({ + type: "SHOW_MIGRATION_WIZARD", + }); + + let wizard = await wizardOpened; + ok(wizard, "Migration wizard opened"); + await BrowserTestUtils.closeMigrationWizard(wizard, FORCE_LEGACY); +}); + +add_task(async function test_SHOW_MIGRATION_WIZARD_WITH_SOURCE() { + let wizardOpened = BrowserTestUtils.waitForMigrationWizard( + window, + FORCE_LEGACY + ); + + await SMATestUtils.executeAndValidateAction({ + type: "SHOW_MIGRATION_WIZARD", + data: { source: "chrome" }, + }); + + let wizard = await wizardOpened; + ok(wizard, "Migrator window opened when source param specified"); + await BrowserTestUtils.closeMigrationWizard(wizard, FORCE_LEGACY); +}); + +add_task(async function test_SHOW_MIGRATION_WIZARD_forcing_legacy() { + await SpecialPowers.pushPrefEnv({ + set: [["browser.migrate.content-modal.about-welcome-behavior", "legacy"]], + }); + + let wizardOpened = BrowserTestUtils.waitForMigrationWizard(window, true); + + await SMATestUtils.executeAndValidateAction({ + type: "SHOW_MIGRATION_WIZARD", + data: { source: "chrome" }, + }); + + let wizard = await wizardOpened; + ok(wizard, "Legacy migrator window opened"); + await BrowserTestUtils.closeMigrationWizard(wizard, true); +}); diff --git a/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/head.js b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/head.js new file mode 100644 index 0000000000..a23b2f67dc --- /dev/null +++ b/toolkit/components/messaging-system/schemas/SpecialMessageActionSchemas/test/browser/head.js @@ -0,0 +1,62 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { sinon } = ChromeUtils.importESModule( + "resource://testing-common/Sinon.sys.mjs" +); +const { JsonSchema } = ChromeUtils.importESModule( + "resource://gre/modules/JsonSchema.sys.mjs" +); + +ChromeUtils.defineESModuleGetters(this, { + SpecialMessageActions: + "resource://messaging-system/lib/SpecialMessageActions.sys.mjs", +}); + +XPCOMUtils.defineLazyGetter(this, "fetchSMASchema", async () => { + const response = await fetch( + "resource://testing-common/SpecialMessageActionSchemas.json" + ); + const schema = await response.json(); + if (!schema) { + throw new Error("Failed to load SpecialMessageActionSchemas"); + } + return schema; +}); + +const EXAMPLE_URL = "https://example.com/"; + +const SMATestUtils = { + /** + * Checks if an action is valid acording to existing schemas + * @param {SpecialMessageAction} action + */ + async validateAction(action) { + const schema = await fetchSMASchema; + const result = JsonSchema.validate(action, schema); + if (result.errors.length) { + throw new Error( + `Action with type ${ + action.type + } was not valid. Errors: ${JSON.stringify(result.errors, undefined, 2)}` + ); + } + is( + result.errors.length, + 0, + `Should be a valid action of type ${action.type}` + ); + }, + + /** + * Executes a Special Message Action after validating it + * @param {SpecialMessageAction} action + * @param {Browser} browser + */ + async executeAndValidateAction(action, browser = gBrowser) { + await SMATestUtils.validateAction(action); + await SpecialMessageActions.handleAction(action, browser); + }, +}; |