e2e-pilot 0.0.69
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/bin.js +3 -0
- package/dist/aria-snapshot.d.ts +95 -0
- package/dist/aria-snapshot.d.ts.map +1 -0
- package/dist/aria-snapshot.js +490 -0
- package/dist/aria-snapshot.js.map +1 -0
- package/dist/bippy.js +971 -0
- package/dist/cdp-relay.d.ts +16 -0
- package/dist/cdp-relay.d.ts.map +1 -0
- package/dist/cdp-relay.js +715 -0
- package/dist/cdp-relay.js.map +1 -0
- package/dist/cdp-session.d.ts +42 -0
- package/dist/cdp-session.d.ts.map +1 -0
- package/dist/cdp-session.js +154 -0
- package/dist/cdp-session.js.map +1 -0
- package/dist/cdp-types.d.ts +63 -0
- package/dist/cdp-types.d.ts.map +1 -0
- package/dist/cdp-types.js +91 -0
- package/dist/cdp-types.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +213 -0
- package/dist/cli.js.map +1 -0
- package/dist/create-logger.d.ts +9 -0
- package/dist/create-logger.d.ts.map +1 -0
- package/dist/create-logger.js +25 -0
- package/dist/create-logger.js.map +1 -0
- package/dist/debugger-api.md +458 -0
- package/dist/debugger-examples-types.d.ts +24 -0
- package/dist/debugger-examples-types.d.ts.map +1 -0
- package/dist/debugger-examples-types.js +2 -0
- package/dist/debugger-examples-types.js.map +1 -0
- package/dist/debugger-examples.d.ts +6 -0
- package/dist/debugger-examples.d.ts.map +1 -0
- package/dist/debugger-examples.js +53 -0
- package/dist/debugger-examples.js.map +1 -0
- package/dist/debugger.d.ts +381 -0
- package/dist/debugger.d.ts.map +1 -0
- package/dist/debugger.js +633 -0
- package/dist/debugger.js.map +1 -0
- package/dist/editor-api.md +364 -0
- package/dist/editor-examples.d.ts +11 -0
- package/dist/editor-examples.d.ts.map +1 -0
- package/dist/editor-examples.js +124 -0
- package/dist/editor-examples.js.map +1 -0
- package/dist/editor.d.ts +203 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +336 -0
- package/dist/editor.js.map +1 -0
- package/dist/execute.d.ts +50 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +576 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-client.d.ts +20 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +56 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/mcp.d.ts +5 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +720 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mcp.test.d.ts +10 -0
- package/dist/mcp.test.d.ts.map +1 -0
- package/dist/mcp.test.js +2999 -0
- package/dist/mcp.test.js.map +1 -0
- package/dist/network-capture.d.ts +23 -0
- package/dist/network-capture.d.ts.map +1 -0
- package/dist/network-capture.js +98 -0
- package/dist/network-capture.js.map +1 -0
- package/dist/protocol.d.ts +54 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +2 -0
- package/dist/protocol.js.map +1 -0
- package/dist/react-source.d.ts +13 -0
- package/dist/react-source.d.ts.map +1 -0
- package/dist/react-source.js +68 -0
- package/dist/react-source.js.map +1 -0
- package/dist/scoped-fs.d.ts +94 -0
- package/dist/scoped-fs.d.ts.map +1 -0
- package/dist/scoped-fs.js +356 -0
- package/dist/scoped-fs.js.map +1 -0
- package/dist/selector-generator.js +8126 -0
- package/dist/start-relay-server.d.ts +6 -0
- package/dist/start-relay-server.d.ts.map +1 -0
- package/dist/start-relay-server.js +33 -0
- package/dist/start-relay-server.js.map +1 -0
- package/dist/styles-api.md +117 -0
- package/dist/styles-examples.d.ts +8 -0
- package/dist/styles-examples.d.ts.map +1 -0
- package/dist/styles-examples.js +64 -0
- package/dist/styles-examples.js.map +1 -0
- package/dist/styles.d.ts +27 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +234 -0
- package/dist/styles.js.map +1 -0
- package/dist/trace-utils.d.ts +14 -0
- package/dist/trace-utils.d.ts.map +1 -0
- package/dist/trace-utils.js +21 -0
- package/dist/trace-utils.js.map +1 -0
- package/dist/utils.d.ts +20 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +75 -0
- package/dist/utils.js.map +1 -0
- package/dist/wait-for-page-load.d.ts +16 -0
- package/dist/wait-for-page-load.d.ts.map +1 -0
- package/dist/wait-for-page-load.js +127 -0
- package/dist/wait-for-page-load.js.map +1 -0
- package/package.json +67 -0
- package/src/aria-snapshot.ts +610 -0
- package/src/assets/aria-labels-github-snapshot.txt +605 -0
- package/src/assets/aria-labels-github.png +0 -0
- package/src/assets/aria-labels-google-snapshot.txt +49 -0
- package/src/assets/aria-labels-google.png +0 -0
- package/src/assets/aria-labels-hacker-news-snapshot.txt +1023 -0
- package/src/assets/aria-labels-hacker-news.png +0 -0
- package/src/cdp-relay.ts +925 -0
- package/src/cdp-session.ts +203 -0
- package/src/cdp-timing.md +128 -0
- package/src/cdp-types.ts +155 -0
- package/src/cli.ts +250 -0
- package/src/create-logger.ts +36 -0
- package/src/debugger-examples-types.ts +13 -0
- package/src/debugger-examples.ts +66 -0
- package/src/debugger.md +453 -0
- package/src/debugger.ts +713 -0
- package/src/editor-examples.ts +148 -0
- package/src/editor.ts +390 -0
- package/src/execute.ts +763 -0
- package/src/index.ts +10 -0
- package/src/mcp-client.ts +78 -0
- package/src/mcp.test.ts +3596 -0
- package/src/mcp.ts +876 -0
- package/src/network-capture.ts +140 -0
- package/src/prompt.bak.md +323 -0
- package/src/prompt.md +7 -0
- package/src/protocol.ts +63 -0
- package/src/react-source.ts +94 -0
- package/src/resource.md +436 -0
- package/src/scoped-fs.ts +411 -0
- package/src/snapshots/hacker-news-focused-accessibility.md +202 -0
- package/src/snapshots/hacker-news-initial-accessibility.md +11 -0
- package/src/snapshots/hacker-news-tabbed-accessibility.md +202 -0
- package/src/snapshots/shadcn-ui-accessibility.md +11 -0
- package/src/start-relay-server.ts +43 -0
- package/src/styles-examples.ts +77 -0
- package/src/styles.ts +345 -0
- package/src/trace-utils.ts +43 -0
- package/src/utils.ts +91 -0
- package/src/wait-for-page-load.ts +174 -0
package/src/cli.ts
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { cac } from 'cac'
|
|
4
|
+
import fs from 'node:fs'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
import { spawn } from 'node:child_process'
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
8
|
+
import { chromium, Page } from 'playwright-core'
|
|
9
|
+
import { startE2EPilotCDPRelayServer } from './cdp-relay.js'
|
|
10
|
+
import { createFileLogger } from './create-logger.js'
|
|
11
|
+
import {
|
|
12
|
+
getCdpUrl,
|
|
13
|
+
VERSION,
|
|
14
|
+
sleep,
|
|
15
|
+
RELAY_PORT,
|
|
16
|
+
getServerVersion,
|
|
17
|
+
setDeviceScaleFactorForMacOS,
|
|
18
|
+
preserveSystemColorScheme,
|
|
19
|
+
} from './utils.js'
|
|
20
|
+
import { executeCode } from './execute.js'
|
|
21
|
+
import { CDPSession } from './cdp-session.js'
|
|
22
|
+
|
|
23
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
24
|
+
|
|
25
|
+
const cli = cac('e2e-pilot')
|
|
26
|
+
|
|
27
|
+
cli
|
|
28
|
+
.command('', 'Start the MCP server (default)')
|
|
29
|
+
.option('--host <host>', 'Remote relay server host to connect to (or use E2E_PILOT_HOST env var)')
|
|
30
|
+
.option('--token <token>', 'Authentication token (or use E2E_PILOT_TOKEN env var)')
|
|
31
|
+
.action(async (options: { host?: string; token?: string }) => {
|
|
32
|
+
const { startMcp } = await import('./mcp.js')
|
|
33
|
+
await startMcp({
|
|
34
|
+
host: options.host,
|
|
35
|
+
token: options.token,
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
cli
|
|
40
|
+
.command('serve', 'Start the CDP relay server for remote MCP connections')
|
|
41
|
+
.option('--host <host>', 'Host to bind to', { default: '0.0.0.0' })
|
|
42
|
+
.option('--token <token>', 'Authentication token (or use E2E_PILOT_TOKEN env var)')
|
|
43
|
+
.action(async (options: { host: string; token?: string }) => {
|
|
44
|
+
const token = options.token || process.env.E2E_PILOT_TOKEN
|
|
45
|
+
if (!token) {
|
|
46
|
+
console.error('Error: Authentication token is required.')
|
|
47
|
+
console.error('Provide --token <token> or set E2E_PILOT_TOKEN environment variable.')
|
|
48
|
+
process.exit(1)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const logger = createFileLogger()
|
|
52
|
+
|
|
53
|
+
process.title = 'e2e-pilot-serve'
|
|
54
|
+
|
|
55
|
+
process.on('uncaughtException', async (err) => {
|
|
56
|
+
await logger.error('Uncaught Exception:', err)
|
|
57
|
+
process.exit(1)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
process.on('unhandledRejection', async (reason) => {
|
|
61
|
+
await logger.error('Unhandled Rejection:', reason)
|
|
62
|
+
process.exit(1)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const server = await startE2EPilotCDPRelayServer({
|
|
66
|
+
port: RELAY_PORT,
|
|
67
|
+
host: options.host,
|
|
68
|
+
token,
|
|
69
|
+
logger,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
console.log('E2E Pilot CDP relay server started')
|
|
73
|
+
console.log(` Host: ${options.host}`)
|
|
74
|
+
console.log(` Port: ${RELAY_PORT}`)
|
|
75
|
+
console.log(` Token: (configured)`)
|
|
76
|
+
console.log(` Logs: ${logger.logFilePath}`)
|
|
77
|
+
console.log('')
|
|
78
|
+
console.log('Endpoints:')
|
|
79
|
+
console.log(` Extension: ws://${options.host}:${RELAY_PORT}/extension`)
|
|
80
|
+
console.log(` CDP: ws://${options.host}:${RELAY_PORT}/cdp/<client-id>?token=<token>`)
|
|
81
|
+
console.log('')
|
|
82
|
+
console.log('Press Ctrl+C to stop.')
|
|
83
|
+
|
|
84
|
+
process.on('SIGINT', () => {
|
|
85
|
+
console.log('\nShutting down...')
|
|
86
|
+
server.close()
|
|
87
|
+
process.exit(0)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
process.on('SIGTERM', () => {
|
|
91
|
+
console.log('\nShutting down...')
|
|
92
|
+
server.close()
|
|
93
|
+
process.exit(0)
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
cli
|
|
98
|
+
.command('run [...files]', 'Execute Playwright code from file(s), --code, or stdin and exit')
|
|
99
|
+
.option('-c, --code <code>', 'Execute code passed as a string')
|
|
100
|
+
.option('--timeout <ms>', 'Execution timeout in milliseconds', { default: 30000 })
|
|
101
|
+
.option('--host <host>', 'Remote relay server host (or use E2E_PILOT_HOST env var)')
|
|
102
|
+
.option('--token <token>', 'Authentication token for remote (or use E2E_PILOT_TOKEN env var)')
|
|
103
|
+
.action(async (files: string[], options: { code?: string; timeout: number; host?: string; token?: string }) => {
|
|
104
|
+
// Priority: --code flag > stdin > files
|
|
105
|
+
const code: string = await (async () => {
|
|
106
|
+
if (options.code) {
|
|
107
|
+
return options.code
|
|
108
|
+
}
|
|
109
|
+
if (!process.stdin.isTTY) {
|
|
110
|
+
return await readStdin()
|
|
111
|
+
}
|
|
112
|
+
if (files.length > 0) {
|
|
113
|
+
const codeChunks: string[] = []
|
|
114
|
+
for (const file of files) {
|
|
115
|
+
const filePath = path.resolve(file)
|
|
116
|
+
if (!fs.existsSync(filePath)) {
|
|
117
|
+
console.error(`Error: File not found: ${filePath}`)
|
|
118
|
+
process.exit(1)
|
|
119
|
+
}
|
|
120
|
+
const content = fs.readFileSync(filePath, 'utf-8')
|
|
121
|
+
codeChunks.push(content)
|
|
122
|
+
}
|
|
123
|
+
return codeChunks.join('\n')
|
|
124
|
+
}
|
|
125
|
+
console.error('Error: Provide code via --code, stdin, or file path(s)')
|
|
126
|
+
console.error('Usage: e2e-pilot run -c "code" | e2e-pilot run <file.js> | echo "code" | e2e-pilot run')
|
|
127
|
+
process.exit(1)
|
|
128
|
+
})()
|
|
129
|
+
|
|
130
|
+
// Set up environment for remote connection if specified
|
|
131
|
+
const host = options.host || process.env.E2E_PILOT_HOST
|
|
132
|
+
const token = options.token || process.env.E2E_PILOT_TOKEN
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
// Ensure relay server is running (for local mode)
|
|
136
|
+
if (!host) {
|
|
137
|
+
await ensureRelayServerForCli()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Connect to browser
|
|
141
|
+
const cdpEndpoint = getCdpUrl(host ? { host, port: RELAY_PORT, token } : { port: RELAY_PORT })
|
|
142
|
+
console.error(`Connecting to CDP endpoint: ${cdpEndpoint}`)
|
|
143
|
+
const browser = await chromium.connectOverCDP(cdpEndpoint)
|
|
144
|
+
console.error('Connected to browser')
|
|
145
|
+
|
|
146
|
+
const contexts = browser.contexts()
|
|
147
|
+
const context = contexts.length > 0 ? contexts[0] : await browser.newContext()
|
|
148
|
+
const pages = context.pages()
|
|
149
|
+
if (pages.length === 0) {
|
|
150
|
+
console.error('Error: No browser tabs are connected.')
|
|
151
|
+
console.error('Please install and enable the E2E Pilot extension on at least one tab.')
|
|
152
|
+
process.exit(1)
|
|
153
|
+
}
|
|
154
|
+
const page = pages[0]
|
|
155
|
+
|
|
156
|
+
// Apply macOS device scale factor
|
|
157
|
+
await setDeviceScaleFactorForMacOS(context)
|
|
158
|
+
await preserveSystemColorScheme(context)
|
|
159
|
+
|
|
160
|
+
// Execute the code
|
|
161
|
+
const result = await executeCode({
|
|
162
|
+
code,
|
|
163
|
+
timeout: options.timeout,
|
|
164
|
+
deps: {
|
|
165
|
+
page,
|
|
166
|
+
context,
|
|
167
|
+
userState: {},
|
|
168
|
+
browserLogs: new Map(),
|
|
169
|
+
lastSnapshots: new WeakMap(),
|
|
170
|
+
cdpSessionCache: new WeakMap<Page, CDPSession>(),
|
|
171
|
+
getPageTargetId: async (p: Page) => (p as any)._guid || '',
|
|
172
|
+
getCdpUrl: () => getCdpUrl(host ? { host, port: RELAY_PORT, token } : { port: RELAY_PORT }),
|
|
173
|
+
resetConnection: async () => {
|
|
174
|
+
throw new Error('resetConnection is not supported in run mode')
|
|
175
|
+
},
|
|
176
|
+
logger: (...args) => {
|
|
177
|
+
console.error(...args)
|
|
178
|
+
},
|
|
179
|
+
sendLogToRelayServer: () => {},
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
// Output result
|
|
184
|
+
for (const item of result.content) {
|
|
185
|
+
if (item.type === 'text') {
|
|
186
|
+
console.log(item.text)
|
|
187
|
+
} else if (item.type === 'image') {
|
|
188
|
+
console.log(`[Image: ${item.mimeType}]`)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Disconnect and exit
|
|
193
|
+
await browser.close().catch(() => {})
|
|
194
|
+
process.exit(result.isError ? 1 : 0)
|
|
195
|
+
} catch (error: any) {
|
|
196
|
+
console.error('Error:', error.message)
|
|
197
|
+
process.exit(1)
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
async function ensureRelayServerForCli(): Promise<void> {
|
|
202
|
+
const serverVersion = await getServerVersion()
|
|
203
|
+
if (serverVersion === VERSION) {
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
console.error('Starting CDP relay server...')
|
|
208
|
+
|
|
209
|
+
const dev = process.env.E2E_PILOT_NODE_ENV === 'development'
|
|
210
|
+
const scriptPath = dev
|
|
211
|
+
? path.resolve(__dirname, '../src/start-relay-server.ts')
|
|
212
|
+
: path.resolve(__dirname, 'start-relay-server.js')
|
|
213
|
+
|
|
214
|
+
const serverProcess = spawn(dev ? 'tsx' : process.execPath, [scriptPath], {
|
|
215
|
+
detached: true,
|
|
216
|
+
stdio: 'ignore',
|
|
217
|
+
})
|
|
218
|
+
serverProcess.unref()
|
|
219
|
+
|
|
220
|
+
for (let i = 0; i < 10; i++) {
|
|
221
|
+
await sleep(500)
|
|
222
|
+
const newVersion = await getServerVersion()
|
|
223
|
+
if (newVersion === VERSION) {
|
|
224
|
+
console.error('CDP relay server started')
|
|
225
|
+
await sleep(1000)
|
|
226
|
+
return
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
throw new Error('Failed to start CDP relay server after 5 seconds')
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function readStdin(): Promise<string> {
|
|
234
|
+
return new Promise((resolve, reject) => {
|
|
235
|
+
let data = ''
|
|
236
|
+
process.stdin.setEncoding('utf-8')
|
|
237
|
+
process.stdin.on('data', (chunk) => {
|
|
238
|
+
data += chunk
|
|
239
|
+
})
|
|
240
|
+
process.stdin.on('end', () => {
|
|
241
|
+
resolve(data)
|
|
242
|
+
})
|
|
243
|
+
process.stdin.on('error', reject)
|
|
244
|
+
})
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
cli.help()
|
|
248
|
+
cli.version(VERSION)
|
|
249
|
+
|
|
250
|
+
cli.parse()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import util from 'node:util'
|
|
4
|
+
import stripAnsi from 'strip-ansi'
|
|
5
|
+
import { LOG_FILE_PATH } from './utils.js'
|
|
6
|
+
|
|
7
|
+
export type Logger = {
|
|
8
|
+
log(...args: unknown[]): Promise<void>
|
|
9
|
+
error(...args: unknown[]): Promise<void>
|
|
10
|
+
logFilePath: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createFileLogger({ logFilePath }: { logFilePath?: string } = {}): Logger {
|
|
14
|
+
const resolvedLogFilePath = logFilePath || LOG_FILE_PATH
|
|
15
|
+
const logDir = path.dirname(resolvedLogFilePath)
|
|
16
|
+
if (!fs.existsSync(logDir)) {
|
|
17
|
+
fs.mkdirSync(logDir, { recursive: true })
|
|
18
|
+
}
|
|
19
|
+
fs.writeFileSync(resolvedLogFilePath, '')
|
|
20
|
+
|
|
21
|
+
let queue: Promise<void> = Promise.resolve()
|
|
22
|
+
|
|
23
|
+
const log = (...args: unknown[]): Promise<void> => {
|
|
24
|
+
const message = args.map(arg =>
|
|
25
|
+
typeof arg === 'string' ? arg : util.inspect(arg, { depth: null, colors: false })
|
|
26
|
+
).join(' ')
|
|
27
|
+
queue = queue.then(() => fs.promises.appendFile(resolvedLogFilePath, stripAnsi(message) + '\n'))
|
|
28
|
+
return queue
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
log,
|
|
33
|
+
error: log,
|
|
34
|
+
logFilePath: resolvedLogFilePath,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Page, Locator } from 'playwright-core'
|
|
2
|
+
import type { CDPSession } from './cdp-session.js'
|
|
3
|
+
import type { Debugger } from './debugger.js'
|
|
4
|
+
import type { Editor } from './editor.js'
|
|
5
|
+
import type { StylesResult } from './styles.js'
|
|
6
|
+
|
|
7
|
+
export declare const page: Page
|
|
8
|
+
export declare const getCDPSession: (options: { page: Page }) => Promise<CDPSession>
|
|
9
|
+
export declare const createDebugger: (options: { cdp: CDPSession }) => Debugger
|
|
10
|
+
export declare const createEditor: (options: { cdp: CDPSession }) => Editor
|
|
11
|
+
export declare const getStylesForLocator: (options: { locator: Locator; includeUserAgentStyles?: boolean }) => Promise<StylesResult>
|
|
12
|
+
export declare const formatStylesAsText: (styles: StylesResult) => string
|
|
13
|
+
export declare const console: { log: (...args: unknown[]) => void }
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { page, getCDPSession, createDebugger, console } from './debugger-examples-types.js'
|
|
2
|
+
|
|
3
|
+
// Example: List available scripts and set a breakpoint
|
|
4
|
+
async function listScriptsAndSetBreakpoint() {
|
|
5
|
+
const cdp = await getCDPSession({ page })
|
|
6
|
+
const dbg = createDebugger({ cdp })
|
|
7
|
+
await dbg.enable()
|
|
8
|
+
|
|
9
|
+
const scripts = await dbg.listScripts({ search: 'app' })
|
|
10
|
+
console.log(scripts)
|
|
11
|
+
|
|
12
|
+
if (scripts.length > 0) {
|
|
13
|
+
const bpId = await dbg.setBreakpoint({ file: scripts[0].url, line: 100 })
|
|
14
|
+
console.log('Breakpoint set:', bpId)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Example: Inspect state when paused at a breakpoint
|
|
19
|
+
async function inspectWhenPaused() {
|
|
20
|
+
const cdp = await getCDPSession({ page })
|
|
21
|
+
const dbg = createDebugger({ cdp })
|
|
22
|
+
await dbg.enable()
|
|
23
|
+
|
|
24
|
+
if (dbg.isPaused()) {
|
|
25
|
+
const loc = await dbg.getLocation()
|
|
26
|
+
console.log('Paused at:', loc.url, 'line', loc.lineNumber)
|
|
27
|
+
console.log('Source:', loc.sourceContext)
|
|
28
|
+
|
|
29
|
+
const vars = await dbg.inspectLocalVariables()
|
|
30
|
+
console.log('Variables:', vars)
|
|
31
|
+
|
|
32
|
+
const result = await dbg.evaluate({ expression: 'myVar.length' })
|
|
33
|
+
console.log('myVar.length =', result.value)
|
|
34
|
+
|
|
35
|
+
await dbg.stepOver()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Example: Step through code
|
|
40
|
+
async function stepThroughCode() {
|
|
41
|
+
const cdp = await getCDPSession({ page })
|
|
42
|
+
const dbg = createDebugger({ cdp })
|
|
43
|
+
await dbg.enable()
|
|
44
|
+
|
|
45
|
+
await dbg.setBreakpoint({ file: 'https://example.com/app.js', line: 42 })
|
|
46
|
+
|
|
47
|
+
if (dbg.isPaused()) {
|
|
48
|
+
await dbg.stepOver()
|
|
49
|
+
await dbg.stepInto()
|
|
50
|
+
await dbg.stepOut()
|
|
51
|
+
await dbg.resume()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Example: Cleanup all breakpoints
|
|
56
|
+
async function cleanupBreakpoints() {
|
|
57
|
+
const cdp = await getCDPSession({ page })
|
|
58
|
+
const dbg = createDebugger({ cdp })
|
|
59
|
+
|
|
60
|
+
const breakpoints = dbg.listBreakpoints()
|
|
61
|
+
for (const bp of breakpoints) {
|
|
62
|
+
await dbg.deleteBreakpoint({ breakpointId: bp.id })
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { listScriptsAndSetBreakpoint, inspectWhenPaused, stepThroughCode, cleanupBreakpoints }
|