venetian 0.2.0-aarch64-linux → 0.2.2-aarch64-linux

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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/exe/aarch64-linux/LICENSE +202 -202
  4. data/exe/aarch64-linux/node +0 -0
  5. data/exe/aarch64-linux/package/browsers.json +12 -18
  6. data/exe/aarch64-linux/package/lib/bootstrap.js +1 -1
  7. data/exe/aarch64-linux/package/lib/coreBundle.js +11344 -9900
  8. data/exe/aarch64-linux/package/lib/server/electron/loader.js +5 -2
  9. data/exe/aarch64-linux/package/lib/serverRegistry.js +5 -1
  10. data/exe/aarch64-linux/package/lib/tools/cli-client/help.json +21 -6
  11. data/exe/aarch64-linux/package/lib/tools/cli-client/program.js +1 -1
  12. data/exe/aarch64-linux/package/lib/tools/cli-client/session.js +4 -0
  13. data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/SKILL.md +21 -5
  14. data/exe/aarch64-linux/package/lib/tools/{cli-client/skill/references/spec-driven-testing.md → skills/playwright-cli/references/test-generation.md} +135 -7
  15. data/exe/aarch64-linux/package/lib/tools/skills/playwright-component-testing/SKILL.md +143 -0
  16. data/exe/aarch64-linux/package/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +144 -0
  17. data/exe/aarch64-linux/package/lib/tools/skills/playwright-component-testing/references/migration.md +85 -0
  18. data/exe/aarch64-linux/package/lib/tools/skills/playwright-component-testing/references/react.md +67 -0
  19. data/exe/aarch64-linux/package/lib/tools/skills/playwright-component-testing/references/vue.md +75 -0
  20. data/exe/aarch64-linux/package/lib/tools/utils/extension.js +31 -8
  21. data/exe/aarch64-linux/package/lib/utilsBundle.js +37698 -33670
  22. data/exe/aarch64-linux/package/lib/utilsBundle.js.LICENSE +391 -268
  23. data/exe/aarch64-linux/package/lib/vite/dashboard/assets/index-CyWAfh-p.js +11 -0
  24. data/exe/aarch64-linux/package/lib/vite/dashboard/assets/index-DhC616m4.css +1 -0
  25. data/exe/aarch64-linux/package/lib/vite/dashboard/index.html +2 -2
  26. data/exe/aarch64-linux/package/lib/vite/htmlReport/report.css +2 -1
  27. data/exe/aarch64-linux/package/lib/vite/htmlReport/report.js +15 -55
  28. data/exe/aarch64-linux/package/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +1 -0
  29. data/exe/aarch64-linux/package/lib/vite/recorder/assets/codeMirrorModule-CwYYHbcZ.js +32 -0
  30. data/exe/aarch64-linux/package/lib/vite/recorder/assets/index-DYjdXIbE.js +129 -0
  31. data/exe/aarch64-linux/package/lib/vite/recorder/assets/index-l_lX622x.css +1 -0
  32. data/exe/aarch64-linux/package/lib/vite/recorder/index.html +2 -2
  33. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/codeMirrorModule-rXmQmLUY.js +32 -0
  34. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/defaultSettingsView-B-dXF5JN.js +181 -0
  35. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +1 -0
  36. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/xtermModule-BuZfJS5v.js +7 -0
  37. data/exe/aarch64-linux/package/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +1 -0
  38. data/exe/aarch64-linux/package/lib/vite/traceViewer/defaultSettingsView.BLFoOugd.css +1 -0
  39. data/exe/aarch64-linux/package/lib/vite/traceViewer/index.B_TqY17P.css +1 -0
  40. data/exe/aarch64-linux/package/lib/vite/traceViewer/index.KZ4wOW1K.js +1 -0
  41. data/exe/aarch64-linux/package/lib/vite/traceViewer/index.html +5 -5
  42. data/exe/aarch64-linux/package/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +1 -0
  43. data/exe/aarch64-linux/package/lib/vite/traceViewer/snapshot.html +2 -2
  44. data/exe/aarch64-linux/package/lib/vite/traceViewer/sw.bundle.js +3 -4
  45. data/exe/aarch64-linux/package/lib/vite/traceViewer/uiMode.C7UW1sC9.css +1 -0
  46. data/exe/aarch64-linux/package/lib/vite/traceViewer/uiMode.Dzuouizj.js +5 -0
  47. data/exe/aarch64-linux/package/lib/vite/traceViewer/uiMode.html +5 -5
  48. data/exe/aarch64-linux/package/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +1 -0
  49. data/exe/aarch64-linux/package/lib/webp_codec.LICENSE +173 -0
  50. data/exe/aarch64-linux/package/lib/webp_codec.wasm +0 -0
  51. data/exe/aarch64-linux/package/lib/xdg-open +338 -137
  52. data/exe/aarch64-linux/package/package.json +2 -2
  53. data/exe/aarch64-linux/package/types/protocol.d.ts +249 -36
  54. data/exe/aarch64-linux/package/types/structs.d.ts +8 -1
  55. data/exe/aarch64-linux/package/types/types.d.ts +2009 -266
  56. data/lib/venetian/executable.rb +6 -2
  57. data/lib/venetian/upstream.rb +35 -18
  58. data/lib/venetian/version.rb +2 -2
  59. metadata +41 -38
  60. data/exe/aarch64-linux/package/api.json +0 -1
  61. data/exe/aarch64-linux/package/lib/server/deviceDescriptorsSource.json +0 -2739
  62. data/exe/aarch64-linux/package/lib/tools/cli-client/skill/references/test-generation.md +0 -134
  63. data/exe/aarch64-linux/package/lib/vite/dashboard/assets/index-BY2S1tHT.css +0 -1
  64. data/exe/aarch64-linux/package/lib/vite/dashboard/assets/index-C_5TMfeg.js +0 -52
  65. data/exe/aarch64-linux/package/lib/vite/recorder/assets/codeMirrorModule-DYBRYzYX.css +0 -1
  66. data/exe/aarch64-linux/package/lib/vite/recorder/assets/codeMirrorModule-DeBYQozu.js +0 -32
  67. data/exe/aarch64-linux/package/lib/vite/recorder/assets/index-4ZiSSCmn.css +0 -1
  68. data/exe/aarch64-linux/package/lib/vite/recorder/assets/index-Bq-mQf8S.js +0 -193
  69. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/codeMirrorModule-LEHpjmcn.js +0 -32
  70. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/defaultSettingsView-BNmKHKpQ.js +0 -264
  71. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/urlMatch-BYQrIQwR.js +0 -1
  72. data/exe/aarch64-linux/package/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +0 -9
  73. data/exe/aarch64-linux/package/lib/vite/traceViewer/codeMirrorModule.DYBRYzYX.css +0 -1
  74. data/exe/aarch64-linux/package/lib/vite/traceViewer/defaultSettingsView.CjdS-WJx.css +0 -1
  75. data/exe/aarch64-linux/package/lib/vite/traceViewer/index.CzXZzn5A.css +0 -1
  76. data/exe/aarch64-linux/package/lib/vite/traceViewer/index.DMMX1gXU.js +0 -2
  77. data/exe/aarch64-linux/package/lib/vite/traceViewer/snapshot.v8KI4P3m.js +0 -2
  78. data/exe/aarch64-linux/package/lib/vite/traceViewer/uiMode.BZQ54Kgt.css +0 -1
  79. data/exe/aarch64-linux/package/lib/vite/traceViewer/uiMode.Ut8wwJNp.js +0 -6
  80. data/exe/aarch64-linux/package/lib/vite/traceViewer/xtermModule.DYP7pi_n.css +0 -32
  81. data/exe/aarch64-linux/package/protocol.yml +0 -4991
  82. /data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/references/element-attributes.md +0 -0
  83. /data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/references/playwright-tests.md +0 -0
  84. /data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/references/request-mocking.md +0 -0
  85. /data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/references/running-code.md +0 -0
  86. /data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/references/session-management.md +0 -0
  87. /data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/references/storage-state.md +0 -0
  88. /data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/references/tracing.md +0 -0
  89. /data/exe/aarch64-linux/package/lib/tools/{cli-client/skill → skills/playwright-cli}/references/video-recording.md +0 -0
  90. /data/exe/aarch64-linux/package/lib/tools/{trace → skills/playwright-trace}/SKILL.md +0 -0
