electron-playwright-cli 0.1.0
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/LICENSE +201 -0
- package/README.md +69 -0
- package/package.json +62 -0
- package/playwright-cli.js +256 -0
- package/playwright-electron/electron-context-factory.js +49 -0
- package/playwright-electron/electron-daemon.js +119 -0
- package/playwright-electron/electron-tools.js +69 -0
- package/skills/playwright-cli/SKILL.md +272 -0
- package/skills/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright-cli/references/running-code.md +226 -0
- package/skills/playwright-cli/references/session-management.md +145 -0
- package/skills/playwright-cli/references/storage-state.md +270 -0
- package/skills/playwright-cli/references/test-generation.md +88 -0
- package/skills/playwright-cli/references/tracing.md +135 -0
- package/skills/playwright-cli/references/video-recording.md +42 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
// electron daemon — launched by playwright-cli.js as a subprocess.
|
|
5
|
+
// assembles a playwright CLI daemon with electron browser support.
|
|
6
|
+
//
|
|
7
|
+
// receives CLI args:
|
|
8
|
+
// --daemon=<socketPath> unix socket path to listen on
|
|
9
|
+
// --config=<configFile> optional path to config JSON file
|
|
10
|
+
// --user-data-dir=<path> optional user data directory
|
|
11
|
+
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
const path = require("path");
|
|
14
|
+
|
|
15
|
+
const playwrightDir = path.dirname(require.resolve("playwright/package.json"));
|
|
16
|
+
|
|
17
|
+
function resolveInternal(relativePath) {
|
|
18
|
+
return path.join(playwrightDir, relativePath);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// --- import playwright internals via absolute paths ---
|
|
22
|
+
|
|
23
|
+
const { BrowserServerBackend } = require(
|
|
24
|
+
resolveInternal("lib/mcp/browser/browserServerBackend.js"),
|
|
25
|
+
);
|
|
26
|
+
const { resolveConfig } = require(resolveInternal("lib/mcp/browser/config.js"));
|
|
27
|
+
const { startMcpDaemonServer } = require(
|
|
28
|
+
resolveInternal("lib/mcp/terminal/daemon.js"),
|
|
29
|
+
);
|
|
30
|
+
const { browserTools } = require(resolveInternal("lib/mcp/browser/tools.js"));
|
|
31
|
+
const { commands } = require(resolveInternal("lib/mcp/terminal/commands.js"));
|
|
32
|
+
const { z } = require("playwright-core/lib/mcpBundle");
|
|
33
|
+
|
|
34
|
+
// --- import our electron extensions ---
|
|
35
|
+
|
|
36
|
+
const { ElectronContextFactory } = require("./electron-context-factory");
|
|
37
|
+
const electronTools = require("./electron-tools");
|
|
38
|
+
|
|
39
|
+
// --- parse CLI args ---
|
|
40
|
+
|
|
41
|
+
const args = require("minimist")(process.argv.slice(2));
|
|
42
|
+
const socketPath = args.daemon;
|
|
43
|
+
if (!socketPath) {
|
|
44
|
+
console.error("--daemon=<socketPath> is required");
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function main() {
|
|
49
|
+
// load config file if provided
|
|
50
|
+
let userConfig = {};
|
|
51
|
+
if (args.config && fs.existsSync(args.config)) {
|
|
52
|
+
userConfig = JSON.parse(fs.readFileSync(args.config, "utf-8"));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// set user data dir if provided
|
|
56
|
+
if (args["user-data-dir"]) {
|
|
57
|
+
userConfig.browser = userConfig.browser || {};
|
|
58
|
+
userConfig.browser.userDataDir = args["user-data-dir"];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// electron uses file: protocol — without this, Context._setupBrowserContext
|
|
62
|
+
// calls _setAllowedProtocols which blocks file: URLs
|
|
63
|
+
userConfig.allowUnrestrictedFileAccess = true;
|
|
64
|
+
|
|
65
|
+
// resolve full config by merging with playwright defaults
|
|
66
|
+
const config = await resolveConfig(userConfig);
|
|
67
|
+
|
|
68
|
+
// apply daemon-mode overrides (matches program.js daemon setup)
|
|
69
|
+
config.outputDir = path.join(process.cwd(), ".playwright-cli");
|
|
70
|
+
config.outputMode = "file";
|
|
71
|
+
config.codegen = "none";
|
|
72
|
+
config.snapshot.mode = "full";
|
|
73
|
+
config.capabilities = ["core", "internal", "tracing", "pdf", "vision"];
|
|
74
|
+
|
|
75
|
+
// register electron tools into the global browserTools array.
|
|
76
|
+
// BrowserServerBackend's constructor calls filteredTools(config) which
|
|
77
|
+
// reads from this same array reference, so pushing here ensures
|
|
78
|
+
// electron tools are included.
|
|
79
|
+
browserTools.push(...electronTools);
|
|
80
|
+
|
|
81
|
+
// register electron CLI commands so the daemon's parseCliCommand can
|
|
82
|
+
// dispatch them. the commands object is shared by reference with daemon.js.
|
|
83
|
+
commands["electron_evaluate"] = {
|
|
84
|
+
name: "electron_evaluate",
|
|
85
|
+
description: "execute JavaScript in the Electron main process",
|
|
86
|
+
args: z.object({
|
|
87
|
+
expression: z
|
|
88
|
+
.string()
|
|
89
|
+
.describe('JS expression, e.g. "electron => electron.app.getName()"'),
|
|
90
|
+
}),
|
|
91
|
+
toolName: "electron_evaluate",
|
|
92
|
+
toolParams: ({ expression }) => ({ expression }),
|
|
93
|
+
};
|
|
94
|
+
commands["electron_windows"] = {
|
|
95
|
+
name: "electron_windows",
|
|
96
|
+
description: "list all open Electron windows",
|
|
97
|
+
args: z.object({}),
|
|
98
|
+
toolName: "electron_windows",
|
|
99
|
+
toolParams: () => ({}),
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// create the backend factory
|
|
103
|
+
const factory = new ElectronContextFactory(config);
|
|
104
|
+
const serverBackendFactory = {
|
|
105
|
+
create: () => new BrowserServerBackend(config, factory),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// start listening on the unix socket
|
|
109
|
+
const resolvedPath = await startMcpDaemonServer(
|
|
110
|
+
socketPath,
|
|
111
|
+
serverBackendFactory,
|
|
112
|
+
);
|
|
113
|
+
console.error(`Electron daemon listening on ${resolvedPath}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
main().catch((e) => {
|
|
117
|
+
console.error(e);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// electron-specific tools for the playwright CLI daemon.
|
|
4
|
+
// operate on the electron app instance stored on browserContext._electronApp.
|
|
5
|
+
|
|
6
|
+
const { z } = require("playwright-core/lib/mcpBundle");
|
|
7
|
+
|
|
8
|
+
const electronEvaluate = {
|
|
9
|
+
capability: "core",
|
|
10
|
+
schema: {
|
|
11
|
+
name: "electron_evaluate",
|
|
12
|
+
title: "Evaluate in Electron main process",
|
|
13
|
+
description:
|
|
14
|
+
"Execute a JavaScript expression in the Electron main process. The function receives the Electron module as its argument.",
|
|
15
|
+
inputSchema: z.object({
|
|
16
|
+
expression: z
|
|
17
|
+
.string()
|
|
18
|
+
.describe(
|
|
19
|
+
'JavaScript expression to evaluate in the main process. Receives electron module as argument, e.g. "electron => electron.app.getName()"',
|
|
20
|
+
),
|
|
21
|
+
}),
|
|
22
|
+
type: "destructive",
|
|
23
|
+
},
|
|
24
|
+
handle: async (context, params, response) => {
|
|
25
|
+
const browserContext = await context.ensureBrowserContext();
|
|
26
|
+
const electronApp = browserContext._electronApp;
|
|
27
|
+
if (!electronApp)
|
|
28
|
+
throw new Error(
|
|
29
|
+
"Not running in Electron mode. This tool requires an Electron app context.",
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const result = await electronApp.evaluate(params.expression);
|
|
33
|
+
const text = JSON.stringify(result, null, 2) ?? "undefined";
|
|
34
|
+
response.addTextResult(text);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const electronWindows = {
|
|
39
|
+
capability: "core",
|
|
40
|
+
schema: {
|
|
41
|
+
name: "electron_windows",
|
|
42
|
+
title: "List Electron windows",
|
|
43
|
+
description:
|
|
44
|
+
"List all open Electron windows with their title, URL, and index.",
|
|
45
|
+
inputSchema: z.object({}),
|
|
46
|
+
type: "readOnly",
|
|
47
|
+
},
|
|
48
|
+
handle: async (context, params, response) => {
|
|
49
|
+
const browserContext = await context.ensureBrowserContext();
|
|
50
|
+
const electronApp = browserContext._electronApp;
|
|
51
|
+
if (!electronApp)
|
|
52
|
+
throw new Error(
|
|
53
|
+
"Not running in Electron mode. This tool requires an Electron app context.",
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const windows = electronApp.windows();
|
|
57
|
+
const windowInfos = await Promise.all(
|
|
58
|
+
windows.map(async (page, index) => ({
|
|
59
|
+
index,
|
|
60
|
+
title: await page.title(),
|
|
61
|
+
url: page.url(),
|
|
62
|
+
})),
|
|
63
|
+
);
|
|
64
|
+
const text = JSON.stringify(windowInfos, null, 2);
|
|
65
|
+
response.addTextResult(text);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
module.exports = [electronEvaluate, electronWindows];
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: electron-playwright-cli
|
|
3
|
+
description: Automates Electron desktop app interactions for testing, screenshots, and data extraction. Use when the user needs to interact with Electron apps, take screenshots, fill forms, click elements, or extract information from desktop applications.
|
|
4
|
+
allowed-tools: Bash(electron-playwright-cli:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Electron App Automation with electron-playwright-cli
|
|
8
|
+
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# take a snapshot of the running electron app (launches via config on first command)
|
|
13
|
+
electron-playwright-cli snapshot
|
|
14
|
+
# interact with the page using refs from the snapshot
|
|
15
|
+
electron-playwright-cli click e15
|
|
16
|
+
electron-playwright-cli type "search query"
|
|
17
|
+
electron-playwright-cli press Enter
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Configuration
|
|
21
|
+
|
|
22
|
+
Create `.playwright/cli.config.json` in your project root:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"browser": {
|
|
27
|
+
"launchOptions": {
|
|
28
|
+
"args": ["path/to/your/main.js"]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The `args` array is passed to Electron. Point it at your app's main process entry point.
|
|
35
|
+
|
|
36
|
+
Optional launch options:
|
|
37
|
+
- `executablePath`: path to the Electron binary (defaults to the one in node_modules)
|
|
38
|
+
- `cwd`: working directory for the Electron process
|
|
39
|
+
- `env`: additional environment variables
|
|
40
|
+
- `timeout`: launch timeout in milliseconds
|
|
41
|
+
|
|
42
|
+
## Commands
|
|
43
|
+
|
|
44
|
+
### Core
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
electron-playwright-cli type "search query"
|
|
48
|
+
electron-playwright-cli click e3
|
|
49
|
+
electron-playwright-cli dblclick e7
|
|
50
|
+
electron-playwright-cli fill e5 "user@example.com"
|
|
51
|
+
electron-playwright-cli drag e2 e8
|
|
52
|
+
electron-playwright-cli hover e4
|
|
53
|
+
electron-playwright-cli select e9 "option-value"
|
|
54
|
+
electron-playwright-cli upload ./document.pdf
|
|
55
|
+
electron-playwright-cli check e12
|
|
56
|
+
electron-playwright-cli uncheck e12
|
|
57
|
+
electron-playwright-cli snapshot
|
|
58
|
+
electron-playwright-cli snapshot --filename=after-click.yaml
|
|
59
|
+
electron-playwright-cli eval "document.title"
|
|
60
|
+
electron-playwright-cli eval "el => el.textContent" e5
|
|
61
|
+
electron-playwright-cli dialog-accept
|
|
62
|
+
electron-playwright-cli dialog-accept "confirmation text"
|
|
63
|
+
electron-playwright-cli dialog-dismiss
|
|
64
|
+
electron-playwright-cli resize 1920 1080
|
|
65
|
+
electron-playwright-cli close
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Navigation
|
|
69
|
+
|
|
70
|
+
Navigate within the Electron app's webview:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
electron-playwright-cli goto https://example.com
|
|
74
|
+
electron-playwright-cli go-back
|
|
75
|
+
electron-playwright-cli go-forward
|
|
76
|
+
electron-playwright-cli reload
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Keyboard
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
electron-playwright-cli press Enter
|
|
83
|
+
electron-playwright-cli press ArrowDown
|
|
84
|
+
electron-playwright-cli keydown Shift
|
|
85
|
+
electron-playwright-cli keyup Shift
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Mouse
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
electron-playwright-cli mousemove 150 300
|
|
92
|
+
electron-playwright-cli mousedown
|
|
93
|
+
electron-playwright-cli mousedown right
|
|
94
|
+
electron-playwright-cli mouseup
|
|
95
|
+
electron-playwright-cli mouseup right
|
|
96
|
+
electron-playwright-cli mousewheel 0 100
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Save as
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
electron-playwright-cli screenshot
|
|
103
|
+
electron-playwright-cli screenshot e5
|
|
104
|
+
electron-playwright-cli screenshot --filename=page.png
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Tabs
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
electron-playwright-cli tab-list
|
|
111
|
+
electron-playwright-cli tab-new
|
|
112
|
+
electron-playwright-cli tab-close
|
|
113
|
+
electron-playwright-cli tab-close 2
|
|
114
|
+
electron-playwright-cli tab-select 0
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Storage
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
electron-playwright-cli state-save
|
|
121
|
+
electron-playwright-cli state-save auth.json
|
|
122
|
+
electron-playwright-cli state-load auth.json
|
|
123
|
+
|
|
124
|
+
# Cookies
|
|
125
|
+
electron-playwright-cli cookie-list
|
|
126
|
+
electron-playwright-cli cookie-list --domain=example.com
|
|
127
|
+
electron-playwright-cli cookie-get session_id
|
|
128
|
+
electron-playwright-cli cookie-set session_id abc123
|
|
129
|
+
electron-playwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure
|
|
130
|
+
electron-playwright-cli cookie-delete session_id
|
|
131
|
+
electron-playwright-cli cookie-clear
|
|
132
|
+
|
|
133
|
+
# LocalStorage
|
|
134
|
+
electron-playwright-cli localstorage-list
|
|
135
|
+
electron-playwright-cli localstorage-get theme
|
|
136
|
+
electron-playwright-cli localstorage-set theme dark
|
|
137
|
+
electron-playwright-cli localstorage-delete theme
|
|
138
|
+
electron-playwright-cli localstorage-clear
|
|
139
|
+
|
|
140
|
+
# SessionStorage
|
|
141
|
+
electron-playwright-cli sessionstorage-list
|
|
142
|
+
electron-playwright-cli sessionstorage-get step
|
|
143
|
+
electron-playwright-cli sessionstorage-set step 3
|
|
144
|
+
electron-playwright-cli sessionstorage-delete step
|
|
145
|
+
electron-playwright-cli sessionstorage-clear
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Network
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
electron-playwright-cli route "**/*.jpg" --status=404
|
|
152
|
+
electron-playwright-cli route "https://api.example.com/**" --body='{"mock": true}'
|
|
153
|
+
electron-playwright-cli route-list
|
|
154
|
+
electron-playwright-cli unroute "**/*.jpg"
|
|
155
|
+
electron-playwright-cli unroute
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### DevTools
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
electron-playwright-cli console
|
|
162
|
+
electron-playwright-cli console warning
|
|
163
|
+
electron-playwright-cli network
|
|
164
|
+
electron-playwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])"
|
|
165
|
+
electron-playwright-cli tracing-start
|
|
166
|
+
electron-playwright-cli tracing-stop
|
|
167
|
+
electron-playwright-cli video-start
|
|
168
|
+
electron-playwright-cli video-stop video.webm
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Electron
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
electron-playwright-cli electron_evaluate "electron => electron.app.getName()"
|
|
175
|
+
electron-playwright-cli electron_evaluate "electron => electron.app.getPath('userData')"
|
|
176
|
+
electron-playwright-cli electron_windows
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Snapshots
|
|
180
|
+
|
|
181
|
+
After each command, electron-playwright-cli provides a snapshot of the current app state.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
> electron-playwright-cli snapshot
|
|
185
|
+
### Page
|
|
186
|
+
- Page URL: file:///path/to/index.html
|
|
187
|
+
- Page Title: My Electron App
|
|
188
|
+
### Snapshot
|
|
189
|
+
[Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
You can also take a snapshot on demand using `electron-playwright-cli snapshot` command.
|
|
193
|
+
|
|
194
|
+
If `--filename` is not provided, a new snapshot file is created with a timestamp. Default to automatic file naming, use `--filename=` when artifact is a part of the workflow result.
|
|
195
|
+
|
|
196
|
+
## Sessions
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
electron-playwright-cli -s=name <cmd> # run command in named session
|
|
200
|
+
electron-playwright-cli -s=name close # stop a named session
|
|
201
|
+
electron-playwright-cli -s=name delete-data # delete user data for named session
|
|
202
|
+
electron-playwright-cli list # list all sessions
|
|
203
|
+
electron-playwright-cli close-all # close all sessions
|
|
204
|
+
electron-playwright-cli kill-all # forcefully kill all daemon processes
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Local installation
|
|
208
|
+
|
|
209
|
+
In some cases you might want to install electron-playwright-cli locally. It requires `playwright` as a peer dependency. If running the globally available `electron-playwright-cli` binary fails, use `npx electron-playwright-cli` to run the commands. For example:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npx electron-playwright-cli snapshot
|
|
213
|
+
npx electron-playwright-cli click e1
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Example: Form submission
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
electron-playwright-cli snapshot
|
|
220
|
+
|
|
221
|
+
electron-playwright-cli fill e1 "user@example.com"
|
|
222
|
+
electron-playwright-cli fill e2 "password123"
|
|
223
|
+
electron-playwright-cli click e3
|
|
224
|
+
electron-playwright-cli snapshot
|
|
225
|
+
electron-playwright-cli close
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Example: Multi-window workflow
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
electron-playwright-cli electron_windows
|
|
232
|
+
electron-playwright-cli tab-select 0
|
|
233
|
+
electron-playwright-cli snapshot
|
|
234
|
+
electron-playwright-cli close
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Example: Debugging with DevTools
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
electron-playwright-cli snapshot
|
|
241
|
+
electron-playwright-cli click e4
|
|
242
|
+
electron-playwright-cli fill e7 "test"
|
|
243
|
+
electron-playwright-cli console
|
|
244
|
+
electron-playwright-cli network
|
|
245
|
+
electron-playwright-cli close
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
electron-playwright-cli tracing-start
|
|
250
|
+
electron-playwright-cli click e4
|
|
251
|
+
electron-playwright-cli fill e7 "test"
|
|
252
|
+
electron-playwright-cli tracing-stop
|
|
253
|
+
electron-playwright-cli close
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Example: Electron main process
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
electron-playwright-cli electron_evaluate "electron => electron.app.getName()"
|
|
260
|
+
electron-playwright-cli electron_evaluate "electron => electron.app.getPath('userData')"
|
|
261
|
+
electron-playwright-cli electron_windows
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Specific tasks
|
|
265
|
+
|
|
266
|
+
* **Request mocking** [references/request-mocking.md](references/request-mocking.md)
|
|
267
|
+
* **Running Playwright code** [references/running-code.md](references/running-code.md)
|
|
268
|
+
* **Session management** [references/session-management.md](references/session-management.md)
|
|
269
|
+
* **Storage state (cookies, localStorage)** [references/storage-state.md](references/storage-state.md)
|
|
270
|
+
* **Test generation** [references/test-generation.md](references/test-generation.md)
|
|
271
|
+
* **Tracing** [references/tracing.md](references/tracing.md)
|
|
272
|
+
* **Video recording** [references/video-recording.md](references/video-recording.md)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Request Mocking
|
|
2
|
+
|
|
3
|
+
Intercept, mock, modify, and block network requests.
|
|
4
|
+
|
|
5
|
+
## CLI Route Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Mock with custom status
|
|
9
|
+
electron-playwright-cli route "**/*.jpg" --status=404
|
|
10
|
+
|
|
11
|
+
# Mock with JSON body
|
|
12
|
+
electron-playwright-cli route "**/api/users" --body='[{"id":1,"name":"Alice"}]' --content-type=application/json
|
|
13
|
+
|
|
14
|
+
# Mock with custom headers
|
|
15
|
+
electron-playwright-cli route "**/api/data" --body='{"ok":true}' --header="X-Custom: value"
|
|
16
|
+
|
|
17
|
+
# Remove headers from requests
|
|
18
|
+
electron-playwright-cli route "**/*" --remove-header=cookie,authorization
|
|
19
|
+
|
|
20
|
+
# List active routes
|
|
21
|
+
electron-playwright-cli route-list
|
|
22
|
+
|
|
23
|
+
# Remove a route or all routes
|
|
24
|
+
electron-playwright-cli unroute "**/*.jpg"
|
|
25
|
+
electron-playwright-cli unroute
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## URL Patterns
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
**/api/users - Exact path match
|
|
32
|
+
**/api/*/details - Wildcard in path
|
|
33
|
+
**/*.{png,jpg,jpeg} - Match file extensions
|
|
34
|
+
**/search?q=* - Match query parameters
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Advanced Mocking with run-code
|
|
38
|
+
|
|
39
|
+
For conditional responses, request body inspection, response modification, or delays:
|
|
40
|
+
|
|
41
|
+
### Conditional Response Based on Request
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
electron-playwright-cli run-code "async page => {
|
|
45
|
+
await page.route('**/api/login', route => {
|
|
46
|
+
const body = route.request().postDataJSON();
|
|
47
|
+
if (body.username === 'admin') {
|
|
48
|
+
route.fulfill({ body: JSON.stringify({ token: 'mock-token' }) });
|
|
49
|
+
} else {
|
|
50
|
+
route.fulfill({ status: 401, body: JSON.stringify({ error: 'Invalid' }) });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Modify Real Response
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
electron-playwright-cli run-code "async page => {
|
|
60
|
+
await page.route('**/api/user', async route => {
|
|
61
|
+
const response = await route.fetch();
|
|
62
|
+
const json = await response.json();
|
|
63
|
+
json.isPremium = true;
|
|
64
|
+
await route.fulfill({ response, json });
|
|
65
|
+
});
|
|
66
|
+
}"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Simulate Network Failures
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
electron-playwright-cli run-code "async page => {
|
|
73
|
+
await page.route('**/api/offline', route => route.abort('internetdisconnected'));
|
|
74
|
+
}"
|
|
75
|
+
# Options: connectionrefused, timedout, connectionreset, internetdisconnected
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Delayed Response
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
electron-playwright-cli run-code "async page => {
|
|
82
|
+
await page.route('**/api/slow', async route => {
|
|
83
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
84
|
+
route.fulfill({ body: JSON.stringify({ data: 'loaded' }) });
|
|
85
|
+
});
|
|
86
|
+
}"
|
|
87
|
+
```
|