Commit Graph

5070 Commits

Author SHA1 Message Date
Karl Seguin
4e2e895cd9 Add --advertise_host option to serve command
Allows overwriting the --host for the json/version payload. When --host is set
to 0.0.0.0, we want to provide a mechanism to specify the specific address to
connect to in /json/version (or anywhere else that we "advertise" the address).

Inspired by https://github.com/lightpanda-io/browser/pull/1923 but rather than
defaulting to 127.0.0.1 (which seems just as unsafe), adds the explicit config
option.
2026-03-22 12:40:17 +08:00
Karl Seguin
c1fc2b1301 Merge pull request #1949 from lightpanda-io/1800-fix-startup-frame-id
Fix Page.getFrameId on STARTUP when a browser context and a target exist
2026-03-22 07:14:33 +08:00
Karl Seguin
324e5eb152 Merge pull request #1945 from lightpanda-io/replace_children
Add validation to replaceChildren
2026-03-22 06:44:53 +08:00
Karl Seguin
df4df64066 Merge pull request #1944 from lightpanda-io/about_blank_location
new URL('about:blank');
2026-03-22 06:44:37 +08:00
Karl Seguin
c557a0fd87 Merge pull request #1942 from lightpanda-io/about_blank_resolve
Search for base page when resolving from about:blank
2026-03-22 06:44:19 +08:00
Karl Seguin
a869f92e9a Merge pull request #1939 from lightpanda-io/timer_cleanup
More aggressive timer cleanup
2026-03-22 06:44:00 +08:00
Pierre Tachoire
fbc71d6ff7 cdp: handle STARTUP session into Page.getFrameTree gracefully 2026-03-21 16:29:58 +01:00
Pierre Tachoire
384b2f7614 cdp: call Page.getFrameTree on startup when possible 2026-03-21 16:07:48 +01:00
Adrià Arrufat
fdc79af55c Merge pull request #1941 from mvanhorn/osc/feat-mcp-waitforselector
Add waitForSelector MCP tool
2026-03-21 23:59:14 +09:00
Matt Van Horn
e9bed18cd8 test: add waitForSelector MCP tool tests
Add three test cases covering:
- Immediate match on an already-present element
- Polling match on an element added after a 200ms setTimeout delay
- Timeout error on a non-existent element with a short timeout

Add mcp_wait_for_selector.html test fixture that injects a #delayed
element after 200ms via setTimeout for the polling test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 06:40:43 -07:00
Karl Seguin
e7d272eaf6 Merge pull request #1940 from lightpanda-io/fix-mcp-crash
mcp: initialize server in mcpThread to avoid V8 isolate crashes
2026-03-21 20:35:31 +08:00
Karl Seguin
e60424a402 Add validation to replaceChildren
Extract Document.replaceChildren, Element.replaceChildren and
DocumentFragment.replaceChildren into a common helper, Node.replaceChildren.

Fixes an infinite loop in WPT test:
/dom/nodes/ParentNode-replaceChildren.html
2026-03-21 19:39:49 +08:00
Karl Seguin
107da49f81 new URL('about:blank');
Add correct handling for new URL('about:blank');

When a frame is navigated to about:blank (which happens often, since it happens
as soon as a dynamic iframe is created), we make sure to give window._location
a unique value. This prevents 2 frames from referencing the same
window._location object.

Fixes a WPT crash in: 0/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-nosrc.html
2026-03-21 18:41:58 +08:00
Karl Seguin
3e309da69f Search for base page when resolving from about:blank
When the base page (*cough* frame *cough*) is about:blank, then we need to go
up the parents to find the actual base url to resolve any new navigation URLs.
2026-03-21 16:03:39 +08:00
Adrià Arrufat
370ae2b85c main: zig fmt 2026-03-21 14:06:08 +09:00
Matt Van Horn
6008187c78 Add waitForSelector MCP tool
Adds a waitForSelector tool to the MCP server that polls for a CSS
selector match with a configurable timeout (default 5000ms). Returns the
backendNodeId of the matched element for use with click/fill tools.

The tool runs the session event loop between selector checks, so
dynamically-created elements are found as they appear from JS execution
or network responses.
2026-03-20 21:38:11 -07:00
Adrià Arrufat
598fa254cf mcp: initialize server in mcpThread to avoid V8 isolate crashes
When running mcp server, it initialized lp.mcp.Server in the main thread
which also implicitly created the V8 isolate in the main thread.
When processing requests (like calling the goto tool) inside mcpThread,
V8 would assert that the isolate doesn't match the current thread.

