@openclaw/diffs 2026.7.2-beta.7 → 2026.7.33

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 (122) hide show
  1. package/README.md +9 -2
  2. package/dist/assets/viewer-runtime.js +31 -31
  3. package/dist/index.js +307 -290
  4. package/node_modules/@pierre/diffs/node_modules/@shikijs/core/package.json +3 -3
  5. package/node_modules/@pierre/diffs/node_modules/@shikijs/engine-javascript/package.json +2 -2
  6. package/node_modules/@pierre/diffs/node_modules/@shikijs/engine-oniguruma/package.json +2 -2
  7. package/node_modules/@pierre/diffs/node_modules/@shikijs/primitive/dist/index.mjs +5 -6
  8. package/node_modules/@pierre/diffs/node_modules/@shikijs/primitive/package.json +2 -2
  9. package/node_modules/@pierre/diffs/node_modules/@shikijs/themes/package.json +2 -2
  10. package/node_modules/@pierre/diffs/node_modules/@shikijs/transformers/package.json +3 -3
  11. package/node_modules/@pierre/diffs/node_modules/@shikijs/types/dist/index.d.mts +1 -9
  12. package/node_modules/@pierre/diffs/node_modules/@shikijs/types/package.json +1 -1
  13. package/node_modules/@pierre/diffs/node_modules/@types/hast/README.md +2 -2
  14. package/node_modules/@pierre/diffs/node_modules/@types/hast/index.d.ts +0 -642
  15. package/node_modules/@pierre/diffs/node_modules/@types/hast/package.json +3 -9
  16. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/cjs/deserialize.js +1 -6
  17. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/cjs/serialize.js +2 -2
  18. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/esm/deserialize.js +1 -6
  19. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/esm/serialize.js +2 -2
  20. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/package.json +1 -1
  21. package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/structured-json.js +1 -1
  22. package/node_modules/@pierre/diffs/node_modules/shiki/package.json +7 -7
  23. package/node_modules/@shikijs/langs/node_modules/@shikijs/types/dist/index.d.mts +1 -9
  24. package/node_modules/@shikijs/langs/node_modules/@shikijs/types/package.json +1 -1
  25. package/node_modules/@shikijs/langs/node_modules/@types/hast/README.md +2 -2
  26. package/node_modules/@shikijs/langs/node_modules/@types/hast/index.d.ts +0 -642
  27. package/node_modules/@shikijs/langs/node_modules/@types/hast/package.json +3 -9
  28. package/node_modules/@shikijs/langs/package.json +2 -2
  29. package/node_modules/playwright-core/browsers.json +18 -12
  30. package/node_modules/playwright-core/lib/bootstrap.js +1 -1
  31. package/node_modules/playwright-core/lib/coreBundle.js +12247 -13691
  32. package/node_modules/playwright-core/lib/server/deviceDescriptorsSource.json +2739 -0
  33. package/node_modules/playwright-core/lib/server/electron/loader.js +2 -5
  34. package/node_modules/playwright-core/lib/serverRegistry.js +1 -5
  35. package/node_modules/playwright-core/lib/tools/cli-client/help.json +6 -21
  36. package/node_modules/playwright-core/lib/tools/cli-client/program.js +1 -1
  37. package/node_modules/playwright-core/lib/tools/cli-client/session.js +0 -4
  38. package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/SKILL.md +5 -21
  39. package/node_modules/playwright-core/lib/tools/{skills/playwright-cli/references/test-generation.md → cli-client/skill/references/spec-driven-testing.md} +7 -135
  40. package/node_modules/playwright-core/lib/tools/cli-client/skill/references/test-generation.md +134 -0
  41. package/node_modules/playwright-core/lib/tools/utils/extension.js +8 -31
  42. package/node_modules/playwright-core/lib/utilsBundle.js +48599 -52627
  43. package/node_modules/playwright-core/lib/utilsBundle.js.LICENSE +268 -391
  44. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-BY2S1tHT.css +1 -0
  45. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-C_5TMfeg.js +52 -0
  46. package/node_modules/playwright-core/lib/vite/dashboard/index.html +2 -2
  47. package/node_modules/playwright-core/lib/vite/htmlReport/report.css +1 -2
  48. package/node_modules/playwright-core/lib/vite/htmlReport/report.js +55 -15
  49. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DYBRYzYX.css +1 -0
  50. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DeBYQozu.js +32 -0
  51. package/node_modules/playwright-core/lib/vite/recorder/assets/index-4ZiSSCmn.css +1 -0
  52. package/node_modules/playwright-core/lib/vite/recorder/assets/index-Bq-mQf8S.js +193 -0
  53. package/node_modules/playwright-core/lib/vite/recorder/index.html +2 -2
  54. package/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-LEHpjmcn.js +32 -0
  55. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-BNmKHKpQ.js +264 -0
  56. package/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-BYQrIQwR.js +1 -0
  57. package/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +9 -0
  58. package/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.DYBRYzYX.css +1 -0
  59. package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.CjdS-WJx.css +1 -0
  60. package/node_modules/playwright-core/lib/vite/traceViewer/index.CzXZzn5A.css +1 -0
  61. package/node_modules/playwright-core/lib/vite/traceViewer/index.DMMX1gXU.js +2 -0
  62. package/node_modules/playwright-core/lib/vite/traceViewer/index.html +5 -5
  63. package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.html +2 -2
  64. package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.v8KI4P3m.js +2 -0
  65. package/node_modules/playwright-core/lib/vite/traceViewer/sw.bundle.js +4 -3
  66. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.BZQ54Kgt.css +1 -0
  67. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.Ut8wwJNp.js +6 -0
  68. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +5 -5
  69. package/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.DYP7pi_n.css +32 -0
  70. package/node_modules/playwright-core/lib/xdg-open +137 -338
  71. package/node_modules/playwright-core/package.json +2 -2
  72. package/node_modules/playwright-core/types/protocol.d.ts +36 -249
  73. package/node_modules/playwright-core/types/structs.d.ts +1 -3
  74. package/node_modules/playwright-core/types/types.d.ts +268 -2011
  75. package/node_modules/typebox/build/compile/validator.d.mts +4 -1
  76. package/node_modules/typebox/build/guard/guard.d.mts +1 -1
  77. package/node_modules/typebox/build/guard/guard.mjs +2 -5
  78. package/node_modules/typebox/build/guard/string.mjs +4 -16
  79. package/node_modules/typebox/build/schema/engine/_functions.mjs +15 -34
  80. package/node_modules/typebox/build/type/action/readonly_object.d.mts +0 -5
  81. package/node_modules/typebox/build/type/action/readonly_object.mjs +0 -8
  82. package/node_modules/typebox/build/typebox.d.mts +1 -1
  83. package/node_modules/typebox/build/typebox.mjs +1 -1
  84. package/node_modules/typebox/package.json +1 -1
  85. package/node_modules/typebox/readme.md +32 -29
  86. package/openclaw.plugin.json +0 -1
  87. package/package.json +7 -7
  88. package/skills/diffs/SKILL.md +2 -2
  89. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/SKILL.md +0 -143
  90. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +0 -144
  91. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/migration.md +0 -85
  92. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/react.md +0 -67
  93. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/vue.md +0 -75
  94. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-CyWAfh-p.js +0 -11
  95. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-DhC616m4.css +0 -1
  96. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +0 -1
  97. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-CwYYHbcZ.js +0 -32
  98. package/node_modules/playwright-core/lib/vite/recorder/assets/index-DYjdXIbE.js +0 -129
  99. package/node_modules/playwright-core/lib/vite/recorder/assets/index-l_lX622x.css +0 -1
  100. package/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-By56iMx7.js +0 -32
  101. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-B34OrIms.js +0 -181
  102. package/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +0 -1
  103. package/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-COQkjINf.js +0 -7
  104. package/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +0 -1
  105. package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.BLFoOugd.css +0 -1
  106. package/node_modules/playwright-core/lib/vite/traceViewer/index.B_TqY17P.css +0 -1
  107. package/node_modules/playwright-core/lib/vite/traceViewer/index.Dl36UVQT.js +0 -1
  108. package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +0 -1
  109. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.C7UW1sC9.css +0 -1
  110. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.D962mr9b.js +0 -5
  111. package/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +0 -1
  112. package/node_modules/playwright-core/lib/webp_codec.LICENSE +0 -173
  113. package/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
  114. /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/element-attributes.md +0 -0
  115. /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/playwright-tests.md +0 -0
  116. /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/request-mocking.md +0 -0
  117. /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/running-code.md +0 -0
  118. /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/session-management.md +0 -0
  119. /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/storage-state.md +0 -0
  120. /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/tracing.md +0 -0
  121. /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/video-recording.md +0 -0
  122. /package/node_modules/playwright-core/lib/tools/{skills/playwright-trace → trace}/SKILL.md +0 -0
