@openclaw/diffs 2026.7.2-beta.7 → 2026.7.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/assets/viewer-runtime.js +31 -31
- package/dist/index.js +307 -290
- package/node_modules/@pierre/diffs/node_modules/@shikijs/core/package.json +3 -3
- package/node_modules/@pierre/diffs/node_modules/@shikijs/engine-javascript/package.json +2 -2
- package/node_modules/@pierre/diffs/node_modules/@shikijs/engine-oniguruma/package.json +2 -2
- package/node_modules/@pierre/diffs/node_modules/@shikijs/primitive/dist/index.mjs +5 -6
- package/node_modules/@pierre/diffs/node_modules/@shikijs/primitive/package.json +2 -2
- package/node_modules/@pierre/diffs/node_modules/@shikijs/themes/package.json +2 -2
- package/node_modules/@pierre/diffs/node_modules/@shikijs/transformers/package.json +3 -3
- package/node_modules/@pierre/diffs/node_modules/@shikijs/types/dist/index.d.mts +1 -9
- package/node_modules/@pierre/diffs/node_modules/@shikijs/types/package.json +1 -1
- package/node_modules/@pierre/diffs/node_modules/@types/hast/README.md +2 -2
- package/node_modules/@pierre/diffs/node_modules/@types/hast/index.d.ts +0 -642
- package/node_modules/@pierre/diffs/node_modules/@types/hast/package.json +3 -9
- package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/cjs/deserialize.js +1 -6
- package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/cjs/serialize.js +2 -2
- package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/esm/deserialize.js +1 -6
- package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/esm/serialize.js +2 -2
- package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/package.json +1 -1
- package/node_modules/@pierre/diffs/node_modules/@ungap/structured-clone/structured-json.js +1 -1
- package/node_modules/@pierre/diffs/node_modules/shiki/package.json +7 -7
- package/node_modules/@shikijs/langs/node_modules/@shikijs/types/dist/index.d.mts +1 -9
- package/node_modules/@shikijs/langs/node_modules/@shikijs/types/package.json +1 -1
- package/node_modules/@shikijs/langs/node_modules/@types/hast/README.md +2 -2
- package/node_modules/@shikijs/langs/node_modules/@types/hast/index.d.ts +0 -642
- package/node_modules/@shikijs/langs/node_modules/@types/hast/package.json +3 -9
- package/node_modules/@shikijs/langs/package.json +2 -2
- package/node_modules/playwright-core/browsers.json +18 -12
- package/node_modules/playwright-core/lib/bootstrap.js +1 -1
- package/node_modules/playwright-core/lib/coreBundle.js +12247 -13691
- package/node_modules/playwright-core/lib/server/deviceDescriptorsSource.json +2739 -0
- package/node_modules/playwright-core/lib/server/electron/loader.js +2 -5
- package/node_modules/playwright-core/lib/serverRegistry.js +1 -5
- package/node_modules/playwright-core/lib/tools/cli-client/help.json +6 -21
- package/node_modules/playwright-core/lib/tools/cli-client/program.js +1 -1
- package/node_modules/playwright-core/lib/tools/cli-client/session.js +0 -4
- package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/SKILL.md +5 -21
- package/node_modules/playwright-core/lib/tools/{skills/playwright-cli/references/test-generation.md → cli-client/skill/references/spec-driven-testing.md} +7 -135
- package/node_modules/playwright-core/lib/tools/cli-client/skill/references/test-generation.md +134 -0
- package/node_modules/playwright-core/lib/tools/utils/extension.js +8 -31
- package/node_modules/playwright-core/lib/utilsBundle.js +48599 -52627
- package/node_modules/playwright-core/lib/utilsBundle.js.LICENSE +268 -391
- package/node_modules/playwright-core/lib/vite/dashboard/assets/index-BY2S1tHT.css +1 -0
- package/node_modules/playwright-core/lib/vite/dashboard/assets/index-C_5TMfeg.js +52 -0
- package/node_modules/playwright-core/lib/vite/dashboard/index.html +2 -2
- package/node_modules/playwright-core/lib/vite/htmlReport/report.css +1 -2
- package/node_modules/playwright-core/lib/vite/htmlReport/report.js +55 -15
- package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DYBRYzYX.css +1 -0
- package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DeBYQozu.js +32 -0
- package/node_modules/playwright-core/lib/vite/recorder/assets/index-4ZiSSCmn.css +1 -0
- package/node_modules/playwright-core/lib/vite/recorder/assets/index-Bq-mQf8S.js +193 -0
- package/node_modules/playwright-core/lib/vite/recorder/index.html +2 -2
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-LEHpjmcn.js +32 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-BNmKHKpQ.js +264 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-BYQrIQwR.js +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +9 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.DYBRYzYX.css +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.CjdS-WJx.css +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/index.CzXZzn5A.css +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/index.DMMX1gXU.js +2 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/index.html +5 -5
- package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.html +2 -2
- package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.v8KI4P3m.js +2 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/sw.bundle.js +4 -3
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.BZQ54Kgt.css +1 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.Ut8wwJNp.js +6 -0
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +5 -5
- package/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.DYP7pi_n.css +32 -0
- package/node_modules/playwright-core/lib/xdg-open +137 -338
- package/node_modules/playwright-core/package.json +2 -2
- package/node_modules/playwright-core/types/protocol.d.ts +36 -249
- package/node_modules/playwright-core/types/structs.d.ts +1 -3
- package/node_modules/playwright-core/types/types.d.ts +268 -2011
- package/node_modules/typebox/build/compile/validator.d.mts +4 -1
- package/node_modules/typebox/build/guard/guard.d.mts +1 -1
- package/node_modules/typebox/build/guard/guard.mjs +2 -5
- package/node_modules/typebox/build/guard/string.mjs +4 -16
- package/node_modules/typebox/build/schema/engine/_functions.mjs +15 -34
- package/node_modules/typebox/build/type/action/readonly_object.d.mts +0 -5
- package/node_modules/typebox/build/type/action/readonly_object.mjs +0 -8
- package/node_modules/typebox/build/typebox.d.mts +1 -1
- package/node_modules/typebox/build/typebox.mjs +1 -1
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/typebox/readme.md +32 -29
- package/openclaw.plugin.json +0 -1
- package/package.json +7 -7
- package/skills/diffs/SKILL.md +2 -2
- package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/SKILL.md +0 -143
- package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +0 -144
- package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/migration.md +0 -85
- package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/react.md +0 -67
- package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/vue.md +0 -75
- package/node_modules/playwright-core/lib/vite/dashboard/assets/index-CyWAfh-p.js +0 -11
- package/node_modules/playwright-core/lib/vite/dashboard/assets/index-DhC616m4.css +0 -1
- package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +0 -1
- package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-CwYYHbcZ.js +0 -32
- package/node_modules/playwright-core/lib/vite/recorder/assets/index-DYjdXIbE.js +0 -129
- package/node_modules/playwright-core/lib/vite/recorder/assets/index-l_lX622x.css +0 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-By56iMx7.js +0 -32
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-B34OrIms.js +0 -181
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +0 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-COQkjINf.js +0 -7
- package/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +0 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.BLFoOugd.css +0 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/index.B_TqY17P.css +0 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/index.Dl36UVQT.js +0 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +0 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.C7UW1sC9.css +0 -1
- package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.D962mr9b.js +0 -5
- package/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +0 -1
- package/node_modules/playwright-core/lib/webp_codec.LICENSE +0 -173
- package/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
- /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/element-attributes.md +0 -0
- /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/playwright-tests.md +0 -0
- /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/request-mocking.md +0 -0
- /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/running-code.md +0 -0
- /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/session-management.md +0 -0
- /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/storage-state.md +0 -0
- /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/tracing.md +0 -0
- /package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/references/video-recording.md +0 -0
- /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
|
-
|
|
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
|
|
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 --
|
|
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
|
|
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
|
-
"
|
|
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
|
|
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
|
|
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", "
|
|
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)
|
package/node_modules/playwright-core/lib/tools/{skills/playwright-cli → cli-client/skill}/SKILL.md
RENAMED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
#
|
|
1
|
+
# Spec-driven testing (plan → generate → heal)
|
|
2
2
|
|
|
3
|
-
End-to-end workflow for authoring and maintaining Playwright tests
|
|
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
|
-
- **
|
|
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
|
-
|
|
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 [
|
|
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 [
|
|
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
|
|
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
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|