@vercel/next-browser 0.5.1 → 0.6.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/README.md +17 -8
- package/dist/browser.js +26 -0
- package/dist/cli.js +18 -1
- package/dist/daemon.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ Requires Node >= 20.
|
|
|
38
38
|
|
|
39
39
|
| Command | Description |
|
|
40
40
|
| ------------------------------------ | -------------------------------------------------- |
|
|
41
|
-
| `open <url> [--cookies
|
|
41
|
+
| `open <url> [--cookies <file>]` | Launch browser and navigate (with optional cookies) |
|
|
42
42
|
| `close` | Close browser and kill daemon |
|
|
43
43
|
|
|
44
44
|
### Navigation
|
|
@@ -62,9 +62,9 @@ Requires Node >= 20.
|
|
|
62
62
|
| `snapshot` | Accessibility tree with `[ref=eN]` markers on interactive elements |
|
|
63
63
|
| `errors` | Build and runtime errors for the current page |
|
|
64
64
|
| `logs` | Recent dev server log output |
|
|
65
|
+
| `browser-logs` | Browser console output (log, warn, error, info) |
|
|
65
66
|
| `network [idx]` | List network requests, or inspect one (headers, body) |
|
|
66
|
-
| `
|
|
67
|
-
| `screenshot` | Viewport PNG to a temp file (`--full-page` for entire page) |
|
|
67
|
+
| `screenshot [caption] [--full-page]` | Viewport PNG to a temp file (caption shown in Screenshot Log) |
|
|
68
68
|
|
|
69
69
|
### Interaction
|
|
70
70
|
|
|
@@ -77,11 +77,20 @@ Requires Node >= 20.
|
|
|
77
77
|
|
|
78
78
|
### Performance & PPR
|
|
79
79
|
|
|
80
|
-
| Command
|
|
81
|
-
|
|
|
82
|
-
| `perf [url]`
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
80
|
+
| Command | Description |
|
|
81
|
+
| ------------------------------ | ---------------------------------------------------- |
|
|
82
|
+
| `perf [url]` | Core Web Vitals + React hydration timing in one pass |
|
|
83
|
+
| `renders start` | Start recording React re-renders |
|
|
84
|
+
| `renders stop [--json]` | Stop and print per-component render profile |
|
|
85
|
+
| `ppr lock` | Freeze dynamic content to inspect the static shell |
|
|
86
|
+
| `ppr unlock` | Resume dynamic content and print shell analysis |
|
|
87
|
+
|
|
88
|
+
### Instrumentation
|
|
89
|
+
|
|
90
|
+
| Command | Description |
|
|
91
|
+
| ------------------------------ | ---------------------------------------------------- |
|
|
92
|
+
| `instrumentation set <path>` | Inject script before page scripts on every navigation |
|
|
93
|
+
| `instrumentation clear` | Remove instrumentation script |
|
|
85
94
|
|
|
86
95
|
### Next.js MCP
|
|
87
96
|
|
package/dist/browser.js
CHANGED
|
@@ -30,6 +30,7 @@ let page = null;
|
|
|
30
30
|
let profileDirPath = null;
|
|
31
31
|
let initialOrigin = null;
|
|
32
32
|
let ssrLocked = false;
|
|
33
|
+
let instrumentationVersion = 0;
|
|
33
34
|
let screenshotBrowser = null;
|
|
34
35
|
let screenshotPage = null;
|
|
35
36
|
let screenshotEntries = [];
|
|
@@ -87,6 +88,7 @@ export async function close() {
|
|
|
87
88
|
release = null;
|
|
88
89
|
settled = null;
|
|
89
90
|
ssrLocked = false;
|
|
91
|
+
instrumentationVersion = 0;
|
|
90
92
|
// Clean up temp profile directory.
|
|
91
93
|
if (profileDirPath) {
|
|
92
94
|
const { rmSync } = await import("node:fs");
|
|
@@ -95,6 +97,30 @@ export async function close() {
|
|
|
95
97
|
initialOrigin = null;
|
|
96
98
|
}
|
|
97
99
|
}
|
|
100
|
+
// ── Instrumentation ─────────────────────────────────────────────────────────
|
|
101
|
+
//
|
|
102
|
+
// addInitScript can't be removed, so we version-gate: each `set` bumps the
|
|
103
|
+
// version and registers a new script that only runs when its version matches.
|
|
104
|
+
// `clear` bumps the version with no matching script, disabling the old one.
|
|
105
|
+
export async function instrumentationSet(script) {
|
|
106
|
+
if (!page)
|
|
107
|
+
throw new Error("browser not open");
|
|
108
|
+
const ctx = page.context();
|
|
109
|
+
const v = ++instrumentationVersion;
|
|
110
|
+
// The version gate runs first, then the guarded script.
|
|
111
|
+
await ctx.addInitScript(`window.__NB_IV__=${v}`);
|
|
112
|
+
await ctx.addInitScript(`if(window.__NB_IV__===${v}){${script}}`);
|
|
113
|
+
// Apply immediately on the current page.
|
|
114
|
+
await page.evaluate(script);
|
|
115
|
+
}
|
|
116
|
+
export async function instrumentationClear() {
|
|
117
|
+
if (!page)
|
|
118
|
+
throw new Error("browser not open");
|
|
119
|
+
const ctx = page.context();
|
|
120
|
+
// Bump version — no matching script, so nothing runs.
|
|
121
|
+
const v = ++instrumentationVersion;
|
|
122
|
+
await ctx.addInitScript(`window.__NB_IV__=${v}`);
|
|
123
|
+
}
|
|
98
124
|
// ── PPR lock/unlock ──────────────────────────────────────────────────────────
|
|
99
125
|
//
|
|
100
126
|
// The lock uses @next/playwright's `instant()` which sets the
|
package/dist/cli.js
CHANGED
|
@@ -369,6 +369,20 @@ if (cmd === "viewport") {
|
|
|
369
369
|
const data = res.data;
|
|
370
370
|
exit(res, `${data.width}x${data.height}`);
|
|
371
371
|
}
|
|
372
|
+
if (cmd === "instrumentation" && arg === "set") {
|
|
373
|
+
const filePath = args[2];
|
|
374
|
+
if (!filePath) {
|
|
375
|
+
console.error("usage: next-browser instrumentation set <path>");
|
|
376
|
+
process.exit(1);
|
|
377
|
+
}
|
|
378
|
+
const script = readFileSync(filePath, "utf-8");
|
|
379
|
+
const res = await send("instrumentation-set", { instrumentationScript: script });
|
|
380
|
+
exit(res, "instrumentation set");
|
|
381
|
+
}
|
|
382
|
+
if (cmd === "instrumentation" && arg === "clear") {
|
|
383
|
+
const res = await send("instrumentation-clear");
|
|
384
|
+
exit(res, "instrumentation cleared");
|
|
385
|
+
}
|
|
372
386
|
if (cmd === "close") {
|
|
373
387
|
const res = await send("close");
|
|
374
388
|
exit(res, "closed");
|
|
@@ -477,5 +491,8 @@ function printUsage() {
|
|
|
477
491
|
" page show current page segments and router info\n" +
|
|
478
492
|
" project show project path and dev server url\n" +
|
|
479
493
|
" routes list app routes\n" +
|
|
480
|
-
" action <id> inspect a server action by id"
|
|
494
|
+
" action <id> inspect a server action by id\n" +
|
|
495
|
+
"\n" +
|
|
496
|
+
" instrumentation set <path> inject script before page scripts\n" +
|
|
497
|
+
" instrumentation clear remove instrumentation script");
|
|
481
498
|
}
|
package/dist/daemon.js
CHANGED
|
@@ -145,6 +145,14 @@ async function run(cmd) {
|
|
|
145
145
|
const data = await browser.viewportSize();
|
|
146
146
|
return { ok: true, data };
|
|
147
147
|
}
|
|
148
|
+
if (cmd.action === "instrumentation-set") {
|
|
149
|
+
await browser.instrumentationSet(cmd.instrumentationScript);
|
|
150
|
+
return { ok: true };
|
|
151
|
+
}
|
|
152
|
+
if (cmd.action === "instrumentation-clear") {
|
|
153
|
+
await browser.instrumentationClear();
|
|
154
|
+
return { ok: true };
|
|
155
|
+
}
|
|
148
156
|
if (cmd.action === "close") {
|
|
149
157
|
await browser.close();
|
|
150
158
|
return { ok: true };
|