Fixes #1938
2026-03-21 13:33:54 +09:00
Karl Seguin
8526770e9f More aggressive timer cleanup
When a timer is cleared, e.g. clearInterval, we flag the task are deleted and
maintain the entry in window._timers. When run, the task is ignored and deleted
from _timers.

This can result in prematurely rejecting timers due to `TooManyTimeout`. One
pattern I've seen is a RAF associated with an element where the RAF is cleared
(cancelAnimationFrame) if already registered. This can quickly result in
TooManyTimers.

This commit removes the timer from _timers as soon as it's canceled. It doesn't
fully eliminate the chance of TooManyTimeout, but it does reduce it.
2026-03-21 11:38:16 +08:00
Karl Seguin
b4b7a7d58a Merge pull request #1901 from lightpanda-io/goodbye_origin
Remove Origins
2026-03-21 07:19:47 +08:00
Karl Seguin
a5378feb1d Merge pull request #1927 from lightpanda-io/feat/fetch-wait-options
Feat/fetch wait options
2026-03-21 07:18:59 +08:00
Adrià Arrufat
b5d3d37f16 Merge pull request #1931 from lightpanda-io/fix/mcp-jsonrpc-response
Fix MCP error responses missing jsonrpc field
2026-03-21 06:23:34 +09:00
Pierre Tachoire
9b02e4963b Merge pull request #1929 from mvanhorn/osc/1819-fix-detach-session-null
Send Target.detachedFromTarget event on detach
2026-03-20 20:06:19 +01:00
Halil Durak
a865b86fa5 Merge pull request #1925 from lightpanda-io/nikneym/promise-error
Return correct errors in promise rejections
2026-03-20 14:05:21 +03:00
Halil Durak
de28d14aff give up on switch (comptime kind), prefer union(enum) 2026-03-20 13:35:12 +03:00
Karl Seguin
88681b1fdb Fix Context's call_arena
The Context's call_arena should be based on the source, e.g. the IsolateWorld
or the Page, not always the page. There's no rule that says all Contexts have
to be a subset of the Page, and thus some might live longer and by doing so
outlive the page_arena.

Also, on context cleanup, isolate worlds now cleanup their identity.
2026-03-20 16:50:03 +08:00
Adrià Arrufat
02d05ae464 Fix MCP error responses missing jsonrpc field
Closes #1928
2026-03-20 09:55:54 +09:00
Matt Van Horn
6925fc3f70 fix(cdp): return real frame ID in STARTUP getFrameTree when page exists
dispatchStartupCommand hard-codes "TID-STARTUP" as the frame ID in
Page.getFrameTree. When a driver connects via connectOverCDP after a
real page already exists, subsequent lifecycle events (frameNavigated)
use the actual page frame ID. The driver's frame tracking was
initialized with "TID-STARTUP", causing a mismatch that hangs
navigation.

Check for an existing browser context with a target_id in
dispatchStartupCommand. If present, return the real frame ID and URL.
Fall back to "TID-STARTUP" only when no page exists yet.

Fixes #1800

This contribution was developed with AI assistance (Claude Code + Codex).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 16:45:17 -07:00
Matt Van Horn
84557cb4e6 fix(cdp): send Target.detachedFromTarget event on detach
detachFromTarget and setAutoAttach(false) both null bc.session_id
without notifying the client. Per the CDP spec, detaching a session
must fire a Target.detachedFromTarget event so the driver stops
sending messages on the stale session ID.

Capture the session_id before nulling it and fire the event in both
code paths. Add tests covering the event emission and the no-session
edge case.

Fixes #1819

