playwriter 0.1.0 → 0.2.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/dist/bippy.js +5 -5
- package/dist/cdp-relay.d.ts.map +1 -1
- package/dist/cdp-relay.js +17 -5
- package/dist/cdp-relay.js.map +1 -1
- package/dist/cli-help.test.js +22 -0
- package/dist/cli-help.test.js.map +1 -1
- package/dist/cli.js +61 -20
- package/dist/cli.js.map +1 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +38 -1
- package/dist/executor.js.map +1 -1
- package/dist/extension/background.js +322 -52
- package/dist/extension/manifest.json +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +6 -1
- package/dist/mcp.js.map +1 -1
- package/dist/performance-examples.d.ts +5 -0
- package/dist/performance-examples.d.ts.map +1 -0
- package/dist/performance-examples.js +112 -0
- package/dist/performance-examples.js.map +1 -0
- package/dist/performance-profiling.md +417 -0
- package/dist/prompt.md +19 -5
- package/dist/react-source.d.ts +44 -0
- package/dist/react-source.d.ts.map +1 -1
- package/dist/react-source.js +207 -20
- package/dist/react-source.js.map +1 -1
- package/dist/readability.js +1 -1
- package/dist/relay-session.test.js +34 -6
- package/dist/relay-session.test.js.map +1 -1
- package/dist/screen-recording.d.ts.map +1 -1
- package/dist/screen-recording.js +19 -4
- package/dist/screen-recording.js.map +1 -1
- package/dist/selector-generator.js +1 -1
- package/package.json +3 -3
- package/src/cdp-relay.ts +17 -5
- package/src/cli-help.test.ts +22 -0
- package/src/cli.ts +66 -19
- package/src/executor.ts +47 -4
- package/src/mcp.ts +6 -1
- package/src/performance-examples.ts +186 -0
- package/src/react-source.ts +310 -24
- package/src/relay-session.test.ts +36 -10
- package/src/screen-recording.ts +20 -4
- package/src/skill.md +30 -6
package/dist/mcp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
declare function collectWebVitals(): Promise<void>;
|
|
2
|
+
declare function collectHeaviestRequests(): Promise<void>;
|
|
3
|
+
declare function measureInteractivity(): Promise<void>;
|
|
4
|
+
export { collectWebVitals, collectHeaviestRequests, measureInteractivity };
|
|
5
|
+
//# sourceMappingURL=performance-examples.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-examples.d.ts","sourceRoot":"","sources":["../src/performance-examples.ts"],"names":[],"mappings":"AAqCA,iBAAe,gBAAgB,kBA6D9B;AAGD,iBAAe,uBAAuB,kBAiCrC;AAGD,iBAAe,oBAAoB,kBA8ClC;AAED,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,CAAA"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Example snippets for profiling website performance with Playwriter and CDP.
|
|
2
|
+
import { console, getCDPSession, page } from './debugger-examples-types.js';
|
|
3
|
+
// Example: Collect navigation timing and basic web vitals from the current page
|
|
4
|
+
async function collectWebVitals() {
|
|
5
|
+
await page.evaluate(() => {
|
|
6
|
+
const metrics = {
|
|
7
|
+
paints: {},
|
|
8
|
+
lcp: 0,
|
|
9
|
+
cls: 0,
|
|
10
|
+
};
|
|
11
|
+
const perfGlobal = globalThis;
|
|
12
|
+
perfGlobal.__pwPerfMetrics = metrics;
|
|
13
|
+
new PerformanceObserver((list) => {
|
|
14
|
+
for (const entry of list.getEntries()) {
|
|
15
|
+
metrics.paints[entry.name] = entry.startTime;
|
|
16
|
+
}
|
|
17
|
+
}).observe({ type: 'paint', buffered: true });
|
|
18
|
+
new PerformanceObserver((list) => {
|
|
19
|
+
const entries = list.getEntries();
|
|
20
|
+
const lastEntry = entries[entries.length - 1];
|
|
21
|
+
if (!lastEntry) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
metrics.lcp = lastEntry.startTime;
|
|
25
|
+
}).observe({ type: 'largest-contentful-paint', buffered: true });
|
|
26
|
+
new PerformanceObserver((list) => {
|
|
27
|
+
for (const entry of list.getEntries()) {
|
|
28
|
+
if (entry.hadRecentInput) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
metrics.cls += entry.value || 0;
|
|
32
|
+
}
|
|
33
|
+
}).observe({ type: 'layout-shift', buffered: true });
|
|
34
|
+
});
|
|
35
|
+
await page.reload({ waitUntil: 'domcontentloaded' });
|
|
36
|
+
const report = await page.evaluate(() => {
|
|
37
|
+
const perfGlobal = globalThis;
|
|
38
|
+
const nav = performance.getEntriesByType('navigation')[0];
|
|
39
|
+
const metrics = perfGlobal.__pwPerfMetrics;
|
|
40
|
+
return {
|
|
41
|
+
ttfb: nav?.responseStart || 0,
|
|
42
|
+
domContentLoaded: nav?.domContentLoadedEventEnd || 0,
|
|
43
|
+
load: nav?.loadEventEnd || 0,
|
|
44
|
+
fcp: metrics?.paints['first-contentful-paint'] || 0,
|
|
45
|
+
lcp: metrics?.lcp || 0,
|
|
46
|
+
cls: metrics?.cls || 0,
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
console.log(report);
|
|
50
|
+
}
|
|
51
|
+
// Example: Measure the biggest transferred requests with raw CDP network events
|
|
52
|
+
async function collectHeaviestRequests() {
|
|
53
|
+
const cdp = await getCDPSession({ page });
|
|
54
|
+
await cdp.send('Network.enable');
|
|
55
|
+
await cdp.send('Network.setCacheDisabled', { cacheDisabled: true });
|
|
56
|
+
const responses = new Map();
|
|
57
|
+
const finished = new Map();
|
|
58
|
+
cdp.on('Network.responseReceived', (event) => {
|
|
59
|
+
responses.set(event.requestId, {
|
|
60
|
+
url: event.response.url,
|
|
61
|
+
mimeType: event.response.mimeType,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
cdp.on('Network.loadingFinished', (event) => {
|
|
65
|
+
finished.set(event.requestId, event.encodedDataLength);
|
|
66
|
+
});
|
|
67
|
+
await page.reload({ waitUntil: 'domcontentloaded' });
|
|
68
|
+
const largest = [...responses.entries()]
|
|
69
|
+
.map(([requestId, response]) => {
|
|
70
|
+
return {
|
|
71
|
+
url: response.url,
|
|
72
|
+
mimeType: response.mimeType,
|
|
73
|
+
bytes: finished.get(requestId) || 0,
|
|
74
|
+
};
|
|
75
|
+
})
|
|
76
|
+
.sort((a, b) => b.bytes - a.bytes)
|
|
77
|
+
.slice(0, 10);
|
|
78
|
+
console.log(largest);
|
|
79
|
+
}
|
|
80
|
+
// Example: Check whether interactivity is blocked by long tasks or slow events
|
|
81
|
+
async function measureInteractivity() {
|
|
82
|
+
await page.evaluate(() => {
|
|
83
|
+
const perfGlobal = globalThis;
|
|
84
|
+
perfGlobal.__pwLongTasks = [];
|
|
85
|
+
perfGlobal.__pwEventTimings = [];
|
|
86
|
+
new PerformanceObserver((list) => {
|
|
87
|
+
perfGlobal.__pwLongTasks?.push(...list.getEntries().map((entry) => ({
|
|
88
|
+
startTime: entry.startTime,
|
|
89
|
+
duration: entry.duration,
|
|
90
|
+
})));
|
|
91
|
+
}).observe({ type: 'longtask', buffered: true });
|
|
92
|
+
new PerformanceObserver((list) => {
|
|
93
|
+
perfGlobal.__pwEventTimings?.push(...list.getEntries().map((entry) => ({
|
|
94
|
+
name: entry.name,
|
|
95
|
+
duration: entry.duration,
|
|
96
|
+
interactionId: entry.interactionId || 0,
|
|
97
|
+
})));
|
|
98
|
+
}).observe({ type: 'event', buffered: true, durationThreshold: 16 });
|
|
99
|
+
});
|
|
100
|
+
const button = page.getByRole('button').first();
|
|
101
|
+
await button.click();
|
|
102
|
+
const report = await page.evaluate(() => {
|
|
103
|
+
const perfGlobal = globalThis;
|
|
104
|
+
return {
|
|
105
|
+
longTasks: (perfGlobal.__pwLongTasks || []).filter((entry) => entry.duration >= 50),
|
|
106
|
+
events: (perfGlobal.__pwEventTimings || []).filter((entry) => entry.interactionId !== 0),
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
console.log(report);
|
|
110
|
+
}
|
|
111
|
+
export { collectWebVitals, collectHeaviestRequests, measureInteractivity };
|
|
112
|
+
//# sourceMappingURL=performance-examples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-examples.js","sourceRoot":"","sources":["../src/performance-examples.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
# Profile Website Performance with Playwriter
|
|
2
|
+
|
|
3
|
+
Playwriter can profile a real website in your own Chrome using **CDP**, **Navigation Timing**,
|
|
4
|
+
and **PerformanceObserver**.
|
|
5
|
+
|
|
6
|
+
Use it to answer four practical questions quickly:
|
|
7
|
+
|
|
8
|
+
1. **Did the page render fast enough?**
|
|
9
|
+
2. **What requests cost the most bytes?**
|
|
10
|
+
3. **What blocked first paint or LCP?**
|
|
11
|
+
4. **What blocked interactivity?**
|
|
12
|
+
|
|
13
|
+
## What to measure
|
|
14
|
+
|
|
15
|
+
| Metric | Good | Needs work | Usually means |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
| **TTFB** | under **800ms** | over **1.2s** | slow server or cache miss |
|
|
18
|
+
| **FCP** | under **1.8s** | over **3s** | content appears late |
|
|
19
|
+
| **LCP** | under **2.5s** | over **4s** | hero image, font, CSS, server, or JS delay |
|
|
20
|
+
| **CLS** | under **0.1** | over **0.25** | unstable layout |
|
|
21
|
+
| **Long task** | under **50ms** | over **100ms** | main thread blocked by JS |
|
|
22
|
+
| **JS transfer** | under **250KB** | over **500KB** | too much hydration or client code |
|
|
23
|
+
| **Font / media transfer** | context dependent | large above-the-fold assets | fonts, posters, videos, hero images |
|
|
24
|
+
|
|
25
|
+
## What usually blocks what
|
|
26
|
+
|
|
27
|
+
- **First paint / FCP** is usually gated by **TTFB**, critical HTML, critical CSS, and above-the-fold fonts/images.
|
|
28
|
+
- **LCP** is usually gated by the **largest hero asset**. Common causes: hero image, poster image, custom font, render-blocking CSS, or slow server response.
|
|
29
|
+
- **Interactivity** is usually gated by **long tasks**. Common causes: too much JS on startup, hydration, or a large framework chunk.
|
|
30
|
+
- **Load event** often stays late because of **non-critical assets** like videos, analytics, background images, and delayed client bundles.
|
|
31
|
+
|
|
32
|
+
## Quick commands
|
|
33
|
+
|
|
34
|
+
Create a session and open a page:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
playwriter session new
|
|
38
|
+
playwriter -s 1 -e 'state.page = context.pages().find((p) => p.url() === "about:blank") ?? (await context.newPage()); await state.page.goto("https://example.com", { waitUntil: "domcontentloaded" })'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Collect a concise vitals report:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
playwriter -s 1 -e "$(cat <<'EOF'
|
|
45
|
+
await state.page.evaluate(() => {
|
|
46
|
+
const metrics = { paints: {}, lcp: 0, cls: 0 }
|
|
47
|
+
globalThis.__pwMetrics = metrics
|
|
48
|
+
|
|
49
|
+
new PerformanceObserver((list) => {
|
|
50
|
+
for (const entry of list.getEntries()) {
|
|
51
|
+
metrics.paints[entry.name] = entry.startTime
|
|
52
|
+
}
|
|
53
|
+
}).observe({ type: 'paint', buffered: true })
|
|
54
|
+
|
|
55
|
+
new PerformanceObserver((list) => {
|
|
56
|
+
const lastEntry = list.getEntries().at(-1)
|
|
57
|
+
if (lastEntry) {
|
|
58
|
+
metrics.lcp = lastEntry.startTime
|
|
59
|
+
}
|
|
60
|
+
}).observe({ type: 'largest-contentful-paint', buffered: true })
|
|
61
|
+
|
|
62
|
+
new PerformanceObserver((list) => {
|
|
63
|
+
for (const entry of list.getEntries()) {
|
|
64
|
+
if (!entry.hadRecentInput) {
|
|
65
|
+
metrics.cls += entry.value
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}).observe({ type: 'layout-shift', buffered: true })
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
await state.page.reload({ waitUntil: 'domcontentloaded' })
|
|
72
|
+
await waitForPageLoad({ page: state.page, timeout: 10000 })
|
|
73
|
+
await state.page.waitForTimeout(3000)
|
|
74
|
+
|
|
75
|
+
const report = await state.page.evaluate(() => {
|
|
76
|
+
const nav = performance.getEntriesByType('navigation')[0]
|
|
77
|
+
const metrics = globalThis.__pwMetrics
|
|
78
|
+
return {
|
|
79
|
+
ttfb: nav?.responseStart || 0,
|
|
80
|
+
domContentLoaded: nav?.domContentLoadedEventEnd || 0,
|
|
81
|
+
load: nav?.loadEventEnd || 0,
|
|
82
|
+
fcp: metrics?.paints['first-contentful-paint'] || 0,
|
|
83
|
+
lcp: metrics?.lcp || 0,
|
|
84
|
+
cls: metrics?.cls || 0,
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
console.log(JSON.stringify(report, null, 2))
|
|
89
|
+
EOF
|
|
90
|
+
)"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
List the heaviest requests with CDP:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
playwriter -s 1 -e "$(cat <<'EOF'
|
|
97
|
+
const cdp = await getCDPSession({ page: state.page })
|
|
98
|
+
await cdp.send('Network.enable')
|
|
99
|
+
await cdp.send('Network.setCacheDisabled', { cacheDisabled: true })
|
|
100
|
+
|
|
101
|
+
const responses = new Map()
|
|
102
|
+
const finished = new Map()
|
|
103
|
+
|
|
104
|
+
cdp.on('Network.responseReceived', (event) => {
|
|
105
|
+
responses.set(event.requestId, {
|
|
106
|
+
url: event.response.url,
|
|
107
|
+
mimeType: event.response.mimeType,
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
cdp.on('Network.loadingFinished', (event) => {
|
|
112
|
+
finished.set(event.requestId, event.encodedDataLength)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
await state.page.reload({ waitUntil: 'domcontentloaded' })
|
|
116
|
+
await waitForPageLoad({ page: state.page, timeout: 10000 })
|
|
117
|
+
await state.page.waitForTimeout(3000)
|
|
118
|
+
|
|
119
|
+
const largest = [...responses.entries()]
|
|
120
|
+
.map(([requestId, response]) => ({
|
|
121
|
+
url: response.url,
|
|
122
|
+
mimeType: response.mimeType,
|
|
123
|
+
bytes: finished.get(requestId) || 0,
|
|
124
|
+
}))
|
|
125
|
+
.sort((a, b) => b.bytes - a.bytes)
|
|
126
|
+
.slice(0, 10)
|
|
127
|
+
|
|
128
|
+
console.log(JSON.stringify(largest, null, 2))
|
|
129
|
+
EOF
|
|
130
|
+
)"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Check interactivity blockers:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
playwriter -s 1 -e "$(cat <<'EOF'
|
|
137
|
+
await state.page.evaluate(() => {
|
|
138
|
+
globalThis.__pwLongTasks = []
|
|
139
|
+
globalThis.__pwEvents = []
|
|
140
|
+
|
|
141
|
+
new PerformanceObserver((list) => {
|
|
142
|
+
globalThis.__pwLongTasks.push(
|
|
143
|
+
...list.getEntries().map((entry) => ({ startTime: entry.startTime, duration: entry.duration })),
|
|
144
|
+
)
|
|
145
|
+
}).observe({ type: 'longtask', buffered: true })
|
|
146
|
+
|
|
147
|
+
new PerformanceObserver((list) => {
|
|
148
|
+
globalThis.__pwEvents.push(
|
|
149
|
+
...list.getEntries().map((entry) => ({
|
|
150
|
+
name: entry.name,
|
|
151
|
+
duration: entry.duration,
|
|
152
|
+
interactionId: entry.interactionId,
|
|
153
|
+
})),
|
|
154
|
+
)
|
|
155
|
+
}).observe({ type: 'event', buffered: true, durationThreshold: 16 })
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
await state.page.getByRole('button').first().click()
|
|
159
|
+
await state.page.waitForTimeout(1000)
|
|
160
|
+
|
|
161
|
+
const report = await state.page.evaluate(() => ({
|
|
162
|
+
longTasks: globalThis.__pwLongTasks.filter((entry) => entry.duration >= 50),
|
|
163
|
+
interactions: globalThis.__pwEvents.filter((entry) => entry.interactionId !== 0),
|
|
164
|
+
}))
|
|
165
|
+
|
|
166
|
+
console.log(JSON.stringify(report, null, 2))
|
|
167
|
+
EOF
|
|
168
|
+
)"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## How to read the results
|
|
172
|
+
|
|
173
|
+
**Fast render, heavy payload**
|
|
174
|
+
|
|
175
|
+
- If **FCP** and **LCP** are good but total bytes are huge, the page probably **looks fast on desktop** but wastes bandwidth on mobile.
|
|
176
|
+
- This often happens with **hero videos**, large poster images, or custom fonts.
|
|
177
|
+
|
|
178
|
+
**Slow first paint**
|
|
179
|
+
|
|
180
|
+
- If **TTFB** is high, fix **server latency** or caching first.
|
|
181
|
+
- If **TTFB** is fine but **FCP** is slow, inspect critical CSS, fonts, and above-the-fold images.
|
|
182
|
+
|
|
183
|
+
**Slow interactivity**
|
|
184
|
+
|
|
185
|
+
- If you see **long tasks over 50ms**, startup JS is the first suspect.
|
|
186
|
+
- Look for large client bundles, hydration-heavy UI, and event handlers doing too much work.
|
|
187
|
+
|
|
188
|
+
**Need deeper CPU answers**
|
|
189
|
+
|
|
190
|
+
- If vitals and request sizes are not enough, record a **`.cpuprofile`** with Playwriter's raw **`Profiler.*`** CDP commands and inspect it with **[profano](https://github.com/remorses/profano)**.
|
|
191
|
+
- A good place to keep your reusable profiling snippets is your dots repo, for example **`~/.config/opencode/`**.
|
|
192
|
+
|
|
193
|
+
**Good load event is not enough**
|
|
194
|
+
|
|
195
|
+
- A page can have a decent `load` time and still feel slow if **LCP** or **long tasks** are bad.
|
|
196
|
+
- Prefer **TTFB + FCP + LCP + CLS + long tasks** over the load event alone.
|
|
197
|
+
|
|
198
|
+
## Performance checklist
|
|
199
|
+
|
|
200
|
+
**If TTFB is bad**
|
|
201
|
+
|
|
202
|
+
- cache HTML closer to users
|
|
203
|
+
- reduce origin work before response
|
|
204
|
+
- avoid expensive server-side data fetching on the critical route
|
|
205
|
+
|
|
206
|
+
**If FCP or LCP is bad**
|
|
207
|
+
|
|
208
|
+
- trim or defer render-blocking CSS
|
|
209
|
+
- avoid large above-the-fold fonts and images
|
|
210
|
+
- preload only truly critical assets
|
|
211
|
+
- compress hero media harder
|
|
212
|
+
|
|
213
|
+
**If interactivity is bad**
|
|
214
|
+
|
|
215
|
+
- reduce startup JS
|
|
216
|
+
- split large client bundles
|
|
217
|
+
- avoid hydrating UI that is not immediately interactive
|
|
218
|
+
- move optional widgets behind user action or idle time
|
|
219
|
+
- if the culprit is still unclear, switch from vitals to a CPU profile and inspect hot functions with **profano**
|
|
220
|
+
|
|
221
|
+
**If bytes are bad but vitals look good**
|
|
222
|
+
|
|
223
|
+
- optimize for slower devices anyway
|
|
224
|
+
- background videos are the first thing to cut
|
|
225
|
+
- subset fonts and trim non-critical client features
|
|
226
|
+
|
|
227
|
+
## Examples
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
// Example snippets for profiling website performance with Playwriter and CDP.
|
|
231
|
+
|
|
232
|
+
import { console, getCDPSession, page } from './debugger-examples-types.js'
|
|
233
|
+
|
|
234
|
+
type PerfMetrics = {
|
|
235
|
+
paints: Record<string, number>
|
|
236
|
+
lcp: number
|
|
237
|
+
cls: number
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
type ObservedPerfEntry = {
|
|
241
|
+
name: string
|
|
242
|
+
startTime: number
|
|
243
|
+
duration: number
|
|
244
|
+
hadRecentInput?: boolean
|
|
245
|
+
value?: number
|
|
246
|
+
interactionId?: number
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
type NavigationTimingEntry = {
|
|
250
|
+
responseStart: number
|
|
251
|
+
domContentLoadedEventEnd: number
|
|
252
|
+
loadEventEnd: number
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
type LongTaskEntry = {
|
|
256
|
+
startTime: number
|
|
257
|
+
duration: number
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
type EventTimingEntry = {
|
|
261
|
+
name: string
|
|
262
|
+
duration: number
|
|
263
|
+
interactionId: number
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Example: Collect navigation timing and basic web vitals from the current page
|
|
267
|
+
async function collectWebVitals() {
|
|
268
|
+
await page.evaluate(() => {
|
|
269
|
+
const metrics: PerfMetrics = {
|
|
270
|
+
paints: {},
|
|
271
|
+
lcp: 0,
|
|
272
|
+
cls: 0,
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const perfGlobal = globalThis as typeof globalThis & {
|
|
276
|
+
__pwPerfMetrics?: PerfMetrics
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
perfGlobal.__pwPerfMetrics = metrics
|
|
280
|
+
|
|
281
|
+
new PerformanceObserver((list) => {
|
|
282
|
+
for (const entry of list.getEntries() as ObservedPerfEntry[]) {
|
|
283
|
+
metrics.paints[entry.name] = entry.startTime
|
|
284
|
+
}
|
|
285
|
+
}).observe({ type: 'paint', buffered: true } as never)
|
|
286
|
+
|
|
287
|
+
new PerformanceObserver((list) => {
|
|
288
|
+
const entries = list.getEntries() as ObservedPerfEntry[]
|
|
289
|
+
const lastEntry = entries[entries.length - 1]
|
|
290
|
+
if (!lastEntry) {
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
metrics.lcp = lastEntry.startTime
|
|
294
|
+
}).observe({ type: 'largest-contentful-paint', buffered: true } as never)
|
|
295
|
+
|
|
296
|
+
new PerformanceObserver((list) => {
|
|
297
|
+
for (const entry of list.getEntries() as ObservedPerfEntry[]) {
|
|
298
|
+
if (entry.hadRecentInput) {
|
|
299
|
+
continue
|
|
300
|
+
}
|
|
301
|
+
metrics.cls += entry.value || 0
|
|
302
|
+
}
|
|
303
|
+
}).observe({ type: 'layout-shift', buffered: true } as never)
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
await page.reload({ waitUntil: 'domcontentloaded' })
|
|
307
|
+
|
|
308
|
+
const report = await page.evaluate(() => {
|
|
309
|
+
const perfGlobal = globalThis as typeof globalThis & {
|
|
310
|
+
__pwPerfMetrics?: PerfMetrics
|
|
311
|
+
}
|
|
312
|
+
const nav = performance.getEntriesByType('navigation' as never)[0] as unknown as
|
|
313
|
+
| NavigationTimingEntry
|
|
314
|
+
| undefined
|
|
315
|
+
const metrics = perfGlobal.__pwPerfMetrics
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
ttfb: nav?.responseStart || 0,
|
|
319
|
+
domContentLoaded: nav?.domContentLoadedEventEnd || 0,
|
|
320
|
+
load: nav?.loadEventEnd || 0,
|
|
321
|
+
fcp: metrics?.paints['first-contentful-paint'] || 0,
|
|
322
|
+
lcp: metrics?.lcp || 0,
|
|
323
|
+
cls: metrics?.cls || 0,
|
|
324
|
+
}
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
console.log(report)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Example: Measure the biggest transferred requests with raw CDP network events
|
|
331
|
+
async function collectHeaviestRequests() {
|
|
332
|
+
const cdp = await getCDPSession({ page })
|
|
333
|
+
await cdp.send('Network.enable')
|
|
334
|
+
await cdp.send('Network.setCacheDisabled', { cacheDisabled: true })
|
|
335
|
+
|
|
336
|
+
const responses = new Map<string, { url: string; mimeType: string }>()
|
|
337
|
+
const finished = new Map<string, number>()
|
|
338
|
+
|
|
339
|
+
cdp.on('Network.responseReceived', (event) => {
|
|
340
|
+
responses.set(event.requestId, {
|
|
341
|
+
url: event.response.url,
|
|
342
|
+
mimeType: event.response.mimeType,
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
cdp.on('Network.loadingFinished', (event) => {
|
|
347
|
+
finished.set(event.requestId, event.encodedDataLength)
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
await page.reload({ waitUntil: 'domcontentloaded' })
|
|
351
|
+
|
|
352
|
+
const largest = [...responses.entries()]
|
|
353
|
+
.map(([requestId, response]) => {
|
|
354
|
+
return {
|
|
355
|
+
url: response.url,
|
|
356
|
+
mimeType: response.mimeType,
|
|
357
|
+
bytes: finished.get(requestId) || 0,
|
|
358
|
+
}
|
|
359
|
+
})
|
|
360
|
+
.sort((a, b) => b.bytes - a.bytes)
|
|
361
|
+
.slice(0, 10)
|
|
362
|
+
|
|
363
|
+
console.log(largest)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Example: Check whether interactivity is blocked by long tasks or slow events
|
|
367
|
+
async function measureInteractivity() {
|
|
368
|
+
await page.evaluate(() => {
|
|
369
|
+
const perfGlobal = globalThis as typeof globalThis & {
|
|
370
|
+
__pwLongTasks?: LongTaskEntry[]
|
|
371
|
+
__pwEventTimings?: EventTimingEntry[]
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
perfGlobal.__pwLongTasks = []
|
|
375
|
+
perfGlobal.__pwEventTimings = []
|
|
376
|
+
|
|
377
|
+
new PerformanceObserver((list) => {
|
|
378
|
+
perfGlobal.__pwLongTasks?.push(
|
|
379
|
+
...(list.getEntries() as ObservedPerfEntry[]).map((entry) => ({
|
|
380
|
+
startTime: entry.startTime,
|
|
381
|
+
duration: entry.duration,
|
|
382
|
+
})),
|
|
383
|
+
)
|
|
384
|
+
}).observe({ type: 'longtask', buffered: true } as never)
|
|
385
|
+
|
|
386
|
+
new PerformanceObserver((list) => {
|
|
387
|
+
perfGlobal.__pwEventTimings?.push(
|
|
388
|
+
...(list.getEntries() as ObservedPerfEntry[]).map((entry) => ({
|
|
389
|
+
name: entry.name,
|
|
390
|
+
duration: entry.duration,
|
|
391
|
+
interactionId: entry.interactionId || 0,
|
|
392
|
+
})),
|
|
393
|
+
)
|
|
394
|
+
}).observe({ type: 'event', buffered: true, durationThreshold: 16 } as never)
|
|
395
|
+
})
|
|
396
|
+
|
|
397
|
+
const button = page.getByRole('button').first()
|
|
398
|
+
await button.click()
|
|
399
|
+
|
|
400
|
+
const report = await page.evaluate(() => {
|
|
401
|
+
const perfGlobal = globalThis as typeof globalThis & {
|
|
402
|
+
__pwLongTasks?: LongTaskEntry[]
|
|
403
|
+
__pwEventTimings?: EventTimingEntry[]
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return {
|
|
407
|
+
longTasks: (perfGlobal.__pwLongTasks || []).filter((entry) => entry.duration >= 50),
|
|
408
|
+
events: (perfGlobal.__pwEventTimings || []).filter((entry) => entry.interactionId !== 0),
|
|
409
|
+
}
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
console.log(report)
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export { collectWebVitals, collectHeaviestRequests, measureInteractivity }
|
|
416
|
+
|
|
417
|
+
```
|
package/dist/prompt.md
CHANGED
|
@@ -57,6 +57,7 @@ You can collaborate with the user - they can help with captchas, difficult eleme
|
|
|
57
57
|
- **Wait for load**: use `state.page.waitForLoadState('domcontentloaded')` not `state.page.waitForEvent('load')` - waitForEvent times out if already loaded
|
|
58
58
|
- **Minimize timeouts**: prefer proper waits (`waitForSelector`, `waitForPageLoad`) over `state.page.waitForTimeout()`. Short timeouts (1-2s) are acceptable for non-deterministic events like animations, tab opens, or async UI updates where no specific selector is available
|
|
59
59
|
- **Snapshot before screenshot**: always use `snapshot()` first to understand page state (text-based, fast, cheap). Only use `screenshot` when you specifically need visual/spatial information. Never take a screenshot just to check if a page loaded or to read text content — snapshot gives you that instantly without burning image tokens
|
|
60
|
+
- **Always use absolute file paths for Playwright artifact APIs**: for `page.screenshot({ path })`, `locator.screenshot({ path })`, `elementHandle.screenshot({ path })`, `page.pdf({ path })`, `download.saveAs(path)`, and `video.saveAs(path)`, always pass an absolute path. Relative paths are resolved by Playwright client internals, not the sandboxed `fs`, so they may use the relay server cwd instead of your session cwd.
|
|
60
61
|
- **Snapshot replaces page.evaluate() for inspection**: do NOT write `page.evaluate()` calls to manually query class names, bounding boxes, child counts, or visibility flags. `snapshot()` already shows every interactive element with its text, role, and a ready-to-use locator. If you catch yourself writing `document.querySelector` or `getBoundingClientRect` inside evaluate — stop and use `snapshot()` instead. Reserve `page.evaluate()` for actions that modify page state (e.g., `localStorage.clear()`, scroll manipulation) or extract non-DOM data (e.g., `window.__CONFIG__`)
|
|
61
62
|
|
|
62
63
|
## interaction feedback loop
|
|
@@ -449,7 +450,7 @@ Instead, use simpler alternatives (single download via `a.click()`, store data i
|
|
|
449
450
|
|
|
450
451
|
```js
|
|
451
452
|
const [download] = await Promise.all([state.page.waitForEvent('download'), state.page.click('button.download')])
|
|
452
|
-
await download.saveAs(`/
|
|
453
|
+
await download.saveAs(`/absolute/path/${download.suggestedFilename()}`)
|
|
453
454
|
```
|
|
454
455
|
|
|
455
456
|
**iFrames** - two approaches depending on what you need:
|
|
@@ -602,6 +603,19 @@ const source = await getReactSource({ locator: state.page.locator('[data-testid=
|
|
|
602
603
|
// => { fileName, lineNumber, columnNumber, componentName }
|
|
603
604
|
```
|
|
604
605
|
|
|
606
|
+
**getReactComponentInfo** - get best-effort React component info for an element. Returns `null` for non-React elements and never throws just because an element was not rendered by React. Source locations are usually only available in React dev builds. Props are sanitized and truncated so functions, DOM nodes, circular refs, and huge objects do not flood the output.
|
|
607
|
+
|
|
608
|
+
```js
|
|
609
|
+
const info = await getReactComponentInfo({ locator: state.page.locator('[data-testid="submit-btn"]') })
|
|
610
|
+
// => { componentName, source, hierarchy, props } | null
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
**inspectPinnedElement** - inspect a Playwriter pinned element and print the element `outerHTML` plus React component info when available. Used by the in-page toolbar and right-click copy flow.
|
|
614
|
+
|
|
615
|
+
```js
|
|
616
|
+
await inspectPinnedElement('https://example.com', 'globalThis.playwriterPinnedElem1')
|
|
617
|
+
```
|
|
618
|
+
|
|
605
619
|
**getStylesForLocator** - inspect CSS styles applied to an element, like browser DevTools "Styles" panel. Useful for debugging styling issues, finding where a CSS property is defined (file:line), and checking inherited styles. Returns selector, source location, and declarations for each matching rule. ALWAYS fetch `https://playwriter.dev/resources/styles-api.md` first with curl or webfetch tool.
|
|
606
620
|
|
|
607
621
|
```js
|
|
@@ -654,7 +668,7 @@ await screenshotWithAccessibilityLabels({ page: state.page })
|
|
|
654
668
|
|
|
655
669
|
Labels are color-coded: yellow=links, orange=buttons, coral=inputs, pink=checkboxes, peach=sliders, salmon=menus, amber=tabs.
|
|
656
670
|
|
|
657
|
-
**resizeImageForAgent** - shrink an image so it consumes fewer tokens when read back into context. The resized image is automatically included in the response (visible to the LLM). `await resizeImageForAgent({ input: '
|
|
671
|
+
**resizeImageForAgent** - shrink an image so it consumes fewer tokens when read back into context. The resized image is automatically included in the response (visible to the LLM). `await resizeImageForAgent({ input: '/absolute/path/to/screenshot.png' })`. Also accepts `width`, `height`, `maxDimension`, `quality`, `format` (default: `'png'`), `output`. Alias: `resizeImage`.
|
|
658
672
|
|
|
659
673
|
**recording.start / recording.stop** - record the page as a video at native FPS (30-60fps). Uses `chrome.tabCapture` so **recording survives page navigation**. Auto-overlays a ghost cursor that follows mouse actions. Requires user to have clicked the Playwriter extension icon on the tab. Auto-resizes viewport to 16:9 (override with `aspectRatio: null`). Auto-stops after 15 min (override with `maxDurationMs`).
|
|
660
674
|
|
|
@@ -663,7 +677,7 @@ For demos, use interaction methods (`locator.click()`, `page.mouse.move()`) inst
|
|
|
663
677
|
```js
|
|
664
678
|
await recording.start({
|
|
665
679
|
page: state.page,
|
|
666
|
-
outputPath: '
|
|
680
|
+
outputPath: '/absolute/path/to/recording.mp4',
|
|
667
681
|
frameRate: 30, // default
|
|
668
682
|
audio: false, // default (tab audio)
|
|
669
683
|
videoBitsPerSecond: 2500000,
|
|
@@ -717,7 +731,7 @@ await el.click()
|
|
|
717
731
|
Always use `scale: 'css'` to avoid 2-4x larger images on high-DPI displays:
|
|
718
732
|
|
|
719
733
|
```js
|
|
720
|
-
await state.page.screenshot({ path: 'shot.png', scale: 'css' })
|
|
734
|
+
await state.page.screenshot({ path: '/absolute/path/to/shot.png', scale: 'css' })
|
|
721
735
|
```
|
|
722
736
|
|
|
723
737
|
If you want to read back the image file into context, resize it first so it consumes fewer tokens:
|
|
@@ -896,7 +910,7 @@ await state.page.setViewportSize({ width: 1280, height: 720 })
|
|
|
896
910
|
### region screenshot (zoom equivalent)
|
|
897
911
|
|
|
898
912
|
```js
|
|
899
|
-
await state.page.screenshot({ path: 'region.png', scale: 'css', clip: { x: 100, y: 200, width: 400, height: 300 } })
|
|
913
|
+
await state.page.screenshot({ path: '/absolute/path/to/region.png', scale: 'css', clip: { x: 100, y: 200, width: 400, height: 300 } })
|
|
900
914
|
```
|
|
901
915
|
|
|
902
916
|
Prefer locator-based actions over coordinates — locators are stable across scroll/resize, auto-wait for elements, and don't require screenshot round-trips that burn ~800 image tokens per cycle.
|