@@ -23,13 +23,12 @@ 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",
29
26
  // See https://github.com/microsoft/playwright/issues/16126
30
27
  "Translate",
31
28
  // See https://issues.chromium.org/u/1/issues/435410220
32
29
  "AutoDeElevate",
30
+ // See https://github.com/microsoft/playwright/issues/37714
31
+ "RenderDocument",
33
32
  // Prevents downloading optimization hints on startup.
34
33
  "OptimizationHints",
35
34
  // Disables forced sign-in in Edge.
@@ -64,8 +63,6 @@ var chromiumSwitches = (options) => [
64
63
  "--disable-popup-blocking",
65
64
  "--disable-prompt-on-repost",
66
65
  "--disable-renderer-backgrounding",
67
- "--disable-updater-scheduler",
68
- // Prevents Edge-specific updater from being launched when Edge is launched on mac.
69
66
  "--force-color-profile=srgb",
70
67
  "--metrics-recording-only",
71
68
  "--no-first-run",
@@ -6,11 +6,7 @@ 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
- try {
10
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
- } catch (e) {
12
- throw mod = 0, e;
13
- }
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
14
10
  };
15
11
  var __export = (target, all) => {
16
12
  for (var name in all)
@@ -1,14 +1,12 @@
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 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",
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",
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 --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.",
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.",
6
6
  "flags": {
7
7
  "browser": "string",
8
8
  "config": "string",
9
- "device": "string",
10
9
  "headed": "boolean",
11
- "mobile": "boolean",
12
10
  "persistent": "boolean",
13
11
  "profile": "string"
14
12
  },
@@ -150,15 +148,6 @@
150
148
  "target"
151
149
  ]
