@vitest/browser 2.1.4 → 2.2.0-beta.1
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/README.md +7 -21
- package/dist/client/.vite/manifest.json +6 -6
- package/dist/client/__vitest__/index.html +2 -2
- package/dist/client/__vitest_browser__/{orchestrator-NReaboR_.js → orchestrator-DnP17K36.js} +5 -117
- package/dist/client/__vitest_browser__/{tester-CAAquV6P.js → tester-BaiNqOPw.js} +1251 -2
- package/dist/client/__vitest_browser__/utils-Owv5OOOf.js +195 -0
- package/dist/client/orchestrator.html +2 -2
- package/dist/client/tester/tester.html +2 -13
- package/dist/context.js +74 -34
- package/dist/{index-Cgg35wOd.js → index-CKtADM3n.js} +35 -3
- package/dist/index.js +59 -18
- package/dist/locators/index.js +1 -1
- package/dist/locators/playwright.js +1 -1
- package/dist/locators/preview.js +10 -10
- package/dist/locators/webdriverio.js +1 -1
- package/dist/providers.js +8 -7
- package/package.json +13 -13
- package/dist/client/__vitest_browser__/utils-CUwLt_eT.js +0 -81
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
(function polyfill() {
|
|
2
|
+
const relList = document.createElement("link").relList;
|
|
3
|
+
if (relList && relList.supports && relList.supports("modulepreload")) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
for (const link of document.querySelectorAll('link[rel="modulepreload"]')) {
|
|
7
|
+
processPreload(link);
|
|
8
|
+
}
|
|
9
|
+
new MutationObserver((mutations) => {
|
|
10
|
+
for (const mutation of mutations) {
|
|
11
|
+
if (mutation.type !== "childList") {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
for (const node of mutation.addedNodes) {
|
|
15
|
+
if (node.tagName === "LINK" && node.rel === "modulepreload")
|
|
16
|
+
processPreload(node);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}).observe(document, { childList: true, subtree: true });
|
|
20
|
+
function getFetchOpts(link) {
|
|
21
|
+
const fetchOpts = {};
|
|
22
|
+
if (link.integrity) fetchOpts.integrity = link.integrity;
|
|
23
|
+
if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
|
|
24
|
+
if (link.crossOrigin === "use-credentials")
|
|
25
|
+
fetchOpts.credentials = "include";
|
|
26
|
+
else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
|
|
27
|
+
else fetchOpts.credentials = "same-origin";
|
|
28
|
+
return fetchOpts;
|
|
29
|
+
}
|
|
30
|
+
function processPreload(link) {
|
|
31
|
+
if (link.ep)
|
|
32
|
+
return;
|
|
33
|
+
link.ep = true;
|
|
34
|
+
const fetchOpts = getFetchOpts(link);
|
|
35
|
+
fetch(link.href, fetchOpts);
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
39
|
+
function normalizeWindowsPath(input = "") {
|
|
40
|
+
if (!input) {
|
|
41
|
+
return input;
|
|
42
|
+
}
|
|
43
|
+
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
|
|
44
|
+
}
|
|
45
|
+
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
|
|
46
|
+
const _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
|
|
47
|
+
function cwd() {
|
|
48
|
+
if (typeof process !== "undefined" && typeof process.cwd === "function") {
|
|
49
|
+
return process.cwd().replace(/\\/g, "/");
|
|
50
|
+
}
|
|
51
|
+
return "/";
|
|
52
|
+
}
|
|
53
|
+
const resolve = function(...arguments_) {
|
|
54
|
+
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
|
|
55
|
+
let resolvedPath = "";
|
|
56
|
+
let resolvedAbsolute = false;
|
|
57
|
+
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
|
|
58
|
+
const path = index >= 0 ? arguments_[index] : cwd();
|
|
59
|
+
if (!path || path.length === 0) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
resolvedPath = `${path}/${resolvedPath}`;
|
|
63
|
+
resolvedAbsolute = isAbsolute(path);
|
|
64
|
+
}
|
|
65
|
+
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
|
|
66
|
+
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
|
|
67
|
+
return `/${resolvedPath}`;
|
|
68
|
+
}
|
|
69
|
+
return resolvedPath.length > 0 ? resolvedPath : ".";
|
|
70
|
+
};
|
|
71
|
+
function normalizeString(path, allowAboveRoot) {
|
|
72
|
+
let res = "";
|
|
73
|
+
let lastSegmentLength = 0;
|
|
74
|
+
let lastSlash = -1;
|
|
75
|
+
let dots = 0;
|
|
76
|
+
let char = null;
|
|
77
|
+
for (let index = 0; index <= path.length; ++index) {
|
|
78
|
+
if (index < path.length) {
|
|
79
|
+
char = path[index];
|
|
80
|
+
} else if (char === "/") {
|
|
81
|
+
break;
|
|
82
|
+
} else {
|
|
83
|
+
char = "/";
|
|
84
|
+
}
|
|
85
|
+
if (char === "/") {
|
|
86
|
+
if (lastSlash === index - 1 || dots === 1) ;
|
|
87
|
+
else if (dots === 2) {
|
|
88
|
+
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
|
|
89
|
+
if (res.length > 2) {
|
|
90
|
+
const lastSlashIndex = res.lastIndexOf("/");
|
|
91
|
+
if (lastSlashIndex === -1) {
|
|
92
|
+
res = "";
|
|
93
|
+
lastSegmentLength = 0;
|
|
94
|
+
} else {
|
|
95
|
+
res = res.slice(0, lastSlashIndex);
|
|
96
|
+
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
97
|
+
}
|
|
98
|
+
lastSlash = index;
|
|
99
|
+
dots = 0;
|
|
100
|
+
continue;
|
|
101
|
+
} else if (res.length > 0) {
|
|
102
|
+
res = "";
|
|
103
|
+
lastSegmentLength = 0;
|
|
104
|
+
lastSlash = index;
|
|
105
|
+
dots = 0;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (allowAboveRoot) {
|
|
110
|
+
res += res.length > 0 ? "/.." : "..";
|
|
111
|
+
lastSegmentLength = 2;
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
if (res.length > 0) {
|
|
115
|
+
res += `/${path.slice(lastSlash + 1, index)}`;
|
|
116
|
+
} else {
|
|
117
|
+
res = path.slice(lastSlash + 1, index);
|
|
118
|
+
}
|
|
119
|
+
lastSegmentLength = index - lastSlash - 1;
|
|
120
|
+
}
|
|
121
|
+
lastSlash = index;
|
|
122
|
+
dots = 0;
|
|
123
|
+
} else if (char === "." && dots !== -1) {
|
|
124
|
+
++dots;
|
|
125
|
+
} else {
|
|
126
|
+
dots = -1;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return res;
|
|
130
|
+
}
|
|
131
|
+
const isAbsolute = function(p) {
|
|
132
|
+
return _IS_ABSOLUTE_RE.test(p);
|
|
133
|
+
};
|
|
134
|
+
const relative = function(from, to) {
|
|
135
|
+
const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/");
|
|
136
|
+
const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
|
|
137
|
+
if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) {
|
|
138
|
+
return _to.join("/");
|
|
139
|
+
}
|
|
140
|
+
const _fromCopy = [..._from];
|
|
141
|
+
for (const segment of _fromCopy) {
|
|
142
|
+
if (_to[0] !== segment) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
_from.shift();
|
|
146
|
+
_to.shift();
|
|
147
|
+
}
|
|
148
|
+
return [..._from.map(() => ".."), ..._to].join("/");
|
|
149
|
+
};
|
|
150
|
+
async function importId(id) {
|
|
151
|
+
const name = `/@id/${id}`.replace(/\\/g, "/");
|
|
152
|
+
return (/* @__PURE__ */ getBrowserState()).wrapModule(() => import(
|
|
153
|
+
/* @vite-ignore */
|
|
154
|
+
name
|
|
155
|
+
));
|
|
156
|
+
}
|
|
157
|
+
async function importFs(id) {
|
|
158
|
+
const name = `/@fs/${id}`.replace(/\\/g, "/");
|
|
159
|
+
return (/* @__PURE__ */ getBrowserState()).wrapModule(() => import(
|
|
160
|
+
/* @vite-ignore */
|
|
161
|
+
name
|
|
162
|
+
));
|
|
163
|
+
}
|
|
164
|
+
const executor = {
|
|
165
|
+
isBrowser: true,
|
|
166
|
+
executeId: (id) => {
|
|
167
|
+
if (id[0] === "/" || id[1] === ":") {
|
|
168
|
+
return importFs(id);
|
|
169
|
+
}
|
|
170
|
+
return importId(id);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
function getConfig() {
|
|
174
|
+
return (/* @__PURE__ */ getBrowserState()).config;
|
|
175
|
+
}
|
|
176
|
+
// @__NO_SIDE_EFFECTS__
|
|
177
|
+
function getBrowserState() {
|
|
178
|
+
return window.__vitest_browser_runner__;
|
|
179
|
+
}
|
|
180
|
+
// @__NO_SIDE_EFFECTS__
|
|
181
|
+
function getWorkerState() {
|
|
182
|
+
const state = window.__vitest_worker__;
|
|
183
|
+
if (!state) {
|
|
184
|
+
throw new Error("Worker state is not found. This is an issue with Vitest. Please, open an issue.");
|
|
185
|
+
}
|
|
186
|
+
return state;
|
|
187
|
+
}
|
|
188
|
+
export {
|
|
189
|
+
getConfig as a,
|
|
190
|
+
resolve as b,
|
|
191
|
+
getWorkerState as c,
|
|
192
|
+
executor as e,
|
|
193
|
+
getBrowserState as g,
|
|
194
|
+
relative as r
|
|
195
|
+
};
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
{__VITEST_INJECTOR__}
|
|
27
27
|
{__VITEST_ERROR_CATCHER__}
|
|
28
28
|
{__VITEST_SCRIPTS__}
|
|
29
|
-
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-
|
|
30
|
-
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-
|
|
29
|
+
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-DnP17K36.js"></script>
|
|
30
|
+
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-Owv5OOOf.js">
|
|
31
31
|
</head>
|
|
32
32
|
<body>
|
|
33
33
|
<div id="vitest-tester"></div>
|
|
@@ -5,19 +5,8 @@
|
|
|
5
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
|
-
<
|
|
9
|
-
|
|
10
|
-
padding: 0;
|
|
11
|
-
margin: 0;
|
|
12
|
-
}
|
|
13
|
-
body {
|
|
14
|
-
padding: 0;
|
|
15
|
-
margin: 0;
|
|
16
|
-
min-height: 100vh;
|
|
17
|
-
}
|
|
18
|
-
</style>
|
|
19
|
-
<script type="module" crossorigin src="/__vitest_browser__/tester-CAAquV6P.js"></script>
|
|
20
|
-
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-CUwLt_eT.js">
|
|
8
|
+
<script type="module" crossorigin src="/__vitest_browser__/tester-BaiNqOPw.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-Owv5OOOf.js">
|
|
21
10
|
</head>
|
|
22
11
|
<body>
|
|
23
12
|
</body>
|
package/dist/context.js
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
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()).then(onFulfilled, onRejected);
|
|
23
|
+
},
|
|
24
|
+
catch(onRejected) {
|
|
25
|
+
return (promiseResult ||= promise()).catch(onRejected);
|
|
26
|
+
},
|
|
27
|
+
finally(onFinally) {
|
|
28
|
+
return (promiseResult ||= promise()).finally(onFinally);
|
|
29
|
+
},
|
|
30
|
+
[Symbol.toStringTag]: "Promise"
|
|
31
|
+
};
|
|
32
|
+
}
|
|
1
33
|
// @__NO_SIDE_EFFECTS__
|
|
2
34
|
function getBrowserState() {
|
|
3
35
|
return window.__vitest_browser_runner__;
|
|
@@ -100,12 +132,14 @@ function createUserEvent(__tl_user_event_base__, options) {
|
|
|
100
132
|
return createUserEvent(__tl_user_event_base__, options2);
|
|
101
133
|
},
|
|
102
134
|
async cleanup() {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
135
|
+
return ensureAwaited(async () => {
|
|
136
|
+
if (typeof __tl_user_event_base__ !== "undefined") {
|
|
137
|
+
__tl_user_event__ = __tl_user_event_base__?.setup(options ?? {});
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
await triggerCommand("__vitest_cleanup", keyboard);
|
|
141
|
+
keyboard.unreleased = [];
|
|
142
|
+
});
|
|
109
143
|
},
|
|
110
144
|
click(element, options2 = {}) {
|
|
111
145
|
return convertToLocator(element).click(processClickOptions(options2));
|
|
@@ -142,38 +176,44 @@ function createUserEvent(__tl_user_event_base__, options) {
|
|
|
142
176
|
},
|
|
143
177
|
// testing-library user-event
|
|
144
178
|
async type(element, text, options2 = {}) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
179
|
+
return ensureAwaited(async () => {
|
|
180
|
+
if (typeof __tl_user_event__ !== "undefined") {
|
|
181
|
+
return __tl_user_event__.type(
|
|
182
|
+
element instanceof Element ? element : element.element(),
|
|
183
|
+
text,
|
|
184
|
+
options2
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
const selector = convertToSelector(element);
|
|
188
|
+
const { unreleased } = await triggerCommand(
|
|
189
|
+
"__vitest_type",
|
|
190
|
+
selector,
|
|
148
191
|
text,
|
|
149
|
-
options2
|
|
192
|
+
{ ...options2, unreleased: keyboard.unreleased }
|
|
150
193
|
);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const { unreleased } = await triggerCommand(
|
|
154
|
-
"__vitest_type",
|
|
155
|
-
selector,
|
|
156
|
-
text,
|
|
157
|
-
{ ...options2, unreleased: keyboard.unreleased }
|
|
158
|
-
);
|
|
159
|
-
keyboard.unreleased = unreleased;
|
|
194
|
+
keyboard.unreleased = unreleased;
|
|
195
|
+
});
|
|
160
196
|
},
|
|
161
197
|
tab(options2 = {}) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
198
|
+
return ensureAwaited(() => {
|
|
199
|
+
if (typeof __tl_user_event__ !== "undefined") {
|
|
200
|
+
return __tl_user_event__.tab(options2);
|
|
201
|
+
}
|
|
202
|
+
return triggerCommand("__vitest_tab", options2);
|
|
203
|
+
});
|
|
166
204
|
},
|
|
167
205
|
async keyboard(text) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
206
|
+
return ensureAwaited(async () => {
|
|
207
|
+
if (typeof __tl_user_event__ !== "undefined") {
|
|
208
|
+
return __tl_user_event__.keyboard(text);
|
|
209
|
+
}
|
|
210
|
+
const { unreleased } = await triggerCommand(
|
|
211
|
+
"__vitest_keyboard",
|
|
212
|
+
text,
|
|
213
|
+
keyboard
|
|
214
|
+
);
|
|
215
|
+
keyboard.unreleased = unreleased;
|
|
216
|
+
});
|
|
177
217
|
}
|
|
178
218
|
};
|
|
179
219
|
}
|
|
@@ -214,10 +254,10 @@ const page = {
|
|
|
214
254
|
screenshotIds[repeatCount] ??= {};
|
|
215
255
|
screenshotIds[repeatCount][taskName] = number + 1;
|
|
216
256
|
const name = options.path || `${taskName.replace(/[^a-z0-9]/gi, "-")}-${number}.png`;
|
|
217
|
-
return triggerCommand("__vitest_screenshot", name, {
|
|
257
|
+
return ensureAwaited(() => triggerCommand("__vitest_screenshot", name, {
|
|
218
258
|
...options,
|
|
219
259
|
element: options.element ? convertToSelector(options.element) : void 0
|
|
220
|
-
});
|
|
260
|
+
}));
|
|
221
261
|
},
|
|
222
262
|
getByRole() {
|
|
223
263
|
throw new Error('Method "getByRole" is not implemented in the current provider.');
|
|
@@ -1,6 +1,38 @@
|
|
|
1
1
|
import { server, page } from '@vitest/browser/context';
|
|
2
2
|
import { I as Ivya, a as getByRoleSelector, c as getByAltTextSelector, g as getByLabelSelector, d as getByPlaceholderSelector, b as getByTestIdSelector, e as getByTextSelector, f as getByTitleSelector, h as getElementError } from './public-utils-D6S2-5kI.js';
|
|
3
3
|
|
|
4
|
+
function ensureAwaited(promise) {
|
|
5
|
+
const test = (/* @__PURE__ */ getWorkerState()).current;
|
|
6
|
+
if (!test || test.type !== "test") {
|
|
7
|
+
return promise();
|
|
8
|
+
}
|
|
9
|
+
let awaited = false;
|
|
10
|
+
const sourceError = new Error("STACK_TRACE_ERROR");
|
|
11
|
+
test.onFinished ??= [];
|
|
12
|
+
test.onFinished.push(() => {
|
|
13
|
+
if (!awaited) {
|
|
14
|
+
const error = new Error(
|
|
15
|
+
`The call was not awaited. This method is asynchronous and must be awaited; otherwise, the call will not start to avoid unhandled rejections.`
|
|
16
|
+
);
|
|
17
|
+
error.stack = sourceError.stack?.replace(sourceError.message, error.message);
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
let promiseResult;
|
|
22
|
+
return {
|
|
23
|
+
then(onFulfilled, onRejected) {
|
|
24
|
+
awaited = true;
|
|
25
|
+
return (promiseResult ||= promise()).then(onFulfilled, onRejected);
|
|
26
|
+
},
|
|
27
|
+
catch(onRejected) {
|
|
28
|
+
return (promiseResult ||= promise()).catch(onRejected);
|
|
29
|
+
},
|
|
30
|
+
finally(onFinally) {
|
|
31
|
+
return (promiseResult ||= promise()).finally(onFinally);
|
|
32
|
+
},
|
|
33
|
+
[Symbol.toStringTag]: "Promise"
|
|
34
|
+
};
|
|
35
|
+
}
|
|
4
36
|
// @__NO_SIDE_EFFECTS__
|
|
5
37
|
function getBrowserState() {
|
|
6
38
|
return window.__vitest_browser_runner__;
|
|
@@ -214,13 +246,13 @@ class Locator {
|
|
|
214
246
|
}
|
|
215
247
|
triggerCommand(command, ...args) {
|
|
216
248
|
const filepath = this.worker.filepath || this.worker.current?.file?.filepath || void 0;
|
|
217
|
-
return this.rpc.triggerCommand(
|
|
249
|
+
return ensureAwaited(() => this.rpc.triggerCommand(
|
|
218
250
|
this.state.contextId,
|
|
219
251
|
command,
|
|
220
252
|
filepath,
|
|
221
253
|
args
|
|
222
|
-
);
|
|
254
|
+
));
|
|
223
255
|
}
|
|
224
256
|
}
|
|
225
257
|
|
|
226
|
-
export { Locator as L, convertElementToCssSelector as c, selectorEngine as s };
|
|
258
|
+
export { Locator as L, convertElementToCssSelector as c, ensureAwaited as e, selectorEngine as s };
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import { WebSocketServer } from 'ws';
|
|
|
16
16
|
import { parseErrorStacktrace, parseStacktrace } from '@vitest/utils/source-map';
|
|
17
17
|
import * as nodeos from 'node:os';
|
|
18
18
|
|
|
19
|
-
var version = "2.1
|
|
19
|
+
var version = "2.2.0-beta.1";
|
|
20
20
|
|
|
21
21
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
22
22
|
function normalizeWindowsPath(input = "") {
|
|
@@ -826,6 +826,7 @@ const keyboardCleanup = async (context, state) => {
|
|
|
826
826
|
throw new TypeError(`Provider "${context.provider.name}" does not support keyboard api`);
|
|
827
827
|
}
|
|
828
828
|
};
|
|
829
|
+
const VALID_KEYS = /* @__PURE__ */ new Set(["Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Backquote", "`", "~", "Digit1", "1", "!", "Digit2", "2", "@", "Digit3", "3", "#", "Digit4", "4", "$", "Digit5", "5", "%", "Digit6", "6", "^", "Digit7", "7", "&", "Digit8", "8", "*", "Digit9", "9", "(", "Digit0", "0", ")", "Minus", "-", "_", "Equal", "=", "+", "Backslash", "\\", "|", "Backspace", "Tab", "KeyQ", "q", "Q", "KeyW", "w", "W", "KeyE", "e", "E", "KeyR", "r", "R", "KeyT", "t", "T", "KeyY", "y", "Y", "KeyU", "u", "U", "KeyI", "i", "I", "KeyO", "o", "O", "KeyP", "p", "P", "BracketLeft", "[", "{", "BracketRight", "]", "}", "CapsLock", "KeyA", "a", "A", "KeyS", "s", "S", "KeyD", "d", "D", "KeyF", "f", "F", "KeyG", "g", "G", "KeyH", "h", "H", "KeyJ", "j", "J", "KeyK", "k", "K", "KeyL", "l", "L", "Semicolon", ";", ":", "Quote", "'", '"', "Enter", "\n", "\r", "ShiftLeft", "Shift", "KeyZ", "z", "Z", "KeyX", "x", "X", "KeyC", "c", "C", "KeyV", "v", "V", "KeyB", "b", "B", "KeyN", "n", "N", "KeyM", "m", "M", "Comma", ",", "<", "Period", ".", ">", "Slash", "/", "?", "ShiftRight", "ControlLeft", "Control", "MetaLeft", "Meta", "AltLeft", "Alt", "Space", " ", "AltRight", "AltGraph", "MetaRight", "ContextMenu", "ControlRight", "PrintScreen", "ScrollLock", "Pause", "PageUp", "PageDown", "Insert", "Delete", "Home", "End", "ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown", "NumLock", "NumpadDivide", "NumpadMultiply", "NumpadSubtract", "Numpad7", "Numpad8", "Numpad9", "Numpad4", "Numpad5", "Numpad6", "NumpadAdd", "Numpad1", "Numpad2", "Numpad3", "Numpad0", "NumpadDecimal", "NumpadEnter"]);
|
|
829
830
|
async function keyboardImplementation(pressed, provider, contextId, text, selectAll2, skipRelease) {
|
|
830
831
|
if (provider instanceof PlaywrightBrowserProvider) {
|
|
831
832
|
const page = provider.getPage(contextId);
|
|
@@ -833,7 +834,9 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
|
|
|
833
834
|
for (const { releasePrevious, releaseSelf, repeat, keyDef } of actions) {
|
|
834
835
|
const key = keyDef.key;
|
|
835
836
|
if (pressed.has(key)) {
|
|
836
|
-
|
|
837
|
+
if (VALID_KEYS.has(key)) {
|
|
838
|
+
await page.keyboard.up(key);
|
|
839
|
+
}
|
|
837
840
|
pressed.delete(key);
|
|
838
841
|
}
|
|
839
842
|
if (!releasePrevious) {
|
|
@@ -842,10 +845,16 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
|
|
|
842
845
|
continue;
|
|
843
846
|
}
|
|
844
847
|
for (let i = 1; i <= repeat; i++) {
|
|
845
|
-
|
|
848
|
+
if (VALID_KEYS.has(key)) {
|
|
849
|
+
await page.keyboard.down(key);
|
|
850
|
+
} else {
|
|
851
|
+
await page.keyboard.insertText(key);
|
|
852
|
+
}
|
|
846
853
|
}
|
|
847
854
|
if (releaseSelf) {
|
|
848
|
-
|
|
855
|
+
if (VALID_KEYS.has(key)) {
|
|
856
|
+
await page.keyboard.up(key);
|
|
857
|
+
}
|
|
849
858
|
} else {
|
|
850
859
|
pressed.add(key);
|
|
851
860
|
}
|
|
@@ -853,7 +862,9 @@ async function keyboardImplementation(pressed, provider, contextId, text, select
|
|
|
853
862
|
}
|
|
854
863
|
if (!skipRelease && pressed.size) {
|
|
855
864
|
for (const key of pressed) {
|
|
856
|
-
|
|
865
|
+
if (VALID_KEYS.has(key)) {
|
|
866
|
+
await page.keyboard.up(key);
|
|
867
|
+
}
|
|
857
868
|
}
|
|
858
869
|
}
|
|
859
870
|
} else if (provider instanceof WebdriverBrowserProvider) {
|
|
@@ -1429,7 +1440,8 @@ async function resolveTester(server, url, res, next) {
|
|
|
1429
1440
|
});
|
|
1430
1441
|
const testerHtml = typeof server.testerHtml === "string" ? server.testerHtml : await server.testerHtml;
|
|
1431
1442
|
try {
|
|
1432
|
-
const
|
|
1443
|
+
const url2 = join("/@fs/", server.testerFilepath);
|
|
1444
|
+
const indexhtml = await server.vite.transformIndexHtml(url2, testerHtml);
|
|
1433
1445
|
return replacer(indexhtml, {
|
|
1434
1446
|
__VITEST_FAVICON__: server.faviconUrl,
|
|
1435
1447
|
__VITEST_INJECTOR__: injector,
|
|
@@ -1621,7 +1633,7 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
1621
1633
|
"msw",
|
|
1622
1634
|
"msw/browser"
|
|
1623
1635
|
];
|
|
1624
|
-
if (project.config.diff) {
|
|
1636
|
+
if (typeof project.config.diff === "string") {
|
|
1625
1637
|
entries.push(project.config.diff);
|
|
1626
1638
|
}
|
|
1627
1639
|
if (project.ctx.coverageProvider) {
|
|
@@ -1798,21 +1810,22 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
1798
1810
|
name: "vitest:browser:transform-tester-html",
|
|
1799
1811
|
enforce: "pre",
|
|
1800
1812
|
async transformIndexHtml(html, ctx) {
|
|
1801
|
-
if (
|
|
1813
|
+
if (ctx.filename !== browserServer.testerFilepath) {
|
|
1802
1814
|
return;
|
|
1803
1815
|
}
|
|
1804
1816
|
if (!browserServer.testerScripts) {
|
|
1805
|
-
const
|
|
1817
|
+
const testerScripts = await browserServer.formatScripts(
|
|
1806
1818
|
project.config.browser.testerScripts
|
|
1807
1819
|
);
|
|
1808
|
-
browserServer.testerScripts =
|
|
1820
|
+
browserServer.testerScripts = testerScripts;
|
|
1809
1821
|
}
|
|
1810
1822
|
const stateJs = typeof browserServer.stateJs === "string" ? browserServer.stateJs : await browserServer.stateJs;
|
|
1811
|
-
const
|
|
1812
|
-
|
|
1823
|
+
const testerTags = [];
|
|
1824
|
+
const isDefaultTemplate = resolve(distRoot, "client/tester/tester.html") === browserServer.testerFilepath;
|
|
1825
|
+
if (!isDefaultTemplate) {
|
|
1813
1826
|
const manifestContent = browserServer.manifest instanceof Promise ? await browserServer.manifest : browserServer.manifest;
|
|
1814
1827
|
const testerEntry = manifestContent["tester/tester.html"];
|
|
1815
|
-
|
|
1828
|
+
testerTags.push({
|
|
1816
1829
|
tag: "script",
|
|
1817
1830
|
attrs: {
|
|
1818
1831
|
type: "module",
|
|
@@ -1824,7 +1837,7 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
1824
1837
|
for (const importName of testerEntry.imports || []) {
|
|
1825
1838
|
const entryManifest = manifestContent[importName];
|
|
1826
1839
|
if (entryManifest) {
|
|
1827
|
-
|
|
1840
|
+
testerTags.push(
|
|
1828
1841
|
{
|
|
1829
1842
|
tag: "link",
|
|
1830
1843
|
attrs: {
|
|
@@ -1837,6 +1850,21 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
1837
1850
|
);
|
|
1838
1851
|
}
|
|
1839
1852
|
}
|
|
1853
|
+
} else {
|
|
1854
|
+
testerTags.push({
|
|
1855
|
+
tag: "style",
|
|
1856
|
+
children: `
|
|
1857
|
+
html {
|
|
1858
|
+
padding: 0;
|
|
1859
|
+
margin: 0;
|
|
1860
|
+
}
|
|
1861
|
+
body {
|
|
1862
|
+
padding: 0;
|
|
1863
|
+
margin: 0;
|
|
1864
|
+
min-height: 100vh;
|
|
1865
|
+
}`,
|
|
1866
|
+
injectTo: "head"
|
|
1867
|
+
});
|
|
1840
1868
|
}
|
|
1841
1869
|
return [
|
|
1842
1870
|
{
|
|
@@ -1866,7 +1894,7 @@ var BrowserPlugin = (browserServer, base = "/") => {
|
|
|
1866
1894
|
injectTo: "head"
|
|
1867
1895
|
} : null,
|
|
1868
1896
|
...browserServer.testerScripts,
|
|
1869
|
-
...
|
|
1897
|
+
...testerTags,
|
|
1870
1898
|
{
|
|
1871
1899
|
tag: "script",
|
|
1872
1900
|
attrs: {
|
|
@@ -2138,7 +2166,9 @@ function setupBrowserRpc(server) {
|
|
|
2138
2166
|
return ctx.report("onUserConsoleLog", log);
|
|
2139
2167
|
},
|
|
2140
2168
|
resolveSnapshotPath(testPath) {
|
|
2141
|
-
return ctx.snapshot.resolvePath(testPath
|
|
2169
|
+
return ctx.snapshot.resolvePath(testPath, {
|
|
2170
|
+
config: project.getSerializableConfig()
|
|
2171
|
+
});
|
|
2142
2172
|
},
|
|
2143
2173
|
resolveSnapshotRawPath(testPath, rawPath) {
|
|
2144
2174
|
return ctx.snapshot.resolveRawPath(testPath, rawPath);
|
|
@@ -2589,8 +2619,13 @@ function createBrowserPool(ctx) {
|
|
|
2589
2619
|
[...files2.map((f) => relative(project.config.root, f))].join(", ")
|
|
2590
2620
|
);
|
|
2591
2621
|
const promise = waitForTests(method, contextId, project, files2);
|
|
2592
|
-
|
|
2593
|
-
|
|
2622
|
+
const tester = orchestrator.createTesters(files2).catch((error) => {
|
|
2623
|
+
if (error instanceof Error && error.message.startsWith("[birpc] rpc is closed")) {
|
|
2624
|
+
return;
|
|
2625
|
+
}
|
|
2626
|
+
return Promise.reject(error);
|
|
2627
|
+
});
|
|
2628
|
+
promises.push(promise, tester);
|
|
2594
2629
|
} else {
|
|
2595
2630
|
const contextId = crypto.randomUUID();
|
|
2596
2631
|
const waitPromise = waitForTests(method, contextId, project, files2);
|
|
@@ -2622,6 +2657,7 @@ function createBrowserPool(ctx) {
|
|
|
2622
2657
|
if (isCancelled) {
|
|
2623
2658
|
break;
|
|
2624
2659
|
}
|
|
2660
|
+
await project.initBrowserProvider();
|
|
2625
2661
|
await executeTests(method, project, files);
|
|
2626
2662
|
}
|
|
2627
2663
|
};
|
|
@@ -2641,6 +2677,11 @@ function createBrowserPool(ctx) {
|
|
|
2641
2677
|
async close() {
|
|
2642
2678
|
await Promise.all([...providers].map((provider) => provider.close()));
|
|
2643
2679
|
providers.clear();
|
|
2680
|
+
ctx.resolvedProjects.forEach((project) => {
|
|
2681
|
+
project.browser?.state.orchestrators.forEach((orchestrator) => {
|
|
2682
|
+
orchestrator.$close();
|
|
2683
|
+
});
|
|
2684
|
+
});
|
|
2644
2685
|
},
|
|
2645
2686
|
runTests: (files) => runWorkspaceTests("run", files),
|
|
2646
2687
|
collectTests: (files) => runWorkspaceTests("collect", files)
|
package/dist/locators/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { page, server } from '@vitest/browser/context';
|
|
2
2
|
import { g as getByLabelSelector, a as getByRoleSelector, b as getByTestIdSelector, c as getByAltTextSelector, d as getByPlaceholderSelector, e as getByTextSelector, f as getByTitleSelector } from '../public-utils-D6S2-5kI.js';
|
|
3
|
-
import { s as selectorEngine, L as Locator } from '../index-
|
|
3
|
+
import { s as selectorEngine, L as Locator } from '../index-CKtADM3n.js';
|
|
4
4
|
import 'vitest/utils';
|
|
5
5
|
|
|
6
6
|
page.extend({
|