1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
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();
});
|