- Handle failures during HTML, Markdown, and link serialization.
- Return MCP internal errors when result serialization fails.
- Refactor resource reading logic for better clarity and consistency.
Replace the hardcoded stub with a working implementation that stores
registered scripts and evaluates them in each new document.
Changes:
- Add ScriptOnNewDocument struct and storage list on BrowserContext
- Store scripts with unique identifiers when addScript is called
- Evaluate all registered scripts in pageNavigated, after the execution
context is created but before frameNavigated/loadEventFired events
are sent to the CDP client
- Add removeScriptToEvaluateOnNewDocument for cleanup
- Return unique identifiers per the CDP spec (was hardcoded to "1")
Scripts are evaluated with error suppression (warns on failure) to
avoid breaking navigation if a script has issues.
This unblocks CDP clients that rely on auto-injected scripts (polyfills,
monitoring, test helpers) persisting across navigations. Previously
clients had to manually re-inject after every Page.navigate.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixes issues reported by polyglot-scanner:
- Removed explicit `return` keywords and trailing semicolons to resolve DEAD_CODE/DEAD_BRANCH warnings.
- Replaced `epoch::advance().unwrap()` and `stats::resident::read().unwrap()` with safer alternatives (`drop` and `unwrap_or(0)`) to resolve ERROR_SWALLOW warnings.
- Replaced `let _ = Box::from_raw(...)` with `drop(Box::from_raw(...))` to correctly drop the box while fixing the ERROR_SWALLOW warning.
This fixes a bug in MCP where interactive elements were not assigned
a backendNodeId, preventing agents from clicking or filling them. Also
extracts link collection to a shared browser module.
Add `Page.reload` to the CDP Page domain dispatch. Reuses the existing
`page.navigate()` path with `NavigationKind.reload`, matching what
`Location.reload` already does for the JS `location.reload()` API.
Accepts the standard CDP params (`ignoreCache`, `scriptToEvaluateOnLoad`)
per the Chrome DevTools Protocol spec.
The current page URL is copied to the stack before `replacePage()` to
avoid a use-after-free when the old page's arena is freed.
This unblocks CDP clients (Puppeteer, capybara-lightpanda, etc.) that
call `Page.reload` and currently get `UnknownMethod`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only look for @ within the first part of the url (up to the first possible
separator, i.e /, # or ?). This fixes potentially incorrect (and insecure)
getOrigin and getHost, both of which use the new helper.
Also make port parsing IPv6-aware.
This causes v8 to verify the receiver of a function, and prevents calling an
accessor or function with the wrong receiver, e.g.:
```
const g = Object.getOwnPropertyDescriptor(Window.prototype, 'document').get;
g.call(null);
```
A few other cleanups in this commit:
1 - Define any accessor with a getter as ReadOnly
2 - Ability to define an accessor with the DontDelete attribute
(window.document and window.location)
3 - Replace v8__ObjectTemplate__SetAccessorProperty__DEFAULTX overloads with
new v8__ObjectTemplate__SetAccessorProperty__Config
4 - Remove unnecessary @constCast for FunctionTemplate which can be const
everywhere.
testing.async(...) is pretty lame. It works for simple cases, where the
microtask is very quickly resolved, but otherwise can't block the test from
exiting.
This adds an overload to testing.async and leverages the new Runner
https://github.com/lightpanda-io/browser/pull/1958 to "tick" until completion
(or timeout).
The overloaded version of testing.async() (called without a callback) will
increment a counter which is only decremented with the promise is resolved. The
test runner will now `tick` until the counter == 0.