gecko-dev/browser/components/payments/test/mochitest/payments_common.js

155 строки
4.3 KiB
JavaScript

"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();
});