summaryrefslogtreecommitdiffstats
path: root/browser/components/payments/test/mochitest/payments_common.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/payments/test/mochitest/payments_common.js')
-rw-r--r--browser/components/payments/test/mochitest/payments_common.js154
1 files changed, 154 insertions, 0 deletions
diff --git a/browser/components/payments/test/mochitest/payments_common.js b/browser/components/payments/test/mochitest/payments_common.js
new file mode 100644
index 0000000000..8e48585318
--- /dev/null
+++ b/browser/components/payments/test/mochitest/payments_common.js
@@ -0,0 +1,154 @@
+"use strict";
+
+/* exported asyncElementRendered, promiseStateChange, promiseContentToChromeMessage, deepClone,
+ PTU, registerConsoleFilter, fillField, importDialogDependencies */
+
+const PTU = SpecialPowers.Cu.import(
+ "resource://testing-common/PaymentTestUtils.jsm",
+ {}
+).PaymentTestUtils;
+
+/**
+ * A helper to await on while waiting for an asynchronous rendering of a Custom
+ * Element.
+ * @returns {Promise}
+ */
+function asyncElementRendered() {
+ return Promise.resolve();
+}
+
+function promiseStateChange(store) {
+ return new Promise(resolve => {
+ store.subscribe({
+ stateChangeCallback(state) {
+ store.unsubscribe(this);
+ resolve(state);
+ },
+ });
+ });
+}
+
+/**
+ * Wait for a message of `messageType` from content to chrome and resolve with the event details.
+ * @param {string} messageType of the expected message
+ * @returns {Promise} when the message is dispatched
+ */
+function promiseContentToChromeMessage(messageType) {
+ return new Promise(resolve => {
+ document.addEventListener("paymentContentToChrome", function onCToC(event) {
+ if (event.detail.messageType != messageType) {
+ return;
+ }
+ document.removeEventListener("paymentContentToChrome", onCToC);
+ resolve(event.detail);
+ });
+ });
+}
+
+/**
+ * Import the templates and stylesheets from the real shipping dialog to avoid
+ * duplication in the tests.
+ * @param {HTMLIFrameElement} templateFrame - Frame to copy the resources from
+ * @param {HTMLElement} destinationEl - Where to append the copied resources
+ */
+function importDialogDependencies(templateFrame, destinationEl) {
+ let templates = templateFrame.contentDocument.querySelectorAll("template");
+ isnot(templates, null, "Check some templates found");
+ for (let template of templates) {
+ let imported = document.importNode(template, true);
+ destinationEl.appendChild(imported);
+ }
+
+ let baseURL = new URL("../../res/", window.location.href);
+ let stylesheetLinks = templateFrame.contentDocument.querySelectorAll(
+ "link[rel~='stylesheet']"
+ );
+ for (let stylesheet of stylesheetLinks) {
+ let imported = document.importNode(stylesheet, true);
+ imported.href = new URL(imported.getAttribute("href"), baseURL);
+ destinationEl.appendChild(imported);
+ }
+}
+
+function deepClone(obj) {
+ return JSON.parse(JSON.stringify(obj));
+}
+
+/**
+ * @param {HTMLElement} field
+ * @param {string} value
+ * @note This is async in case we need to make it async to handle focus in the future.
+ * @note Keep in sync with the copy in head.js
+ */
+async function fillField(field, value) {
+ field.focus();
+ if (field.localName == "select") {
+ if (field.value == value) {
+ // Do nothing
+ return;
+ }
+ field.value = value;
+ field.dispatchEvent(new Event("input", { bubbles: true }));
+ field.dispatchEvent(new Event("change", { bubbles: true }));
+ return;
+ }
+ while (field.value) {
+ sendKey("BACK_SPACE");
+ }
+ sendString(value);
+}
+
+/**
+ * If filterFunction is a function which returns true given a console message
+ * then the test won't fail from that message.
+ */
+let filterFunction = null;
+function registerConsoleFilter(filterFn) {
+ filterFunction = filterFn;
+}
+
+// Listen for errors to fail tests
+SpecialPowers.registerConsoleListener(function onConsoleMessage(msg) {
+ if (
+ msg.isWarning ||
+ !msg.errorMessage ||
+ msg.errorMessage == "paymentRequest.xhtml:"
+ ) {
+ // Ignore warnings and non-errors.
+ return;
+ }
+ if (
+ msg.category == "CSP_CSPViolationWithURI" &&
+ msg.errorMessage.includes("at inline")
+ ) {
+ // Ignore unknown CSP error.
+ return;
+ }
+ if (
+ msg.message &&
+ msg.message.includes("Security Error: Content at http://mochi.test:8888")
+ ) {
+ // Check for same-origin policy violations and ignore specific errors
+ if (
+ msg.message.includes("icon-credit-card-generic.svg") ||
+ msg.message.includes("accepted-cards.css") ||
+ msg.message.includes("editDialog-shared.css") ||
+ msg.message.includes("editAddress.css") ||
+ msg.message.includes("editDialog.css") ||
+ msg.message.includes("editCreditCard.css")
+ ) {
+ return;
+ }
+ }
+ if (msg.message == "SENTINEL") {
+ filterFunction = null;
+ }
+ if (filterFunction && filterFunction(msg)) {
+ return;
+ }
+ ok(false, msg.message || msg.errorMessage);
+});
+
+SimpleTest.registerCleanupFunction(function cleanup() {
+ SpecialPowers.postConsoleSentinel();
+});