152
150
  },
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
- },
162
151
  "eval": {
163
152
  "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.",
164
153
  "flags": {
@@ -279,12 +268,10 @@
279
268
  ]
280
269
  },
281
270
  "screenshot": {
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.",
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.",
283
272
  "flags": {
284
273
  "filename": "string",
285
- "type": "string",
286
- "full-page": "boolean",
287
- "hires": "boolean"
274
+ "full-page": "boolean"
288
275
  },
289
276
  "args": [
290
277
  "target"
@@ -355,7 +342,7 @@
355
342
  "raw": true
356
343
  },
357
344
  "cookie-set": {
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)",
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",
359
346
  "flags": {
360
347
  "domain": "string",
361
348
  "path": "string",
@@ -601,7 +588,7 @@
601
588
  ]
602
589
  },
603
590
  "video-show-actions": {
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)",
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.",
605
592
  "flags": {
606
593
  "duration": "string",
607
594
  "position": "string",
@@ -684,13 +671,11 @@
684
671
  },
685
672
  "booleanOptions": [
686
673
  "headed",
687
- "mobile",
688
674
  "persistent",
689
675
  "submit",
690
676
  "boxes",
691
677
  "clear",
692
678
  "full-page",
693
- "hires",
694
679
  "httpOnly",
695
680
  "secure",
696
681
  "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", "skills", "playwright-cli", "SKILL.md"))}`);
81
+ lines.push(`Agent skill: ${import_path.default.relative(process.cwd(), (0, import_package.libPath)("tools", "cli-client", "skill", "SKILL.md"))}`);
82
82
  lines.push(help.global);
83
83
  output.help(lines.join("\n\n"));
84
84
  }
@@ -130,10 +130,6 @@ 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}`);
137
133
  if (cliArgs.browser)
138
134
  args.push(`--browser=${cliArgs.browser}`);
139
135
  if (cliArgs.persistent)
@@ -47,11 +47,6 @@ 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"
55
50
  playwright-cli eval "document.title"
56
51
  playwright-cli eval "el => el.textContent" e5
57
52
  # get element id, class, or any attribute not visible in the snapshot
@@ -98,7 +93,6 @@ playwright-cli mousewheel 0 100
98
93
  playwright-cli screenshot
99
94
  playwright-cli screenshot e5
100
95
  playwright-cli screenshot --filename=page.png
101
- playwright-cli screenshot --hires
102
96
  playwright-cli pdf --filename=page.pdf
