Skip to content

feat: register adopted contexts from what Node reports - #5372

Merged
aaltat merged 3 commits into
MarketSquare:mainfrom
aaltat:adopted-context-registration
Oct 22, 2026
Merged

aaltat merged 3 commits into
MarketSquare:mainfrom
aaltat:adopted-context-registration

Conversation

@aaltat

@aaltat aaltat commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Summary

Browser registers an adopted context itself, the way New Context registers its own: the
keyword calls become trace groups, the video size is cached, the log embeds the video. Until now
a library built on Browser had to call register_adopted_context after the extension call, and
a plain jsextension keyword could not do it at all. Decision and rejected options: ADR 0010.

sequenceDiagram
    participant Python as call_js_keyword
    participant Node as extensionKeywordCall
    participant Ext as extension function
    Python->>Node: CallExtensionKeyword
    Node->>Ext: fn(..., adoptContext)
    Ext->>Node: adoptContext(context, {tracing, contextOptions})
    Node-->>Python: Json{adoptedContext: {id, traceFile, contextOptions, video}}
    Note over Python: registers it while reading the stream
    Ext-->>Node: result (or throws)
    Node-->>Python: Json{bodyPart} (or the error)
Loading

The report goes out as soon as adoptContext resolves, so a context adopted before the function
throws is registered too. Node is the source of truth: the trace file it started, the options
the extension passed, the video it got. The video size comes from the reported recordVideo,
then the viewport, then 1280x720.

What a library built on Browser no longer does:

 options = self.adopted_context_options(tracing=tracing, recordVideo=record_video)
 adopted = self.call_js_keyword("openApplication", **options)
-return self.register_adopted_context(adopted["contextId"], options, adopted["videoPath"])
+return adopted["videoPath"]
 message Json {
   string log = 1;
   string json = 2;
   string bodyPart = 3;
+  string adoptedContext = 4;
 }

register_adopted_context is removed. It came with #5326 and was never released.

adoptContext(context, { activePage }) makes that page the active page, and Browser reports its
id and its video. An Electron app that shows a WebContentsView or <webview> first makes the view
the first page, while the library wants the window; a WebView page of an Android app is the same
case. The page must belong to the adopted context, otherwise adoptContext adopts nothing.

Evidence

  • Before: a plain jsextension keyword adopts a traced context; the trace has no keyword
    groups ([ ] does not contain match for pattern 'Browser.Open Adopted Persistent Context ...').
    After: An Adopted Context Is Traced With Keyword Groups And Accepts Downloads passes.
  • The video size tests from test: pin the video size of an adopted context through a library built on Browser #5369 pass unchanged through the new path.
  • Unit tests at the call_js_keyword seam: trace groups, tracing group modes, several contexts
    in one call, video embedding and its size, a context adopted without pages or without its
    options, and a report sent before the extension function fails.
  • Jest: the report is written on the stream, also when the function throws after adopting.
  • Before: an extension adopts a context whose second page it wants active; Get Url is
    about:blank. After: The Creator Of An Adopted Context Chooses Its Active Page passes.
  • feat(elector): Browser browser do more work in the plugin side robotcodedev/robotframework-electron-vscode#2 runs on this branch: 151 of 154 acceptance tests
    pass on macOS, the two failures are unrelated (/private/var path, a .vsix not built).
  • inv utest, inv utest-node, inv lint, inv atest pass locally, apart from three Firefox
    tests whose browser does not launch on my machine.

Merge Danger

Door: two-way

The proto field is new; nothing else reads it.

Blast Radius: extensions

Only extension calls that adopt a context behave differently, and adoptContext is unreleased.
The Electron library (robotcodedev/robotframework-electron-vscode) calls
register_adopted_context and must drop that call before it runs on the next release.

🤖 Generated with Claude Code

aaltat and others added 2 commits October 21, 2026 21:04
Node writes a report on the response stream of the extension call as soon
as adoptContext resolves: the context id, its trace file, the options the
extension passed as contextOptions and the video of its active page.
call_js_keyword registers each report the way New Context registers its own
contexts: keyword trace groups, cached video size, embedded video. Every
extension call goes through call_js_keyword, so a plain jsextension keyword
now gets this too, where before only a library built on Browser could.

The video size comes from the reported recordVideo, then the viewport, then
1280x720, so a context adopted without its options still embeds its video.

register_adopted_context is removed. It was never released; a library built
on Browser no longer passes the options twice nor returns the video path.

ADR 0010 records the decision, and Browser/CONTEXT.md names the adopted
context.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adoptContext(context, { activePage }) makes that page the active page, and
Browser reports its id and the video of it. Without the option the page that
Playwright saw first stays active, as before.

An Electron application that shows a WebContentsView or a <webview> first
makes the view the first page, while the library wants the window. A WebView
page of an Android app is the same case. The page must belong to the adopted
context; otherwise adoptContext fails and adopts nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aaltat
aaltat merged commit 850f4cd into MarketSquare:main Oct 22, 2026
59 of 60 checks passed
@aaltat
aaltat deleted the adopted-context-registration branch October 22, 2026 04:13
d-biehl pushed a commit to robotcodedev/robotframework-electron-vscode that referenced this pull request Oct 22, 2026
Browser registers an adopted context itself now, from the report that
adoptContext writes on the stream of the extension call
(MarketSquare/robotframework-browser#5372). It gives the context the
library timeout, returns the video of its active page
(MarketSquare/robotframework-browser#5370), and adoptContext takes the
page to make active.

electron.js passes the first window's own page as activePage, so Browser
makes the window the active page, not a WebContentsView or <webview>
that Playwright saw first, and reports the window's video. Start
Electron Application no longer switches pages after the start and no
longer calls register_adopted_context; it returns the page id and the
video path that Browser reported. When the first window closes during
the start, Browser keeps the page that Playwright saw first, and the
returned video is that page's.

Co-authored-by: Tatu Aalto <aalto.tatu@gmail.com>
d-biehl added a commit to d-biehl/robotframework-browser.org that referenced this pull request Oct 22, 2026
…itself

Browser now registers an adopted context from the report of the extension call (MarketSquare/robotframework-browser#5372), gives it the library timeout and returns the video of its active page (MarketSquare/robotframework-browser#5370), and adoptContext takes an activePage. The examples no longer set the timeout, read the video path or call register_adopted_context, and the page describes activePage, the registration and videoPath.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant