@vitest/browser 3.0.9 → 3.1.0-beta.2

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/dist/context.js CHANGED
@@ -1,432 +1,416 @@
1
1
  function ensureAwaited(promise) {
2
- const test = (/* @__PURE__ */ 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(
12
- `The call was not awaited. This method is asynchronous and must be awaited; otherwise, the call will not start to avoid unhandled rejections.`
13
- );
14
- error.stack = sourceError.stack?.replace(sourceError.message, error.message);
15
- throw error;
16
- }
17
- });
18
- let promiseResult;
19
- return {
20
- then(onFulfilled, onRejected) {
21
- awaited = true;
22
- return (promiseResult ||= promise(sourceError)).then(onFulfilled, onRejected);
23
- },
24
- catch(onRejected) {
25
- return (promiseResult ||= promise(sourceError)).catch(onRejected);
26
- },
27
- finally(onFinally) {
28
- return (promiseResult ||= promise(sourceError)).finally(onFinally);
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
- // @__NO_SIDE_EFFECTS__
31
+ /* @__NO_SIDE_EFFECTS__ */
34
32
  function getBrowserState() {
35
- return window.__vitest_browser_runner__;
33
+ return window.__vitest_browser_runner__;
36
34
  }
37
- // @__NO_SIDE_EFFECTS__
35
+ /* @__NO_SIDE_EFFECTS__ */
38
36
  function getWorkerState() {
39
- const state = window.__vitest_worker__;
40
- if (!state) {
41
- throw new Error("Worker state is not found. This is an issue with Vitest. Please, open an issue.");
42
- }
43
- return state;
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
- // @__NO_SIDE_EFFECTS__
45
+ /* @__NO_SIDE_EFFECTS__ */
48
46
  function convertElementToCssSelector(element) {
49
- if (!element || !(element instanceof Element)) {
50
- throw new Error(
51
- `Expected DOM element to be an instance of Element, received ${typeof element}`
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
- return id.split("").map((char) => {
58
- const code = char.charCodeAt(0);
59
- if (char === " " || char === "#" || char === "." || char === ":" || char === "[" || char === "]" || char === ">" || char === "+" || char === "~" || char === "\\") {
60
- return `\\${char}`;
61
- } else if (code >= 65536) {
62
- return `\\${code.toString(16).toUpperCase().padStart(6, "0")} `;
63
- } else if (code < 32 || code === 127) {
64
- return `\\${code.toString(16).toUpperCase().padStart(2, "0")} `;
65
- } else if (code >= 128) {
66
- return `\\${code.toString(16).toUpperCase().padStart(2, "0")} `;
67
- } else {
68
- return char;
69
- }
70
- }).join("");
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
- const path = [];
74
- let parent;
75
- let hasShadowRoot = false;
76
- while (parent = getParent(el)) {
77
- if (parent.shadowRoot) {
78
- hasShadowRoot = true;
79
- }
80
- const tag = el.tagName;
81
- if (el.id) {
82
- path.push(`#${escapeIdForCSSSelector(el.id)}`);
83
- } else if (!el.nextElementSibling && !el.previousElementSibling) {
84
- path.push(tag.toLowerCase());
85
- } else {
86
- let index = 0;
87
- let sameTagSiblings = 0;
88
- let elementIndex = 0;
89
- for (const sibling of parent.children) {
90
- index++;
91
- if (sibling.tagName === tag) {
92
- sameTagSiblings++;
93
- }
94
- if (sibling === el) {
95
- elementIndex = index;
96
- }
97
- }
98
- if (sameTagSiblings > 1) {
99
- path.push(`${tag.toLowerCase()}:nth-child(${elementIndex})`);
100
- } else {
101
- path.push(tag.toLowerCase());
102
- }
103
- }
104
- el = parent;
105
- }
106
- return `${getBrowserState().provider === "webdriverio" && hasShadowRoot ? ">>>" : ""}${path.reverse().join(" > ")}`;
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
- const parent = el.parentNode;
110
- if (parent instanceof ShadowRoot) {
111
- return parent.host;
112
- }
113
- return parent;
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
- if (
118
- // if timeout is set, keep it
119
- options_ && options_.timeout != null || provider$1 !== "playwright"
120
- ) {
121
- return options_;
122
- }
123
- if (getWorkerState().config.browser.providerOptions.actionTimeout != null) {
124
- return options_;
125
- }
126
- const currentTest = getWorkerState().current;
127
- const startTime = currentTest?.result?.startTime;
128
- if (!currentTest || currentTest.type === "suite" || !startTime) {
129
- return options_;
130
- }
131
- const timeout = currentTest.timeout;
132
- if (timeout === 0 || timeout === Number.POSITIVE_INFINITY) {
133
- return options_;
134
- }
135
- options_ = options_ || {};
136
- const currentTime = now();
137
- const endTime = startTime + timeout;
138
- const remainingTime = endTime - currentTime;
139
- if (remainingTime <= 0) {
140
- return options_;
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 currentTest = getWorkerState().current;
120
+ const startTime = currentTest?.result?.startTime;
121
+ if (!currentTest || currentTest.type === "suite" || !startTime) {
122
+ return options_;
123
+ }
124
+ const timeout = currentTest.timeout;
125
+ if (timeout === 0 || 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
- return getBrowserState().commands.triggerCommand(command, args, error);
143
+ return getBrowserState().commands.triggerCommand(command, args, error);
151
144
  }
152
145
  function createUserEvent(__tl_user_event_base__, options) {
153
- if (__tl_user_event_base__) {
154
- return createPreviewUserEvent(__tl_user_event_base__, options ?? {});
155
- }
156
- const keyboard = {
157
- unreleased: []
158
- };
159
- const modifier = provider === `playwright` ? "ControlOrMeta" : provider === "webdriverio" ? "Ctrl" : "Control";
160
- const userEvent = {
161
- setup() {
162
- return createUserEvent();
163
- },
164
- async cleanup() {
165
- if (!keyboard.unreleased.length) {
166
- return;
167
- }
168
- return ensureAwaited(async (error) => {
169
- await triggerCommand("__vitest_cleanup", [keyboard], error);
170
- keyboard.unreleased = [];
171
- });
172
- },
173
- click(element, options2) {
174
- return convertToLocator(element).click(options2);
175
- },
176
- dblClick(element, options2) {
177
- return convertToLocator(element).dblClick(options2);
178
- },
179
- tripleClick(element, options2) {
180
- return convertToLocator(element).tripleClick(options2);
181
- },
182
- selectOptions(element, value, options2) {
183
- return convertToLocator(element).selectOptions(value, options2);
184
- },
185
- clear(element, options2) {
186
- return convertToLocator(element).clear(options2);
187
- },
188
- hover(element, options2) {
189
- return convertToLocator(element).hover(options2);
190
- },
191
- unhover(element, options2) {
192
- return convertToLocator(element).unhover(options2);
193
- },
194
- upload(element, files, options2) {
195
- return convertToLocator(element).upload(files, options2);
196
- },
197
- // non userEvent events, but still useful
198
- fill(element, text, options2) {
199
- return convertToLocator(element).fill(text, options2);
200
- },
201
- dragAndDrop(source, target, options2) {
202
- const sourceLocator = convertToLocator(source);
203
- const targetLocator = convertToLocator(target);
204
- return sourceLocator.dropTo(targetLocator, options2);
205
- },
206
- // testing-library user-event
207
- async type(element, text, options2) {
208
- return ensureAwaited(async (error) => {
209
- const selector = convertToSelector(element);
210
- const { unreleased } = await triggerCommand(
211
- "__vitest_type",
212
- [
213
- selector,
214
- text,
215
- { ...options2, unreleased: keyboard.unreleased }
216
- ],
217
- error
218
- );
219
- keyboard.unreleased = unreleased;
220
- });
221
- },
222
- tab(options2 = {}) {
223
- return ensureAwaited((error) => triggerCommand("__vitest_tab", [options2], error));
224
- },
225
- async keyboard(text) {
226
- return ensureAwaited(async (error) => {
227
- const { unreleased } = await triggerCommand(
228
- "__vitest_keyboard",
229
- [text, keyboard],
230
- error
231
- );
232
- keyboard.unreleased = unreleased;
233
- });
234
- },
235
- async copy() {
236
- await userEvent.keyboard(`{${modifier}>}{c}{/${modifier}}`);
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
- let userEvent = userEventBase.setup(options);
249
- let clipboardData;
250
- function toElement(element) {
251
- return element instanceof Element ? element : element.element();
252
- }
253
- const vitestUserEvent = {
254
- setup(options2) {
255
- return createPreviewUserEvent(userEventBase, options2);
256
- },
257
- async cleanup() {
258
- userEvent = userEventBase.setup(options ?? {});
259
- },
260
- async click(element) {
261
- await userEvent.click(toElement(element));
262
- },
263
- async dblClick(element) {
264
- await userEvent.dblClick(toElement(element));
265
- },
266
- async tripleClick(element) {
267
- await userEvent.tripleClick(toElement(element));
268
- },
269
- async selectOptions(element, value) {
270
- const options2 = (Array.isArray(value) ? value : [value]).map((option) => {
271
- if (typeof option !== "string") {
272
- return toElement(option);
273
- }
274
- return option;
275
- });
276
- await userEvent.selectOptions(
277
- element,
278
- options2
279
- );
280
- },
281
- async clear(element) {
282
- await userEvent.clear(toElement(element));
283
- },
284
- async hover(element) {
285
- await userEvent.hover(toElement(element));
286
- },
287
- async unhover(element) {
288
- await userEvent.unhover(toElement(element));
289
- },
290
- async upload(element, files) {
291
- const uploadPromise = (Array.isArray(files) ? files : [files]).map(async (file) => {
292
- if (typeof file !== "string") {
293
- return file;
294
- }
295
- const { content: base64, basename, mime } = await triggerCommand("__vitest_fileInfo", [file, "base64"]);
296
- const fileInstance = fetch(`data:${mime};base64,${base64}`).then((r) => r.blob()).then((blob) => new File([blob], basename, { type: mime }));
297
- return fileInstance;
298
- });
299
- const uploadFiles = await Promise.all(uploadPromise);
300
- return userEvent.upload(toElement(element), uploadFiles);
301
- },
302
- async fill(element, text) {
303
- await userEvent.clear(toElement(element));
304
- return userEvent.type(toElement(element), text);
305
- },
306
- async dragAndDrop() {
307
- throw new Error(`The "preview" provider doesn't support 'userEvent.dragAndDrop'`);
308
- },
309
- async type(element, text, options2) {
310
- await userEvent.type(toElement(element), text, options2);
311
- },
312
- async tab(options2) {
313
- await userEvent.tab(options2);
314
- },
315
- async keyboard(text) {
316
- await userEvent.keyboard(text);
317
- },
318
- async copy() {
319
- clipboardData = await userEvent.copy();
320
- },
321
- async cut() {
322
- clipboardData = await userEvent.cut();
323
- },
324
- async paste() {
325
- await userEvent.paste(clipboardData);
326
- }
327
- };
328
- for (const [name, fn] of Object.entries(vitestUserEvent)) {
329
- if (name !== "setup") {
330
- vitestUserEvent[name] = function(...args) {
331
- return ensureAwaited(() => fn.apply(this, args));
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
- return getBrowserState().cdp;
319
+ return getBrowserState().cdp;
339
320
  }
340
321
  const screenshotIds = {};
341
322
  const page = {
342
- viewport(width, height) {
343
- const id = getBrowserState().iframeId;
344
- channel.postMessage({ type: "viewport", width, height, id });
345
- return new Promise((resolve, reject) => {
346
- channel.addEventListener("message", function handler(e) {
347
- if (e.data.type === "viewport:done" && e.data.id === id) {
348
- channel.removeEventListener("message", handler);
349
- resolve();
350
- }
351
- if (e.data.type === "viewport:fail" && e.data.id === id) {
352
- channel.removeEventListener("message", handler);
353
- reject(new Error(e.data.error));
354
- }
355
- });
356
- });
357
- },
358
- async screenshot(options = {}) {
359
- const currentTest = getWorkerState().current;
360
- if (!currentTest) {
361
- throw new Error("Cannot take a screenshot outside of a test.");
362
- }
363
- if (currentTest.concurrent) {
364
- throw new Error(
365
- "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."
366
- );
367
- }
368
- const repeatCount = currentTest.result?.repeatCount ?? 0;
369
- const taskName = getTaskFullName(currentTest);
370
- const number = screenshotIds[repeatCount]?.[taskName] ?? 1;
371
- screenshotIds[repeatCount] ??= {};
372
- screenshotIds[repeatCount][taskName] = number + 1;
373
- const name = options.path || `${taskName.replace(/[^a-z0-9]/gi, "-")}-${number}.png`;
374
- return ensureAwaited((error) => triggerCommand("__vitest_screenshot", [name, processTimeoutOptions({
375
- ...options,
376
- element: options.element ? convertToSelector(options.element) : void 0
377
- })], error));
378
- },
379
- getByRole() {
380
- throw new Error(`Method "getByRole" is not implemented in the "${provider}" provider.`);
381
- },
382
- getByLabelText() {
383
- throw new Error(`Method "getByLabelText" is not implemented in the "${provider}" provider.`);
384
- },
385
- getByTestId() {
386
- throw new Error(`Method "getByTestId" is not implemented in the "${provider}" provider.`);
387
- },
388
- getByAltText() {
389
- throw new Error(`Method "getByAltText" is not implemented in the "${provider}" provider.`);
390
- },
391
- getByPlaceholder() {
392
- throw new Error(`Method "getByPlaceholder" is not implemented in the "${provider}" provider.`);
393
- },
394
- getByText() {
395
- throw new Error(`Method "getByText" is not implemented in the "${provider}" provider.`);
396
- },
397
- getByTitle() {
398
- throw new Error(`Method "getByTitle" is not implemented in the "${provider}" provider.`);
399
- },
400
- elementLocator() {
401
- throw new Error(`Method "elementLocator" is not implemented in the "${provider}" provider.`);
402
- },
403
- extend(methods) {
404
- for (const key in methods) {
405
- page[key] = methods[key];
406
- }
407
- return page;
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
- if (element instanceof Element) {
412
- return page.elementLocator(element);
413
- }
414
- return element;
395
+ if (element instanceof Element) {
396
+ return page.elementLocator(element);
397
+ }
398
+ return element;
415
399
  }
416
400
  function convertToSelector(elementOrLocator) {
417
- if (!elementOrLocator) {
418
- throw new Error("Expected element or locator to be defined.");
419
- }
420
- if (elementOrLocator instanceof Element) {
421
- return convertElementToCssSelector(elementOrLocator);
422
- }
423
- if ("selector" in elementOrLocator) {
424
- return elementOrLocator.selector;
425
- }
426
- throw new Error("Expected element or locator to be an instance of Element or Locator.");
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
- return task.suite ? `${getTaskFullName(task.suite)} ${task.name}` : task.name;
413
+ return task.suite ? `${getTaskFullName(task.suite)} ${task.name}` : task.name;
430
414
  }
431
415
 
432
416
  export { cdp, createUserEvent, page };