103
97
  ```
104
98
 
@@ -215,12 +209,6 @@ playwright-cli open --browser=firefox
215
209
  playwright-cli open --browser=webkit
216
210
  playwright-cli open --browser=msedge
217
211
 
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
-
224
212
  # Use persistent profile (by default profile is in-memory)
225
213
  playwright-cli open --persistent
226
214
  # Use persistent profile with custom directory
@@ -290,11 +278,6 @@ playwright-cli snapshot e34
290
278
 
291
279
  # include each element's bounding box as [box=x,y,width,height]
292
280
  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}"
298
281
  ```
299
282
 
300
283
  ## Targeting elements
@@ -342,13 +325,13 @@ playwright-cli kill-all
342
325
 
343
326
  ## Installation
344
327
 
345
- If global `playwright-cli` command is not available, try a local version via `npx playwright cli`:
328
+ If global `playwright-cli` command is not available, try a local version via `npx playwright-cli`:
346
329
 
347
330
  ```bash
348
- npx --no-install playwright --version
331
+ npx --no-install playwright-cli --version
349
332
  ```
350
333
 
351
- When local version is available, use `npx playwright cli` in all commands. Otherwise, install `playwright-cli` as a global command:
334
+ When local version is available, use `npx playwright-cli` in all commands. Otherwise, install `playwright-cli` as a global command:
352
335
 
353
336
  ```bash
354
337
  npm install -g @playwright/cli@latest
@@ -413,8 +396,9 @@ playwright-cli show --annotate
413
396
  * **Request mocking** [references/request-mocking.md](references/request-mocking.md)
414
397
  * **Running Playwright code** [references/running-code.md](references/running-code.md)
415
398
  * **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)
416
400
  * **Storage state (cookies, localStorage)** [references/storage-state.md](references/storage-state.md)
417
- * **Test generation (plan / generate / heal)** [references/test-generation.md](references/test-generation.md)
401
+ * **Test generation** [references/test-generation.md](references/test-generation.md)
418
402
  * **Tracing** [references/tracing.md](references/tracing.md)
419
403
  * **Video recording** [references/video-recording.md](references/video-recording.md)
420
404
  * **Inspecting element attributes** [references/element-attributes.md](references/element-attributes.md)
@@ -1,141 +1,12 @@
1
- # Test generation (plan → generate → heal)
1
+ # Spec-driven testing (plan → generate → heal)
2
2
 
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:
3
+ End-to-end workflow for authoring and maintaining Playwright tests using `playwright-cli`. The three sections below can be used independently:
4
4
 
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.
5
+ - **Planning** — explore the app, produce a spec file describing what to test.
7
6
  - **Generate** — turn a spec into Playwright test files. Update the spec if it's vague or stale.
8
7
  - **Heal** — diagnose failing tests, fix the code, reconcile the spec with reality.
9
8
 
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
- ```
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.
139
10
 
140
11
  ---
141
12
 
@@ -302,7 +173,7 @@ playwright-cli attach tw-XXXX
302
173
 
303
174
  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.
304
175
 
