@vitest/browser 4.1.8 → 4.1.10
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/client/.vite/manifest.json +2 -2
- package/dist/client/__vitest_browser__/{orchestrator-B-wB8WWP.js → orchestrator-KVYrTcFi.js} +38 -6
- package/dist/client/__vitest_browser__/{tester-DQAp97S5.js → tester-BJtsJFpD.js} +4 -0
- package/dist/client/orchestrator.html +1 -1
- package/dist/client/tester/tester.html +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +46 -28
- package/dist/types.d.ts +1 -0
- package/package.json +6 -6
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"name": "utils"
|
|
5
5
|
},
|
|
6
6
|
"orchestrator.html": {
|
|
7
|
-
"file": "__vitest_browser__/orchestrator-
|
|
7
|
+
"file": "__vitest_browser__/orchestrator-KVYrTcFi.js",
|
|
8
8
|
"name": "orchestrator",
|
|
9
9
|
"src": "orchestrator.html",
|
|
10
10
|
"isEntry": true,
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
]
|
|
14
14
|
},
|
|
15
15
|
"tester/tester.html": {
|
|
16
|
-
"file": "__vitest_browser__/tester-
|
|
16
|
+
"file": "__vitest_browser__/tester-BJtsJFpD.js",
|
|
17
17
|
"name": "tester",
|
|
18
18
|
"src": "tester/tester.html",
|
|
19
19
|
"isEntry": true,
|
package/dist/client/__vitest_browser__/{orchestrator-B-wB8WWP.js → orchestrator-KVYrTcFi.js}
RENAMED
|
@@ -10,6 +10,8 @@ class IframeOrchestrator {
|
|
|
10
10
|
cancelled = false;
|
|
11
11
|
recreateNonIsolatedIframe = false;
|
|
12
12
|
iframes = /* @__PURE__ */ new Map();
|
|
13
|
+
readyIframes = /* @__PURE__ */ new Set();
|
|
14
|
+
readyWaiters = /* @__PURE__ */ new Map();
|
|
13
15
|
eventTarget = new EventTarget();
|
|
14
16
|
traces;
|
|
15
17
|
constructor() {
|
|
@@ -27,6 +29,9 @@ class IframeOrchestrator {
|
|
|
27
29
|
"message",
|
|
28
30
|
(e) => this.onGlobalChannelEvent(e)
|
|
29
31
|
);
|
|
32
|
+
void client.waitForConnection().then(() => client.rpc.onOrchestratorReady()).catch((error) => {
|
|
33
|
+
debug("failed to notify orchestrator readiness", error);
|
|
34
|
+
});
|
|
30
35
|
}
|
|
31
36
|
async createTesters(options) {
|
|
32
37
|
await this.traces.waitInit();
|
|
@@ -63,6 +68,8 @@ class IframeOrchestrator {
|
|
|
63
68
|
}
|
|
64
69
|
this.iframes.forEach((iframe) => iframe.remove());
|
|
65
70
|
this.iframes.clear();
|
|
71
|
+
this.readyIframes.clear();
|
|
72
|
+
this.readyWaiters.clear();
|
|
66
73
|
for (let i = 0; i < options.files.length; i++) {
|
|
67
74
|
if (this.cancelled) {
|
|
68
75
|
await endSpan();
|
|
@@ -104,8 +111,7 @@ class IframeOrchestrator {
|
|
|
104
111
|
async runNonIsolatedTests(container, options, startTime, otelContext) {
|
|
105
112
|
if (this.recreateNonIsolatedIframe) {
|
|
106
113
|
this.recreateNonIsolatedIframe = false;
|
|
107
|
-
this.
|
|
108
|
-
this.iframes.delete(ID_ALL);
|
|
114
|
+
this.removeIframe(ID_ALL);
|
|
109
115
|
debug("recreate non-isolated iframe");
|
|
110
116
|
}
|
|
111
117
|
if (!this.iframes.has(ID_ALL)) {
|
|
@@ -131,8 +137,7 @@ class IframeOrchestrator {
|
|
|
131
137
|
const { width, height } = config.browser.viewport;
|
|
132
138
|
const file = spec.filepath;
|
|
133
139
|
if (this.iframes.has(file)) {
|
|
134
|
-
this.
|
|
135
|
-
this.iframes.delete(file);
|
|
140
|
+
this.removeIframe(file);
|
|
136
141
|
}
|
|
137
142
|
const iframe = await this.prepareIframe(
|
|
138
143
|
container,
|
|
@@ -181,12 +186,12 @@ Expected: ${iframe.src}`
|
|
|
181
186
|
}
|
|
182
187
|
} else {
|
|
183
188
|
this.iframes.set(iframeId, iframe);
|
|
184
|
-
this.sendEventToIframe({
|
|
189
|
+
this.waitForReady(iframeId).then(() => this.sendEventToIframe({
|
|
185
190
|
event: "prepare",
|
|
186
191
|
iframeId,
|
|
187
192
|
startTime,
|
|
188
193
|
otelCarrier: this.traces.getContextCarrier(otelContext)
|
|
189
|
-
}).then(resolve, (error) => reject(this.dispatchIframeError(error)));
|
|
194
|
+
})).then(resolve, (error) => reject(this.dispatchIframeError(error)));
|
|
190
195
|
}
|
|
191
196
|
};
|
|
192
197
|
iframe.onerror = (e) => {
|
|
@@ -201,6 +206,29 @@ Expected: ${iframe.src}`
|
|
|
201
206
|
});
|
|
202
207
|
return iframe;
|
|
203
208
|
}
|
|
209
|
+
markReady(iframeId) {
|
|
210
|
+
this.readyIframes.add(iframeId);
|
|
211
|
+
const waiter = this.readyWaiters.get(iframeId);
|
|
212
|
+
if (waiter) {
|
|
213
|
+
this.readyWaiters.delete(iframeId);
|
|
214
|
+
waiter();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
waitForReady(iframeId) {
|
|
218
|
+
if (this.readyIframes.has(iframeId)) {
|
|
219
|
+
return Promise.resolve();
|
|
220
|
+
}
|
|
221
|
+
return new Promise((resolve) => {
|
|
222
|
+
this.readyWaiters.set(iframeId, resolve);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
removeIframe(iframeId) {
|
|
226
|
+
const iframe = this.iframes.get(iframeId);
|
|
227
|
+
this.iframes.delete(iframeId);
|
|
228
|
+
this.readyIframes.delete(iframeId);
|
|
229
|
+
this.readyWaiters.delete(iframeId);
|
|
230
|
+
iframe == null ? void 0 : iframe.remove();
|
|
231
|
+
}
|
|
204
232
|
loggedIframe = /* @__PURE__ */ new WeakSet();
|
|
205
233
|
createWarningMessage(iframeId, location) {
|
|
206
234
|
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.
|
|
@@ -257,6 +285,10 @@ If you are using a framework that manipulates browser history (like React Router
|
|
|
257
285
|
async onIframeEvent(e) {
|
|
258
286
|
debug("iframe event", JSON.stringify(e.data));
|
|
259
287
|
switch (e.data.event) {
|
|
288
|
+
case "ready": {
|
|
289
|
+
this.markReady(e.data.iframeId);
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
260
292
|
case "viewport": {
|
|
261
293
|
const { width, height, iframeId: id } = e.data;
|
|
262
294
|
const iframe = this.iframes.get(id);
|
|
@@ -2151,6 +2151,10 @@ const commands = new CommandsManager();
|
|
|
2151
2151
|
getBrowserState().commands = commands;
|
|
2152
2152
|
getBrowserState().activeTraceTaskIds = /* @__PURE__ */ new Set();
|
|
2153
2153
|
getBrowserState().iframeId = iframeId;
|
|
2154
|
+
channel.postMessage({
|
|
2155
|
+
event: "ready",
|
|
2156
|
+
iframeId
|
|
2157
|
+
});
|
|
2154
2158
|
let contextSwitched = false;
|
|
2155
2159
|
async function prepareTestEnvironment(options) {
|
|
2156
2160
|
debug == null ? void 0 : debug("trying to resolve the runner");
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
{__VITEST_INJECTOR__}
|
|
27
27
|
{__VITEST_ERROR_CATCHER__}
|
|
28
28
|
{__VITEST_SCRIPTS__}
|
|
29
|
-
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-
|
|
29
|
+
<script type="module" crossorigin src="/__vitest_browser__/orchestrator-KVYrTcFi.js"></script>
|
|
30
30
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-BsFW67Gk.js">
|
|
31
31
|
</head>
|
|
32
32
|
<body>
|
|
@@ -5,7 +5,7 @@
|
|
|
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
|
-
<script type="module" crossorigin src="/__vitest_browser__/tester-
|
|
8
|
+
<script type="module" crossorigin src="/__vitest_browser__/tester-BJtsJFpD.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/__vitest_browser__/utils-BsFW67Gk.js">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ResolvedConfig, BrowserServerFactory, BrowserCommand, BrowserProviderOption } from 'vitest/node';
|
|
1
|
+
import { TestProject, ResolvedConfig, BrowserServerFactory, BrowserCommand, BrowserProviderOption } from 'vitest/node';
|
|
2
2
|
import { ScreenshotMatcherOptions, NonStandardScreenshotComparators, ScreenshotComparatorRegistry } from '@vitest/browser/context';
|
|
3
3
|
|
|
4
4
|
interface BaseMetadata {
|
|
@@ -61,6 +61,8 @@ declare function parseKeyDef(text: string): {
|
|
|
61
61
|
repeat: number;
|
|
62
62
|
}[];
|
|
63
63
|
declare function resolveScreenshotPath(testPath: string, name: string, config: ResolvedConfig, customPath: string | undefined): string;
|
|
64
|
+
declare function assertBrowserFileAccess(project: TestProject, path: string): void;
|
|
65
|
+
declare function assertBrowserApiWrite(project: TestProject, path: string): void;
|
|
64
66
|
|
|
65
67
|
//#endregion
|
|
66
68
|
//#region src/locatorGenerators.d.ts
|
|
@@ -89,5 +91,5 @@ declare function defineBrowserProvider<T extends object = object>(options: Omit<
|
|
|
89
91
|
options?: T;
|
|
90
92
|
}): BrowserProviderOption;
|
|
91
93
|
|
|
92
|
-
export { asLocator, createBrowserServer, defineBrowserCommand, defineBrowserProvider, parseKeyDef, resolveScreenshotPath };
|
|
94
|
+
export { asLocator, assertBrowserApiWrite, assertBrowserFileAccess, createBrowserServer, defineBrowserCommand, defineBrowserProvider, parseKeyDef, resolveScreenshotPath };
|
|
93
95
|
export type { CustomComparatorsRegistry };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ManualMockedModule, RedirectedModule, AutomockedModule, AutospiedModule, MockerRegistry } from '@vitest/mocker';
|
|
2
2
|
import { dynamicImportPlugin, ServerMockResolver, interceptorPlugin } from '@vitest/mocker/node';
|
|
3
3
|
import c from 'tinyrainbow';
|
|
4
|
-
import { isValidApiRequest, isFileServingAllowed, distDir, rolldownVersion, resolveApiServerConfig, resolveFsAllow,
|
|
4
|
+
import { isFileLoadingAllowed, isValidApiRequest, isFileServingAllowed, distDir, rolldownVersion, resolveApiServerConfig, resolveFsAllow, createDebugger, createViteLogger, createViteServer } from 'vitest/node';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import fs, { readFileSync, createReadStream, promises, existsSync } from 'node:fs';
|
|
7
7
|
import { createRequire } from 'node:module';
|
|
@@ -18,7 +18,7 @@ import { PNG } from 'pngjs';
|
|
|
18
18
|
import { diff } from '@blazediff/core';
|
|
19
19
|
import { WebSocketServer } from 'ws';
|
|
20
20
|
|
|
21
|
-
var version = "4.1.
|
|
21
|
+
var version = "4.1.10";
|
|
22
22
|
|
|
23
23
|
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
|
|
24
24
|
function normalizeWindowsPath(input = "") {
|
|
@@ -674,6 +674,17 @@ async function getBrowserProvider(options, project) {
|
|
|
674
674
|
function slash(path) {
|
|
675
675
|
return path.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
676
676
|
}
|
|
677
|
+
function assertBrowserFileAccess(project, path) {
|
|
678
|
+
const normalized = slash(path);
|
|
679
|
+
if (!isFileLoadingAllowed(project.vite.config, normalized) && !isFileLoadingAllowed(project.vitest.vite.config, normalized)) {
|
|
680
|
+
throw new Error(`Access denied to "${path}". See Vite config documentation for "server.fs": https://vitejs.dev/config/server-options.html#server-fs-strict.`);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function assertBrowserApiWrite(project, path) {
|
|
684
|
+
if (!project.config.browser.api.allowWrite || !project.vitest.config.api.allowWrite) {
|
|
685
|
+
throw new Error(`Cannot modify file "${path}". File writing is disabled because the server is exposed to the internet, see https://vitest.dev/config/browser/api.`);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
677
688
|
|
|
678
689
|
async function resolveOrchestrator(globalServer, url, res) {
|
|
679
690
|
let sessionId = url.searchParams.get("sessionId");
|
|
@@ -1896,19 +1907,9 @@ _Mime_extensionToType = new WeakMap(), _Mime_typeToExtension = new WeakMap(), _M
|
|
|
1896
1907
|
|
|
1897
1908
|
var mime = new Mime(types)._freeze();
|
|
1898
1909
|
|
|
1899
|
-
function assertFileAccess(path, project) {
|
|
1900
|
-
if (!isFileLoadingAllowed(project.vite.config, path) && !isFileLoadingAllowed(project.vitest.vite.config, path)) {
|
|
1901
|
-
throw new Error(`Access denied to "${path}". See Vite config documentation for "server.fs": https://vitejs.dev/config/server-options.html#server-fs-strict.`);
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
function assertWrite(path, project) {
|
|
1905
|
-
if (!project.config.browser.api.allowWrite || !project.vitest.config.api.allowWrite) {
|
|
1906
|
-
throw new Error(`Cannot modify file "${path}". File writing is disabled because server is exposed to the internet, see https://vitest.dev/config/browser/api.`);
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
1910
|
const readFile = async ({ project }, path, options = {}) => {
|
|
1910
1911
|
const filepath = resolve$1(project.config.root, path);
|
|
1911
|
-
|
|
1912
|
+
assertBrowserFileAccess(project, filepath);
|
|
1912
1913
|
// never return a Buffer
|
|
1913
1914
|
if (typeof options === "object" && !options.encoding) {
|
|
1914
1915
|
options.encoding = "utf-8";
|
|
@@ -1916,9 +1917,9 @@ const readFile = async ({ project }, path, options = {}) => {
|
|
|
1916
1917
|
return promises.readFile(filepath, options);
|
|
1917
1918
|
};
|
|
1918
1919
|
const writeFile = async ({ project }, path, data, options) => {
|
|
1919
|
-
|
|
1920
|
+
assertBrowserApiWrite(project, path);
|
|
1920
1921
|
const filepath = resolve$1(project.config.root, path);
|
|
1921
|
-
|
|
1922
|
+
assertBrowserFileAccess(project, filepath);
|
|
1922
1923
|
const dir = dirname$1(filepath);
|
|
1923
1924
|
if (!fs.existsSync(dir)) {
|
|
1924
1925
|
await promises.mkdir(dir, { recursive: true });
|
|
@@ -1926,14 +1927,14 @@ const writeFile = async ({ project }, path, data, options) => {
|
|
|
1926
1927
|
await promises.writeFile(filepath, data, options);
|
|
1927
1928
|
};
|
|
1928
1929
|
const removeFile = async ({ project }, path) => {
|
|
1929
|
-
|
|
1930
|
+
assertBrowserApiWrite(project, path);
|
|
1930
1931
|
const filepath = resolve$1(project.config.root, path);
|
|
1931
|
-
|
|
1932
|
+
assertBrowserFileAccess(project, filepath);
|
|
1932
1933
|
await promises.rm(filepath);
|
|
1933
1934
|
};
|
|
1934
1935
|
const _fileInfo = async ({ project }, path, encoding) => {
|
|
1935
1936
|
const filepath = resolve$1(project.config.root, path);
|
|
1936
|
-
|
|
1937
|
+
assertBrowserFileAccess(project, filepath);
|
|
1937
1938
|
const content = await promises.readFile(filepath, encoding || "base64");
|
|
1938
1939
|
return {
|
|
1939
1940
|
content,
|
|
@@ -2249,7 +2250,7 @@ const screenshotMatcher = async (context, name, testName, options) => {
|
|
|
2249
2250
|
comparator,
|
|
2250
2251
|
comparatorOptions
|
|
2251
2252
|
});
|
|
2252
|
-
await performSideEffects(outcome, codec);
|
|
2253
|
+
await performSideEffects(outcome, codec, context.project);
|
|
2253
2254
|
return buildOutput(outcome, timeout);
|
|
2254
2255
|
};
|
|
2255
2256
|
/**
|
|
@@ -2335,17 +2336,17 @@ async function determineOutcome({ comparator, comparatorOptions, paths, referenc
|
|
|
2335
2336
|
*
|
|
2336
2337
|
* Only `missing-reference`, `update-reference`, and `mismatch` write files. Successful matches produce no side effects.
|
|
2337
2338
|
*/
|
|
2338
|
-
async function performSideEffects(outcome, codec) {
|
|
2339
|
+
async function performSideEffects(outcome, codec, project) {
|
|
2339
2340
|
switch (outcome.type) {
|
|
2340
2341
|
case "missing-reference":
|
|
2341
2342
|
case "update-reference": {
|
|
2342
|
-
await writeScreenshot(outcome.reference.path, await codec.encode(outcome.reference.image, {}));
|
|
2343
|
+
await writeScreenshot(outcome.reference.path, await codec.encode(outcome.reference.image, {}), project);
|
|
2343
2344
|
break;
|
|
2344
2345
|
}
|
|
2345
2346
|
case "mismatch": {
|
|
2346
|
-
await writeScreenshot(outcome.actual.path, await codec.encode(outcome.actual.image, {}));
|
|
2347
|
+
await writeScreenshot(outcome.actual.path, await codec.encode(outcome.actual.image, {}), project);
|
|
2347
2348
|
if (outcome.diff) {
|
|
2348
|
-
await writeScreenshot(outcome.diff.path, await codec.encode(outcome.diff.image, {}));
|
|
2349
|
+
await writeScreenshot(outcome.diff.path, await codec.encode(outcome.diff.image, {}), project);
|
|
2349
2350
|
}
|
|
2350
2351
|
break;
|
|
2351
2352
|
}
|
|
@@ -2479,8 +2480,10 @@ async function getStableScreenshot({ codec, context, comparator, comparatorOptio
|
|
|
2479
2480
|
};
|
|
2480
2481
|
}
|
|
2481
2482
|
/** Writes encoded images to disk, creating parent directories as needed. */
|
|
2482
|
-
async function writeScreenshot(path, image) {
|
|
2483
|
+
async function writeScreenshot(path, image, project) {
|
|
2483
2484
|
try {
|
|
2485
|
+
assertBrowserApiWrite(project, path);
|
|
2486
|
+
assertBrowserFileAccess(project, path);
|
|
2484
2487
|
await mkdir(dirname(path), { recursive: true });
|
|
2485
2488
|
await writeFile$1(path, image);
|
|
2486
2489
|
} catch (cause) {
|
|
@@ -3024,7 +3027,8 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3024
3027
|
}
|
|
3025
3028
|
if (type === "orchestrator") {
|
|
3026
3029
|
const session = sessions.getSession(sessionId);
|
|
3027
|
-
// it's possible the session was already resolved by the preview provider
|
|
3030
|
+
// it's possible the session was already resolved by the preview provider,
|
|
3031
|
+
// but we still mark the websocket connection when the page reconnects
|
|
3028
3032
|
session?.connected();
|
|
3029
3033
|
}
|
|
3030
3034
|
const project = vitest.getProjectByName(projectName);
|
|
@@ -3033,7 +3037,7 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3033
3037
|
}
|
|
3034
3038
|
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
3035
3039
|
wss.emit("connection", ws, request);
|
|
3036
|
-
const { rpc, offCancel } = setupClient(project, rpcId, ws);
|
|
3040
|
+
const { rpc, offCancel } = setupClient(project, rpcId, ws, { sessionId });
|
|
3037
3041
|
const state = project.browser.state;
|
|
3038
3042
|
const clients = type === "tester" ? state.testers : state.orchestrators;
|
|
3039
3043
|
clients.set(rpcId, rpc);
|
|
@@ -3072,10 +3076,14 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3072
3076
|
throw new Error(`Cannot use CDP because browser API write or exec operations are disabled. See https://vitest.dev/config/browser/api.`);
|
|
3073
3077
|
}
|
|
3074
3078
|
}
|
|
3075
|
-
function setupClient(project, rpcId, ws) {
|
|
3079
|
+
function setupClient(project, rpcId, ws, options) {
|
|
3076
3080
|
const mockResolver = new ServerMockResolver(globalServer.vite, { moduleDirectories: project.config?.deps?.moduleDirectories });
|
|
3077
3081
|
const mocker = project.browser?.provider.mocker;
|
|
3078
3082
|
const rpc = createBirpc({
|
|
3083
|
+
onOrchestratorReady() {
|
|
3084
|
+
const sessions = vitest._browserSessions;
|
|
3085
|
+
sessions.getSession(options.sessionId)?.ready();
|
|
3086
|
+
},
|
|
3079
3087
|
async onUnhandledError(error, type) {
|
|
3080
3088
|
if (error && typeof error === "object") {
|
|
3081
3089
|
const _error = error;
|
|
@@ -3109,6 +3117,16 @@ function setupBrowserRpc(globalServer, defaultMockerRegistry) {
|
|
|
3109
3117
|
artifact.attachments = [];
|
|
3110
3118
|
vitest.logger.error(`[vitest] Cannot record attachments ("${attachments}") because file writing is disabled, removing attachments from artifact "${artifact.type}". See https://vitest.dev/config/browser/api.`);
|
|
3111
3119
|
}
|
|
3120
|
+
} else {
|
|
3121
|
+
// attachment files are copied into `attachmentsDir`, so confine
|
|
3122
|
+
// client-supplied paths to Vite's `server.fs` boundary
|
|
3123
|
+
const attachments = artifact.type === "internal:annotation" ? artifact.annotation.attachment ? [artifact.annotation.attachment] : [] : artifact.attachments ?? [];
|
|
3124
|
+
for (const attachment of attachments) {
|
|
3125
|
+
const path = attachment.path;
|
|
3126
|
+
if (path && !path.startsWith("http://") && !path.startsWith("https://")) {
|
|
3127
|
+
checkFileAccess(resolve(project.config.root, path));
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3112
3130
|
}
|
|
3113
3131
|
return vitest._testRun.recordArtifact(id, artifact);
|
|
3114
3132
|
},
|
|
@@ -7945,4 +7963,4 @@ function defineBrowserProvider(options) {
|
|
|
7945
7963
|
};
|
|
7946
7964
|
}
|
|
7947
7965
|
|
|
7948
|
-
export { asLocator, createBrowserServer, defineBrowserCommand, defineBrowserProvider, parseKeyDef, resolveScreenshotPath };
|
|
7966
|
+
export { asLocator, assertBrowserApiWrite, assertBrowserFileAccess, createBrowserServer, defineBrowserCommand, defineBrowserProvider, parseKeyDef, resolveScreenshotPath };
|
package/dist/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface WebSocketBrowserHandlers {
|
|
|
11
11
|
onTaskArtifactRecord: <Artifact extends TestArtifact>(testId: string, artifact: Artifact) => Promise<Artifact>;
|
|
12
12
|
onTaskUpdate: (method: TestExecutionMethod, packs: TaskResultPack[], events: TaskEventPack[]) => void;
|
|
13
13
|
onAfterSuiteRun: (meta: AfterSuiteRunMeta) => void;
|
|
14
|
+
onOrchestratorReady: () => void;
|
|
14
15
|
cancelCurrentRun: (reason: CancelReason) => void;
|
|
15
16
|
getCountOfFailedTests: () => number;
|
|
16
17
|
readSnapshotFile: (id: string) => Promise<string | null>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest/browser",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.1.
|
|
4
|
+
"version": "4.1.10",
|
|
5
5
|
"description": "Browser running for Vitest",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": "https://opencollective.com/vitest",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"providers"
|
|
58
58
|
],
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"vitest": "4.1.
|
|
60
|
+
"vitest": "4.1.10"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@blazediff/core": "1.9.1",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"sirv": "^3.0.2",
|
|
67
67
|
"tinyrainbow": "^3.1.0",
|
|
68
68
|
"ws": "^8.19.0",
|
|
69
|
-
"@vitest/mocker": "4.1.
|
|
70
|
-
"@vitest/utils": "4.1.
|
|
69
|
+
"@vitest/mocker": "4.1.10",
|
|
70
|
+
"@vitest/utils": "4.1.10"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@opentelemetry/api": "^1.9.0",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"ivya": "^1.8.0",
|
|
80
80
|
"mime": "^4.1.0",
|
|
81
81
|
"pathe": "^2.0.3",
|
|
82
|
-
"vitest": "4.1.
|
|
83
|
-
"
|
|
82
|
+
"@vitest/runner": "4.1.10",
|
|
83
|
+
"vitest": "4.1.10"
|
|
84
84
|
},
|
|
85
85
|
"scripts": {
|
|
86
86
|
"typecheck": "tsc -p ./src/client/tsconfig.json --noEmit",
|