This contribution was developed with AI assistance (Claude Code + Codex).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 16:42:32 -07:00
Karl Seguin
4cdc24326a Merge pull request #1918 from lightpanda-io/shadowroot_adoptedstyle
Add `adoptedStyleSheets` property to ShadowRoot, just like Document
2026-03-20 07:11:49 +08:00
Karl Seguin
cf46f0097a Merge pull request #1915 from lightpanda-io/unhandled_rejection_improvements
Improve unhandled rejection
2026-03-20 07:11:35 +08:00
Pierre Tachoire
d94fd2a43b Merge pull request #1793 from lightpanda-io/wpt-selfhost
Move WPT runs on a dedicated host
2026-03-19 17:35:21 +01:00
Pierre Tachoire
8c5e737669 ci: use mem-limit with wptrunner 2026-03-19 15:40:18 +01:00
Pierre Tachoire
fb29a1c5bf ci: adjust wpt serve wait time 2026-03-19 15:40:18 +01:00
Halil Durak
94190f93af return correct errors from promises 2026-03-19 16:30:09 +03:00
Halil Durak
93e239f682 bind more ECMAScript errors 2026-03-19 16:27:51 +03:00
Karl Seguin
a4cb5031d1 Tweak wait_until option
Small tweaks to https://github.com/lightpanda-io/browser/pull/1896

Improve the wait ergonomics with an Option with default parameter. Revert
page pointer logic to original (don't think that change was necessary).
2026-03-19 20:29:20 +08:00
Karl Seguin
a2e59af44c Merge pull request #1911 from lightpanda-io/fix/turnstile-300030-missing-navigator-apis
Fix/turnstile 300030 missing navigator apis
2026-03-19 20:26:27 +08:00
Karl Seguin
00c962bdd8 Merge pull request #1914 from lightpanda-io/semantic-tree-depth
SemanticTree: add progressive discoverability
2026-03-19 20:12:02 +08:00
Karl Seguin
1fa87442b8 log not_implemented on navigator.getBattery 2026-03-19 20:11:03 +08:00
Karl Seguin
ac5400696a Merge pull request #1916 from lightpanda-io/request_abort
Add Request.signal
2026-03-19 20:07:12 +08:00
Adrià Arrufat
5062273b7a SemanticTree: use CDPNode.Id for NodeData id 2026-03-19 20:29:54 +09:00
Adrià Arrufat
9c2393351d SemanticTree: simplify max_depth logic 2026-03-19 20:25:20 +09:00
Adrià Arrufat
f0cfe3ffc8 SemanticTree: use logger better
Co-authored-by: Karl Seguin <karlseguin@users.noreply.github.com>
2026-03-19 20:15:56 +09:00
Karl Seguin
f70865e174 Take 2.
History: We started with 1 context and thus only had 1 identity map. Frames
were added, and we tried to stick with 1 identity map per context. That didn't
work - it breaks cross-frame scripting. We introduced "Origin" so that all
frames on the same origin share the same objects. That almost worked, by
the v8::Inspector isn't bound by a Context's SecurityToken. So we tried 1 global
identity map. But that doesn't work. CDP IsolateWorlds do, in fact, need some
isolation. They need new v8::Objects created in their context, even if the
object already exists in the main context.

In the end, you end up with something like this: A page (and all its frames)
needs 1 view of the data. And each IsolateWorld needs it own view. This commit
introduces a js.Identity which is referenced by the context. The Session has a
js.Identity (used by all pages), and each IsolateWorld has its own js.Identity.

As a bonus, the arena pool memory-leak detection has been moved out of the
session and into the ArenaPool. This means _all_ arena pool access is audited
(in debug mode). This seems superfluous, but it's actually necessary since
IsolateWorlds (which now own their own identity) can outlive the Page so there's
no clear place to "check" for leaks - except on ArenaPool deinit.
2026-03-19 18:46:35 +08:00
Pierre Tachoire
615fcffb99 Merge pull request #1924 from lightpanda-io/wba-test
Adjust wba test
2026-03-19 10:47:23 +01:00
Karl Seguin
13b746f9e4 Merge pull request #1919 from lightpanda-io/remove-make-shell
build: remove shell target from Makefile
2026-03-19 17:39:19 +08:00
Adrià Arrufat
e90fce4c55 Merge pull request #1920 from lightpanda-io/markdown-renderer-refactor
markdown: refactor renderer into a struct to simplify argument passing
2026-03-19 18:26:57 +09:00
Pierre Tachoire
59175437b5 wpt: force a wakeup of the wbauth server before the test 2026-03-19 09:40:47 +01:00
Pierre Tachoire
e950384b9b ci: sleep 5s to wait node startup 2026-03-19 09:36:47 +01:00
Pierre Tachoire
78440350dc ci: slow down execution 2026-03-19 09:32:27 +01:00