@vitest/browser 3.2.0-beta.2 → 3.2.0

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.
@@ -59,6 +59,7 @@ class PlaywrightBrowserProvider {
59
59
  headless: options.headless
60
60
  };
61
61
  if (this.project.config.inspector.enabled) {
62
+ // NodeJS equivalent defaults: https://nodejs.org/en/learn/getting-started/debugging#enable-inspector
62
63
  const port = this.project.config.inspector.port || 9229;
63
64
  const host = this.project.config.inspector.host || "127.0.0.1";
64
65
  launchOptions.args ||= [];
@@ -66,6 +67,7 @@ class PlaywrightBrowserProvider {
66
67
  launchOptions.args.push(`--remote-debugging-address=${host}`);
67
68
  this.project.vitest.logger.log(`Debugger listening on ws://${host}:${port}`);
68
69
  }
70
+ // start Vitest UI maximized only on supported browsers
69
71
  if (this.project.config.browser.ui && this.browserName === "chromium") {
70
72
  if (!launchOptions.args) {
71
73
  launchOptions.args = [];
@@ -90,15 +92,18 @@ class PlaywrightBrowserProvider {
90
92
  if (url.searchParams.has("_vitest_original")) {
91
93
  return false;
92
94
  }
95
+ // different modules, ignore request
93
96
  if (url.pathname !== moduleUrl.pathname) {
94
97
  return false;
95
98
  }
96
99
  url.searchParams.delete("t");
97
100
  url.searchParams.delete("v");
98
101
  url.searchParams.delete("import");
102
+ // different search params, ignore request
99
103
  if (url.searchParams.size !== moduleUrl.searchParams.size) {
100
104
  return false;
101
105
  }
106
+ // check that all search params are the same
102
107
  for (const [param, value] of url.searchParams.entries()) {
103
108
  if (moduleUrl.searchParams.get(param) !== value) {
104
109
  return false;
@@ -109,9 +114,12 @@ class PlaywrightBrowserProvider {
109
114
  const ids = sessionIds.get(sessionId) || [];
110
115
  ids.push(moduleUrl.href);
111
116
  sessionIds.set(sessionId, ids);
112
- idPreficates.set(moduleUrl.href, predicate);
117
+ idPreficates.set(predicateKey(sessionId, moduleUrl.href), predicate);
113
118
  return predicate;
114
119
  }
120
+ function predicateKey(sessionId, url) {
121
+ return `${sessionId}:${url}`;
122
+ }
115
123
  return {
116
124
  register: async (sessionId, module) => {
117
125
  const page = this.getPage(sessionId);
@@ -124,16 +132,19 @@ class PlaywrightBrowserProvider {
124
132
  headers: getHeaders(this.project.browser.vite.config)
125
133
  });
126
134
  }
135
+ // webkit doesn't support redirect responses
136
+ // https://github.com/microsoft/playwright/issues/18318
127
137
  const isWebkit = this.browserName === "webkit";
128
138
  if (isWebkit) {
129
- const url = module.type === "redirect" ? (() => {
130
- const url = new URL(module.redirect);
131
- return url.href.slice(url.origin.length);
132
- })() : (() => {
133
- const url = new URL(route.request().url());
134
- url.searchParams.set("mock", module.type);
135
- return url.href.slice(url.origin.length);
136
- })();
139
+ let url;
140
+ if (module.type === "redirect") {
141
+ const redirect = new URL(module.redirect);
142
+ url = redirect.href.slice(redirect.origin.length);
143
+ } else {
144
+ const request = new URL(route.request().url());
145
+ request.searchParams.set("mock", module.type);
146
+ url = request.href.slice(request.origin.length);
147
+ }
137
148
  const result = await this.project.browser.vite.transformRequest(url).catch(() => null);
138
149
  if (!result) {
139
150
  return route.continue();
@@ -165,18 +176,20 @@ class PlaywrightBrowserProvider {
165
176
  },
166
177
  delete: async (sessionId, id) => {
167
178
  const page = this.getPage(sessionId);
168
- const predicate = idPreficates.get(id);
179
+ const key = predicateKey(sessionId, id);
180
+ const predicate = idPreficates.get(key);
169
181
  if (predicate) {
170
- await page.unroute(predicate).finally(() => idPreficates.delete(id));
182
+ await page.unroute(predicate).finally(() => idPreficates.delete(key));
171
183
  }
172
184
  },
173
185
  clear: async (sessionId) => {
174
186
  const page = this.getPage(sessionId);
175
187
  const ids = sessionIds.get(sessionId) || [];
176
188
  const promises = ids.map((id) => {
177
- const predicate = idPreficates.get(id);
189
+ const key = predicateKey(sessionId, id);
190
+ const predicate = idPreficates.get(key);
178
191
  if (predicate) {
179
- return page.unroute(predicate).finally(() => idPreficates.delete(id));
192
+ return page.unroute(predicate).finally(() => idPreficates.delete(key));
180
193
  }
181
194
  return null;
182
195
  });
@@ -359,6 +372,8 @@ class WebdriverBrowserProvider {
359
372
  project;
360
373
  options;
361
374
  closing = false;
375
+ iframeSwitched = false;
376
+ topLevelContext;
362
377
  getSupportedBrowsers() {
363
378
  return webdriverBrowsers;
364
379
  }
@@ -368,14 +383,19 @@ class WebdriverBrowserProvider {
368
383
  this.browserName = browser;
369
384
  this.options = options;
370
385
  }
386
+ isIframeSwitched() {
387
+ return this.iframeSwitched;
388
+ }
371
389
  async switchToTestFrame() {
372
390
  const page = this.browser;
391
+ // support wdio@9
373
392
  if (page.switchFrame) {
374
393
  await page.switchFrame(page.$("iframe[data-vitest]"));
375
394
  } else {
376
395
  const iframe = await page.findElement("css selector", "iframe[data-vitest]");
377
396
  await page.switchToFrame(iframe);
378
397
  }
398
+ this.iframeSwitched = true;
379
399
  }
380
400
  async switchToMainFrame() {
381
401
  const page = this.browser;
@@ -384,6 +404,20 @@ class WebdriverBrowserProvider {
384
404
  } else {
385
405
  await page.switchToParentFrame();
386
406
  }
407
+ this.iframeSwitched = false;
408
+ }
409
+ async setViewport(options) {
410
+ if (this.topLevelContext == null || !this.browser) {
411
+ throw new Error(`The browser has no open pages.`);
412
+ }
413
+ await this.browser.send({
414
+ method: "browsingContext.setViewport",
415
+ params: {
416
+ context: this.topLevelContext,
417
+ devicePixelRatio: 1,
418
+ viewport: options
419
+ }
420
+ });
387
421
  }
388
422
  getCommandsContext() {
389
423
  return { browser: this.browser };
@@ -407,6 +441,7 @@ class WebdriverBrowserProvider {
407
441
  capabilities: this.buildCapabilities()
408
442
  };
409
443
  debug?.("[%s] opening the browser with options: %O", this.browserName, remoteOptions);
444
+ // TODO: close everything, if browser is closed from the outside
410
445
  this.browser = await remote(remoteOptions);
411
446
  await this._throwIfClosing();
412
447
  return this.browser;
@@ -432,6 +467,7 @@ class WebdriverBrowserProvider {
432
467
  args: newArgs
433
468
  };
434
469
  }
470
+ // start Vitest UI maximized only on supported browsers
435
471
  if (options.ui && (browser === "chrome" || browser === "edge")) {
436
472
  const key = browser === "chrome" ? "goog:chromeOptions" : "ms:edgeOptions";
437
473
  const args = capabilities[key]?.args || [];
@@ -449,6 +485,7 @@ class WebdriverBrowserProvider {
449
485
  const browserInstance = await this.openBrowser();
450
486
  debug?.("[%s][%s] browser page is created, opening %s", sessionId, this.browserName, url);
451
487
  await browserInstance.url(url);
488
+ this.topLevelContext = await browserInstance.getWindowHandle();
452
489
  await this._throwIfClosing("opening the url");
453
490
  }
454
491
  async _throwIfClosing(action) {
@@ -462,6 +499,8 @@ class WebdriverBrowserProvider {
462
499
  debug?.("[%s] closing provider", this.browserName);
463
500
  this.closing = true;
464
501
  await Promise.all([this.browser?.sessionId ? this.browser?.deleteSession?.() : null]);
502
+ // TODO: right now process can only exit with timeout, if we use browser
503
+ // needs investigating
465
504
  process.exit();
466
505
  }
467
506
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/browser",
3
3
  "type": "module",
4
- "version": "3.2.0-beta.2",
4
+ "version": "3.2.0",
5
5
  "description": "Browser running for Vitest",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -66,7 +66,7 @@
66
66
  "peerDependencies": {
67
67
  "playwright": "*",
68
68
  "webdriverio": "^7.0.0 || ^8.0.0 || ^9.0.0",
69
- "vitest": "3.2.0-beta.2"
69
+ "vitest": "3.2.0"
70
70
  },
71
71
  "peerDependenciesMeta": {
72
72
  "playwright": {
@@ -85,14 +85,14 @@
85
85
  "magic-string": "^0.30.17",
86
86
  "sirv": "^3.0.1",
87
87
  "tinyrainbow": "^2.0.0",
88
- "ws": "^8.18.1",
89
- "@vitest/mocker": "3.2.0-beta.2",
90
- "@vitest/utils": "3.2.0-beta.2"
88
+ "ws": "^8.18.2",
89
+ "@vitest/mocker": "3.2.0",
90
+ "@vitest/utils": "3.2.0"
91
91
  },
92
92
  "devDependencies": {
93
93
  "@types/ws": "^8.18.1",
94
- "@wdio/protocols": "^9.12.5",
95
- "@wdio/types": "^9.12.6",
94
+ "@wdio/protocols": "^9.15.0",
95
+ "@wdio/types": "^9.15.0",
96
96
  "birpc": "2.3.0",
97
97
  "flatted": "^3.3.3",
98
98
  "ivya": "^1.6.0",
@@ -102,11 +102,11 @@
102
102
  "playwright": "^1.52.0",
103
103
  "playwright-core": "^1.52.0",
104
104
  "safaridriver": "^1.0.0",
105
- "webdriverio": "^9.12.7",
106
- "@vitest/runner": "3.2.0-beta.2",
107
- "@vitest/ui": "3.2.0-beta.2",
108
- "@vitest/ws-client": "3.2.0-beta.2",
109
- "vitest": "3.2.0-beta.2"
105
+ "webdriverio": "^9.15.0",
106
+ "@vitest/runner": "3.2.0",
107
+ "vitest": "3.2.0",
108
+ "@vitest/ws-client": "3.2.0",
109
+ "@vitest/ui": "3.2.0"
110
110
  },
111
111
  "scripts": {
112
112
  "build": "rimraf dist && pnpm build:node && pnpm build:client",