@vitest/browser 5.0.2 → 5.0.4
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/aria-role.d.ts +84 -84
- package/context.d.ts +27 -11
- package/context.js +5 -5
- package/dist/client/.vite/manifest.json +2 -2
- package/dist/client/__vitest_browser__/{orchestrator-M9828UZ-.js → orchestrator-Czo025Y6.js} +27 -6
- package/dist/client/__vitest_browser__/{tester-COH68OX9.js → tester-BH7uPfyB.js} +27 -16
- package/dist/client/error-catcher.js +16 -16
- package/dist/client/orchestrator.html +7 -6
- package/dist/client/tester/tester.html +3 -3
- package/dist/client/tester/trace.d.ts +1 -1
- package/dist/client.js +11 -2
- package/dist/context.js +9 -13
- package/dist/expect-element.js +26 -26
- package/dist/index.js +67 -300
- package/dist/locators-BHr21v4S.js +5 -0
- package/dist/locators.js +1 -1
- package/dist/shared/serialization.d.ts +2 -0
- package/jest-dom.d.ts +39 -21
- package/matchers.d.ts +5 -5
- package/package.json +14 -13
- package/utils.d.ts +1 -1
- package/dist/locators-BaWxQJd7.js +0 -5
package/aria-role.d.ts
CHANGED
|
@@ -1,96 +1,96 @@
|
|
|
1
1
|
type ARIAWidgetRole =
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
2
|
+
| 'button'
|
|
3
|
+
| 'checkbox'
|
|
4
|
+
| 'gridcell'
|
|
5
|
+
| 'link'
|
|
6
|
+
| 'menuitem'
|
|
7
|
+
| 'menuitemcheckbox'
|
|
8
|
+
| 'menuitemradio'
|
|
9
|
+
| 'option'
|
|
10
|
+
| 'progressbar'
|
|
11
|
+
| 'radio'
|
|
12
|
+
| 'scrollbar'
|
|
13
|
+
| 'searchbox'
|
|
14
|
+
| 'slider'
|
|
15
|
+
| 'spinbutton'
|
|
16
|
+
| 'switch'
|
|
17
|
+
| 'tab'
|
|
18
|
+
| 'tabpanel'
|
|
19
|
+
| 'textbox'
|
|
20
|
+
| 'treeitem'
|
|
21
21
|
|
|
22
22
|
type ARIACompositeWidgetRole =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
| 'combobox'
|
|
24
|
+
| 'grid'
|
|
25
|
+
| 'listbox'
|
|
26
|
+
| 'menu'
|
|
27
|
+
| 'menubar'
|
|
28
|
+
| 'radiogroup'
|
|
29
|
+
| 'tablist'
|
|
30
|
+
| 'tree'
|
|
31
|
+
| 'treegrid'
|
|
32
32
|
|
|
33
33
|
type ARIADocumentStructureRole =
|
|
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
|
-
|
|
34
|
+
| 'application'
|
|
35
|
+
| 'article'
|
|
36
|
+
| 'blockquote'
|
|
37
|
+
| 'caption'
|
|
38
|
+
| 'cell'
|
|
39
|
+
| 'columnheader'
|
|
40
|
+
| 'definition'
|
|
41
|
+
| 'deletion'
|
|
42
|
+
| 'directory'
|
|
43
|
+
| 'document'
|
|
44
|
+
| 'emphasis'
|
|
45
|
+
| 'feed'
|
|
46
|
+
| 'figure'
|
|
47
|
+
| 'generic'
|
|
48
|
+
| 'group'
|
|
49
|
+
| 'heading'
|
|
50
|
+
| 'img'
|
|
51
|
+
| 'insertion'
|
|
52
|
+
| 'list'
|
|
53
|
+
| 'listitem'
|
|
54
|
+
| 'math'
|
|
55
|
+
| 'meter'
|
|
56
|
+
| 'none'
|
|
57
|
+
| 'note'
|
|
58
|
+
| 'paragraph'
|
|
59
|
+
| 'presentation'
|
|
60
|
+
| 'row'
|
|
61
|
+
| 'rowgroup'
|
|
62
|
+
| 'rowheader'
|
|
63
|
+
| 'separator'
|
|
64
|
+
| 'strong'
|
|
65
|
+
| 'subscript'
|
|
66
|
+
| 'superscript'
|
|
67
|
+
| 'table'
|
|
68
|
+
| 'term'
|
|
69
|
+
| 'time'
|
|
70
|
+
| 'toolbar'
|
|
71
|
+
| 'tooltip'
|
|
72
72
|
|
|
73
73
|
type ARIALandmarkRole =
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
| 'banner'
|
|
75
|
+
| 'complementary'
|
|
76
|
+
| 'contentinfo'
|
|
77
|
+
| 'form'
|
|
78
|
+
| 'main'
|
|
79
|
+
| 'navigation'
|
|
80
|
+
| 'region'
|
|
81
|
+
| 'search'
|
|
82
82
|
|
|
83
|
-
type ARIALiveRegionRole =
|
|
83
|
+
type ARIALiveRegionRole = 'alert' | 'log' | 'marquee' | 'status' | 'timer'
|
|
84
84
|
|
|
85
|
-
type ARIAWindowRole =
|
|
85
|
+
type ARIAWindowRole = 'alertdialog' | 'dialog'
|
|
86
86
|
|
|
87
|
-
type ARIAUncategorizedRole =
|
|
87
|
+
type ARIAUncategorizedRole = 'code'
|
|
88
88
|
|
|
89
89
|
export type ARIARole =
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
| ARIAWidgetRole
|
|
91
|
+
| ARIACompositeWidgetRole
|
|
92
|
+
| ARIADocumentStructureRole
|
|
93
|
+
| ARIALandmarkRole
|
|
94
|
+
| ARIALiveRegionRole
|
|
95
|
+
| ARIAWindowRole
|
|
96
|
+
| ARIAUncategorizedRole
|
package/context.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import { __ivyaAriaTypes } from '@vitest/browser/internal/vendor-types'
|
|
1
2
|
import { SerializedConfig } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
StringifyOptions,
|
|
5
|
+
CDPSession,
|
|
6
|
+
BrowserCommands,
|
|
7
|
+
BrowserTraceEntryKind,
|
|
8
|
+
MarkOptions,
|
|
9
|
+
} from 'vitest/internal/browser'
|
|
3
10
|
import { ARIARole } from './aria-role.js'
|
|
4
11
|
import {} from './matchers.js'
|
|
5
|
-
import { __ivyaAriaTypes } from '@vitest/browser/internal/vendor-types'
|
|
6
12
|
|
|
7
13
|
export type BufferEncoding =
|
|
8
14
|
| 'ascii'
|
|
@@ -18,7 +24,7 @@ export type BufferEncoding =
|
|
|
18
24
|
| 'binary'
|
|
19
25
|
| 'hex'
|
|
20
26
|
|
|
21
|
-
export { BrowserTraceEntryKind, CDPSession, MarkOptions }
|
|
27
|
+
export { BrowserTraceEntryKind, CDPSession, MarkOptions }
|
|
22
28
|
|
|
23
29
|
export interface ScreenshotOptions extends SelectorOptions {
|
|
24
30
|
/**
|
|
@@ -146,7 +152,7 @@ export type NonStandardScreenshotComparators = Omit<
|
|
|
146
152
|
>
|
|
147
153
|
|
|
148
154
|
export interface ScreenshotMatcherOptions<
|
|
149
|
-
ComparatorName extends keyof ScreenshotComparatorRegistry = keyof ScreenshotComparatorRegistry
|
|
155
|
+
ComparatorName extends keyof ScreenshotComparatorRegistry = keyof ScreenshotComparatorRegistry,
|
|
150
156
|
> {
|
|
151
157
|
/**
|
|
152
158
|
* The name of the comparator to use for visual diffing.
|
|
@@ -320,7 +326,11 @@ export interface UserEvent {
|
|
|
320
326
|
* @see {@link https://playwright.dev/docs/api/class-locator#locator-set-input-files} Playwright API
|
|
321
327
|
* @see {@link https://testing-library.com/docs/user-event/utility#upload} testing-library API
|
|
322
328
|
*/
|
|
323
|
-
upload: (
|
|
329
|
+
upload: (
|
|
330
|
+
element: Element | Locator,
|
|
331
|
+
files: File | File[] | string | string[],
|
|
332
|
+
options?: UserEventUploadOptions,
|
|
333
|
+
) => Promise<void>
|
|
324
334
|
/**
|
|
325
335
|
* Copies the selected content.
|
|
326
336
|
* @see {@link https://playwright.dev/docs/api/class-keyboard} Playwright API
|
|
@@ -360,7 +370,11 @@ export interface UserEvent {
|
|
|
360
370
|
* @see {@link https://playwright.dev/docs/api/class-frame#frame-drag-and-drop} Playwright API
|
|
361
371
|
* @see {@link https://webdriver.io/docs/api/element/dragAndDrop/} WebdriverIO API
|
|
362
372
|
*/
|
|
363
|
-
dragAndDrop: (
|
|
373
|
+
dragAndDrop: (
|
|
374
|
+
source: Element | Locator,
|
|
375
|
+
target: Element | Locator,
|
|
376
|
+
options?: UserEventDragAndDropOptions,
|
|
377
|
+
) => Promise<void>
|
|
364
378
|
}
|
|
365
379
|
|
|
366
380
|
export interface UserEventFillOptions {}
|
|
@@ -851,10 +865,13 @@ export interface BrowserPage extends LocatorSelectors {
|
|
|
851
865
|
base64: string
|
|
852
866
|
}>
|
|
853
867
|
screenshot(options?: Omit<ScreenshotOptions, 'base64'>): Promise<string>
|
|
854
|
-
screenshot(options?: ScreenshotOptions): Promise<
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
868
|
+
screenshot(options?: ScreenshotOptions): Promise<
|
|
869
|
+
| string
|
|
870
|
+
| {
|
|
871
|
+
path: string
|
|
872
|
+
base64: string
|
|
873
|
+
}
|
|
874
|
+
>
|
|
858
875
|
/**
|
|
859
876
|
* Add a trace marker when browser tracing is enabled.
|
|
860
877
|
* @see {@link https://vitest.dev/api/browser/context#mark}
|
|
@@ -927,7 +944,6 @@ export interface BrowserLocators {
|
|
|
927
944
|
}): void
|
|
928
945
|
}
|
|
929
946
|
|
|
930
|
-
|
|
931
947
|
export type PrettyDOMOptions = Omit<StringifyOptions, 'maxLength'>
|
|
932
948
|
|
|
933
949
|
export const utils: {
|
package/context.js
CHANGED
|
@@ -12,9 +12,9 @@ export const utils = null
|
|
|
12
12
|
const pool = globalThis.__vitest_worker__?.ctx?.pool
|
|
13
13
|
|
|
14
14
|
throw new Error(
|
|
15
|
-
//
|
|
16
|
-
'vitest/browser can be imported only inside the Browser Mode. '
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
// oxlint-disable-next-line prefer-template
|
|
16
|
+
'vitest/browser can be imported only inside the Browser Mode. ' +
|
|
17
|
+
(pool
|
|
18
|
+
? `Your test is running in ${pool} pool. Make sure your regular tests are excluded from the "test.include" glob pattern.`
|
|
19
|
+
: 'Instead, it was imported outside of Vitest.'),
|
|
20
20
|
)
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "defineProperty"
|
|
11
11
|
},
|
|
12
12
|
"orchestrator.html": {
|
|
13
|
-
"file": "__vitest_browser__/orchestrator-
|
|
13
|
+
"file": "__vitest_browser__/orchestrator-Czo025Y6.js",
|
|
14
14
|
"name": "orchestrator",
|
|
15
15
|
"src": "orchestrator.html",
|
|
16
16
|
"isEntry": true,
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
]
|
|
23
23
|
},
|
|
24
24
|
"tester/tester.html": {
|
|
25
|
-
"file": "__vitest_browser__/tester-
|
|
25
|
+
"file": "__vitest_browser__/tester-BH7uPfyB.js",
|
|
26
26
|
"name": "tester",
|
|
27
27
|
"src": "tester/tester.html",
|
|
28
28
|
"isEntry": true,
|
package/dist/client/__vitest_browser__/{orchestrator-M9828UZ-.js → orchestrator-Czo025Y6.js}
RENAMED
|
@@ -11,6 +11,7 @@ function getUiAPI() {
|
|
|
11
11
|
//#endregion
|
|
12
12
|
//#region src/client/orchestrator.ts
|
|
13
13
|
var ID_ALL = "__vitest_all__";
|
|
14
|
+
var IFRAME_UNLOAD_TIMEOUT = 5e3;
|
|
14
15
|
var IframeOrchestrator = class {
|
|
15
16
|
constructor() {
|
|
16
17
|
_defineProperty(this, "cancelled", false);
|
|
@@ -22,6 +23,7 @@ var IframeOrchestrator = class {
|
|
|
22
23
|
_defineProperty(this, "eventTarget", new EventTarget());
|
|
23
24
|
_defineProperty(this, "traces", void 0);
|
|
24
25
|
_defineProperty(this, "loggedIframe", /* @__PURE__ */ new WeakSet());
|
|
26
|
+
_defineProperty(this, "iframeLoads", /* @__PURE__ */ new WeakMap());
|
|
25
27
|
_defineProperty(this, "iframeEvents", /* @__PURE__ */ new WeakMap());
|
|
26
28
|
debug("init orchestrator", (/* @__PURE__ */ getBrowserState()).sessionId);
|
|
27
29
|
if (getConfig().browser.traceView.enabled) {
|
|
@@ -151,15 +153,18 @@ var IframeOrchestrator = class {
|
|
|
151
153
|
iframe.onload = () => {
|
|
152
154
|
const href = this.getIframeHref(iframe);
|
|
153
155
|
debug("iframe loaded with href", href);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Received URL: ${href || "unknown due to CORS"}\nExpected: ${iframe.src}`)));
|
|
156
|
+
this.iframeLoads.set(iframe, (this.iframeLoads.get(iframe) ?? 0) + 1);
|
|
157
|
+
if (href !== iframe.src) reject(this.dispatchIframeError(this.createConnectError(iframe, href)));
|
|
157
158
|
else if (this.iframes.has(iframeId)) {
|
|
158
159
|
const events = this.iframeEvents.get(iframe);
|
|
159
160
|
if (events === null || events === void 0 ? void 0 : events.size) this.dispatchIframeError(new Error(this.createWarningMessage(iframeId, "during a test")));
|
|
160
|
-
else
|
|
161
|
+
else {
|
|
162
|
+
this.warnReload(iframe, iframeId);
|
|
163
|
+
this.watchUnload(iframe, iframeId);
|
|
164
|
+
}
|
|
161
165
|
} else {
|
|
162
166
|
this.iframes.set(iframeId, iframe);
|
|
167
|
+
this.watchUnload(iframe, iframeId);
|
|
163
168
|
this.waitForReady(iframeId).then(() => this.sendEventToIframe({
|
|
164
169
|
event: "prepare",
|
|
165
170
|
iframeId,
|
|
@@ -215,6 +220,22 @@ Received URL: ${href || "unknown due to CORS"}\nExpected: ${iframe.src}`)));
|
|
|
215
220
|
}
|
|
216
221
|
iframe === null || iframe === void 0 || iframe.remove();
|
|
217
222
|
}
|
|
223
|
+
createConnectError(iframe, href) {
|
|
224
|
+
return /* @__PURE__ */ new Error(`Cannot connect to the iframe. Did you change the location or submitted a form? If so, don't forget to call \`event.preventDefault()\` to avoid reloading the page.
|
|
225
|
+
|
|
226
|
+
Received URL: ${href || "unknown due to CORS"}\nExpected: ${iframe.src}`);
|
|
227
|
+
}
|
|
228
|
+
watchUnload(iframe, iframeId) {
|
|
229
|
+
var _iframe$contentWindow;
|
|
230
|
+
const loads = this.iframeLoads.get(iframe) ?? 0;
|
|
231
|
+
(_iframe$contentWindow = iframe.contentWindow) === null || _iframe$contentWindow === void 0 || _iframe$contentWindow.addEventListener("pagehide", () => {
|
|
232
|
+
setTimeout(() => {
|
|
233
|
+
var _this$iframeEvents$ge;
|
|
234
|
+
if (this.iframes.get(iframeId) !== iframe || !((_this$iframeEvents$ge = this.iframeEvents.get(iframe)) === null || _this$iframeEvents$ge === void 0 ? void 0 : _this$iframeEvents$ge.size) || this.iframeLoads.get(iframe) !== loads) return;
|
|
235
|
+
this.dispatchIframeError(this.createConnectError(iframe, this.getIframeHref(iframe)));
|
|
236
|
+
}, IFRAME_UNLOAD_TIMEOUT);
|
|
237
|
+
}, { once: true });
|
|
238
|
+
}
|
|
218
239
|
createWarningMessage(iframeId, location) {
|
|
219
240
|
return `The iframe${iframeId === ID_ALL ? "" : ` for "${iframeId}"`} was reloaded ${location}. This can lead to unexpected behavior during tests, duplicated test results or tests hanging.\n\nMake sure that your test code does not change window's location, submit forms without preventing default behavior, or imports unoptimized dependencies.\nIf you are using a framework that manipulates browser history (like React Router), consider using memory-based routing for tests. If you think this is a false positive, open an issue with a reproduction: https://github.com/vitest-dev/vitest/issues/new`;
|
|
220
241
|
}
|
|
@@ -232,8 +253,8 @@ Received URL: ${href || "unknown due to CORS"}\nExpected: ${iframe.src}`)));
|
|
|
232
253
|
}
|
|
233
254
|
getIframeHref(iframe) {
|
|
234
255
|
try {
|
|
235
|
-
var _iframe$
|
|
236
|
-
return (_iframe$
|
|
256
|
+
var _iframe$contentWindow2;
|
|
257
|
+
return (_iframe$contentWindow2 = iframe.contentWindow) === null || _iframe$contentWindow2 === void 0 ? void 0 : _iframe$contentWindow2.location.href;
|
|
237
258
|
} catch {
|
|
238
259
|
return;
|
|
239
260
|
}
|
|
@@ -561,7 +561,7 @@ function extractLocation(urlLike) {
|
|
|
561
561
|
const urlObj = new URL(url);
|
|
562
562
|
urlObj.searchParams.delete("import");
|
|
563
563
|
urlObj.searchParams.delete("browserv");
|
|
564
|
-
url = urlObj.pathname + urlObj.hash + urlObj.search;
|
|
564
|
+
url = tryDecode(urlObj.pathname, decodeURI) + urlObj.hash + urlObj.search;
|
|
565
565
|
}
|
|
566
566
|
if (url.startsWith("/@fs/")) {
|
|
567
567
|
const isWindows = /^\/@fs\/[a-zA-Z]:\//.test(url);
|
|
@@ -574,6 +574,13 @@ function extractLocation(urlLike) {
|
|
|
574
574
|
parts[3] || void 0
|
|
575
575
|
];
|
|
576
576
|
}
|
|
577
|
+
function tryDecode(value, decode) {
|
|
578
|
+
try {
|
|
579
|
+
return decode(value);
|
|
580
|
+
} catch {
|
|
581
|
+
return value;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
577
584
|
function parseSingleFFOrSafariStack(raw) {
|
|
578
585
|
let line = raw.trim();
|
|
579
586
|
if (SAFARI_NATIVE_CODE_REGEXP.test(line)) return null;
|
|
@@ -613,7 +620,7 @@ function parseSingleV8Stack(raw) {
|
|
|
613
620
|
let file = url && ["eval", "<anonymous>"].includes(url) ? void 0 : url;
|
|
614
621
|
if (!file || !lineNumber || !columnNumber) return null;
|
|
615
622
|
if (method.startsWith("async ")) method = method.slice(6);
|
|
616
|
-
if (file.startsWith("file://")) file = file.slice(7);
|
|
623
|
+
if (file.startsWith("file://")) file = tryDecode(file.slice(7), decodeURIComponent);
|
|
617
624
|
file = file.startsWith("node:") || file.startsWith("internal:") ? file : resolve(file);
|
|
618
625
|
if (method) method = method.replace(/\(0\s?,\s?__vite_ssr_import_\d+__.(\w+)\)/g, "$1").replace(/__(vite_ssr_import|vi_import)_\d+__\./g, "").replace(/(Object\.)?__vite_ssr_export_default__\s?/g, "");
|
|
619
626
|
return {
|
|
@@ -818,15 +825,11 @@ function takeSnapshot(serializedLocator) {
|
|
|
818
825
|
result.pseudoClassIds[className] = ids;
|
|
819
826
|
}
|
|
820
827
|
if (serializedLocator) try {
|
|
821
|
-
const
|
|
822
|
-
if (
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
result.selectorId = id;
|
|
827
|
-
result.selectorResolution = "matched";
|
|
828
|
-
} else result.selectorResolution = "missing";
|
|
829
|
-
}
|
|
828
|
+
const ids = engine.querySelectorAll(engine.parseSelector(serializedLocator._pwSelector ?? serializedLocator.selector), document.documentElement).map((el) => mirror.getId(el)).filter((id) => id !== -1);
|
|
829
|
+
if (ids.length > 0) {
|
|
830
|
+
result.selectorIds = ids;
|
|
831
|
+
result.selectorResolution = "matched";
|
|
832
|
+
} else result.selectorResolution = "missing";
|
|
830
833
|
} catch (error) {
|
|
831
834
|
result.selectorResolution = "error";
|
|
832
835
|
result.selectorError = error instanceof Error ? error.message : String(error);
|
|
@@ -1000,6 +1003,7 @@ function createBrowserRunner(mocker, state, coverageModule) {
|
|
|
1000
1003
|
const importpath = `${`/${/^\w:/.test(filepath) ? "@fs/" : ""}`}${filepath}?${`browserv=${hash}`}`.replace(/\/+/g, "/");
|
|
1001
1004
|
const trace = this.config.browser.trace;
|
|
1002
1005
|
if (mode === "collect" && trace !== "off") await this.commands.triggerCommand("__vitest_startTracing", []);
|
|
1006
|
+
await mocker.prepare();
|
|
1003
1007
|
try {
|
|
1004
1008
|
await __vitePreload(() => import(
|
|
1005
1009
|
/* @vite-ignore */
|
|
@@ -1206,6 +1210,13 @@ function sendLog(type, content, disableStack) {
|
|
|
1206
1210
|
});
|
|
1207
1211
|
}
|
|
1208
1212
|
|
|
1213
|
+
//#endregion
|
|
1214
|
+
//#region ../mocker/dist/chunk-helpers.js
|
|
1215
|
+
function withTrailingSlash(path) {
|
|
1216
|
+
if (path.at(-1) !== "/") return `${path}/`;
|
|
1217
|
+
return path;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1209
1220
|
//#endregion
|
|
1210
1221
|
//#region ../mocker/dist/chunk-registry.js
|
|
1211
1222
|
var MockerRegistry = class {
|
|
@@ -1685,7 +1696,7 @@ var ModuleMocker = class {
|
|
|
1685
1696
|
}
|
|
1686
1697
|
async prepare() {
|
|
1687
1698
|
if (!this.queue.size) return;
|
|
1688
|
-
await Promise.all(
|
|
1699
|
+
await Promise.all(this.queue.values());
|
|
1689
1700
|
}
|
|
1690
1701
|
async resolveFactoryModule(id) {
|
|
1691
1702
|
const mock = this.registry.get(id);
|
|
@@ -1699,6 +1710,7 @@ var ModuleMocker = class {
|
|
|
1699
1710
|
return mock.cache;
|
|
1700
1711
|
}
|
|
1701
1712
|
async invalidate() {
|
|
1713
|
+
await Promise.allSettled(this.queue);
|
|
1702
1714
|
const ids = Array.from(this.mockedIds);
|
|
1703
1715
|
if (!ids.length) return;
|
|
1704
1716
|
await this.rpc.invalidate(ids);
|
|
@@ -1822,8 +1834,8 @@ var ModuleMocker = class {
|
|
|
1822
1834
|
resolveMockPath(path) {
|
|
1823
1835
|
const config = this.config;
|
|
1824
1836
|
const fsRoot = join("/@fs/", config.root);
|
|
1825
|
-
if (path.startsWith(config.root)) return path.slice(config.root.length);
|
|
1826
|
-
if (path.startsWith(fsRoot)) return path.slice(fsRoot.length);
|
|
1837
|
+
if (path.startsWith(withTrailingSlash(config.root))) return path.slice(config.root.length);
|
|
1838
|
+
if (path.startsWith(withTrailingSlash(fsRoot))) return path.slice(fsRoot.length);
|
|
1827
1839
|
return path;
|
|
1828
1840
|
}
|
|
1829
1841
|
};
|
|
@@ -1896,7 +1908,6 @@ var CommandsManager = class {
|
|
|
1896
1908
|
const rpc = state.rpc;
|
|
1897
1909
|
const { sessionId, traces } = /* @__PURE__ */ getBrowserState();
|
|
1898
1910
|
const filepath = state.filepath || ((_state$current = state.current) === null || _state$current === void 0 || (_state$current = _state$current.file) === null || _state$current === void 0 ? void 0 : _state$current.filepath);
|
|
1899
|
-
args = args.filter((arg) => arg !== void 0);
|
|
1900
1911
|
const actionTraceGroupName = ACTION_TRACE_COMMANDS.has(command) ? `vitest:${command.slice(9)}` : void 0;
|
|
1901
1912
|
const currentTest = (/* @__PURE__ */ getWorkerState()).current;
|
|
1902
1913
|
const hasActiveTrace = !!actionTraceGroupName && !!currentTest && (/* @__PURE__ */ getBrowserState()).activeTraceTaskIds.has(currentTest.id);
|
|
@@ -1912,7 +1923,7 @@ var CommandsManager = class {
|
|
|
1912
1923
|
}]);
|
|
1913
1924
|
let status = "pass";
|
|
1914
1925
|
const traceRangeId = hasActiveTraceView ? createBrowserTraceRangeId() : void 0;
|
|
1915
|
-
const element = typeof args[0] === "object" && "selector" in args[0] && "locator" in args[0] ? args[0] : void 0;
|
|
1926
|
+
const element = typeof args[0] === "object" && args[0] !== null && "selector" in args[0] && "locator" in args[0] ? args[0] : void 0;
|
|
1916
1927
|
if (hasActiveTraceView) await recordBrowserTraceEntry(currentTest, {
|
|
1917
1928
|
name: actionTraceGroupName,
|
|
1918
1929
|
kind: "action",
|
|
@@ -2,9 +2,8 @@ import { client } from '@vitest/browser/client'
|
|
|
2
2
|
|
|
3
3
|
function serializeError(unhandledError) {
|
|
4
4
|
const state = globalThis.__vitest_worker__
|
|
5
|
-
const VITEST_TEST_NAME =
|
|
6
|
-
? state.current.name
|
|
7
|
-
: undefined
|
|
5
|
+
const VITEST_TEST_NAME =
|
|
6
|
+
state && state.current && state.current.type === 'test' ? state.current.name : undefined
|
|
8
7
|
const VITEST_TEST_PATH = state && state.filepath ? state.filepath : undefined
|
|
9
8
|
|
|
10
9
|
if (typeof unhandledError !== 'object' || !unhandledError) {
|
|
@@ -29,8 +28,7 @@ function catchWindowErrors(errorEvent, prop, cb) {
|
|
|
29
28
|
function throwUnhandlerError(e) {
|
|
30
29
|
if (userErrorListenerCount === 0 && e[prop] != null) {
|
|
31
30
|
cb(e)
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
31
|
+
} else {
|
|
34
32
|
// `ErrorEvent` doesn't necessary have `ErrorEvent.error` defined
|
|
35
33
|
// but some has `ErrorEvent.message` defined, e.g. ResizeObserver error.
|
|
36
34
|
// https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent/error
|
|
@@ -59,24 +57,26 @@ function catchWindowErrors(errorEvent, prop, cb) {
|
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
function registerUnexpectedErrors() {
|
|
62
|
-
const offError = catchWindowErrors('error', 'error', event =>
|
|
63
|
-
reportUnexpectedError('Error', event.error)
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
const offError = catchWindowErrors('error', 'error', (event) =>
|
|
61
|
+
reportUnexpectedError('Error', event.error),
|
|
62
|
+
)
|
|
63
|
+
const offRejection = catchWindowErrors('unhandledrejection', 'reason', (event) =>
|
|
64
|
+
reportUnexpectedError('Unhandled Rejection', event.reason),
|
|
65
|
+
)
|
|
66
66
|
return () => {
|
|
67
67
|
offError()
|
|
68
68
|
offRejection()
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
async function reportUnexpectedError(
|
|
73
|
-
type,
|
|
74
|
-
error,
|
|
75
|
-
) {
|
|
72
|
+
async function reportUnexpectedError(type, error) {
|
|
76
73
|
const processedError = serializeError(error)
|
|
77
|
-
await client
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
await client
|
|
75
|
+
.waitForConnection()
|
|
76
|
+
.then(() => {
|
|
77
|
+
return client.rpc.onUnhandledError(processedError, type)
|
|
78
|
+
})
|
|
79
|
+
.catch(console.error)
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
globalThis.__vitest_browser_runner__.disposeExceptionTracker = registerUnexpectedErrors()
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml"
|
|
5
|
+
<link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Vitest Browser Runner</title>
|
|
8
8
|
<style>
|
|
@@ -22,11 +22,12 @@
|
|
|
22
22
|
width: 100%;
|
|
23
23
|
height: 100%;
|
|
24
24
|
}
|
|
25
|
+
iframe[data-vitest] {
|
|
26
|
+
display: block;
|
|
27
|
+
}
|
|
25
28
|
</style>
|
|
26
|
-
{__VITEST_INJECTOR__}
|
|
27
|
-
|
|
28
|
-
{__VITEST_SCRIPTS__}
|
|
29
|
-
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-M9828UZ-.js"></script>
|
|
29
|
+
{__VITEST_INJECTOR__} {__VITEST_ERROR_CATCHER__} {__VITEST_SCRIPTS__}
|
|
30
|
+
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-Czo025Y6.js"></script>
|
|
30
31
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/defineProperty-DgkPJYVE.js">
|
|
31
32
|
</head>
|
|
32
33
|
<body>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml"
|
|
5
|
+
<link rel="icon" href="{__VITEST_FAVICON__}" type="image/svg+xml" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>Vitest Browser Tester</title>
|
|
8
|
-
<script type="module" crossorigin src="/__vitest_browser__/tester-
|
|
8
|
+
<script type="module" crossorigin src="/__vitest_browser__/tester-BH7uPfyB.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/defineProperty-DgkPJYVE.js">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/client.js
CHANGED
|
@@ -311,6 +311,15 @@ const stringify = (value, replacer, space) => {
|
|
|
311
311
|
}
|
|
312
312
|
};
|
|
313
313
|
|
|
314
|
+
// JSON drops `undefined` in objects and turns it into `null` in arrays
|
|
315
|
+
const UNDEFINED_VALUE = "__vitest_undefined__";
|
|
316
|
+
function replaceUndefined(value) {
|
|
317
|
+
return value === undefined ? UNDEFINED_VALUE : value;
|
|
318
|
+
}
|
|
319
|
+
function reviveUndefined(_key, value) {
|
|
320
|
+
return value === UNDEFINED_VALUE ? undefined : value;
|
|
321
|
+
}
|
|
322
|
+
|
|
314
323
|
globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now;
|
|
315
324
|
/* @__NO_SIDE_EFFECTS__ */
|
|
316
325
|
function getBrowserState() {
|
|
@@ -424,9 +433,9 @@ function createClient() {
|
|
|
424
433
|
stack: v.stack
|
|
425
434
|
};
|
|
426
435
|
}
|
|
427
|
-
return v;
|
|
436
|
+
return replaceUndefined(v);
|
|
428
437
|
}),
|
|
429
|
-
deserialize: parse,
|
|
438
|
+
deserialize: (e) => parse(e, reviveUndefined),
|
|
430
439
|
timeout: -1
|
|
431
440
|
});
|
|
432
441
|
let openPromise;
|