@vitest/browser 1.0.0-beta.2 → 1.0.0-beta.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.
@@ -17,8 +17,8 @@
17
17
  })()
18
18
  </script>
19
19
  <!-- !LOAD_METADATA! -->
20
- <script type="module" crossorigin src="./assets/index-14ea7095.js"></script>
21
- <link rel="stylesheet" href="./assets/index-528f947f.css">
20
+ <script type="module" crossorigin src="./assets/index-877c8735.js"></script>
21
+ <link rel="stylesheet" href="./assets/index-575791d1.css">
22
22
  </head>
23
23
  <body>
24
24
  <div id="app"></div>
@@ -674,8 +674,13 @@ function createBrowserRunner(original, coverageModule) {
674
674
  var _a, _b;
675
675
  await ((_a = super.onAfterRun) == null ? void 0 : _a.call(this));
676
676
  const coverage = await ((_b = coverageModule == null ? void 0 : coverageModule.takeCoverage) == null ? void 0 : _b.call(coverageModule));
677
- if (coverage)
678
- await rpc().onAfterSuiteRun({ coverage });
677
+ if (coverage) {
678
+ await rpc().onAfterSuiteRun({
679
+ coverage,
680
+ transformMode: "web",
681
+ projectName: this.config.name
682
+ });
683
+ }
679
684
  }
680
685
  onCollected(files) {
681
686
  return rpc().onCollected(files);
@@ -895,6 +900,8 @@ async function defaultErrorReport(type, unhandledError) {
895
900
  message: unhandledError.message,
896
901
  stack: unhandledError.stack
897
902
  };
903
+ if (testId !== "no-isolate")
904
+ error.VITEST_TEST_PATH = testId;
898
905
  await client.rpc.onUnhandledError(error, type);
899
906
  await client.rpc.onDone(testId);
900
907
  }
