Repository navigation
Replies: 3 comments 1 reply
|
Thanks for the idea. It is released as v0.22.0.
See |
|
Thank you for turning this around so quickly! Biloba v0.22.0 is out and uses the new listeners :) Claude encountered this during the port, in case it's useful: When a target detaches, a Target.Call still waiting on that target can wait until its context ends. Chrome doesn't always answer a command whose target goes away (an evaluate that runs window.close(), for example), and the routing loop can take the detach ahead of a reply already in its queue, after which the reply is dropped. We work around it in our transport wrapper by answering a detached session's pending commands with Chrome's "Inspected target navigated or closed" error. If you'd like an issue or a PR for failing those calls in chromedp itself, I'm happy to open one. |
|
Thanks for the quick fix in v0.22.1! Biloba is on it, and it let us delete most of the workaround. While adopting it, Claude found three smaller gaps that still keep a wrapper around the
Each part has its own commit, test and Proposed decision file. Happy to split it into three PRs, or to reshape any of it. Thanks again!! |
Uh oh!
There was an error while loading. Please reload this page.
The use case
I maintain Biloba, a browser-testing framework for Go built on chromedp. It brings automated browser testing to Ginkgo and Gomega. One Chrome process is shared by every parallel test process, and each process drives its own tabs. There is also a TypeScript client for Vitest that talks to a small Go daemon built on the same engine. Every Biloba tab exposes its chromedp context, so users drop to chromedp for anything Biloba doesn't wrap. In a reproducible comparison, Biloba runs the same suite about 3× faster than Playwright in parallel and 4× faster serially.
I'm porting Biloba from chromedp v0.15.1 to v0.21.1. The new API is a real improvement. One thing is missing: a way to see a session's events across methods, in the order Chrome sent them, before the reply to a later command reaches the caller.
Biloba depends on that order in several critical places, and while I can try to reconstruct the order externally there are many subtle edge cases that are proving difficult to pin down. It works, but it is fragile code doing something chromedp already does correctly inside.
EventsandBrowserEventsgive one iterator per event type, so they can't express the order between types. They are also buffered, so a call can return before a subscriber sees the earlier events. In v0.15.1,ListenTargetandListenBrowsergave both guarantees.What chromedp already has
The unexported
(*Target).listenand(*Browser).listeninchromedp.godo exactly this.Navigate,NavigateResponse,RunResponseand the new-target code use them. The decision record2026-10-03-generic-iterator-api-instead-of-action.mdsays why they stayed: the internal listener "keeps the order of events across methods, and a subscription to one method does not."The proposal
Export the existing listener with a narrow contract. For example:
The name and the shape are your call, of course. Package-level
chromedp.Listen(ctx, fn)/ListenBrowser(ctx, fn)that resolve the target from the context would work just as well for Biloba. Only events need to reachfn. The command replies that the internal listener also sees can stay internal. TheEventsiterators stay the recommended API, and this would be documented as the lower-level tool for code that needs the order across methods.I'm happy to send a PR with the change, the docs, a
docs/decisions/entry and tests, if you're open to the idea.All reactions