@vitest/browser-playwright 4.0.18 → 4.1.0-beta.2

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/index.d.ts CHANGED
@@ -31,6 +31,18 @@ interface PlaywrightProviderOptions {
31
31
  * @default 0 (no timeout)
32
32
  */
33
33
  actionTimeout?: number;
34
+ /**
35
+ * Use a persistent context instead of a regular browser context.
36
+ * This allows browser state (cookies, localStorage, DevTools settings, etc.) to persist between test runs.
37
+ * When set to `true`, the user data is stored in `./node_modules/.cache/vitest-playwright-user-data`.
38
+ * When set to a string, the value is used as the path to the user data directory.
39
+ *
40
+ * Note: This option is ignored when running tests in parallel (e.g. headless with fileParallelism enabled)
41
+ * because persistent context cannot be shared across parallel sessions.
42
+ * @default false
43
+ * @see {@link https://playwright.dev/docs/api/class-browsertype#browser-type-launch-persistent-context}
44
+ */
45
+ persistentContext?: boolean | string;
34
46
  }
35
47
  declare function playwright(options?: PlaywrightProviderOptions): BrowserProviderOption<PlaywrightProviderOptions>;
36
48
  declare class PlaywrightBrowserProvider implements BrowserProvider {
@@ -39,6 +51,7 @@ declare class PlaywrightBrowserProvider implements BrowserProvider {
39
51
  name: "playwright";
40
52
  supportsParallelism: boolean;
41
53
  browser: Browser | null;
54
+ persistentContext: BrowserContext | null;
42
55
  contexts: Map<string, BrowserContext>;
43
56
  pages: Map<string, Page>;
44
57
  mocker: BrowserModuleMocker;
@@ -52,6 +65,7 @@ declare class PlaywrightBrowserProvider implements BrowserProvider {
52
65
  private openBrowser;
53
66
  private createMocker;
54
67
  private createContext;
68
+ private getContextOptions;
55
69
  getPage(sessionId: string): Page;
56
70
  getCommandsContext(sessionId: string): {
57
71
  page: Page;
@@ -60,7 +74,9 @@ declare class PlaywrightBrowserProvider implements BrowserProvider {
60
74
  readonly iframe: FrameLocator;
61
75
  };
62
76
  private openBrowserPage;
63
- openPage(sessionId: string, url: string): Promise<void>;
77
+ openPage(sessionId: string, url: string, options: {
78
+ parallel: boolean;
79
+ }): Promise<void>;
64
80
  private _throwIfClosing;
65
81
  getCDPSession(sessionid: string): Promise<CDPSession$1>;
66
82
  close(): Promise<void>;
package/dist/index.js CHANGED
@@ -694,11 +694,22 @@ const upload = async (context, selector, files, options) => {
694
694
  await iframe.locator(selector).setInputFiles(playwrightFiles, options);
695
695
  };
696
696
 
697
+ const wheel = async (context, selector, options) => {
698
+ await hover(context, selector);
699
+ const times = options.times ?? 1;
700
+ const deltaX = options.delta.x ?? 0;
701
+ const deltaY = options.delta.y ?? 0;
702
+ for (let count = 0; count < times; count += 1) {
703
+ await context.page.mouse.wheel(deltaX, deltaY);
704
+ }
705
+ };
706
+
697
707
  var commands = {
698
708
  __vitest_upload: upload,
699
709
  __vitest_click: click,
700
710
  __vitest_dblClick: dblClick,
701
711
  __vitest_tripleClick: tripleClick,
712
+ __vitest_wheel: wheel,
702
713
  __vitest_takeScreenshot: takeScreenshot,
703
714
  __vitest_type: type,
704
715
  __vitest_clear: clear,
@@ -742,6 +753,7 @@ class PlaywrightBrowserProvider {
742
753
  name = "playwright";
743
754
  supportsParallelism = true;
744
755
  browser = null;
756
+ persistentContext = null;
745
757
  contexts = new Map();
746
758
  pages = new Map();
747
759
  mocker;
@@ -774,7 +786,7 @@ class PlaywrightBrowserProvider {
774
786
  return Promise.allSettled(promises);
775
787
  });
776
788
  }
777
- async openBrowser() {
789
+ async openBrowser(openBrowserOptions) {
778
790
  await this._throwIfClosing();
779
791
  if (this.browserPromise) {
780
792
  debug?.("[%s] the browser is resolving, reusing the promise", this.browserName);
@@ -825,7 +837,22 @@ class PlaywrightBrowserProvider {
825
837
  }
826
838
  }
827
839
  debug?.("[%s] initializing the browser with launch options: %O", this.browserName, launchOptions);
828
- this.browser = await playwright[this.browserName].launch(launchOptions);
840
+ let persistentContextOption = this.options.persistentContext;
841
+ if (persistentContextOption && openBrowserOptions.parallel) {
842
+ persistentContextOption = false;
843
+ this.project.vitest.logger.warn(c.yellow(`The persistentContext option is ignored because tests are running in parallel.`));
844
+ }
845
+ if (persistentContextOption) {
846
+ const userDataDir = typeof this.options.persistentContext === "string" ? this.options.persistentContext : "./node_modules/.cache/vitest-playwright-user-data";
847
+ // TODO: how to avoid default "about" page?
848
+ this.persistentContext = await playwright[this.browserName].launchPersistentContext(userDataDir, {
849
+ ...launchOptions,
850
+ ...this.getContextOptions()
851
+ });
852
+ this.browser = this.persistentContext.browser();
853
+ } else {
854
+ this.browser = await playwright[this.browserName].launch(launchOptions);
855
+ }
829
856
  this.browserPromise = null;
830
857
  return this.browser;
831
858
  })();
@@ -945,29 +972,22 @@ class PlaywrightBrowserProvider {
945
972
  }
946
973
  };
947
974
  }
948
- async createContext(sessionId) {
975
+ async createContext(sessionId, openBrowserOptions) {
949
976
  await this._throwIfClosing();
950
977
  if (this.contexts.has(sessionId)) {
951
978
  debug?.("[%s][%s] the context already exists, reusing it", sessionId, this.browserName);
952
979
  return this.contexts.get(sessionId);
953
980
  }
954
- const browser = await this.openBrowser();
981
+ const browser = await this.openBrowser(openBrowserOptions);
955
982
  await this._throwIfClosing(browser);
956
983
  const actionTimeout = this.options.actionTimeout;
957
- const contextOptions = this.options.contextOptions ?? {};
958
- const options = {
959
- ...contextOptions,
960
- ignoreHTTPSErrors: true
961
- };
962
- if (this.project.config.browser.ui) {
963
- options.viewport = null;
964
- }
984
+ const options = this.getContextOptions();
965
985
  // TODO: investigate the consequences for Vitest 5
966
986
  // else {
967
987
  // if UI is disabled, keep the iframe scale to 1
968
988
  // options.viewport ??= this.project.config.browser.viewport
969
989
  // }
970
- const context = await browser.newContext(options);
990
+ const context = this.persistentContext ?? await browser.newContext(options);
971
991
  await this._throwIfClosing(context);
972
992
  if (actionTimeout != null) {
973
993
  context.setDefaultTimeout(actionTimeout);
@@ -976,6 +996,17 @@ class PlaywrightBrowserProvider {
976
996
  this.contexts.set(sessionId, context);
977
997
  return context;
978
998
  }
999
+ getContextOptions() {
1000
+ const contextOptions = this.options.contextOptions ?? {};
1001
+ const options = {
1002
+ ...contextOptions,
1003
+ ignoreHTTPSErrors: true
1004
+ };
1005
+ if (this.project.config.browser.ui) {
1006
+ options.viewport = null;
1007
+ }
1008
+ return options;
1009
+ }
979
1010
  getPage(sessionId) {
980
1011
  const page = this.pages.get(sessionId);
981
1012
  if (!page) {
@@ -1009,7 +1040,7 @@ class PlaywrightBrowserProvider {
1009
1040
  }
1010
1041
  };
1011
1042
  }
1012
- async openBrowserPage(sessionId) {
1043
+ async openBrowserPage(sessionId, options) {
1013
1044
  await this._throwIfClosing();
1014
1045
  if (this.pages.has(sessionId)) {
1015
1046
  debug?.("[%s][%s] the page already exists, closing the old one", sessionId, this.browserName);
@@ -1017,7 +1048,7 @@ class PlaywrightBrowserProvider {
1017
1048
  await page.close();
1018
1049
  this.pages.delete(sessionId);
1019
1050
  }
1020
- const context = await this.createContext(sessionId);
1051
+ const context = await this.createContext(sessionId, options);
1021
1052
  const page = await context.newPage();
1022
1053
  debug?.("[%s][%s] the page is ready", sessionId, this.browserName);
1023
1054
  await this._throwIfClosing(page);
@@ -1029,9 +1060,9 @@ class PlaywrightBrowserProvider {
1029
1060
  }
1030
1061
  return page;
1031
1062
  }
1032
- async openPage(sessionId, url) {
1063
+ async openPage(sessionId, url, options) {
1033
1064
  debug?.("[%s][%s] creating the browser page for %s", sessionId, this.browserName, url);
1034
- const browserPage = await this.openBrowserPage(sessionId);
1065
+ const browserPage = await this.openBrowserPage(sessionId, options);
1035
1066
  debug?.("[%s][%s] browser page is created, opening %s", sessionId, this.browserName, url);
1036
1067
  await browserPage.goto(url, { timeout: 0 });
1037
1068
  await this._throwIfClosing(browserPage);
@@ -1077,7 +1108,11 @@ class PlaywrightBrowserProvider {
1077
1108
  this.browser = null;
1078
1109
  await Promise.all([...this.pages.values()].map((p) => p.close()));
1079
1110
  this.pages.clear();
1080
- await Promise.all([...this.contexts.values()].map((c) => c.close()));
1111
+ if (this.persistentContext) {
1112
+ await this.persistentContext.close();
1113
+ } else {
1114
+ await Promise.all([...this.contexts.values()].map((c) => c.close()));
1115
+ }
1081
1116
  this.contexts.clear();
1082
1117
  await browser?.close();
1083
1118
  debug?.("[%s] provider is closed", this.browserName);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/browser-playwright",
3
3
  "type": "module",
4
- "version": "4.0.18",
4
+ "version": "4.1.0-beta.2",
5
5
  "description": "Browser running for Vitest using playwright",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -42,7 +42,7 @@
42
42
  ],
43
43
  "peerDependencies": {
44
44
  "playwright": "*",
45
- "vitest": "4.0.18"
45
+ "vitest": "4.1.0-beta.2"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
48
  "playwright": {
@@ -51,12 +51,12 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "tinyrainbow": "^3.0.3",
54
- "@vitest/browser": "4.0.18",
55
- "@vitest/mocker": "4.0.18"
54
+ "@vitest/browser": "4.1.0-beta.2",
55
+ "@vitest/mocker": "4.1.0-beta.2"
56
56
  },
57
57
  "devDependencies": {
58
58
  "playwright": "^1.57.0",
59
- "vitest": "4.0.18"
59
+ "vitest": "4.1.0-beta.2"
60
60
  },
61
61
  "scripts": {
62
62
  "build": "premove dist && pnpm rollup -c",