@@ -23,12 +23,13 @@ var disabledFeatures = [
23
23
  "PaintHolding",
24
24
  // See https://github.com/microsoft/playwright/issues/32230
25
25
  "ThirdPartyStoragePartitioning",
26
+ // Chromium 149 rejects re-applying the `origin` header on a redirect (as request interception
27
+ // does) with net::ERR_INVALID_ARGUMENT. See https://github.com/microsoft/playwright/issues/41690
28
+ "BlockOriginHeaderModificationOnRedirect",
26
29
  // See https://github.com/microsoft/playwright/issues/16126
27
30
  "Translate",
28
31
  // See https://issues.chromium.org/u/1/issues/435410220
29
32
  "AutoDeElevate",
30
- // See https://github.com/microsoft/playwright/issues/37714
31
- "RenderDocument",
32
33
  // Prevents downloading optimization hints on startup.
33
34
  "OptimizationHints",
34
35
  // Disables forced sign-in in Edge.
@@ -63,6 +64,8 @@ var chromiumSwitches = (options) => [
63
64
  "--disable-popup-blocking",
64
65
  "--disable-prompt-on-repost",
65
66
  "--disable-renderer-backgrounding",
67
+ "--disable-updater-scheduler",
68
+ // Prevents Edge-specific updater from being launched when Edge is launched on mac.
66
69
  "--force-color-profile=srgb",
67
70
  "--metrics-recording-only",
68
71
  "--no-first-run",
@@ -6,7 +6,11 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
8
  var __commonJS = (cb, mod) => function __require() {
9
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ try {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ } catch (e) {
12
+ throw mod = 0, e;
13
+ }
10
14
  };
11
15
  var __export = (target, all) => {
12
16
  for (var name in all)
@@ -1,12 +1,14 @@
1
1
  {
2
- "global": "Usage: playwright-cli <command> [args] [options]\nUsage: playwright-cli -s=<session> <command> [args] [options]\n\nCore:\n open [url] open the browser\n attach [name] attach to a running playwright browser\n close close the browser\n detach detach from an attached browser\n goto <url> navigate to a url\n type <text> type text into editable element\n click <target> [button] perform click on a web page\n dblclick <target> [button] perform double click on a web page\n fill <target> <text> fill text into editable element\n drag <startTarget> <endTarget> perform drag and drop between two elements\n drop <target> drop files or data onto an element\n hover <target> hover over element on page\n select <target> <val> select an option in a dropdown\n upload <file> upload one or multiple files\n check <target> check a checkbox or radio button\n uncheck <target> uncheck a checkbox or radio button\n snapshot [target] capture page snapshot to obtain element ref\n eval <func> [target] evaluate javascript expression on page or element\n dialog-accept [prompt] accept a dialog\n dialog-dismiss dismiss a dialog\n resize <w> <h> resize the browser window\n delete-data delete session data\n\nNavigation:\n go-back go back to the previous page\n go-forward go forward to the next page\n reload reload the current page\n\nKeyboard:\n press <key> press a key on the keyboard, `a`, `arrowleft`\n keydown <key> press a key down on the keyboard\n keyup <key> press a key up on the keyboard\n\nMouse:\n mousemove <x> <y> move mouse to a given position\n mousedown [button] press mouse down\n mouseup [button] press mouse up\n mousewheel <dx> <dy> scroll mouse wheel\n\nSave as:\n screenshot [target] screenshot of the current page or element\n pdf save page as pdf\n\nTabs:\n tab-list list all tabs\n tab-new [url] create a new tab\n tab-close [index] close a browser tab\n tab-select <index> select a browser tab\n\nStorage:\n state-load <filename> loads browser storage (authentication) state from a file\n state-save [filename] saves the current storage (authentication) state to a file\n cookie-list list all cookies (optionally filtered by domain/path)\n cookie-get <name> get a specific cookie by name\n cookie-set <name> <value> set a cookie with optional flags\n cookie-delete <name> delete a specific cookie\n cookie-clear clear all cookies\n localstorage-list list all localstorage key-value pairs\n localstorage-get <key> get a localstorage item by key\n localstorage-set <key> <value> set a localstorage item\n localstorage-delete <key> delete a localstorage item\n localstorage-clear clear all localstorage\n sessionstorage-list list all sessionstorage key-value pairs\n sessionstorage-get <key> get a sessionstorage item by key\n sessionstorage-set <key> <value> set a sessionstorage item\n sessionstorage-delete <key> delete a sessionstorage item\n sessionstorage-clear clear all sessionstorage\n\nNetwork:\n requests list all network requests since loading the page. each request is numbered for use with the `request` command.\n request <index> show full details (headers, body, response) of a single network request by its number from the `requests` command.\n request-headers <index> print only the request headers for a single network request by its number from the `requests` command.\n request-body <index> print only the request body for a single network request by its number from the `requests` command.\n response-headers <index> print only the response headers for a single network request by its number from the `requests` command.\n response-body <index> print the response body for a single network request by its number from the `requests` command. textual bodies are inlined; binary bodies are saved to a file and the path is printed.\n route <pattern> mock network requests matching a url pattern\n route-list list all active network routes\n unroute [pattern] remove routes matching a pattern (or all routes)\n network-state-set <state> set the browser network state to online or offline\n\nDevTools:\n console [min-level] list console messages\n run-code [code] run playwright code snippet\n tracing-start start trace recording\n tracing-stop stop trace recording\n video-start [filename] start video recording\n video-stop stop video recording\n video-chapter <title> add a chapter marker to the video recording\n video-show-actions annotate subsequent cli/mcp actions on the page with a callout that names the action and highlights the target element\n video-hide-actions stop annotating actions performed on the page\n show show playwright dashboard\n pause-at <location> run the test up to a specific location and pause there\n resume resume the test execution\n step-over step over the next call in the test\n generate-locator <target> generate a playwright locator for the given element\n highlight [target] show (or with --hide, remove) a highlight overlay for an element; `--hide` without a target hides all page highlights.\n\nInstall:\n install initialize workspace\n install-browser [browser] install browser\n\nBrowser sessions:\n list list browser sessions\n close-all close all browser sessions\n kill-all forcefully kill all browser sessions (for stale/zombie processes)\n\nGlobal options:\n --help [command] print help\n --json output response as JSON\n --raw output only the result value, without status and code\n --version print version",
2
+ "global": "Usage: playwright-cli <command> [args] [options]\nUsage: playwright-cli -s=<session> <command> [args] [options]\n\nCore:\n open [url] open the browser\n attach [name] attach to a running playwright browser\n close close the browser\n detach detach from an attached browser\n goto <url> navigate to a url\n type <text> type text into editable element\n click <target> [button] perform click on a web page\n dblclick <target> [button] perform double click on a web page\n fill <target> <text> fill text into editable element\n drag <startTarget> <endTarget> perform drag and drop between two elements\n drop <target> drop files or data onto an element\n hover <target> hover over element on page\n select <target> <val> select an option in a dropdown\n upload <file> upload one or multiple files\n check <target> check a checkbox or radio button\n uncheck <target> uncheck a checkbox or radio button\n snapshot [target] capture page snapshot to obtain element ref\n find [text] search the page snapshot for text or a regexp, returning matching nodes with surrounding context (like search snippets)\n eval <func> [target] evaluate javascript expression on page or element\n dialog-accept [prompt] accept a dialog\n dialog-dismiss dismiss a dialog\n resize <w> <h> resize the browser window\n delete-data delete session data\n\nNavigation:\n go-back go back to the previous page\n go-forward go forward to the next page\n reload reload the current page\n\nKeyboard:\n press <key> press a key on the keyboard, `a`, `arrowleft`\n keydown <key> press a key down on the keyboard\n keyup <key> press a key up on the keyboard\n\nMouse:\n mousemove <x> <y> move mouse to a given position\n mousedown [button] press mouse down\n mouseup [button] press mouse up\n mousewheel <dx> <dy> scroll mouse wheel\n\nSave as:\n screenshot [target] screenshot of the current page or element\n pdf save page as pdf\n\nTabs:\n tab-list list all tabs\n tab-new [url] create a new tab\n tab-close [index] close a browser tab\n tab-select <index> select a browser tab\n\nStorage:\n state-load <filename> loads browser storage (authentication) state from a file\n state-save [filename] saves the current storage (authentication) state to a file\n cookie-list list all cookies (optionally filtered by domain/path)\n cookie-get <name> get a specific cookie by name\n cookie-set <name> <value> set a cookie with optional flags\n cookie-delete <name> delete a specific cookie\n cookie-clear clear all cookies\n localstorage-list list all localstorage key-value pairs\n localstorage-get <key> get a localstorage item by key\n localstorage-set <key> <value> set a localstorage item\n localstorage-delete <key> delete a localstorage item\n localstorage-clear clear all localstorage\n sessionstorage-list list all sessionstorage key-value pairs\n sessionstorage-get <key> get a sessionstorage item by key\n sessionstorage-set <key> <value> set a sessionstorage item\n sessionstorage-delete <key> delete a sessionstorage item\n sessionstorage-clear clear all sessionstorage\n\nNetwork:\n requests list all network requests since loading the page. each request is numbered for use with the `request` command.\n request <index> show full details (headers, body, response) of a single network request by its number from the `requests` command.\n request-headers <index> print only the request headers for a single network request by its number from the `requests` command.\n request-body <index> print only the request body for a single network request by its number from the `requests` command.\n response-headers <index> print only the response headers for a single network request by its number from the `requests` command.\n response-body <index> print the response body for a single network request by its number from the `requests` command. textual bodies are inlined; binary bodies are saved to a file and the path is printed.\n route <pattern> mock network requests matching a url pattern\n route-list list all active network routes\n unroute [pattern] remove routes matching a pattern (or all routes)\n network-state-set <state> set the browser network state to online or offline\n\nDevTools:\n console [min-level] list console messages\n run-code [code] run playwright code snippet\n tracing-start start trace recording\n tracing-stop stop trace recording\n video-start [filename] start video recording\n video-stop stop video recording\n video-chapter <title> add a chapter marker to the video recording\n video-show-actions annotate subsequent cli/mcp actions on the page with a callout that names the action and highlights the target element\n video-hide-actions stop annotating actions performed on the page\n show show playwright dashboard\n pause-at <location> run the test up to a specific location and pause there\n resume resume the test execution\n step-over step over the next call in the test\n generate-locator <target> generate a playwright locator for the given element\n highlight [target] show (or with --hide, remove) a highlight overlay for an element; `--hide` without a target hides all page highlights.\n\nInstall:\n install initialize workspace\n install-browser [browser] install browser\n\nBrowser sessions:\n list list browser sessions\n close-all close all browser sessions\n kill-all forcefully kill all browser sessions (for stale/zombie processes)\n\nGlobal options:\n --help [command] print help\n --json output response as JSON\n --raw output only the result value, without status and code\n --version print version",
3
3
  "commands": {
4
4
  "open": {
5
- "help": "playwright-cli open [url]\n\nOpen the browser\n\nArguments:\n [url] the url to navigate to\nOptions:\n --browser browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.\n --config path to the configuration file, defaults to .playwright/cli.config.json\n --headed run browser in headed mode\n --persistent use persistent browser profile\n --profile path to a persistent user data directory.",
5
+ "help": "playwright-cli open [url]\n\nOpen the browser\n\nArguments:\n [url] the url to navigate to\nOptions:\n --browser browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.\n --config path to the configuration file, defaults to .playwright/cli.config.json\n --device emulate a specific device, for example \"iphone 15\".\n --headed run browser in headed mode\n --mobile emulate a generic mobile device (pixel 10 for chromium, iphone 17 for webkit). mobile pages are usually lighter, which saves tokens.\n --persistent use persistent browser profile\n --profile path to a persistent user data directory.",
6
6
  "flags": {
7
7
  "browser": "string",
8
8
  "config": "string",
9
+ "device": "string",
9
10
  "headed": "boolean",
11
+ "mobile": "boolean",
10
12
  "persistent": "boolean",
11
13
  "profile": "string"
12
14
  },
@@ -148,6 +150,15 @@
148
150
  "target"
149
151
  ]
150
152
  },
153
+ "find": {
154
+ "help": "playwright-cli find [text]\n\nSearch the page snapshot for text or a regexp, returning matching nodes with surrounding context (like search snippets)\n\nArguments:\n [text] plain text to search for in the page snapshot (case-insensitive substring match)\nOptions:\n --regex regular expression to search for in the page snapshot. provide either a text argument or --regex, not both.",
155
+ "flags": {
156
+ "regex": "string"
157
+ },
158
+ "args": [
159
+ "text"
160
+ ]
161
+ },
151
162
  "eval": {
152
163
  "help": "playwright-cli eval <func> [target]\n\nEvaluate JavaScript expression on page or element\n\nArguments:\n <func> () => { /* code */ } or (element) => { /* code */ } when element is provided\n [target] exact target element reference from the page snapshot, or a unique element selector\nOptions:\n --filename save evaluation result to a file instead of returning it in the response.",
153
164
  "flags": {
@@ -268,10 +279,12 @@
268
279
  ]
269
280
  },
270
281
  "screenshot": {
271
- "help": "playwright-cli screenshot [target]\n\nscreenshot of the current page or element\n\nArguments:\n [target] exact target element reference from the page snapshot, or a unique element selector\nOptions:\n --filename file name to save the screenshot to. defaults to `page-{timestamp}.{png|jpeg}` if not specified.\n --full-page when true, takes a screenshot of the full scrollable page, instead of the currently visible viewport.",
282
+ "help": "playwright-cli screenshot [target]\n\nscreenshot of the current page or element\n\nArguments:\n [target] exact target element reference from the page snapshot, or a unique element selector\nOptions:\n --filename file name to save the screenshot to. defaults to `page-{timestamp}.{png|jpeg|webp}` if not specified.\n --type image format. if unset, inferred from the filename extension, otherwise png. (one of: png, jpeg, webp)\n --full-page when true, takes a screenshot of the full scrollable page, instead of the currently visible viewport.\n --hires when true, captures a high-resolution screenshot using device pixels (accounts for the device pixel ratio), instead of css pixels.",
272
283
  "flags": {
273
284
  "filename": "string",
274
- "full-page": "boolean"
285
+ "type": "string",
286
+ "full-page": "boolean",
287
+ "hires": "boolean"
275
288
  },
276
289
  "args": [
277
290
  "target"
@@ -342,7 +355,7 @@
342
355
  "raw": true
343
356
  },
344
357
  "cookie-set": {
345
- "help": "playwright-cli cookie-set <name> <value>\n\nSet a cookie with optional flags\n\nArguments:\n <name> cookie name\n <value> cookie value\nOptions:\n --domain cookie domain\n --path cookie path\n --expires cookie expiration as unix timestamp\n --httpOnly whether the cookie is http only\n --secure whether the cookie is secure\n --sameSite cookie samesite attribute",
358
+ "help": "playwright-cli cookie-set <name> <value>\n\nSet a cookie with optional flags\n\nArguments:\n <name> cookie name\n <value> cookie value\nOptions:\n --domain cookie domain\n --path cookie path\n --expires cookie expiration as unix timestamp\n --httpOnly whether the cookie is http only\n --secure whether the cookie is secure\n --sameSite cookie samesite attribute (one of: Strict, Lax, None)",
346
359
  "flags": {
347
360
  "domain": "string",
348
361
  "path": "string",
@@ -588,7 +601,7 @@
588
601
  ]
589
602
  },
590
603
  "video-show-actions": {
591
- "help": "playwright-cli video-show-actions \n\nAnnotate subsequent CLI/MCP actions on the page with a callout that names the action and highlights the target element\n\nOptions:\n --duration how long each action annotation stays on screen, in milliseconds. defaults to 500.\n --position where to place the action title: top-left, top, top-right, bottom-left, bottom, bottom-right. defaults to top-right.\n --cursor cursor decoration: \"pointer\" (default) animates a mouse pointer between action points; \"none\" disables it.",
604
+ "help": "playwright-cli video-show-actions \n\nAnnotate subsequent CLI/MCP actions on the page with a callout that names the action and highlights the target element\n\nOptions:\n --duration how long each action annotation stays on screen, in milliseconds. defaults to 500.\n --position where to place the action title: top-left, top, top-right, bottom-left, bottom, bottom-right. defaults to top-right. (one of: top-left, top, top-right, bottom-left, bottom, bottom-right)\n --cursor cursor decoration: \"pointer\" (default) animates a mouse pointer between action points; \"none\" disables it. (one of: none, pointer)",
592
605
  "flags": {
593
606
  "duration": "string",
594
607
  "position": "string",
@@ -671,11 +684,13 @@
671
684
  },
672
685
  "booleanOptions": [
673
686
  "headed",
687
+ "mobile",
674
688
  "persistent",
675
689
  "submit",
676
690
  "boxes",
677
691
  "clear",
678
692
  "full-page",
693
+ "hires",
679
694
  "httpOnly",
680
695
  "secure",
681
696
  "static",
@@ -78,7 +78,7 @@ async function program(options) {
78
78
  } else {
79
79
  const lines = ["playwright-cli - run playwright mcp commands from terminal"];
80
80
  if (process.env.CLAUDECODE || process.env.COPILOT_CLI)
81
- lines.push(`Agent skill: ${import_path.default.relative(process.cwd(), (0, import_package.libPath)("tools", "cli-client", "skill", "SKILL.md"))}`);
81
+ lines.push(`Agent skill: ${import_path.default.relative(process.cwd(), (0, import_package.libPath)("tools", "skills", "playwright-cli", "SKILL.md"))}`);
82
82
  lines.push(help.global);
83
83
  output.help(lines.join("\n\n"));
84
84
  }
@@ -130,6 +130,10 @@ to start the browser session.`);
130
130
  ];
131
131
  if (cliArgs.headed)
132
132
  args.push("--headed");
133
+ if (cliArgs.mobile)
134
+ args.push("--mobile");
135
+ if (cliArgs.device)
136
+ args.push(`--device=${cliArgs.device}`);
133
137
  if (cliArgs.browser)
134
138
  args.push(`--browser=${cliArgs.browser}`);
135
139
  if (cliArgs.persistent)
@@ -47,6 +47,11 @@ playwright-cli upload ./document.pdf
47
47
  playwright-cli check e12
48
48
  playwright-cli uncheck e12
49
49
  playwright-cli snapshot
50
+ # search the snapshot for text or a regexp, returns matching nodes with surrounding context
51
+ playwright-cli find "Sign in"
52
+ playwright-cli find --regex "Sign (in|up)"
53
+ # wrap the regexp in slashes to add flags, e.g. /i for case-insensitive
54
+ playwright-cli find --regex "/sign (in|up)/i"
50
55
  playwright-cli eval "document.title"
51
56
  playwright-cli eval "el => el.textContent" e5
52
57
  # get element id, class, or any attribute not visible in the snapshot
@@ -93,6 +98,7 @@ playwright-cli mousewheel 0 100
93
98
  playwright-cli screenshot
94
99
  playwright-cli screenshot e5
95
100
  playwright-cli screenshot --filename=page.png
101
+ playwright-cli screenshot --hires
96
102
  playwright-cli pdf --filename=page.pdf
97
103
  ```
98
104
 
@@ -209,6 +215,12 @@ playwright-cli open --browser=firefox
209
215
  playwright-cli open --browser=webkit
210
216
  playwright-cli open --browser=msedge
211
217
 
218
+ # Emulate a generic mobile device (Pixel 10 for Chromium, iPhone 17 for WebKit).
219
+ # Prefer this when a mobile layout is acceptable: mobile pages are usually
220
+ # lighter, so snapshots are smaller and cheaper.
221
+ playwright-cli open --mobile
222
+ playwright-cli open --device="iPhone 15"
223
+
212
224
  # Use persistent profile (by default profile is in-memory)
213
225
  playwright-cli open --persistent
214
226
  # Use persistent profile with custom directory
@@ -278,6 +290,11 @@ playwright-cli snapshot e34
278
290
 
279
291
  # include each element's bounding box as [box=x,y,width,height]
280
292
  playwright-cli snapshot --boxes
293
+
294
+ # search a large snapshot instead of capturing it all — returns matching nodes
295
+ # with 3 lines of context around each match (like grep -C)
296
+ playwright-cli find "Add to cart"
297
+ playwright-cli find --regex "\\$[0-9]+\\.[0-9]{2}"
281
298
  ```
282
299
 
283
300
  ## Targeting elements
@@ -325,13 +342,13 @@ playwright-cli kill-all
325
342
 
326
343
  ## Installation
327
344
 
328
- If global `playwright-cli` command is not available, try a local version via `npx playwright-cli`:
345
+ If global `playwright-cli` command is not available, try a local version via `npx playwright cli`:
329
346
 
330
347
  ```bash
331
- npx --no-install playwright-cli --version
348
+ npx --no-install playwright --version
332
349
  ```
333
350
 
334
- When local version is available, use `npx playwright-cli` in all commands. Otherwise, install `playwright-cli` as a global command:
351
+ When local version is available, use `npx playwright cli` in all commands. Otherwise, install `playwright-cli` as a global command:
335
352
 
336
353
  ```bash
337
354
  npm install -g @playwright/cli@latest
@@ -396,9 +413,8 @@ playwright-cli show --annotate
396
413
  * **Request mocking** [references/request-mocking.md](references/request-mocking.md)
397
414
  * **Running Playwright code** [references/running-code.md](references/running-code.md)
398
415
  * **Browser session management** [references/session-management.md](references/session-management.md)
399
- * **Spec-driven testing (plan / generate / heal)** [references/spec-driven-testing.md](references/spec-driven-testing.md)
400
416
  * **Storage state (cookies, localStorage)** [references/storage-state.md](references/storage-state.md)
401
- * **Test generation** [references/test-generation.md](references/test-generation.md)
417
+ * **Test generation (plan / generate / heal)** [references/test-generation.md](references/test-generation.md)
402
418
  * **Tracing** [references/tracing.md](references/tracing.md)
403
419
  * **Video recording** [references/video-recording.md](references/video-recording.md)
404
420
  * **Inspecting element attributes** [references/element-attributes.md](references/element-attributes.md)
@@ -1,12 +1,141 @@
1
- # Spec-driven testing (plan → generate → heal)
1
+ # Test generation (plan → generate → heal)
2
2
 
3
- End-to-end workflow for authoring and maintaining Playwright tests using `playwright-cli`. The three sections below can be used independently:
3
+ End-to-end workflow for authoring and maintaining Playwright tests with `playwright-cli`. Every `playwright-cli` action emits the equivalent Playwright TypeScript, and that generated code is the raw material for every test. The sections below can be used independently:
4
4
 
5
- - **Planning** — explore the app, produce a spec file describing what to test.
5
+ - **How generation works** — the core mechanic everything else relies on: actions become TypeScript, plus how to add assertions.
6
+ - **Plan** — explore the app, produce a spec file describing what to test.
6
7
  - **Generate** — turn a spec into Playwright test files. Update the spec if it's vague or stale.
7
8
  - **Heal** — diagnose failing tests, fix the code, reconcile the spec with reality.
8
9
 
9
- All three lean on the same mechanic: run `npx playwright test --debug=cli` in the background, then `playwright-cli attach tw-XXXX` to drive the paused page interactively. See [playwright-tests.md](playwright-tests.md) for the debug/attach mechanics and [test-generation.md](test-generation.md) for how every `playwright-cli` action emits Playwright TypeScript.
10
+ Plan / generate / heal lean on the same mechanic: run `npx playwright test --debug=cli` in the background, then `playwright-cli attach tw-XXXX` to drive the paused page interactively. See [playwright-tests.md](playwright-tests.md) for the debug/attach mechanics.
11
+
12
+ ---
13
+
14
+ ## 0. How generation works
15
+
16
+ Every action you perform with `playwright-cli` generates corresponding Playwright TypeScript code. This code appears in the output and can be copied directly into your test files.
17
+
18
+ ```bash
19
+ # Start a session
20
+ playwright-cli open https://example.com/login
21
+
22
+ # Take a snapshot to see elements
23
+ playwright-cli snapshot
24
+ # Output shows: e1 [textbox "Email"], e2 [textbox "Password"], e3 [button "Sign In"]
25
+
26
+ # Fill form fields - generates code automatically
27
+ playwright-cli fill e1 "user@example.com"
28
+ # Ran Playwright code:
29
+ # await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com');
30
+
31
+ playwright-cli fill e2 "password123"
32
+ # Ran Playwright code:
33
+ # await page.getByRole('textbox', { name: 'Password' }).fill('password123');
34
+
35
+ playwright-cli click e3
36
+ # Ran Playwright code:
37
+ # await page.getByRole('button', { name: 'Sign In' }).click();
38
+ ```
39
+
40
+ ### Building a test file
41
+
42
+ Collect the generated code into a Playwright test:
43
+
44
+ ```typescript
45
+ import { test, expect } from '@playwright/test';
46
+
47
+ test('login flow', async ({ page }) => {
48
+ // Generated code from playwright-cli session:
49
+ await page.goto('https://example.com/login');
50
+ await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com');
51
+ await page.getByRole('textbox', { name: 'Password' }).fill('password123');
52
+ await page.getByRole('button', { name: 'Sign In' }).click();
53
+
54
+ // Add assertions
55
+ await expect(page).toHaveURL(/.*dashboard/);
56
+ });
57
+ ```
58
+
59
+ ### Use semantic locators
60
+
61
+ The generated code uses role-based locators when possible, which are more resilient:
62
+
63
+ ```typescript
64
+ // Generated (good - semantic)
65
+ await page.getByRole('button', { name: 'Submit' }).click();
66
+
67
+ // Avoid (fragile - CSS selectors)
68
+ await page.locator('#submit-btn').click();
69
+ ```
70
+
71
+ ### Explore before recording
72
+
73
+ Take snapshots to understand the page structure before recording actions:
74
+
75
+ ```bash
76
+ playwright-cli open https://example.com
77
+ playwright-cli snapshot
78
+ # Review the element structure
79
+ playwright-cli click e5
80
+ ```
81
+
82
+ ### Add assertions manually
83
+
84
+ Generated code captures actions but not assertions. Add expectations in your test using one of the recommended matchers:
85
+
86
+ - `toBeVisible()` — element is rendered and visible
87
+ - `toHaveText(text)` — element text content matches
88
+ - `toHaveValue(value) / toBeEmpty()` — input/select value matches
89
+ - `toBeChecked() / toBeUnchecked()` — checkbox state matches
90
+ - `toMatchAriaSnapshot(snapshot)` — page (or locator) matches a partial accessibility snapshot
91
+
92
+ Use `playwright-cli generate-locator <target>` to produce the locator expression for the assertion, and the snapshot/eval commands to capture the expected value.
93
+
94
+ When asserting text content, make sure that generated locator does not contain text from the element itself. `getByTestId()` or `getByLabel()` usually work well with asserting text. When locator is text-based, prefer `toBeVisible()` instead.
95
+
96
+ Snapshot to be matched does not have to contain all the information - only capture what's necessary for the assertion. You can use regular expressions for unstable values.
97
+
98
+ ```bash
99
+ # Get a stable locator for an element ref to use in the assertion
100
+ playwright-cli --raw generate-locator e5
101
+ # getByRole('button', { name: 'Submit' })
102
+
103
+ # Capture expected text content for toHaveText
104
+ playwright-cli --raw eval "el => el.textContent" e5
105
+
106
+ # Capture expected input value for toHaveValue/toBeEmpty
107
+ playwright-cli --raw eval "el => el.value" e5
108
+
109
+ # Capture expected aria snapshot for toMatchAriaSnapshot/toBeChecked
110
+ # (whole page, or use a ref to scope to a region)
111
+ playwright-cli --raw snapshot
112
+ playwright-cli --raw snapshot e5
113
+ ```
114
+
115
+ ```typescript
116
+ // Generated action
117
+ await page.getByRole('button', { name: 'Submit' }).click();
118
+
119
+ // Manual assertions using the outputs above:
120
+ await expect(page.getByRole('alert', { name: 'Success' })).toBeVisible();
121
+ await expect(page.getByTestId('main-header')).toHaveText('Welcome, user');
122
+ await expect(page.getByRole('textbox', { name: 'Email' })).toHaveValue('user@example.com');
123
+ await expect(page.getByRole('checkbox', { name: 'Enable notifications' })).toBeChecked();
124
+
125
+ // toMatchAriaSnapshot on the whole page, finds a matching region
126
+ await expect(page).toMatchAriaSnapshot(`
127
+ - heading "Welcome, user"
128
+ - link /\\d+ new messages?/
129
+ - button "Sign out"
130
+ `);
131
+
132
+ // toMatchAriaSnapshot scoped to a region
133
+ await expect(page.getByRole('navigation')).toMatchAriaSnapshot(`
134
+ - link "Home"
135
+ - link /\\d+ new messages?/
136
+ - link "Profile"
137
+ `);
138
+ ```
10
139
 
11
140
  ---
12
141
 
@@ -173,7 +302,7 @@ playwright-cli attach tw-XXXX
173
302
 
174
303
  Walk the scenario's `Steps:` one by one with `playwright-cli`, treating the spec as the plan and the live app as the source of truth. If a step is vague ("click the button" — which button?), references an element that no longer exists, or contradicts the app's actual behaviour, use your judgement: update the spec to match what the app really does, then keep going. Editing the spec mid-generation is expected.
175
304
 
176
- Every action prints the equivalent Playwright TypeScript (see [test-generation.md](test-generation.md)):
305
+ Every action prints the equivalent Playwright TypeScript (see [How generation works](#0-how-generation-works)):
177
306
 
178
307
  ```bash
179
308
  playwright-cli snapshot # find refs
@@ -182,7 +311,7 @@ playwright-cli press Enter
182
311
  playwright-cli click e7
183
312
  ```
184
313
 
185
- For each `- expect:` bullet, add an explicit assertion. See [test-generation.md](test-generation.md) for details.
314
+ For each `- expect:` bullet, add an explicit assertion. See [How generation works](#0-how-generation-works) for details.
186
315
 
187
316
  Collect the generated code and write the test file at the path given in the spec:
188
317
 
@@ -300,6 +429,5 @@ Only after the user answers, either update the spec (intentional change) or file
300
429
  | For... | See |
301
430
  |---|---|
302
431
  | `--debug=cli` / attach mechanics | [playwright-tests.md](playwright-tests.md) |
303
- | How `playwright-cli` actions become TS | [test-generation.md](test-generation.md) |
304
432
  | Mocking requests during exploration/generation | [request-mocking.md](request-mocking.md) |
305
433
  | Managing the CLI browser session | [session-management.md](session-management.md) |
@@ -0,0 +1,143 @@
1
+ ---
2
+ name: playwright-component-testing
3
+ description: Set up component testing with Playwright using a story gallery — scaffold stories and a gallery dev page driven by the built-in mount fixture, no dedicated component-testing runtime. Use when asked to test React or Vue components in isolation with Playwright, or to migrate off @playwright/experimental-ct-react / -vue.
4
+ ---
5
+
6
+ # Component Testing with Playwright
7
+
8
+ Test components with regular Playwright e2e tests against a small **story gallery** page hosted by the app's own dev server. No extra test runner, bundler integration or npm packages are required.
9
+
10
+ ## Concept
11
+
12
+ - A **story** is a tiny wrapper component that embeds the component under test in one specific scenario: hard-coded props, mock data, providers, recorded callbacks. Stories live next to the component in `*.story.tsx` (or `.ts`/`.jsx`/`.js`/`.vue`) files; each named export is one story.
13
+ - The **gallery** is a single page you implement to `references/gallery-spec.md`: it exposes `window.mount(params)` / `window.unmount()` that render a story — resolved from your story files (e.g. with `import.meta.glob`) — into `#root`. It is framework-specific and yours to own — there is no template to copy for it.
14
+ - Tests are plain Playwright tests. The built-in **`mount(storyId, props?)` fixture** (from `@playwright/test`) drives the gallery's `window.mount` and returns a `Locator` for the gallery root (`#root`). Scope the queries from there — `component.getByRole('button').click()`, not `component.click()`. Nothing to scaffold for it.
15
+
16
+ Everything the component needs must be set up *inside the story* (it runs in the browser); everything the test asserts must be observable *through the page* (DOM, URL, network). Where the component takes callbacks, the story creates the state, provides the callbacks and records the state into a hidden form for the test to assert on. `mount(id, props)` passes plain serializable `props` to the story.
17
+
18
+ ## Setup workflow
19
+
20
+ 1. **Detect the framework and bundler.** React vs Vue decides the framework notes and example story to follow. Then:
21
+ - **App runs on Vite** (has `vite.config.*`): the gallery is served by the existing dev server at `/playwright/gallery/index.html` — Vite serves any `.html` file under the project root, the app's plugins/aliases/CSS apply automatically, and `vite build` ignores it. No extra server needed.
22
+ - **Anything else** (Next.js, webpack, no dev server): run a small standalone dev server (e.g. Vite) that serves the gallery page, and point `baseURL` at it. Requires `vite` and the framework plugin as devDependencies.
23
+ 2. **Implement the gallery** to `references/gallery-spec.md`: a page at `<project>/playwright/gallery/` that renders the requested story into `#root`. Start from the worked example in the spec and the framework notes in `references/react.md` / `references/vue.md`. Keep story discovery (`import.meta.glob`) and the framework mount here — this is the only framework-specific glue, so keep it small. Import the app's global CSS the same way the app's own entry does.
24
+ 3. **Configure Playwright** — add to `playwright.config.ts`:
25
+
26
+ ```ts
27
+ projects: [
28
+ {
29
+ name: 'components',
30
+ testDir: './tests/components',
31
+ use: { ...devices['Desktop Chrome'], baseURL: 'http://localhost:5173/playwright/gallery/index.html', serviceWorkers: 'block', reuseContext: true },
32
+ },
33
+ ],
34
+ webServer: {
35
+ command: 'npm run dev', // or: npx vite --config playwright/vite.config.ts
36
+ url: 'http://localhost:5173/playwright/gallery/index.html', // standalone server: http://localhost:3100/playwright/gallery/index.html
37
+ reuseExistingServer: !process.env.CI,
38
+ },
39
+ ```
40
+
41
+ Match the port to the dev server. `mount` navigates to `baseURL`, so set `baseURL` to the gallery's URL. `serviceWorkers: 'block'` keeps the app's own service worker from serving cached responses that would shadow your `page.route()` mocks. `reuseContext: true` reuses the browser context across tests in a worker (as the old component-testing runtime did) — a large speedup for component suites. If the config already has projects/webServer, merge instead of replacing.
42
+ 4. **Write a first story** next to an existing component, modeled on `templates/<react|vue>/Button.story.*`.
43
+ 5. **Write a first spec**, modeled on `templates/react/button.spec.ts`, importing `test`/`expect` from `@playwright/test`.
44
+ 6. **Run**: `npx playwright test --project=components`. Open `http://localhost:5173/playwright/gallery/index.html` in a browser to eyeball all stories.
45
+
46
+ ## Conventions
47
+
48
+ - Story id: path under `src/` without the `.story.*` extension, plus the export name — `src/components/Button.story.tsx` export `Primary` → `components/Button/Primary`. Any unique suffix works too: `mount('Button/Primary')`. A `.story.vue` single-file component is one story, addressable by its path alone (its `default` export).
49
+ - One export per scenario. Prefer a new story export over parameterizing an existing one — stories are greppable, reviewable documentation of component states.
50
+
51
+ ## Testing patterns
52
+
53
+ Examples are React; the Vue equivalents differ only in story syntax.
54
+
55
+ ### Callbacks and events
56
+
57
+ **The story owns the state and provides the callbacks.** Where the component takes callbacks, create the state inside the story, wire the callbacks to it, and record the state into a hidden form next to the component. Tests perform operations and assert on the recorded values:
58
+
59
+ ```tsx
60
+ export const Stateful = () => {
61
+ const [expanded, setExpanded] = useState(false);
62
+ return <>
63
+ <Expandable expanded={expanded} setExpanded={setExpanded} title="Title">Details</Expandable>
64
+ <form hidden><input data-testid="expanded" readOnly value={String(expanded)} /></form>
65
+ </>;
66
+ };
67
+ ```
68
+
69
+ ```ts
70
+ test('click should expand', async ({ mount }) => {
71
+ const component = await mount('components/Expandable/Stateful');
72
+ await component.locator('.codicon-chevron-right').click();
73
+ await expect(component.getByTestId('expanded')).toHaveValue('true');
74
+ });
75
+ ```
76
+
77
+ This keeps the whole scenario in the browser: no callback marshalling, the story doubles as documentation, and the recorded state is visible when eyeballing the gallery. Record each observed value in its own `data-testid` input (`String(...)` or `JSON.stringify(...)` for payloads) and assert with `toHaveValue()` — a web-first assertion that retries until the state lands. The negative direction works the same way: perform the operation, then assert the value did **not** change.
78
+
79
+ ### Per-test props
80
+
81
+ When a scenario is genuinely parametric (e.g. a boundary-value sweep), pass props as the second argument to `mount`; the gallery hands them to the story as its props. Keep props to plain serializable data — callbacks belong inside the story.
82
+
83
+ ```tsx
84
+ export const WithTitle = ({ title = 'Default' }: { title?: string }) =>
85
+ <Button title={title} />;
86
+ ```
87
+
88
+ ```ts
89
+ const component = await mount('components/Button/WithTitle', { title: 'Hello' });
90
+ ```
91
+
92
+ `mount` is generic over the story: pass the story type as a template argument to type-check the props (and `update()`):
93
+
94
+ ```ts
95
+ import type { WithTitle } from './Button.story';
96
+
97
+ const component = await mount<typeof WithTitle>('components/Button/WithTitle', { title: 'Hello' });
98
+ ```
99
+
100
+ This works for React and Vue stories alike; Vue stories must additionally declare the props at runtime — see the `Typed props` sections in `references/react.md` / `references/vue.md`.
101
+
102
+ ### Prop transitions with `update()`
103
+
104
+ To test how a component reacts to a prop change **without remounting** (state preserved), call `component.update(newProps)` — it re-renders the same story with new props on the existing root:
105
+
106
+ ```ts
107
+ const component = await mount('components/Counter/Default', { value: 1 });
108
+ await expect(component.getByTestId('value')).toHaveText('1');
109
+ await component.update({ value: 2 });
110
+ await expect(component.getByTestId('value')).toHaveText('2');
111
+ ```
112
+
113
+ This requires the gallery to reuse its root/instance (`references/gallery-spec.md`); state survives as long as the story stays the same.
114
+
115
+ ### Multiple states in one test
116
+
117
+ Each `mount()` navigates fresh, so tests are fully isolated and mounting several stories in one test is cheap:
118
+
119
+ ```ts
120
+ await expect(await mount('Button/Primary')).toHaveScreenshot('primary.png');
121
+ await expect(await mount('Button/Disabled')).toHaveScreenshot('disabled.png');
122
+ ```
123
+
124
+ For visual comparison, screenshot the returned root locator (as above), not the page, to avoid asserting on browser chrome.
125
+
126
+ ### Network mocking
127
+
128
+ Use `page.route()` as usual — register routes before `mount()`, since mounting navigates. `serviceWorkers: 'block'` (set in the config above) keeps the app's own service worker from serving cached responses that shadow the routes. Teams with MSW handler libraries can start the worker inside a story or decorator instead.
129
+
130
+ ### Debugging stories
131
+
132
+ Open your gallery URL (`baseURL`) in a browser and call `await window.mount({ story: 'components/Button/Primary' })` from the devtools console — that is exactly what the `mount` fixture does. An unknown story rejects `window.mount`, which surfaces as the test's `mount()` throwing with a real stack. To browse without the console, give your gallery an optional index page.
133
+
134
+ ## Decision points
135
+
136
+ - **Monorepos / non-`src` layouts**: change the glob and the id derivation in your gallery (`references/gallery-spec.md`) to match.
137
+ - **Global providers** (theme, i18n, store, router): create a shared `decorator` helper next to the gallery and wrap components in stories; see `references/react.md` / `references/vue.md`.
138
+ ## References
139
+
140
+ - `references/gallery-spec.md` — the gallery endpoint contract to implement (**start here**).
141
+ - `references/react.md` — React walkthrough: providers, StrictMode, CSS.
142
+ - `references/vue.md` — Vue walkthrough: `.story.ts` and `.story.vue` stories, plugins.
143
+ - `references/migration.md` — migrating off `@playwright/experimental-ct-react` / `-vue`.