@@ -903,7 +910,10 @@ const stopRejectionHandler = on("unhandledrejection", (e) => defaultErrorReport(
903
910
  let runningTests = false;
904
911
  async function reportUnexpectedError(rpc2, type, error) {
905
912
  const { processError } = await importId("vitest/browser");
906
- await rpc2.onUnhandledError(processError(error), type);
913
+ const processedError = processError(error);
914
+ if (testId !== "no-isolate")
915
+ error.VITEST_TEST_PATH = testId;
916
+ await rpc2.onUnhandledError(processedError, type);
907
917
  if (!runningTests)
908
918
  await rpc2.onDone(testId);
909
919
  }
@@ -929,7 +939,8 @@ ws.addEventListener("open", async () => {
929
939
  durations: {
930
940
  environment: 0,
931
941
  prepare: 0
932
- }
942
+ },
943
+ providedContext: await client.rpc.getProvidedContext()
933
944
  };
934
945
  globalThis.__vitest_mocker__ = new VitestBrowserClientMocker();
935
946
  const paths = getQueryPaths();
@@ -21,7 +21,7 @@
21
21
  border: none;
22
22
  }
23
23
  </style>
24
- <script type="module" crossorigin src="/__vitest_browser__/index-a6988d73.js"></script>
24
+ <script type="module" crossorigin src="/__vitest_browser__/index-cb73f258.js"></script>
25
25
  </head>
26
26
  <body>
27
27
  <iframe id="vitest-ui" src=""></iframe>
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { fileURLToPath } from 'url';
2
- import { resolve } from 'path';
3
- import { builtinModules } from 'module';
1
+ import { fileURLToPath } from 'node:url';
2
+ import { resolve } from 'node:path';
3
+ import { builtinModules } from 'node:module';
4
4
  import sirv from 'sirv';
5
5
  import MagicString from 'magic-string';
6
6
  import { walk } from 'estree-walker';
@@ -93,10 +93,7 @@ function esmWalker(root, { onIdentifier, onImportMeta, onDynamicImport }) {
93
93
  scopeIds.add(name);
94
94
  };
95
95
  function isInScope(name, parents) {
96
- return parents.some((node) => {
97
- var _a;
98
- return node && ((_a = scopeMap.get(node)) == null ? void 0 : _a.has(name));
99
- });
96
+ return parents.some((node) => node && scopeMap.get(node)?.has(name));
100
97
  }
101
98
  function handlePattern(p, parentScope) {
102
99
  if (p.type === "Identifier") {
@@ -150,13 +147,13 @@ function esmWalker(root, { onIdentifier, onImportMeta, onDynamicImport }) {
150
147
  }
151
148
  walk(p.type === "AssignmentPattern" ? p.left : p, {
152
149
  enter(child, parent2) {
153
- if ((parent2 == null ? void 0 : parent2.type) === "AssignmentPattern" && (parent2 == null ? void 0 : parent2.right) === child)
150
+ if (parent2?.type === "AssignmentPattern" && parent2?.right === child)
154
151
  return this.skip();
155
152
  if (child.type !== "Identifier")
156
153
  return;
157
154
  if (isStaticPropertyKey(child, parent2))
158
155
  return;
159
- if ((parent2 == null ? void 0 : parent2.type) === "TemplateLiteral" && (parent2 == null ? void 0 : parent2.expressions.includes(child)) || (parent2 == null ? void 0 : parent2.type) === "CallExpression" && (parent2 == null ? void 0 : parent2.callee) === child)
156
+ if (parent2?.type === "TemplateLiteral" && parent2?.expressions.includes(child) || parent2?.type === "CallExpression" && parent2?.callee === child)
160
157
  return;
161
158
  setScope(node, child.name);
162
159
  }
@@ -398,7 +395,7 @@ export default { ${viInjectedKey}: ${viInjectedKey}.default };
398
395
  if (isStaticProperty(parent) && parent.shorthand) {
399
396
  if (!isNodeInPattern(parent) || isInDestructuringAssignment(parent, parentStack))
400
397
  s.appendLeft(id2.end, `: ${binding}`);
401
- } else if (parent.type === "PropertyDefinition" && (grandparent == null ? void 0 : grandparent.type) === "ClassBody" || parent.type === "ClassDeclaration" && id2 === parent.superClass) {
398
+ } else if (parent.type === "PropertyDefinition" && grandparent?.type === "ClassBody" || parent.type === "ClassDeclaration" && id2 === parent.superClass) {
402
399
  if (!declaredConst.has(id2.name)) {
403
400
  declaredConst.add(id2.name);
404
401
  const topNode = parentStack[parentStack.length - 2];
@@ -443,7 +440,7 @@ var index = (project, base = "/") => {
443
440
  name: "vitest:browser",
444
441
  async config(viteConfig) {
445
442
  // Enables using ignore hint for coverage providers with @preserve keyword
446
- viteConfig.esbuild || (viteConfig.esbuild = {});
443
+ viteConfig.esbuild ||= {};
447
444
  viteConfig.esbuild.legalComments = "inline";
448
445
  },
449
446
  async configureServer(server) {
@@ -0,0 +1,172 @@
1
+ import { ensurePackageInstalled } from 'vitest/node';
2
+
3
+ const playwrightBrowsers = ["firefox", "webkit", "chromium"];
4
+ class PlaywrightBrowserProvider {
5
+ name = "playwright";
6
+ cachedBrowser = null;
7
+ cachedPage = null;
8
+ browser;
9
+ ctx;
10
+ options;
11
+ getSupportedBrowsers() {
12
+ return playwrightBrowsers;
13
+ }
14
+ async initialize(ctx, { browser, options }) {
15
+ this.ctx = ctx;
16
+ this.browser = browser;
17
+ this.options = options;
18
+ const root = this.ctx.config.root;
19
+ if (!await ensurePackageInstalled("playwright", root))
20
+ throw new Error('Cannot find "playwright" package. Please install it manually.');
21
+ }
22
+ async openBrowserPage() {
23
+ if (this.cachedPage)
24
+ return this.cachedPage;
25
+ const options = this.ctx.config.browser;
26
+ const playwright = await import('playwright');
27
+ const browser = await playwright[this.browser].launch({
28
+ ...this.options?.launch,
29
+ headless: options.headless
30
+ });
31
+ this.cachedBrowser = browser;
32
+ this.cachedPage = await browser.newPage(this.options?.page);
33
+ this.cachedPage.on("close", () => {
34
+ browser.close();
35
+ });
36
+ return this.cachedPage;
37
+ }
38
+ catchError(cb) {
39
+ this.cachedPage?.on("pageerror", cb);
40
+ return () => {
41
+ this.cachedPage?.off("pageerror", cb);
42
+ };
43
+ }
44
+ async openPage(url) {
45
+ const browserPage = await this.openBrowserPage();
46
+ await browserPage.goto(url);
47
+ }
48
+ async close() {
49
+ await this.cachedPage?.close();
50
+ await this.cachedBrowser?.close();
51
+ }
52
+ }
53
+
54
+ const webdriverBrowsers = ["firefox", "chrome", "edge", "safari"];
55
+ class WebdriverBrowserProvider {
56
+ name = "webdriverio";
57
+ cachedBrowser = null;
58
+ stopSafari = () => {
59
+ };
60
+ browser;
61
+ ctx;
62
+ options;
63
+ getSupportedBrowsers() {
64
+ return webdriverBrowsers;
65
+ }
66
+ async initialize(ctx, { browser, options }) {
67
+ this.ctx = ctx;
68
+ this.browser = browser;
69
+ this.options = options;
70
+ const root = this.ctx.config.root;
71
+ if (!await ensurePackageInstalled("webdriverio", root))
72
+ throw new Error('Cannot find "webdriverio" package. Please install it manually.');
73
+ if (browser === "safari" && !await ensurePackageInstalled("safaridriver", root))
74
+ throw new Error('Cannot find "safaridriver" package. Please install it manually.');
75
+ }
76
+ async openBrowser() {
77
+ if (this.cachedBrowser)
78
+ return this.cachedBrowser;
79
+ const options = this.ctx.config.browser;
80
+ if (this.browser === "safari") {
81
+ if (options.headless)
82
+ throw new Error("You've enabled headless mode for Safari but it doesn't currently support it.");
83
+ const safaridriver = await import('safaridriver');
84
+ safaridriver.start({ diagnose: true });
85
+ this.stopSafari = () => safaridriver.stop();
86
+ process.on("beforeExit", () => {
87
+ safaridriver.stop();
88
+ });
89
+ }
90
+ const { remote } = await import('webdriverio');
91
+ this.cachedBrowser = await remote({
92
+ ...this.options,
93
+ logLevel: "error",
94
+ capabilities: this.buildCapabilities()
95
+ });
96
+ return this.cachedBrowser;
97
+ }
98
+ buildCapabilities() {
99
+ const capabilities = {
100
+ ...this.options?.capabilities,
101
+ browserName: this.browser
102
+ };
103
+ const headlessMap = {
104
+ chrome: ["goog:chromeOptions", ["headless", "disable-gpu"]],
105
+ firefox: ["moz:firefoxOptions", ["-headless"]],
106
+ edge: ["ms:edgeOptions", ["--headless"]]
107
+ };
108
+ const options = this.ctx.config.browser;
109
+ const browser = this.browser;
110
+ if (browser !== "safari" && options.headless) {
111
+ const [key, args] = headlessMap[browser];
112
+ const currentValues = this.options?.capabilities?.[key] || {};
113
+ const newArgs = [...currentValues.args || [], ...args];
114
+ capabilities[key] = { ...currentValues, args: newArgs };
115
+ }
116
+ return capabilities;
117
+ }
118
+ async openPage(url) {
119
+ const browserInstance = await this.openBrowser();
120
+ await browserInstance.url(url);
121
+ }
122
+ // TODO
123
+ catchError(_cb) {
124
+ return () => {
125
+ };
126
+ }
127
+ async close() {
128
+ await Promise.all([
129
+ this.stopSafari(),
130
+ this.cachedBrowser?.sessionId ? this.cachedBrowser?.deleteSession?.() : null
131
+ ]);
132
+ process.exit();
133
+ }
134
+ }
135
+
136
+ class NoneBrowserProvider {
137
+ name = "none";
138
+ ctx;
139
+ open = false;
140
+ getSupportedBrowsers() {
141
+ return [];
142
+ }
143
+ isOpen() {
144
+ return this.open;
145
+ }
146
+ async initialize(ctx) {
147
+ this.ctx = ctx;
148
+ this.open = false;
149
+ }
150
+ catchError(_cb) {
151
+ return () => {
152
+ };
153
+ }
154
+ async openPage(_url) {
155
+ this.open = true;
156
+ if (!this.ctx.browser)
157
+ throw new Error("Browser is not initialized");
158
+ const options = this.ctx.browser.config.server;
159
+ const _open = options.open;
160
+ options.open = _url;
161
+ this.ctx.browser.openBrowser();
162
+ options.open = _open;
163
+ }
164
+ async close() {
165
+ }
166
+ }
167
+
168
+ const webdriverio = WebdriverBrowserProvider;
169
+ const playwright = PlaywrightBrowserProvider;
170
+ const none = NoneBrowserProvider;
171
+
172
+ export { none, playwright, webdriverio };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/browser",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.2",
4
+ "version": "1.0.0-beta.4",
5
5
  "description": "Browser running for Vitest",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -20,6 +20,16 @@
20
20
  "types": "./dist/index.d.ts",
21
21
  "import": "./dist/index.js"
22
22
  },
23
+ "./providers": {
24
+ "types": "./providers.d.ts",
25
+ "import": "./dist/providers.js"
26
+ },
27
+ "./providers/webdriverio": {
28
+ "types": "./dist/providers/webdriverio.d.ts"
29
+ },
30
+ "./providers/playwright": {
31
+ "types": "./dist/providers/playwright.d.ts"
32
+ },
23
33
  "./*": "./*"
24
34
  },
25
35
  "main": "./dist/index.js",
@@ -27,24 +37,43 @@
27
37
  "types": "./dist/index.d.ts",
28
38
  "files": [
29
39
  "dist",
30
- "stubs"
40
+ "providers"
31
41
  ],
32
42
  "peerDependencies": {
33
- "vitest": ">=0.34.0"
43
+ "playwright": "*",
44
+ "safaridriver": "*",
45
+ "vitest": "^1.0.0-0",
46
+ "webdriverio": "*"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "webdriverio": {
50
+ "optional": true
51
+ },
52
+ "safaridriver": {
53
+ "optional": true
54
+ },
55
+ "playwright": {
56
+ "optional": true
57
+ }
34
58
  },
35
59
  "dependencies": {
36
60
  "estree-walker": "^3.0.3",
37
- "magic-string": "^0.30.4",
61
+ "magic-string": "^0.30.5",
38
62
  "sirv": "^2.0.3"
39
63
  },
40
64
  "devDependencies": {
41
65
  "@types/estree": "^1.0.1",
42
66
  "@types/ws": "^8.5.5",
67
+ "@wdio/protocols": "^8.18.0",
43
68
  "periscopic": "^3.1.0",
44
- "@vitest/runner": "1.0.0-beta.2",
45
- "@vitest/ui": "1.0.0-beta.2",
46
- "vitest": "1.0.0-beta.2",
47
- "@vitest/ws-client": "1.0.0-beta.2"
69
+ "playwright": "^1.39.0",
70
+ "playwright-core": "^1.39.0",
71
+ "safaridriver": "^0.1.0",
72
+ "webdriverio": "^8.20.0",
73
+ "@vitest/runner": "1.0.0-beta.4",
74
+ "@vitest/ui": "1.0.0-beta.4",
75
+ "@vitest/ws-client": "1.0.0-beta.4",
76
+ "vitest": "1.0.0-beta.4"
48
77
  },
49
78
  "scripts": {
50
79
  "build": "rimraf dist && pnpm build:node && pnpm build:client",
@@ -0,0 +1,8 @@
1
+ import type { Browser, LaunchOptions } from 'playwright'
2
+
3
+ declare module 'vitest/node' {
4
+ interface BrowserProviderOptions {
5
+ launch?: LaunchOptions
6
+ page?: Parameters<Browser['newPage']>[0]
7
+ }
8
+ }
@@ -0,0 +1,5 @@
1
+ import type { RemoteOptions } from 'webdriverio'
2
+
3
+ declare module 'vitest/node' {
4
+ interface BrowserProviderOptions extends RemoteOptions {}
5
+ }