305
- Every action prints the equivalent Playwright TypeScript (see [How generation works](#0-how-generation-works)):
176
+ Every action prints the equivalent Playwright TypeScript (see [test-generation.md](test-generation.md)):
306
177
 
307
178
  ```bash
308
179
  playwright-cli snapshot # find refs
@@ -311,7 +182,7 @@ playwright-cli press Enter
311
182
  playwright-cli click e7
312
183
  ```
313
184
 
314
- For each `- expect:` bullet, add an explicit assertion. See [How generation works](#0-how-generation-works) for details.
185
+ For each `- expect:` bullet, add an explicit assertion. See [test-generation.md](test-generation.md) for details.
315
186
 
316
187
  Collect the generated code and write the test file at the path given in the spec:
317
188
 
@@ -429,5 +300,6 @@ Only after the user answers, either update the spec (intentional change) or file
429
300
  | For... | See |
430
301
  |---|---|
431
302
  | `--debug=cli` / attach mechanics | [playwright-tests.md](playwright-tests.md) |
303
+ | How `playwright-cli` actions become TS | [test-generation.md](test-generation.md) |
432
304
  | Mocking requests during exploration/generation | [request-mocking.md](request-mocking.md) |
433
305
  | Managing the CLI browser session | [session-management.md](session-management.md) |
@@ -0,0 +1,134 @@
1
+ # Test Generation
2
+
3
+ Generate Playwright test code automatically as you interact with the browser.
4
+
5
+ ## How It Works
6
+
7
+ Every action you perform with `playwright-cli` generates corresponding Playwright TypeScript code.
8
+ This code appears in the output and can be copied directly into your test files.
9
+
10
+ ## Example Workflow
11
+
12
+ ```bash
13
+ # Start a session
14
+ playwright-cli open https://example.com/login
15
+
16
+ # Take a snapshot to see elements
17
+ playwright-cli snapshot
18
+ # Output shows: e1 [textbox "Email"], e2 [textbox "Password"], e3 [button "Sign In"]
19
+
20
+ # Fill form fields - generates code automatically
21
+ playwright-cli fill e1 "user@example.com"
22
+ # Ran Playwright code:
23
+ # await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com');
24
+
25
+ playwright-cli fill e2 "password123"
26
+ # Ran Playwright code:
27
+ # await page.getByRole('textbox', { name: 'Password' }).fill('password123');
28
+
29
+ playwright-cli click e3
30
+ # Ran Playwright code:
31
+ # await page.getByRole('button', { name: 'Sign In' }).click();
32
+ ```
33
+
34
+ ## Building a Test File
35
+
36
+ Collect the generated code into a Playwright test:
37
+
38
+ ```typescript
39
+ import { test, expect } from '@playwright/test';
40
+
41
+ test('login flow', async ({ page }) => {
42
+ // Generated code from playwright-cli session:
43
+ await page.goto('https://example.com/login');
44
+ await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com');
45
+ await page.getByRole('textbox', { name: 'Password' }).fill('password123');
46
+ await page.getByRole('button', { name: 'Sign In' }).click();
47
+
48
+ // Add assertions
49
+ await expect(page).toHaveURL(/.*dashboard/);
50
+ });
51
+ ```
52
+
53
+ ## Best Practices
54
+
55
+ ### 1. Use Semantic Locators
56
+
57
+ The generated code uses role-based locators when possible, which are more resilient:
58
+
59
+ ```typescript
60
+ // Generated (good - semantic)
61
+ await page.getByRole('button', { name: 'Submit' }).click();
62
+
63
+ // Avoid (fragile - CSS selectors)
64
+ await page.locator('#submit-btn').click();
65
+ ```
66
+
67
+ ### 2. Explore Before Recording
68
+
69
+ Take snapshots to understand the page structure before recording actions:
70
+
71
+ ```bash
72
+ playwright-cli open https://example.com
73
+ playwright-cli snapshot
74
+ # Review the element structure
75
+ playwright-cli click e5
76
+ ```
77
+
78
+ ### 3. Add Assertions Manually
79
+
80
+ Generated code captures actions but not assertions. Add expectations in your test using one of the recommended matchers:
81
+
82
+ - `toBeVisible()` — element is rendered and visible
83
+ - `toHaveText(text)` — element text content matches
84
+ - `toHaveValue(value) / toBeEmpty()` — input/select value matches
85
+ - `toBeChecked() / toBeUnchecked()` — checkbox state matches
86
+ - `toMatchAriaSnapshot(snapshot)` — page (or locator) matches a partial accessibility snapshot
87
+
88
+ Use `playwright-cli generate-locator <target>` to produce the locator expression for the assertion, and the snapshot/eval commands to capture the expected value.
89
+
90
+ 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.
91
+
92
+ 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.
93
+
94
+ ```bash
95
+ # Get a stable locator for an element ref to use in the assertion
96
+ playwright-cli --raw generate-locator e5
97
+ # getByRole('button', { name: 'Submit' })
98
+
99
+ # Capture expected text content for toHaveText
100
+ playwright-cli --raw eval "el => el.textContent" e5
101
+
102
+ # Capture expected input value for toHaveValue/toBeEmpty
103
+ playwright-cli --raw eval "el => el.value" e5
104
+
105
+ # Capture expected aria snapshot for toMatchAriaSnapshot/toBeChecked
106
+ # (whole page, or use a ref to scope to a region)
107
+ playwright-cli --raw snapshot
108
+ playwright-cli --raw snapshot e5
109
+ ```
110
+
111
+ ```typescript
112
+ // Generated action
113
+ await page.getByRole('button', { name: 'Submit' }).click();
114
+
115
+ // Manual assertions using the outputs above:
116
+ await expect(page.getByRole('alert', { name: 'Success' })).toBeVisible();
117
+ await expect(page.getByTestId('main-header')).toHaveText('Welcome, user');
118
+ await expect(page.getByRole('textbox', { name: 'Email' })).toHaveValue('user@example.com');
119
+ await expect(page.getByRole('checkbox', { name: 'Enable notifications' })).toBeChecked();
120
+
121
+ // toMatchAriaSnapshot on the whole page, finds a matching region
122
+ await expect(page).toMatchAriaSnapshot(`
123
+ - heading "Welcome, user"
124
+ - link /\\d+ new messages?/
125
+ - button "Sign out"
126
+ `);
127
+
128
+ // toMatchAriaSnapshot scoped to a region
129
+ await expect(page.getByRole('navigation')).toMatchAriaSnapshot(`
130
+ - link "Home"
131
+ - link /\\d+ new messages?/
132
+ - link "Profile"
133
+ `);
134
+ ```
@@ -28,7 +28,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var extension_exports = {};
30
30
  __export(extension_exports, {
31
- findPlaywrightExtensionProfile: () => findPlaywrightExtensionProfile,
32
31
  isPlaywrightExtensionInstalled: () => isPlaywrightExtensionInstalled,
33
32
  playwrightExtensionId: () => playwrightExtensionId,
34
33
  playwrightExtensionInstallUrl: () => playwrightExtensionInstallUrl
@@ -38,41 +37,20 @@ var import_fs = __toESM(require("fs"));
38
37
  var import_path = __toESM(require("path"));
39
38
  const playwrightExtensionId = "mmlmfjhmonkocbjadbfplnigmagldckm";
40
39
  const playwrightExtensionInstallUrl = `https://chromewebstore.google.com/detail/playwright-extension/${playwrightExtensionId}`;
41
- async function findPlaywrightExtensionProfile(userDataDir) {
42
- const profiles = await listProfileDirectories(userDataDir);
43
- const lastUsed = await readLastUsedProfile(userDataDir);
44
- const ordered = lastUsed && profiles.includes(lastUsed) ? [lastUsed, ...profiles.filter((profile) => profile !== lastUsed)] : profiles;
45
- for (const profile of ordered) {
46
- if (await isExtensionInstalledInProfile(import_path.default.join(userDataDir, profile)))
47
- return profile;
48
- }
49
- return void 0;
50
- }
51
- async function listProfileDirectories(userDataDir) {
40
+ async function isPlaywrightExtensionInstalled(userDataDir) {
52
41
  let entries;
53
42
  try {
54
43
  entries = await import_fs.default.promises.readdir(userDataDir);
55
44
  } catch {
56
- return [];
45
+ return false;
57
46
  }
58
- const profiles = entries.filter((entry) => entry === "Default" || /^Profile \d+$/.test(entry));
59
- profiles.sort((a, b) => profileRank(a) - profileRank(b));
60
- return profiles;
61
- }
62
- function profileRank(profile) {
63
- return profile === "Default" ? -1 : parseInt(profile.slice("Profile ".length), 10);
64
- }
65
- async function readLastUsedProfile(userDataDir) {
66
- try {
67
- const localState = JSON.parse(await import_fs.default.promises.readFile(import_path.default.join(userDataDir, "Local State"), "utf-8"));
68
- const lastUsed = localState?.profile?.last_used;
69
- return typeof lastUsed === "string" ? lastUsed : void 0;
70
- } catch {
71
- return void 0;
47
+ for (const entry of entries) {
48
+ if (entry !== "Default" && !entry.startsWith("Profile "))
49
+ continue;
50
+ if (await isExtensionInstalledInProfile(import_path.default.join(userDataDir, entry)))
51
+ return true;
72
52
  }
73
- }
74
- async function isPlaywrightExtensionInstalled(userDataDir) {
75
- return await findPlaywrightExtensionProfile(userDataDir) !== void 0;
53
+ return false;
76
54
  }
77
55
  async function isExtensionInstalledInProfile(profileDir) {
78
56
  if (await pathExists(import_path.default.join(profileDir, "Extensions", playwrightExtensionId)))
@@ -94,7 +72,6 @@ async function pathExists(p) {
94
72
  }
95
73
  // Annotate the CommonJS export names for ESM import in node:
96
74
  0 && (module.exports = {
97
- findPlaywrightExtensionProfile,
98
75
  isPlaywrightExtensionInstalled,
99
76
  playwrightExtensionId,
100
77
  playwrightExtensionInstallUrl