@liqngliz/browser-coding-agent 0.0.0-stage → 0.1.3

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 (133) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +46 -2
  3. package/app/.playwright/package/LICENSE +202 -0
  4. package/app/.playwright/package/NOTICE +5 -0
  5. package/app/.playwright/package/README.md +3 -0
  6. package/app/.playwright/package/ThirdPartyNotices.txt +13 -0
  7. package/app/.playwright/package/bin/install_media_pack.ps1 +5 -0
  8. package/app/.playwright/package/bin/install_webkit_wsl.ps1 +33 -0
  9. package/app/.playwright/package/bin/reinstall_chrome_beta_linux.sh +42 -0
  10. package/app/.playwright/package/bin/reinstall_chrome_beta_mac.sh +13 -0
  11. package/app/.playwright/package/bin/reinstall_chrome_beta_win.ps1 +24 -0
  12. package/app/.playwright/package/bin/reinstall_chrome_stable_linux.sh +42 -0
  13. package/app/.playwright/package/bin/reinstall_chrome_stable_mac.sh +12 -0
  14. package/app/.playwright/package/bin/reinstall_chrome_stable_win.ps1 +24 -0
  15. package/app/.playwright/package/bin/reinstall_msedge_beta_linux.sh +48 -0
  16. package/app/.playwright/package/bin/reinstall_msedge_beta_mac.sh +11 -0
  17. package/app/.playwright/package/bin/reinstall_msedge_beta_win.ps1 +23 -0
  18. package/app/.playwright/package/bin/reinstall_msedge_dev_linux.sh +48 -0
  19. package/app/.playwright/package/bin/reinstall_msedge_dev_mac.sh +11 -0
  20. package/app/.playwright/package/bin/reinstall_msedge_dev_win.ps1 +23 -0
  21. package/app/.playwright/package/bin/reinstall_msedge_stable_linux.sh +48 -0
  22. package/app/.playwright/package/bin/reinstall_msedge_stable_mac.sh +11 -0
  23. package/app/.playwright/package/bin/reinstall_msedge_stable_win.ps1 +24 -0
  24. package/app/.playwright/package/browsers.json +52 -0
  25. package/app/.playwright/package/cli.js +21 -0
  26. package/app/.playwright/package/index.d.ts +17 -0
  27. package/app/.playwright/package/index.js +17 -0
  28. package/app/.playwright/package/index.mjs +28 -0
  29. package/app/.playwright/package/lib/bootstrap.js +88 -0
  30. package/app/.playwright/package/lib/coreBundle.js +75813 -0
  31. package/app/.playwright/package/lib/entry/cliDaemon.js +5 -0
  32. package/app/.playwright/package/lib/entry/dashboardApp.js +3 -0
  33. package/app/.playwright/package/lib/entry/mcp.js +10 -0
  34. package/app/.playwright/package/lib/entry/oopBrowserDownload.js +3 -0
  35. package/app/.playwright/package/lib/package.js +50 -0
  36. package/app/.playwright/package/lib/server/chromium/appIcon.png +0 -0
  37. package/app/.playwright/package/lib/server/electron/loader.js +116 -0
  38. package/app/.playwright/package/lib/serverRegistry.js +1939 -0
  39. package/app/.playwright/package/lib/serverRegistry.js.LICENSE +65 -0
  40. package/app/.playwright/package/lib/tools/cli-client/channelSessions.js +141 -0
  41. package/app/.playwright/package/lib/tools/cli-client/cli.js +6 -0
  42. package/app/.playwright/package/lib/tools/cli-client/help.json +721 -0
  43. package/app/.playwright/package/lib/tools/cli-client/minimist.js +128 -0
  44. package/app/.playwright/package/lib/tools/cli-client/output.js +351 -0
  45. package/app/.playwright/package/lib/tools/cli-client/program.js +418 -0
  46. package/app/.playwright/package/lib/tools/cli-client/registry.js +180 -0
  47. package/app/.playwright/package/lib/tools/cli-client/session.js +259 -0
  48. package/app/.playwright/package/lib/tools/dashboard/appIcon.png +0 -0
  49. package/app/.playwright/package/lib/tools/skills/playwright-cli/SKILL.md +425 -0
  50. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/element-attributes.md +23 -0
  51. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/playwright-tests.md +39 -0
  52. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/request-mocking.md +87 -0
  53. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/running-code.md +241 -0
  54. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/session-management.md +225 -0
  55. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/storage-state.md +275 -0
  56. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/test-generation.md +433 -0
  57. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/tracing.md +139 -0
  58. package/app/.playwright/package/lib/tools/skills/playwright-cli/references/video-recording.md +143 -0
  59. package/app/.playwright/package/lib/tools/skills/playwright-component-testing/SKILL.md +136 -0
  60. package/app/.playwright/package/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +144 -0
  61. package/app/.playwright/package/lib/tools/skills/playwright-component-testing/references/migration.md +89 -0
  62. package/app/.playwright/package/lib/tools/skills/playwright-component-testing/references/react.md +69 -0
  63. package/app/.playwright/package/lib/tools/skills/playwright-component-testing/references/typing.md +173 -0
  64. package/app/.playwright/package/lib/tools/skills/playwright-component-testing/references/vue.md +77 -0
  65. package/app/.playwright/package/lib/tools/skills/playwright-trace/SKILL.md +174 -0
  66. package/app/.playwright/package/lib/tools/utils/extension.js +112 -0
  67. package/app/.playwright/package/lib/tools/utils/socketConnection.js +108 -0
  68. package/app/.playwright/package/lib/utilsBundle.js +85357 -0
  69. package/app/.playwright/package/lib/utilsBundle.js.LICENSE +1890 -0
  70. package/app/.playwright/package/lib/vite/dashboard/assets/codeMirrorModule--QdMvsKi.css +1 -0
  71. package/app/.playwright/package/lib/vite/dashboard/assets/codeMirrorModule-CQ8RZGBm.js +32 -0
  72. package/app/.playwright/package/lib/vite/dashboard/assets/codicon-DCmgc-ay.ttf +0 -0
  73. package/app/.playwright/package/lib/vite/dashboard/assets/firefox-1bWoP6pv.svg +1 -0
  74. package/app/.playwright/package/lib/vite/dashboard/assets/firefox-beta-k3eOH_eK.svg +1 -0
  75. package/app/.playwright/package/lib/vite/dashboard/assets/firefox-nightly-Cp5nfeDT.svg +1 -0
  76. package/app/.playwright/package/lib/vite/dashboard/assets/index-AwgwcYie.css +1 -0
  77. package/app/.playwright/package/lib/vite/dashboard/assets/index-hRvO4yU2.js +12 -0
  78. package/app/.playwright/package/lib/vite/dashboard/assets/safari-na3_-uQk.svg +1 -0
  79. package/app/.playwright/package/lib/vite/dashboard/index.html +29 -0
  80. package/app/.playwright/package/lib/vite/dashboard/playwright-logo.svg +24 -0
  81. package/app/.playwright/package/lib/vite/htmlReport/index.html +16 -0
  82. package/app/.playwright/package/lib/vite/htmlReport/report.css +2 -0
  83. package/app/.playwright/package/lib/vite/htmlReport/report.js +32 -0
  84. package/app/.playwright/package/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +1 -0
  85. package/app/.playwright/package/lib/vite/recorder/assets/codeMirrorModule-CVQWJZAA.js +32 -0
  86. package/app/.playwright/package/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
  87. package/app/.playwright/package/lib/vite/recorder/assets/index-BZpYJZ-P.css +1 -0
  88. package/app/.playwright/package/lib/vite/recorder/assets/index-hrlLqLtq.js +129 -0
  89. package/app/.playwright/package/lib/vite/recorder/index.html +29 -0
  90. package/app/.playwright/package/lib/vite/recorder/playwright-logo.svg +9 -0
  91. package/app/.playwright/package/lib/vite/traceViewer/assets/codeMirrorModule-BbkfBe3n.js +32 -0
  92. package/app/.playwright/package/lib/vite/traceViewer/assets/defaultSettingsView-Ds6CBOo0.js +182 -0
  93. package/app/.playwright/package/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +1 -0
  94. package/app/.playwright/package/lib/vite/traceViewer/assets/xtermModule-DywYcAf8.js +7 -0
  95. package/app/.playwright/package/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +1 -0
  96. package/app/.playwright/package/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
  97. package/app/.playwright/package/lib/vite/traceViewer/defaultSettingsView.Bqk9acqE.css +1 -0
  98. package/app/.playwright/package/lib/vite/traceViewer/index.B4cLoZK3.js +1 -0
  99. package/app/.playwright/package/lib/vite/traceViewer/index.B_TqY17P.css +1 -0
  100. package/app/.playwright/package/lib/vite/traceViewer/index.html +44 -0
  101. package/app/.playwright/package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  102. package/app/.playwright/package/lib/vite/traceViewer/playwright-logo.svg +9 -0
  103. package/app/.playwright/package/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +1 -0
  104. package/app/.playwright/package/lib/vite/traceViewer/snapshot.html +10 -0
  105. package/app/.playwright/package/lib/vite/traceViewer/sw.bundle.js +4 -0
  106. package/app/.playwright/package/lib/vite/traceViewer/uiMode.CU5KtEkS.js +5 -0
  107. package/app/.playwright/package/lib/vite/traceViewer/uiMode.CyMfwkXJ.css +1 -0
  108. package/app/.playwright/package/lib/vite/traceViewer/uiMode.html +18 -0
  109. package/app/.playwright/package/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +1 -0
  110. package/app/.playwright/package/lib/webp_codec.LICENSE +173 -0
  111. package/app/.playwright/package/lib/webp_codec.wasm +0 -0
  112. package/app/.playwright/package/lib/xdg-open +1267 -0
  113. package/app/.playwright/package/package.json +34 -0
  114. package/app/.playwright/package/types/protocol.d.ts +24645 -0
  115. package/app/.playwright/package/types/structs.d.ts +52 -0
  116. package/app/.playwright/package/types/types.d.ts +26632 -0
  117. package/app/BrowserCodingAgent.Api.deps.json +109 -0
  118. package/app/BrowserCodingAgent.Api.dll +0 -0
  119. package/app/BrowserCodingAgent.Api.pdb +0 -0
  120. package/app/BrowserCodingAgent.Api.runtimeconfig.json +20 -0
  121. package/app/BrowserCodingAgent.Api.staticwebassets.endpoints.json +1 -0
  122. package/app/Microsoft.AspNetCore.OpenApi.dll +0 -0
  123. package/app/Microsoft.Bcl.AsyncInterfaces.dll +0 -0
  124. package/app/Microsoft.OpenApi.dll +0 -0
  125. package/app/Microsoft.Playwright.dll +0 -0
  126. package/app/Swashbuckle.AspNetCore.SwaggerUI.dll +0 -0
  127. package/app/appsettings.Development.json +8 -0
  128. package/app/appsettings.json +16 -0
  129. package/app/playwright.ps1 +7 -0
  130. package/app/replacements.json +48 -0
  131. package/app/web.config +11 -0
  132. package/browser-coding-agent.cjs +99 -0
  133. package/package.json +34 -4
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var session_exports = {};
30
+ __export(session_exports, {
31
+ Session: () => Session
32
+ });
33
+ module.exports = __toCommonJS(session_exports);
34
+ var import_child_process = require("child_process");
35
+ var import_fs = __toESM(require("fs"));
36
+ var import_net = __toESM(require("net"));
37
+ var import_os = __toESM(require("os"));
38
+ var import_path = __toESM(require("path"));
39
+ var import_package = require("../../package");
40
+ var import_socketConnection = require("../utils/socketConnection");
41
+ var import_registry = require("./registry");
42
+ class Session {
43
+ constructor(sessionFile) {
44
+ this.config = sessionFile.config;
45
+ this.name = this.config.name;
46
+ this._sessionFile = sessionFile;
47
+ }
48
+ isCompatible(clientInfo) {
49
+ return (0, import_socketConnection.compareSemver)(clientInfo.version, this.config.version) >= 0;
50
+ }
51
+ async run(clientInfo, args, options) {
52
+ if (!this.isCompatible(clientInfo))
53
+ throw new Error(`Client is v${clientInfo.version}, session '${this.name}' is v${this.config.version}. Run
54
+
55
+ playwright-cli${this.name !== "default" ? ` -s=${this.name}` : ""} open
56
+
57
+ to restart the browser session.`);
58
+ const { socket } = await this._connect();
59
+ if (!socket)
60
+ throw new Error(`Browser '${this.name}' is not open. Run
61
+
62
+ playwright-cli${this.name !== "default" ? ` -s=${this.name}` : ""} open
63
+
64
+ to start the browser session.`);
65
+ return await SocketConnectionClient.sendAndClose(socket, "run", { args, cwd: process.cwd(), raw: options?.raw, json: options?.json });
66
+ }
67
+ async stop() {
68
+ if (!await this.canConnect())
69
+ return { wasOpen: false };
70
+ await this._stopDaemon();
71
+ return { wasOpen: true };
72
+ }
73
+ async deleteData() {
74
+ await this.stop();
75
+ const dataDirs = await import_fs.default.promises.readdir(this._sessionFile.daemonDir).catch(() => []);
76
+ const matchingEntries = dataDirs.filter((file) => file === `${this.name}.session` || file.startsWith(`ud-${this.name}-`));
77
+ if (matchingEntries.length === 0)
78
+ return { existed: false, deletedUserDataDir: false };
79
+ let deletedUserDataDir = false;
80
+ for (const entry of matchingEntries) {
81
+ const userDataDir = import_path.default.resolve(this._sessionFile.daemonDir, entry);
82
+ for (let i = 0; i < 5; i++) {
83
+ try {
84
+ await import_fs.default.promises.rm(userDataDir, { recursive: true });
85
+ if (entry.startsWith("ud-"))
86
+ deletedUserDataDir = true;
87
+ break;
88
+ } catch (e) {
89
+ if (e.code === "ENOENT")
90
+ break;
91
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
92
+ if (i === 4)
93
+ throw e;
94
+ }
95
+ }
96
+ }
97
+ return { existed: true, deletedUserDataDir };
98
+ }
99
+ async _connect() {
100
+ return await new Promise((resolve) => {
101
+ const socket = import_net.default.createConnection(this.config.socketPath, () => {
102
+ resolve({ socket });
103
+ });
104
+ socket.on("error", (error) => {
105
+ if (import_os.default.platform() !== "win32")
106
+ void import_fs.default.promises.unlink(this.config.socketPath).catch(() => {
107
+ }).then(() => resolve({ error }));
108
+ else
109
+ resolve({ error });
110
+ });
111
+ });
112
+ }
113
+ async canConnect() {
114
+ const { socket } = await this._connect();
115
+ if (socket) {
116
+ socket.destroy();
117
+ return true;
118
+ }
119
+ return false;
120
+ }
121
+ static async startDaemon(clientInfo, cliArgs, mode) {
122
+ await import_fs.default.promises.mkdir(clientInfo.daemonProfilesDir, { recursive: true });
123
+ const cliPath = (0, import_package.libPath)("entry", "cliDaemon.js");
124
+ const sessionName = (0, import_registry.resolveSessionName)(cliArgs.session);
125
+ const errLog = import_path.default.join(clientInfo.daemonProfilesDir, sessionName + ".err");
126
+ const err = import_fs.default.openSync(errLog, "w");
127
+ const args = [
128
+ cliPath,
129
+ sessionName
130
+ ];
131
+ if (cliArgs.headed)
132
+ args.push("--headed");
133
+ if (cliArgs.mobile)
134
+ args.push("--mobile");
135
+ if (cliArgs.device)
136
+ args.push(`--device=${cliArgs.device}`);
137
+ if (cliArgs.browser)
138
+ args.push(`--browser=${cliArgs.browser}`);
139
+ if (cliArgs.persistent)
140
+ args.push("--persistent");
141
+ if (cliArgs.profile)
142
+ args.push(`--profile=${cliArgs.profile}`);
143
+ if (cliArgs.config)
144
+ args.push(`--config=${cliArgs.config}`);
145
+ if (cliArgs.extension)
146
+ args.push("--extension");
147
+ else if (cliArgs.cdp)
148
+ args.push(`--cdp=${cliArgs.cdp}`);
149
+ else if (cliArgs.endpoint)
150
+ args.push(`--endpoint=${cliArgs.endpoint}`);
151
+ const child = (0, import_child_process.spawn)(process.execPath, args, {
152
+ detached: true,
153
+ stdio: ["ignore", "pipe", err],
154
+ cwd: process.cwd(),
155
+ // Will be used as root.
156
+ windowsHide: true
157
+ });
158
+ let signalled = false;
159
+ const sigintHandler = () => {
160
+ signalled = true;
161
+ child.kill("SIGINT");
162
+ };
163
+ const sigtermHandler = () => {
164
+ signalled = true;
165
+ child.kill("SIGTERM");
166
+ };
167
+ process.on("SIGINT", sigintHandler);
168
+ process.on("SIGTERM", sigtermHandler);
169
+ let outLog = "";
170
+ const rejectWithPid = (reject, message) => reject(Object.assign(new Error(`Daemon pid=${child.pid}: ${message}`), { daemonPid: child.pid }));
171
+ await new Promise((resolve, reject) => {
172
+ child.stdout.on("data", (data) => {
173
+ outLog += data.toString();
174
+ if (outLog.includes("Daemon listening on"))
175
+ resolve();
176
+ });
177
+ child.on("close", (code) => {
178
+ if (!signalled) {
179
+ const errLogContent = import_fs.default.readFileSync(errLog, "utf-8");
180
+ rejectWithPid(reject, `Daemon process exited with code ${code}` + (outLog ? "\n" + outLog : "") + (errLogContent ? "\n" + errLogContent : ""));
181
+ }
182
+ });
183
+ });
184
+ process.off("SIGINT", sigintHandler);
185
+ process.off("SIGTERM", sigtermHandler);
186
+ child.stdout.destroy();
187
+ child.unref();
188
+ return { pid: child.pid, sessionName, endpoint: cliArgs.endpoint };
189
+ }
190
+ async _stopDaemon() {
191
+ const { socket } = await this._connect();
192
+ if (!socket)
193
+ return;
194
+ let error;
195
+ await SocketConnectionClient.sendAndClose(socket, "stop", {}).catch((e) => error = e);
196
+ if (error && !error?.message?.includes("Session closed"))
197
+ throw error;
198
+ }
199
+ async deleteSessionConfig() {
200
+ await import_fs.default.promises.rm(this._sessionFile.file).catch(() => {
201
+ });
202
+ }
203
+ }
204
+ class SocketConnectionClient {
205
+ constructor(socket) {
206
+ this._nextMessageId = 1;
207
+ this._callbacks = /* @__PURE__ */ new Map();
208
+ this._connection = new import_socketConnection.SocketConnection(socket);
209
+ this._connection.onmessage = (message) => this._onMessage(message);
210
+ this._connection.onclose = () => this._rejectCallbacks();
211
+ }
212
+ async send(method, params = {}) {
213
+ const messageId = this._nextMessageId++;
214
+ const message = {
215
+ id: messageId,
216
+ method,
217
+ params
218
+ };
219
+ const responsePromise = new Promise((resolve, reject) => {
220
+ this._callbacks.set(messageId, { resolve, reject, method, params });
221
+ });
222
+ const [result] = await Promise.all([responsePromise, this._connection.send(message)]);
223
+ return result;
224
+ }
225
+ static async sendAndClose(socket, method, params = {}) {
226
+ const connection = new SocketConnectionClient(socket);
227
+ try {
228
+ return await connection.send(method, params);
229
+ } finally {
230
+ connection.close();
231
+ }
232
+ }
233
+ close() {
234
+ this._connection.close();
235
+ }
236
+ _onMessage(object) {
237
+ if (object.id && this._callbacks.has(object.id)) {
238
+ const callback = this._callbacks.get(object.id);
239
+ this._callbacks.delete(object.id);
240
+ if (object.error)
241
+ callback.reject(new Error(object.error));
242
+ else
243
+ callback.resolve(object.result);
244
+ } else if (object.id) {
245
+ throw new Error(`Unexpected message id: ${object.id}`);
246
+ } else {
247
+ throw new Error(`Unexpected message without id: ${JSON.stringify(object)}`);
248
+ }
249
+ }
250
+ _rejectCallbacks() {
251
+ for (const callback of this._callbacks.values())
252
+ callback.reject(new Error("Session closed"));
253
+ this._callbacks.clear();
254
+ }
255
+ }
256
+ // Annotate the CommonJS export names for ESM import in node:
257
+ 0 && (module.exports = {
258
+ Session
259
+ });
@@ -0,0 +1,425 @@
1
+ ---
2
+ name: playwright-cli
3
+ description: Automate browser interactions, test web pages and work with Playwright tests.
4
+ allowed-tools: Bash(playwright-cli:*) Bash(npx:*) Bash(npm:*)
5
+ ---
6
+
7
+ # Browser Automation with playwright-cli
8
+
9
+ ## Quick start
10
+
11
+ ```bash
12
+ # open new browser
13
+ playwright-cli open
14
+ # navigate to a page
15
+ playwright-cli goto https://playwright.dev
16
+ # interact with the page using refs from the snapshot
17
+ playwright-cli click e15
18
+ playwright-cli type "page.click"
19
+ playwright-cli press Enter
20
+ # take a screenshot (rarely used, as snapshot is more common)
21
+ playwright-cli screenshot
22
+ # close the browser
23
+ playwright-cli close
24
+ ```
25
+
26
+ ## Commands
27
+
28
+ ### Core
29
+
30
+ ```bash
31
+ playwright-cli open
32
+ # open and navigate right away
33
+ playwright-cli open https://example.com/
34
+ playwright-cli goto https://playwright.dev
35
+ playwright-cli type "search query"
36
+ playwright-cli click e3
37
+ playwright-cli dblclick e7
38
+ # --submit presses Enter after filling the element
39
+ playwright-cli fill e5 "user@example.com" --submit
40
+ playwright-cli drag e2 e8
41
+ # drop files or data onto an element (from outside the page)
42
+ playwright-cli drop e4 --path=./image.png
43
+ playwright-cli drop e4 --data="text/plain=hello world"
44
+ playwright-cli hover e4
45
+ playwright-cli select e9 "option-value"
46
+ playwright-cli upload ./document.pdf
47
+ playwright-cli check e12
48
+ playwright-cli uncheck e12
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
+ playwright-cli eval "document.title"
56
+ playwright-cli eval "el => el.textContent" e5
57
+ # get element id, class, or any attribute not visible in the snapshot
58
+ playwright-cli eval "el => el.id" e5
59
+ playwright-cli eval "el => el.getAttribute('data-testid')" e5
60
+ playwright-cli dialog-accept
61
+ playwright-cli dialog-accept "confirmation text"
62
+ playwright-cli dialog-dismiss
63
+ playwright-cli resize 1920 1080
64
+ playwright-cli close
65
+ ```
66
+
67
+ ### Navigation
68
+
69
+ ```bash
70
+ playwright-cli go-back
71
+ playwright-cli go-forward
72
+ playwright-cli reload
73
+ ```
74
+
75
+ ### Keyboard
76
+
77
+ ```bash
78
+ playwright-cli press Enter
79
+ playwright-cli press ArrowDown
80
+ playwright-cli keydown Shift
81
+ playwright-cli keyup Shift
82
+ ```
83
+
84
+ ### Mouse
85
+
86
+ ```bash
87
+ playwright-cli mousemove 150 300
88
+ playwright-cli mousedown
89
+ playwright-cli mousedown right
90
+ playwright-cli mouseup
91
+ playwright-cli mouseup right
92
+ playwright-cli mousewheel 0 100
93
+ ```
94
+
95
+ ### Save as
96
+
97
+ ```bash
98
+ playwright-cli screenshot
99
+ playwright-cli screenshot e5
100
+ playwright-cli screenshot --filename=page.png
101
+ playwright-cli screenshot --hires
102
+ playwright-cli pdf --filename=page.pdf
103
+ ```
104
+
105
+ ### Tabs
106
+
107
+ ```bash
108
+ playwright-cli tab-list
109
+ playwright-cli tab-new
110
+ playwright-cli tab-new https://example.com/page
111
+ playwright-cli tab-close
112
+ playwright-cli tab-close 2
113
+ playwright-cli tab-select 0
114
+ ```
115
+
116
+ ### Storage
117
+
118
+ ```bash
119
+ playwright-cli state-save
120
+ playwright-cli state-save auth.json
121
+ playwright-cli state-load auth.json
122
+
123
+ # Cookies
124
+ playwright-cli cookie-list
125
+ playwright-cli cookie-list --domain=example.com
126
+ playwright-cli cookie-get session_id
127
+ playwright-cli cookie-set session_id abc123
128
+ playwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure
129
+ playwright-cli cookie-delete session_id
130
+ playwright-cli cookie-clear
131
+
132
+ # LocalStorage
133
+ playwright-cli localstorage-list
134
+ playwright-cli localstorage-get theme
135
+ playwright-cli localstorage-set theme dark
136
+ playwright-cli localstorage-delete theme
137
+ playwright-cli localstorage-clear
138
+
139
+ # SessionStorage
140
+ playwright-cli sessionstorage-list
141
+ playwright-cli sessionstorage-get step
142
+ playwright-cli sessionstorage-set step 3
143
+ playwright-cli sessionstorage-delete step
144
+ playwright-cli sessionstorage-clear
145
+ ```
146
+
147
+ ### Network
148
+
149
+ ```bash
150
+ playwright-cli route "**/*.jpg" --status=404
151
+ playwright-cli route "https://api.example.com/**" --body='{"mock": true}'
152
+ playwright-cli route-list
153
+ playwright-cli unroute "**/*.jpg"
154
+ playwright-cli unroute
155
+ ```
156
+
157
+ ### DevTools
158
+
159
+ ```bash
160
+ playwright-cli console
161
+ playwright-cli console warning
162
+ playwright-cli requests
163
+ playwright-cli request 5
164
+ playwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])"
165
+ playwright-cli run-code --filename=script.js
166
+ playwright-cli tracing-start
167
+ playwright-cli tracing-stop
168
+
169
+ # record user actions in the browser, print them as Playwright code on stop
170
+ playwright-cli recording-start
171
+ playwright-cli recording-stop
172
+
173
+ playwright-cli video-start video.webm
174
+ playwright-cli video-chapter "Chapter Title" --description="Details" --duration=2000
175
+ playwright-cli video-stop
176
+
177
+ # annotate each subsequent action (click, type, ...) with a callout naming the action and highlighting the target
178
+ playwright-cli video-show-actions --duration=600 --position=top-right
179
+ playwright-cli video-hide-actions
180
+
181
+ # launch the dashboard for UI review / design feedback — user annotates the page, you receive the annotated screenshot, snapshot, and notes
182
+ playwright-cli show --annotate
183
+
184
+ # generate a Playwright locator for an element from its ref or selector
185
+ playwright-cli generate-locator e5 --raw
186
+
187
+ # show a persistent highlight overlay for an element, optionally with a custom style
188
+ playwright-cli highlight e5
189
+ playwright-cli highlight e5 --style="outline: 3px dashed red"
190
+ # hide a single element highlight, or all page highlights when no target is given
191
+ playwright-cli highlight e5 --hide
192
+ playwright-cli highlight --hide
193
+ ```
194
+
195
+ ## Raw output
196
+
197
+ The global `--raw` option strips page status, generated code, and snapshot sections from the output, returning only the result value. Use it to pipe command output into other tools. Commands that don't produce output return nothing.
198
+
199
+ ```bash
200
+ playwright-cli --raw eval "JSON.stringify(performance.timing)" | jq '.loadEventEnd - .navigationStart'
201
+ playwright-cli --raw eval "JSON.stringify([...document.querySelectorAll('a')].map(a => a.href))" > links.json
202
+ playwright-cli --raw snapshot > before.yml
203
+ playwright-cli click e5
204
+ playwright-cli --raw snapshot > after.yml
205
+ diff before.yml after.yml
206
+ TOKEN=$(playwright-cli --raw cookie-get session_id)
207
+ playwright-cli --raw localstorage-get theme
208
+ ```
209
+
210
+ For structured output wrapping every reply as JSON, pass --json
211
+ ```bash
212
+ playwright-cli list --json
213
+ ```
214
+
215
+ ## Open parameters
216
+ ```bash
217
+ # Use specific browser when creating session
218
+ playwright-cli open --browser=chrome
219
+ playwright-cli open --browser=firefox
220
+ playwright-cli open --browser=webkit
221
+ playwright-cli open --browser=msedge
222
+
223
+ # Emulate a generic mobile device (Pixel 10 for Chromium, iPhone 17 for WebKit).
224
+ # Prefer this when a mobile layout is acceptable: mobile pages are usually
225
+ # lighter, so snapshots are smaller and cheaper.
226
+ playwright-cli open --mobile
227
+ playwright-cli open --device="iPhone 15"
228
+
229
+ # Use persistent profile (by default profile is in-memory)
230
+ playwright-cli open --persistent
231
+ # Use persistent profile with custom directory
232
+ playwright-cli open --profile=/path/to/profile
233
+
234
+ # Connect to browser via Playwright Extension
235
+ playwright-cli attach --extension=chrome
236
+
237
+ # Connect to a running Chrome or Edge by channel name
238
+ playwright-cli attach --cdp=chrome
239
+ playwright-cli attach --cdp=msedge
240
+
241
+ # Connect to a running browser via CDP endpoint
242
+ playwright-cli attach --cdp=http://localhost:9222
243
+
244
+ # Start with config file
245
+ playwright-cli open --config=my-config.json
246
+
247
+ # Close the browser
248
+ playwright-cli close
249
+ # Detach from an attached browser (leaves the external browser running)
250
+ playwright-cli -s=msedge detach
251
+ # Delete user data for the default session
252
+ playwright-cli delete-data
253
+ ```
254
+
255
+ ## URLs with `&` on Windows
256
+
257
+ On Windows, `cmd.exe` and PowerShell treat `&` as a command separator, so URLs with multiple query parameters get truncated before `playwright-cli` runs. Escape `&` with `^&` in `cmd.exe`, or use `--%` in PowerShell:
258
+
259
+ ```batch
260
+ playwright-cli goto "https://example.com/?a=1^&b=2"
261
+ ```
262
+
263
+ ```powershell
264
+ playwright-cli --% goto "https://example.com/?a=1&b=2"
265
+ ```
266
+
267
+ ## Snapshots
268
+
269
+ After each command, playwright-cli provides a snapshot of the current browser state.
270
+
271
+ ```bash
272
+ > playwright-cli goto https://example.com
273
+ ### Page
274
+ - Page URL: https://example.com/
275
+ - Page Title: Example Domain
276
+ ### Snapshot
277
+ [Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml)
278
+ ```
279
+
280
+ You can also take a snapshot on demand using `playwright-cli snapshot` command. All the options below can be combined as needed.
281
+
282
+ ```bash
283
+ # default - save to a file with timestamp-based name
284
+ playwright-cli snapshot
285
+
286
+ # save to file, use when snapshot is a part of the workflow result
287
+ playwright-cli snapshot --filename=after-click.yaml
288
+
289
+ # snapshot an element instead of the whole page
290
+ playwright-cli snapshot "#main"
291
+
292
+ # limit snapshot depth for efficiency, take a partial snapshot afterwards
293
+ playwright-cli snapshot --depth=4
294
+ playwright-cli snapshot e34
295
+
296
+ # include each element's bounding box as [box=x,y,width,height]
297
+ playwright-cli snapshot --boxes
298
+
299
+ # search a large snapshot instead of capturing it all — returns matching nodes
300
+ # with 3 lines of context around each match (like grep -C)
301
+ playwright-cli find "Add to cart"
302
+ playwright-cli find --regex "\\$[0-9]+\\.[0-9]{2}"
303
+ ```
304
+
305
+ ## Targeting elements
306
+
307
+ By default, use refs from the snapshot to interact with page elements.
308
+
309
+ ```bash
310
+ # get snapshot with refs
311
+ playwright-cli snapshot
312
+
313
+ # interact using a ref
314
+ playwright-cli click e15
315
+ ```
316
+
317
+ You can also use css selectors or Playwright locators.
318
+
319
+ ```bash
320
+ # css selector
321
+ playwright-cli click "#main > button.submit"
322
+
323
+ # role locator
324
+ playwright-cli click "getByRole('button', { name: 'Submit' })"
325
+
326
+ # test id
327
+ playwright-cli click "getByTestId('submit-button')"
328
+ ```
329
+
330
+ ## Browser Sessions
331
+
332
+ ```bash
333
+ # create new browser session named "mysession" with persistent profile
334
+ playwright-cli -s=mysession open example.com --persistent
335
+ # same with manually specified profile directory (use when requested explicitly)
336
+ playwright-cli -s=mysession open example.com --profile=/path/to/profile
337
+ playwright-cli -s=mysession click e6
338
+ playwright-cli -s=mysession close # stop a named browser
339
+ playwright-cli -s=mysession delete-data # delete user data for persistent session
340
+
341
+ playwright-cli list
342
+ # Close all browsers
343
+ playwright-cli close-all
344
+ # Forcefully kill all browser processes
345
+ playwright-cli kill-all
346
+ ```
347
+
348
+ ## Installation
349
+
350
+ If global `playwright-cli` command is not available, try a local version via `npx playwright cli`:
351
+
352
+ ```bash
353
+ npx --no-install playwright --version
354
+ ```
355
+
356
+ When local version is available, use `npx playwright cli` in all commands. Otherwise, install `playwright-cli` as a global command:
357
+
358
+ ```bash
359
+ npm install -g @playwright/cli@latest
360
+ ```
361
+
362
+ ## Example: Form submission
363
+
364
+ ```bash
365
+ playwright-cli open https://example.com/form
366
+ playwright-cli snapshot
367
+
368
+ playwright-cli fill e1 "user@example.com"
369
+ playwright-cli fill e2 "password123"
370
+ playwright-cli click e3
371
+ playwright-cli snapshot
372
+ playwright-cli close
373
+ ```
374
+
375
+ ## Example: Multi-tab workflow
376
+
377
+ ```bash
378
+ playwright-cli open https://example.com
379
+ playwright-cli tab-new https://example.com/other
380
+ playwright-cli tab-list
381
+ playwright-cli tab-select 0
382
+ playwright-cli snapshot
383
+ playwright-cli close
384
+ ```
385
+
386
+ ## Example: Debugging with DevTools
387
+
388
+ ```bash
389
+ playwright-cli open https://example.com
390
+ playwright-cli click e4
391
+ playwright-cli fill e7 "test"
392
+ playwright-cli console
393
+ playwright-cli requests
394
+ playwright-cli close
395
+ ```
396
+
397
+ ```bash
398
+ playwright-cli open https://example.com
399
+ playwright-cli tracing-start
400
+ playwright-cli click e4
401
+ playwright-cli fill e7 "test"
402
+ playwright-cli tracing-stop
403
+ playwright-cli close
404
+ ```
405
+
406
+ ## Example: Interactive session
407
+
408
+ Ask the user for UI review or design feedback. The user draws boxes on the live page and types comments; you receive the annotated screenshot, the snapshot of the marked region, and the user's notes. Use this whenever the user asks for "UI review", "design feedback", or to "ask the user what they think / want / mean":
409
+
410
+ ```bash
411
+ playwright-cli open https://example.com
412
+ playwright-cli show --annotate
413
+ ```
414
+
415
+ ## Specific tasks
416
+
417
+ * **Running and Debugging Playwright tests** [references/playwright-tests.md](references/playwright-tests.md)
418
+ * **Request mocking** [references/request-mocking.md](references/request-mocking.md)
419
+ * **Running Playwright code** [references/running-code.md](references/running-code.md)
420
+ * **Browser session management** [references/session-management.md](references/session-management.md)
421
+ * **Storage state (cookies, localStorage)** [references/storage-state.md](references/storage-state.md)
422
+ * **Test generation (plan / generate / heal)** [references/test-generation.md](references/test-generation.md)
423
+ * **Tracing** [references/tracing.md](references/tracing.md)
424
+ * **Video recording** [references/video-recording.md](references/video-recording.md)
425
+ * **Inspecting element attributes** [references/element-attributes.md](references/element-attributes.md)
@@ -0,0 +1,23 @@
1
+ # Inspecting Element Attributes
2
+
3
+ When the snapshot doesn't show an element's `id`, `class`, `data-*` attributes, or other DOM properties, use `eval` to inspect them.
4
+
5
+ ## Examples
6
+
7
+ ```bash
8
+ playwright-cli snapshot
9
+ # snapshot shows a button as e7 but doesn't reveal its id or data attributes
10
+
11
+ # get the element's id
12
+ playwright-cli eval "el => el.id" e7
13
+
14
+ # get all CSS classes
15
+ playwright-cli eval "el => el.className" e7
16
+
17
+ # get a specific attribute
18
+ playwright-cli eval "el => el.getAttribute('data-testid')" e7
19
+ playwright-cli eval "el => el.getAttribute('aria-label')" e7
20
+
21
+ # get a computed style property
22
+ playwright-cli eval "el => getComputedStyle(el).display" e7
23
+ ```