@vitest/browser 3.1.0-beta.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/context.d.ts +24 -1
- package/dist/client/.vite/manifest.json +1 -1
- package/dist/client/__vitest__/assets/index-B0KEk_KY.css +1 -0
- package/dist/client/__vitest__/assets/index-BLZJq7cG.js +52 -0
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/tester-DiLSqOx4.js +3431 -0
- package/dist/client/tester/tester.html +1 -1
- package/dist/client.js +109 -105
- package/dist/context.js +374 -390
- package/dist/expect-element.js +25 -0
- package/dist/index-DjDyxzt8.js +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.js +1991 -1887
- package/dist/locators/index.d.ts +64 -0
- package/dist/locators/index.js +1 -4
- package/dist/locators/playwright.js +1 -123
- package/dist/locators/preview.js +1 -85
- package/dist/locators/webdriverio.js +1 -157
- package/dist/providers.js +35 -37
- package/dist/public-utils-xf4CCUzp.js +6 -0
- package/dist/state.js +170 -1
- package/dist/utils.js +1 -3
- package/dist/webdriver-2iYWIzBv.js +403 -0
- package/jest-dom.d.ts +623 -712
- package/matchers.d.ts +4 -4
- package/package.json +14 -16
- package/dist/client/__vitest__/assets/index-Bne9c1R6.css +0 -1
- package/dist/client/__vitest__/assets/index-CsZqQx26.js +0 -52
- package/dist/client/__vitest_browser__/tester-lo_P6U-u.js +0 -15577
- package/dist/index-DrTP5i7N.js +0 -195
- package/dist/public-utils-J4vwTaki.js +0 -5561
- package/dist/utils-VCysLhWp.js +0 -115
- package/dist/webdriver-C5-VI7VH.js +0 -275
package/dist/context.js
CHANGED
|
@@ -1,432 +1,416 @@
|
|
|
1
1
|
function ensureAwaited(promise) {
|
|
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
|
-
[Symbol.toStringTag]: "Promise"
|
|
31
|
-
};
|
|
2
|
+
const test = getWorkerState().current;
|
|
3
|
+
if (!test || test.type !== "test") {
|
|
4
|
+
return promise();
|
|
5
|
+
}
|
|
6
|
+
let awaited = false;
|
|
7
|
+
const sourceError = new Error("STACK_TRACE_ERROR");
|
|
8
|
+
test.onFinished ??= [];
|
|
9
|
+
test.onFinished.push(() => {
|
|
10
|
+
if (!awaited) {
|
|
11
|
+
const error = new Error(`The call was not awaited. This method is asynchronous and must be awaited; otherwise, the call will not start to avoid unhandled rejections.`);
|
|
12
|
+
error.stack = sourceError.stack?.replace(sourceError.message, error.message);
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
let promiseResult;
|
|
17
|
+
return {
|
|
18
|
+
then(onFulfilled, onRejected) {
|
|
19
|
+
awaited = true;
|
|
20
|
+
return (promiseResult ||= promise(sourceError)).then(onFulfilled, onRejected);
|
|
21
|
+
},
|
|
22
|
+
catch(onRejected) {
|
|
23
|
+
return (promiseResult ||= promise(sourceError)).catch(onRejected);
|
|
24
|
+
},
|
|
25
|
+
finally(onFinally) {
|
|
26
|
+
return (promiseResult ||= promise(sourceError)).finally(onFinally);
|
|
27
|
+
},
|
|
28
|
+
[Symbol.toStringTag]: "Promise"
|
|
29
|
+
};
|
|
32
30
|
}
|
|
33
|
-
|
|
31
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
34
32
|
function getBrowserState() {
|
|
35
|
-
|
|
33
|
+
return window.__vitest_browser_runner__;
|
|
36
34
|
}
|
|
37
|
-
|
|
35
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
38
36
|
function getWorkerState() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
const state = window.__vitest_worker__;
|
|
38
|
+
if (!state) {
|
|
39
|
+
throw new Error("Worker state is not found. This is an issue with Vitest. Please, open an issue.");
|
|
40
|
+
}
|
|
41
|
+
return state;
|
|
44
42
|
}
|
|
45
43
|
|
|
46
44
|
const provider$1 = getBrowserState().provider;
|
|
47
|
-
|
|
45
|
+
/* @__NO_SIDE_EFFECTS__ */
|
|
48
46
|
function convertElementToCssSelector(element) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
return getUniqueCssSelector(element);
|
|
47
|
+
if (!element || !(element instanceof Element)) {
|
|
48
|
+
throw new Error(`Expected DOM element to be an instance of Element, received ${typeof element}`);
|
|
49
|
+
}
|
|
50
|
+
return getUniqueCssSelector(element);
|
|
55
51
|
}
|
|
56
52
|
function escapeIdForCSSSelector(id) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
53
|
+
return id.split("").map((char) => {
|
|
54
|
+
const code = char.charCodeAt(0);
|
|
55
|
+
if (char === " " || char === "#" || char === "." || char === ":" || char === "[" || char === "]" || char === ">" || char === "+" || char === "~" || char === "\\") {
|
|
56
|
+
return `\\${char}`;
|
|
57
|
+
} else if (code >= 65536) {
|
|
58
|
+
return `\\${code.toString(16).toUpperCase().padStart(6, "0")} `;
|
|
59
|
+
} else if (code < 32 || code === 127) {
|
|
60
|
+
return `\\${code.toString(16).toUpperCase().padStart(2, "0")} `;
|
|
61
|
+
} else if (code >= 128) {
|
|
62
|
+
return `\\${code.toString(16).toUpperCase().padStart(2, "0")} `;
|
|
63
|
+
} else {
|
|
64
|
+
return char;
|
|
65
|
+
}
|
|
66
|
+
}).join("");
|
|
71
67
|
}
|
|
72
68
|
function getUniqueCssSelector(el) {
|
|
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
|
-
|
|
69
|
+
const path = [];
|
|
70
|
+
let parent;
|
|
71
|
+
let hasShadowRoot = false;
|
|
72
|
+
while (parent = getParent(el)) {
|
|
73
|
+
if (parent.shadowRoot) {
|
|
74
|
+
hasShadowRoot = true;
|
|
75
|
+
}
|
|
76
|
+
const tag = el.tagName;
|
|
77
|
+
if (el.id) {
|
|
78
|
+
path.push(`#${escapeIdForCSSSelector(el.id)}`);
|
|
79
|
+
} else if (!el.nextElementSibling && !el.previousElementSibling) {
|
|
80
|
+
path.push(tag.toLowerCase());
|
|
81
|
+
} else {
|
|
82
|
+
let index = 0;
|
|
83
|
+
let sameTagSiblings = 0;
|
|
84
|
+
let elementIndex = 0;
|
|
85
|
+
for (const sibling of parent.children) {
|
|
86
|
+
index++;
|
|
87
|
+
if (sibling.tagName === tag) {
|
|
88
|
+
sameTagSiblings++;
|
|
89
|
+
}
|
|
90
|
+
if (sibling === el) {
|
|
91
|
+
elementIndex = index;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (sameTagSiblings > 1) {
|
|
95
|
+
path.push(`${tag.toLowerCase()}:nth-child(${elementIndex})`);
|
|
96
|
+
} else {
|
|
97
|
+
path.push(tag.toLowerCase());
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
el = parent;
|
|
101
|
+
}
|
|
102
|
+
return `${getBrowserState().provider === "webdriverio" && hasShadowRoot ? ">>>" : ""}${path.reverse().join(" > ")}`;
|
|
107
103
|
}
|
|
108
104
|
function getParent(el) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
const parent = el.parentNode;
|
|
106
|
+
if (parent instanceof ShadowRoot) {
|
|
107
|
+
return parent.host;
|
|
108
|
+
}
|
|
109
|
+
return parent;
|
|
114
110
|
}
|
|
115
111
|
const now = Date.now;
|
|
116
112
|
function processTimeoutOptions(options_) {
|
|
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
|
-
options_.timeout = remainingTime - 100;
|
|
143
|
-
return options_;
|
|
113
|
+
if (options_ && options_.timeout != null || provider$1 !== "playwright") {
|
|
114
|
+
return options_;
|
|
115
|
+
}
|
|
116
|
+
if (getWorkerState().config.browser.providerOptions.actionTimeout != null) {
|
|
117
|
+
return options_;
|
|
118
|
+
}
|
|
119
|
+
const runner = getBrowserState().runner;
|
|
120
|
+
const startTime = runner._currentTaskStartTime;
|
|
121
|
+
if (!startTime) {
|
|
122
|
+
return options_;
|
|
123
|
+
}
|
|
124
|
+
const timeout = runner._currentTaskTimeout;
|
|
125
|
+
if (timeout === 0 || timeout == null || timeout === Number.POSITIVE_INFINITY) {
|
|
126
|
+
return options_;
|
|
127
|
+
}
|
|
128
|
+
options_ = options_ || {};
|
|
129
|
+
const currentTime = now();
|
|
130
|
+
const endTime = startTime + timeout;
|
|
131
|
+
const remainingTime = endTime - currentTime;
|
|
132
|
+
if (remainingTime <= 0) {
|
|
133
|
+
return options_;
|
|
134
|
+
}
|
|
135
|
+
options_.timeout = remainingTime - 100;
|
|
136
|
+
return options_;
|
|
144
137
|
}
|
|
145
138
|
|
|
146
139
|
const provider = __vitest_browser_runner__.provider;
|
|
147
140
|
const sessionId = getBrowserState().sessionId;
|
|
148
141
|
const channel = new BroadcastChannel(`vitest:${sessionId}`);
|
|
149
142
|
function triggerCommand(command, args, error) {
|
|
150
|
-
|
|
143
|
+
return getBrowserState().commands.triggerCommand(command, args, error);
|
|
151
144
|
}
|
|
152
145
|
function createUserEvent(__tl_user_event_base__, options) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
},
|
|
238
|
-
async cut() {
|
|
239
|
-
await userEvent.keyboard(`{${modifier}>}{x}{/${modifier}}`);
|
|
240
|
-
},
|
|
241
|
-
async paste() {
|
|
242
|
-
await userEvent.keyboard(`{${modifier}>}{v}{/${modifier}}`);
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
return userEvent;
|
|
146
|
+
if (__tl_user_event_base__) {
|
|
147
|
+
return createPreviewUserEvent(__tl_user_event_base__, options ?? {});
|
|
148
|
+
}
|
|
149
|
+
const keyboard = { unreleased: [] };
|
|
150
|
+
const modifier = provider === `playwright` ? "ControlOrMeta" : provider === "webdriverio" ? "Ctrl" : "Control";
|
|
151
|
+
const userEvent = {
|
|
152
|
+
setup() {
|
|
153
|
+
return createUserEvent();
|
|
154
|
+
},
|
|
155
|
+
async cleanup() {
|
|
156
|
+
if (!keyboard.unreleased.length) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
return ensureAwaited(async (error) => {
|
|
160
|
+
await triggerCommand("__vitest_cleanup", [keyboard], error);
|
|
161
|
+
keyboard.unreleased = [];
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
click(element, options) {
|
|
165
|
+
return convertToLocator(element).click(options);
|
|
166
|
+
},
|
|
167
|
+
dblClick(element, options) {
|
|
168
|
+
return convertToLocator(element).dblClick(options);
|
|
169
|
+
},
|
|
170
|
+
tripleClick(element, options) {
|
|
171
|
+
return convertToLocator(element).tripleClick(options);
|
|
172
|
+
},
|
|
173
|
+
selectOptions(element, value, options) {
|
|
174
|
+
return convertToLocator(element).selectOptions(value, options);
|
|
175
|
+
},
|
|
176
|
+
clear(element, options) {
|
|
177
|
+
return convertToLocator(element).clear(options);
|
|
178
|
+
},
|
|
179
|
+
hover(element, options) {
|
|
180
|
+
return convertToLocator(element).hover(options);
|
|
181
|
+
},
|
|
182
|
+
unhover(element, options) {
|
|
183
|
+
return convertToLocator(element).unhover(options);
|
|
184
|
+
},
|
|
185
|
+
upload(element, files, options) {
|
|
186
|
+
return convertToLocator(element).upload(files, options);
|
|
187
|
+
},
|
|
188
|
+
fill(element, text, options) {
|
|
189
|
+
return convertToLocator(element).fill(text, options);
|
|
190
|
+
},
|
|
191
|
+
dragAndDrop(source, target, options) {
|
|
192
|
+
const sourceLocator = convertToLocator(source);
|
|
193
|
+
const targetLocator = convertToLocator(target);
|
|
194
|
+
return sourceLocator.dropTo(targetLocator, options);
|
|
195
|
+
},
|
|
196
|
+
async type(element, text, options) {
|
|
197
|
+
return ensureAwaited(async (error) => {
|
|
198
|
+
const selector = convertToSelector(element);
|
|
199
|
+
const { unreleased } = await triggerCommand("__vitest_type", [
|
|
200
|
+
selector,
|
|
201
|
+
text,
|
|
202
|
+
{
|
|
203
|
+
...options,
|
|
204
|
+
unreleased: keyboard.unreleased
|
|
205
|
+
}
|
|
206
|
+
], error);
|
|
207
|
+
keyboard.unreleased = unreleased;
|
|
208
|
+
});
|
|
209
|
+
},
|
|
210
|
+
tab(options = {}) {
|
|
211
|
+
return ensureAwaited((error) => triggerCommand("__vitest_tab", [options], error));
|
|
212
|
+
},
|
|
213
|
+
async keyboard(text) {
|
|
214
|
+
return ensureAwaited(async (error) => {
|
|
215
|
+
const { unreleased } = await triggerCommand("__vitest_keyboard", [text, keyboard], error);
|
|
216
|
+
keyboard.unreleased = unreleased;
|
|
217
|
+
});
|
|
218
|
+
},
|
|
219
|
+
async copy() {
|
|
220
|
+
await userEvent.keyboard(`{${modifier}>}{c}{/${modifier}}`);
|
|
221
|
+
},
|
|
222
|
+
async cut() {
|
|
223
|
+
await userEvent.keyboard(`{${modifier}>}{x}{/${modifier}}`);
|
|
224
|
+
},
|
|
225
|
+
async paste() {
|
|
226
|
+
await userEvent.keyboard(`{${modifier}>}{v}{/${modifier}}`);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
return userEvent;
|
|
246
230
|
}
|
|
247
231
|
function createPreviewUserEvent(userEventBase, options) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
return vitestUserEvent;
|
|
232
|
+
let userEvent = userEventBase.setup(options);
|
|
233
|
+
let clipboardData;
|
|
234
|
+
function toElement(element) {
|
|
235
|
+
return element instanceof Element ? element : element.element();
|
|
236
|
+
}
|
|
237
|
+
const vitestUserEvent = {
|
|
238
|
+
setup(options) {
|
|
239
|
+
return createPreviewUserEvent(userEventBase, options);
|
|
240
|
+
},
|
|
241
|
+
async cleanup() {
|
|
242
|
+
userEvent = userEventBase.setup(options ?? {});
|
|
243
|
+
},
|
|
244
|
+
async click(element) {
|
|
245
|
+
await userEvent.click(toElement(element));
|
|
246
|
+
},
|
|
247
|
+
async dblClick(element) {
|
|
248
|
+
await userEvent.dblClick(toElement(element));
|
|
249
|
+
},
|
|
250
|
+
async tripleClick(element) {
|
|
251
|
+
await userEvent.tripleClick(toElement(element));
|
|
252
|
+
},
|
|
253
|
+
async selectOptions(element, value) {
|
|
254
|
+
const options = (Array.isArray(value) ? value : [value]).map((option) => {
|
|
255
|
+
if (typeof option !== "string") {
|
|
256
|
+
return toElement(option);
|
|
257
|
+
}
|
|
258
|
+
return option;
|
|
259
|
+
});
|
|
260
|
+
await userEvent.selectOptions(element, options);
|
|
261
|
+
},
|
|
262
|
+
async clear(element) {
|
|
263
|
+
await userEvent.clear(toElement(element));
|
|
264
|
+
},
|
|
265
|
+
async hover(element) {
|
|
266
|
+
await userEvent.hover(toElement(element));
|
|
267
|
+
},
|
|
268
|
+
async unhover(element) {
|
|
269
|
+
await userEvent.unhover(toElement(element));
|
|
270
|
+
},
|
|
271
|
+
async upload(element, files) {
|
|
272
|
+
const uploadPromise = (Array.isArray(files) ? files : [files]).map(async (file) => {
|
|
273
|
+
if (typeof file !== "string") {
|
|
274
|
+
return file;
|
|
275
|
+
}
|
|
276
|
+
const { content: base64, basename, mime } = await triggerCommand("__vitest_fileInfo", [file, "base64"]);
|
|
277
|
+
const fileInstance = fetch(`data:${mime};base64,${base64}`).then((r) => r.blob()).then((blob) => new File([blob], basename, { type: mime }));
|
|
278
|
+
return fileInstance;
|
|
279
|
+
});
|
|
280
|
+
const uploadFiles = await Promise.all(uploadPromise);
|
|
281
|
+
return userEvent.upload(toElement(element), uploadFiles);
|
|
282
|
+
},
|
|
283
|
+
async fill(element, text) {
|
|
284
|
+
await userEvent.clear(toElement(element));
|
|
285
|
+
return userEvent.type(toElement(element), text);
|
|
286
|
+
},
|
|
287
|
+
async dragAndDrop() {
|
|
288
|
+
throw new Error(`The "preview" provider doesn't support 'userEvent.dragAndDrop'`);
|
|
289
|
+
},
|
|
290
|
+
async type(element, text, options) {
|
|
291
|
+
await userEvent.type(toElement(element), text, options);
|
|
292
|
+
},
|
|
293
|
+
async tab(options) {
|
|
294
|
+
await userEvent.tab(options);
|
|
295
|
+
},
|
|
296
|
+
async keyboard(text) {
|
|
297
|
+
await userEvent.keyboard(text);
|
|
298
|
+
},
|
|
299
|
+
async copy() {
|
|
300
|
+
clipboardData = await userEvent.copy();
|
|
301
|
+
},
|
|
302
|
+
async cut() {
|
|
303
|
+
clipboardData = await userEvent.cut();
|
|
304
|
+
},
|
|
305
|
+
async paste() {
|
|
306
|
+
await userEvent.paste(clipboardData);
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
for (const [name, fn] of Object.entries(vitestUserEvent)) {
|
|
310
|
+
if (name !== "setup") {
|
|
311
|
+
vitestUserEvent[name] = function(...args) {
|
|
312
|
+
return ensureAwaited(() => fn.apply(this, args));
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return vitestUserEvent;
|
|
336
317
|
}
|
|
337
318
|
function cdp() {
|
|
338
|
-
|
|
319
|
+
return getBrowserState().cdp;
|
|
339
320
|
}
|
|
340
321
|
const screenshotIds = {};
|
|
341
322
|
const page = {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
323
|
+
viewport(width, height) {
|
|
324
|
+
const id = getBrowserState().iframeId;
|
|
325
|
+
channel.postMessage({
|
|
326
|
+
type: "viewport",
|
|
327
|
+
width,
|
|
328
|
+
height,
|
|
329
|
+
id
|
|
330
|
+
});
|
|
331
|
+
return new Promise((resolve, reject) => {
|
|
332
|
+
channel.addEventListener("message", function handler(e) {
|
|
333
|
+
if (e.data.type === "viewport:done" && e.data.id === id) {
|
|
334
|
+
channel.removeEventListener("message", handler);
|
|
335
|
+
resolve();
|
|
336
|
+
}
|
|
337
|
+
if (e.data.type === "viewport:fail" && e.data.id === id) {
|
|
338
|
+
channel.removeEventListener("message", handler);
|
|
339
|
+
reject(new Error(e.data.error));
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
},
|
|
344
|
+
async screenshot(options = {}) {
|
|
345
|
+
const currentTest = getWorkerState().current;
|
|
346
|
+
if (!currentTest) {
|
|
347
|
+
throw new Error("Cannot take a screenshot outside of a test.");
|
|
348
|
+
}
|
|
349
|
+
if (currentTest.concurrent) {
|
|
350
|
+
throw new Error("Cannot take a screenshot in a concurrent test because " + "concurrent tests run at the same time in the same iframe and affect each other's environment. " + "Use a non-concurrent test to take a screenshot.");
|
|
351
|
+
}
|
|
352
|
+
const repeatCount = currentTest.result?.repeatCount ?? 0;
|
|
353
|
+
const taskName = getTaskFullName(currentTest);
|
|
354
|
+
const number = screenshotIds[repeatCount]?.[taskName] ?? 1;
|
|
355
|
+
screenshotIds[repeatCount] ??= {};
|
|
356
|
+
screenshotIds[repeatCount][taskName] = number + 1;
|
|
357
|
+
const name = options.path || `${taskName.replace(/[^a-z0-9]/gi, "-")}-${number}.png`;
|
|
358
|
+
return ensureAwaited((error) => triggerCommand("__vitest_screenshot", [name, processTimeoutOptions({
|
|
359
|
+
...options,
|
|
360
|
+
element: options.element ? convertToSelector(options.element) : undefined
|
|
361
|
+
})], error));
|
|
362
|
+
},
|
|
363
|
+
getByRole() {
|
|
364
|
+
throw new Error(`Method "getByRole" is not implemented in the "${provider}" provider.`);
|
|
365
|
+
},
|
|
366
|
+
getByLabelText() {
|
|
367
|
+
throw new Error(`Method "getByLabelText" is not implemented in the "${provider}" provider.`);
|
|
368
|
+
},
|
|
369
|
+
getByTestId() {
|
|
370
|
+
throw new Error(`Method "getByTestId" is not implemented in the "${provider}" provider.`);
|
|
371
|
+
},
|
|
372
|
+
getByAltText() {
|
|
373
|
+
throw new Error(`Method "getByAltText" is not implemented in the "${provider}" provider.`);
|
|
374
|
+
},
|
|
375
|
+
getByPlaceholder() {
|
|
376
|
+
throw new Error(`Method "getByPlaceholder" is not implemented in the "${provider}" provider.`);
|
|
377
|
+
},
|
|
378
|
+
getByText() {
|
|
379
|
+
throw new Error(`Method "getByText" is not implemented in the "${provider}" provider.`);
|
|
380
|
+
},
|
|
381
|
+
getByTitle() {
|
|
382
|
+
throw new Error(`Method "getByTitle" is not implemented in the "${provider}" provider.`);
|
|
383
|
+
},
|
|
384
|
+
elementLocator() {
|
|
385
|
+
throw new Error(`Method "elementLocator" is not implemented in the "${provider}" provider.`);
|
|
386
|
+
},
|
|
387
|
+
extend(methods) {
|
|
388
|
+
for (const key in methods) {
|
|
389
|
+
page[key] = methods[key];
|
|
390
|
+
}
|
|
391
|
+
return page;
|
|
392
|
+
}
|
|
409
393
|
};
|
|
410
394
|
function convertToLocator(element) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
395
|
+
if (element instanceof Element) {
|
|
396
|
+
return page.elementLocator(element);
|
|
397
|
+
}
|
|
398
|
+
return element;
|
|
415
399
|
}
|
|
416
400
|
function convertToSelector(elementOrLocator) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
401
|
+
if (!elementOrLocator) {
|
|
402
|
+
throw new Error("Expected element or locator to be defined.");
|
|
403
|
+
}
|
|
404
|
+
if (elementOrLocator instanceof Element) {
|
|
405
|
+
return convertElementToCssSelector(elementOrLocator);
|
|
406
|
+
}
|
|
407
|
+
if ("selector" in elementOrLocator) {
|
|
408
|
+
return elementOrLocator.selector;
|
|
409
|
+
}
|
|
410
|
+
throw new Error("Expected element or locator to be an instance of Element or Locator.");
|
|
427
411
|
}
|
|
428
412
|
function getTaskFullName(task) {
|
|
429
|
-
|
|
413
|
+
return task.suite ? `${getTaskFullName(task.suite)} ${task.name}` : task.name;
|
|
430
414
|
}
|
|
431
415
|
|
|
432
416
|
export { cdp, createUserEvent, page };
|