Skip to content

fix(ci): keep CI green after relicense - #7

Merged
kblok merged 555 commits into
mainfrom
cursor/fix-ci-after-relicense-d391
Oct 3, 2026
Merged

kblok merged 555 commits into
mainfrom
cursor/fix-ci-after-relicense-d391

Conversation

@kblok

@kblok kblok commented Sep 2, 2026 •

Copy link
Copy Markdown
Member

Summary

Keep tip CI green on the post-relicense branch with product-only fixes (no TestExpectations / skip workarounds).

Latest tip (a0fd549)

  • Chromium GoTo / CDP: After load, fire-and-forget Page.getFrameTree but yield first so SendAsync is not started on the CDP receive thread (Windows headful HAR abort / CSS screencast stalls). Task.Run for that sync raced AdoptFrameTreeChildren with live frameAttached (should work inside iframe, CRClickTests.ShouldClickTheButton). Skip the tree sync when the page is already closed. Favicon Network.* events stay suppressed on user CDP sessions.
  • Video: Do not write a stub .webm at RecordVideo start (EmptyVideo / ShouldEmulateAnIphone ffprobe). Empty recordings still fall back to ffmpeg white-frame encode on stop.
  • WebKit: Retry EvaluateInFrameAsync on TargetClosed from process-swap dispose.
  • Prior: textarea scroll-before-press, OOPIF getTargets, console wait under tracing, worker attach, TS-title alignment.

Note

Tip 9d3f0b2 (transport Task.Yield + sync GoTo TCS + client-root attach) was reverted; it caused widespread 30s hangs on navigation/locator error tests.

Test plan

  • Local Chromium: ShouldSendEvents, ShouldReturnPage, HAR abort, CSS/empty ffmpeg, EmptyVideo, iframe drag, CRClickTests.ShouldClickTheButton (10 passed)
  • Tip CI green after a0fd549
Open in Web Open in Cursor 

@kblok
kblok marked this pull request as ready for review September 2, 2026 20:30
@cursor cursor Bot changed the title Fix CI failures from Apache-2.0 relicense Fix CI after Apache-2.0 relicense Sep 3, 2026
@cursor cursor Bot changed the title Fix CI after Apache-2.0 relicense Fix CI after relicense: cookies, HAR, bindings, pageerror Sep 4, 2026
@cursor cursor Bot changed the title Fix CI after relicense: cookies, HAR, bindings, pageerror Fix CI after relicense: HAR routeFromHAR, cookies, Accept-Encoding Sep 5, 2026
@cursor cursor Bot changed the title Fix CI after relicense: HAR routeFromHAR, cookies, Accept-Encoding Fix CI after relicense: HAR, cookies, Unroute, popup URL, certs Sep 5, 2026
@cursor cursor Bot changed the title Fix CI after relicense: HAR, cookies, Unroute, popup URL, certs Fix CI after relicense: HAR, cookies, Unroute, popup URL, certs, dispose Sep 5, 2026
@cursor cursor Bot changed the title Fix CI after relicense: HAR, cookies, Unroute, popup URL, certs, dispose Fix CI after relicense: HAR defaults, dispose, URL, credentials Sep 5, 2026
@cursor cursor Bot changed the title Fix CI after relicense: HAR defaults, dispose, URL, credentials Fix CI after relicense: HAR, dispose, WebSocket routes, CSP, tracing, SW Sep 5, 2026
@cursor cursor Bot changed the title Fix CI after relicense: HAR, dispose, WebSocket routes, CSP, tracing, SW Fix CI failures after relicense Sep 5, 2026
Comment thread .github/workflows/dotnet.yml Outdated
Comment on lines +149 to +169
run: |
# List every test's fully-qualified name straight from the built
# assembly (dotnet test --list-tests only prints the bare method
# name, which collides across classes and isn't safe to filter on).
# $RUNNER_TEMP (not /tmp) so the path is already OS-native on Windows.
all_tests="$RUNNER_TEMP/all_tests.txt"
dotnet vstest src/PlaywrightNative.Tests/bin/Release/net10.0/PlaywrightNative.Tests.dll \
/ListFullyQualifiedTests "/ListTestsTargetPath:$all_tests"
# Drop the trailing ".MethodName" (and any TestCase "(...)" suffix)
# to get one entry per test class, then assign classes to shards by
# position in a stable sort -- deterministic across the shardTotal
# jobs of a single run without the shards needing to coordinate.
all_classes="$RUNNER_TEMP/all_classes.txt"
sed -E 's/\.[A-Za-z0-9_]+(\([^)]*\))?$//' "$all_tests" | sort -u > "$all_classes"
echo "Discovered $(wc -l < "$all_classes") test classes"
shard_classes="$RUNNER_TEMP/shard_classes.txt"
awk -v shard="${{ matrix.shardIndex }}" -v total="${{ matrix.shardTotal }}" \
'NR % total == (shard - 1) { print }' "$all_classes" > "$shard_classes"
echo "Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}: $(wc -l < "$shard_classes") classes"
filter=$(awk '{ printf "%sFullyQualifiedName~%s.", (NR > 1 ? "|" : ""), $0 }' "$shard_classes")
echo "TEST_FILTER=$filter" >> "$GITHUB_ENV"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can move this to a bash file

@cursor cursor Bot changed the title Fix CI failures after relicense Fix CI after relicense: WebKit network/bindings/dispose green path Sep 15, 2026
@cursor cursor Bot changed the title Fix CI after relicense: WebKit network/bindings/dispose green path Fix CI after relicense: WebKit network/bindings/TLS green path Sep 15, 2026
@cursor cursor Bot changed the title Fix CI after relicense: WebKit network/bindings/TLS green path Fix CI after relicense: Darwin WebKit proxy, UA, navigation Sep 15, 2026
@cursor cursor Bot changed the title Fix CI after relicense: Darwin WebKit proxy, UA, navigation Fix CI after relicense: WebKit proxy, client certs, evaluate, headers Sep 15, 2026
cursoragent and others added 16 commits September 20, 2026 04:34
Ubuntu CI ran update-ca-certificates on the ASP.NET testCert so
WebKit/libsoup treated https://localhost as trusted. page.goto then
succeeded and Bad SSL / ignoreHTTPSErrors isolation tests saw
caughtException null. Chromium was unaffected (own root store).
Keep exporting key.pfx/testCert.cer for Kestrel only; tests that need
successful HTTPS must use IgnoreHTTPSErrors, matching upstream.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
…spose.

Prefer per-fetch abort signals across UA/cookie/SendAsync/body awaits so a
Windows hang-route that still yields HTTP success cannot mask
"Request context disposed" when Close races WaitForRequest.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Last-chance blank text recovery for 1ms expect timeouts, abort-aware
evaluate retries, utility-world drag setup, chrome://crash fallback,
shorter WebKit action signal polls with Page.enable epilogue and rAF
stability, Darwin WS close-frame drain, and lazy-iframe aria skip.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
…A, nav, workers.

Tolerate missing target session when applying emulated viewport during NewPage.
Skip ActionSignals waits for force clicks so overlay handlers do not hang.
Use a one-shot preview+visibility probe and merge wait logs so intermediate
nodes survive timeout call logs. Harden requestStorageAccess evaluate (window
anchor, returnByValue). Resolve child WaitForNavigation on matching responses
and match frames by id. Retry Worker.workerCreated when the page session is
briefly unavailable.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Resolving waitForNavigation on the document Response completed before
FrameNavigated and regressed click/fill/select navigation waits across
Chromium. Restore FrameNavigated-only commit, dispose aborted HttpClients
off the CloseAsync thread, keep WaitForSelector two-step visibility probes
with merge-only timeout logs, lengthen the WebKit empty action poll to
640ms, and tighten WebKit aria/RSA/scroll/route-override handling.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
… settle.

Restore RaceDestroyed NavigationMessage so hanging evaluates fail instead of
retrying after reload. Treat ERR_ABORTED as superseded navigation, keep
document request across lifecycle clear, reset clock ticks on install, and
order load waiters before clickload. WebKit: abort-proof document retains,
navigable-target settle after click, redirect response URL keying, stronger
aria fail-closed and RSA gesture, wait-log preview persistence.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Page.navigate ERR_ABORTED must still fail for 204 / canceled / replaced
navigations. Stop intercepting Chromium redirect hops, fail-closed WebKit
bad-SSL click retains, harden aria lazy-iframe and RSA gesture, persist
Darwin wait-visible logs, and tighten expect last-chance / HAR header match.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Windows Abort hung because fetch unwind sync-Disposed HttpClient while
SendAsync waited on the hang route; track sockets and RST on close, and
always background-dispose clients. Skip getComputedStyle on loading=lazy
iframes (Darwin WaitForSelector wedge). Prefer ChildFrames for aria stitch.
Do not await clock real-time dispose (pauseAt/runFor deadlock). Restore
async RSA under emulateUserGesture with frame-session pulse first.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
RSA: pulse parent iframe click then OOPIF frame-session last (no early
return); only pulse after the window anchor so activation survives into
async callFunctionOn.

Clock: kick pauseAt/runFor off a microtask and poll a marker so Darwin
WIP does not hold awaitPromise across embedder.setTimeout (deadlock).

WaitForSelector: document-scoped AtomicSelectorRead visibility on WebKit
before constructing handles; skip InitializePreview callFunctionOn that
wedged loading=lazy iframe objectIds.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
ContentFrame-first again so ChildFrames creation-order no longer swaps
srcdoc stitches after remove/re-add. Match fallback ChildFrames by
name/src. Only microtask-defer pauseAt/runFor/fastForward — wrapping the
injector script broke install with Unexpected token.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Restore InitializePreview via PreviewNodeFunction (AtomicSelectorRead
already avoids lazy-iframe handle construction). Propagate WaitForSelector
strict violations instead of swallowing them into 30s polls. Skip
AtomicSelectorRead for enter-frame selectors so FrameSelector validation
runs. Abort sockets with Close(0) for a true RST on Windows hang routes.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Abort: RST sockets before completing abort gates; NetworkStream ownsSocket
false so HttpClient dispose cannot FIN under AbortSocket. Preview: skip
callFunctionOn for iframe/frame via describeNode (timeout = skip) so Darwin
ReturnEmptySnapshot does not wedge. Aria: FrameElement identity match and
250ms ContentFrame races so Windows frameset/srcdoc stitch finishes in budget.
RSA: page-proxy-only fast click without slow hit-test or frame-session Input.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
SocketsHttpHandler never finished responses when ConnectCallback streams
did not own the socket, so credential and timeout fetches hit 30s.
Keep RST-before-abort-gate. Skip WebKit InitializePreview for iframe/frame
so callFunctionOn cannot wedge Darwin ReturnEmptySnapshot.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Reading window.__pwQueryTag after querySelector returned a remote object
on WebKit and threw on GetByTestId. Skip iframe preview from the selector
instead. Do not touch iframe contentDocument in aria capture-ready, and
bound FrameElement identity so Darwin stitch stays inside the snapshot budget.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
WaitForSelector used StrictSelector → QuerySelectorAll, which still ran
InitializePreview on lazy iframes and wedged Darwin ReturnEmptySnapshot.
Thread initializePreview:false for iframe/frame selectors through unwrap.

SimpleServer notifies WaitForRequest after the hang-route registers
RequestAborted so Windows Abort RST cannot race registration. Defer
HttpClient dispose slightly after RST. RSA pulse clicks iframe center via
one cheap querySelector. Aria resolves ChildFrame by name/src (incl. data:)
before ContentFrame/identity.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
The storage-access pulse evaluated a function object, so WebKit threw before the click. Lazy iframe snapshots still called getComputedStyle, which wedges Darwin. Frameset stitch now searches descendant frames and keeps budget for children.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
cursoragent and others added 11 commits October 1, 2026 04:12
Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Fire-and-forget FulfillAsync on the probe/apply origin page could race
GoTo and hang until the 30s navigation timeout, which matched the
Windows headful SetStorageStateAsyncShouldRestoreCookies CI failure.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
ContentFrame could spend 3s+3s on describeNode/frameAttached while
locator-handler visibility probes WaitAsync-capped at 5s, so
ShouldWorkWhenOwnerFrameDetaches skipped the overlay under Windows
headful load. Share one 5s ContentFrame budget and raise frame-scoped
handler probe/retry caps so attach fits inside the visibility wait.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
System Chrome under Ubuntu headful suite load can leave Target.closeTarget
unanswered while the startup about:blank is still mid-InitializeAsync /
waitForDebuggerOnStart, hanging LaunchShouldUseChromeChannel for the full
NUnit 30s. Wait briefly for auto-attach, resume if needed, and cap both
the close CDP send and ClosedTask wait so ConnectAsync can finish.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
GoTo's fast-path ORed LifecycleEvents.Contains(load) with sawTargetLifecycle.
about:blank still lists load until FrameNavigated clears it while Page.navigate
may already advance DocumentId, so ShouldProperlyWaitForLoad could return after
the classic script and before module/DOMContentLoaded/load (Windows headless).
Require a fresh lifecycle observation for non-networkidle waits.

Also slim CloseAutomaticLaunchPagesAsync: keep bounded Target.closeTarget for
Channel Chrome hangs without early runIfWaitingForDebugger.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
e0c90cd required sawTargetLifecycle alone for non-networkidle GoTo. After
FrameNavigated cleared that flag, a load already in LifecycleEvents was
ignored and navigations hung under Windows suite load (storage/Channel
cascades, ShouldTimeoutWaitingForLoad via data: evaluate replay).

Trust LifecycleEvents again only when frame.Url matches the target so
stale about:blank load cannot race DocumentId. Do not start the network
idle timer on ClearLifecycle when no document request is kept — restart
it on load. Cap CloseAutomaticLaunchPagesAsync with runIfWaitingForDebugger
and a 2.5s budget so Channel Chrome cannot burn the launch timeout.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
…mismatch

Exact frame.Url == target matching blocked LifecycleEvents after load for
data: navigations (Chromium normalizes the URL). With sawTargetLifecycle
cleared mid-navigate, GoTo then awaited a lifecycleTcs that never re-fired
(ShouldClearRecordedPageErrors / Clock suite hangs on Windows headful).

Treat LifecycleEvents as ready unless frame.Url is still about:blank while
the target is not, and complete the waiter when load is already recorded.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Early lifecycle completion treated a null loaderId + prior load as ready,
so hash navigations returned before navigatedWithinDocument updated
frame.Url (ShouldWorkWithAnchorNavigation). Require urlMatches for
same-document early-complete, and only pulse OnNavigated when the frame
URL already matches the target.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Discard worker targets closed by document replacement so late autoAttach /
orphan adoption cannot resurrect Page.Workers after GoTo. Gate GoTo
lifecycleReady on non-stale blank URL and briefly wait for iframe
frameAttached. Bound AllHeaders response wait; best-effort locator preview
on toBeEnabled timeout.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
…shot

HandleFrameAttached no longer discards Page.frameAttached when parentFrameId
is briefly missing from FrameManager. toBeEnabled uses the same 5s first
ElementHandles probe as toBeAttached. Delayed worker attach skips targets
already closed by document replacement.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
WaitForChildFramesAttachedLocalAsync ran an evaluate after every GoTo
lifecycle, delaying return enough that Chromium no longer prioritized
url-bar navigation over a pending JS redirect (JsRedirectOverridesUrlBarNavigation).
Frame attach races remain covered by HandleFrameAttached's MainFrame fallback.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Comment thread .github/workflows/dotnet.yml Outdated
Comment on lines +70 to +94
# builds.dotnet.microsoft.com occasionally fails to serve the Windows SDK
# zip (transient CDN / network). Retry a few times before failing the job.
- name: Setup .NET
id: setup-dotnet-1
continue-on-error: true
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Wait before Setup .NET retry
if: steps.setup-dotnet-1.outcome == 'failure'
shell: bash
run: sleep 20
- name: Setup .NET (retry 2)
id: setup-dotnet-2
if: steps.setup-dotnet-1.outcome == 'failure'
continue-on-error: true
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Wait before Setup .NET final retry
if: steps.setup-dotnet-1.outcome == 'failure' && steps.setup-dotnet-2.outcome == 'failure'
shell: bash
run: sleep 40
- name: Setup .NET (retry 3)
if: steps.setup-dotnet-1.outcome == 'failure' && steps.setup-dotnet-2.outcome == 'failure'

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove these retries

Address PR review: use a single setup-dotnet step, and move the
class-based TEST_FILTER computation into compute-test-shard-filter.sh.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests on this class don't match upstream. Review

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed leftover ClockInstallOptionsTests — coverage lives in LibraryPageClockParityTests (upstream page-clock.spec.ts / playwright-dotnet PageClockTests).

const long frozen = 1_706_871_600_000;
await page.Clock.InstallAsync(frozen).ConfigureAwait(false);

await page.Clock.PauseAtAsync(frozen).ConfigureAwait(false);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests on this class don't match upstream. Review

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed leftover ClockTests — same reason; official parity is LibraryPageClockParityTests / LibraryPageClockFrozenParityTests.

cursoragent and others added 10 commits October 2, 2026 17:59
LibraryPageClockParityTests already covers page-clock.spec.ts /
playwright-dotnet PageClockTests. The invented ClockTests and
ClockInstallOptionsTests claimed that spec with non-upstream titles and
PauseAt-after-Install adaptations.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Compare every [PlaywrightTest] (spec, title) against microsoft/playwright
tests/page and tests/library (test/it/browserTest, including fixme and
template titles). Remove invented leftover suites and mismatched methods;
keep only exact TypeScript upstream twins.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Do not await Network.enable/Runtime.enable before WorkerCreated and
runIfWaitingForDebugger. Official fire-and-forgets those; awaiting them
left PlzDedicatedWorker paused under Windows suite load (worker console
and offline evaluates hung to the 30s NUnit budget).

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Stamp evaluate's consoleMessages baseline on the open action-trace call
so waitForEvent(Console) can replay a console.log that landed before the
waiter subscribed (ShouldNotEmitAfterWithoutBefore on Windows CI).

After text-select mousePressed, double-rAF settle before the held move and
skip setInterceptDrags when no down was recorded, so headful Chromium does
not anchor selection near the end of a still-scrolled textarea.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Flush text-field scrollTop/scrollLeft at the pointer before mousePressed
so headful Chromium selection is not anchored near the end of a still-
scrolled textarea (ShouldSelectTheTextWithMouse).

Count OOPIF targets with Target.getTargets after setDiscoverTargets —
Node delivers targetCreated synchronously during the command, but our
session can detach before those events are observed on Windows CI.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
After main-frame navigation completes, sync children from Page.getFrameTree
so Page.Frames is not left with only the main frame when frameAttached
lags past load under Windows suite load (ShouldReturnPage).

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Process-swap dispose during document.open/write/close can still surface as
TargetClosed when the dying session looks closed. Remap disposed-but-not-
closing sessions to the navigation destroyed-context error and retry
EvaluateInFrameAsync while the page stays open so Linux WebKit CI
ShouldReportNonNavigationDownloads SetContent survives the race.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
GoToFrameAsync awaited SyncChildFramesFromTreeAsync (Page.getFrameTree)
after the load lifecycle, delaying page.goto return. During that round-trip
Network.requestWillBeSent for /favicon.ico was delivered to user CDP
sessions, so LibrarySessionParityTests.ShouldSendEvents saw 2 events.

Official goto resolves at lifecycle without blocking on getFrameTree; keep
the child-frame re-adopt as fire-and-forget.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Awaiting Page.getFrameTree after GoTo let /favicon.ico requestWillBeSent
reach NewCDPSession listeners before page.goto returned (ShouldSendEvents
expected 1, got 2). Keep child-frame re-adopt as fire-and-forget, and
suppress favicon Network.* on user CDP sessions the same way page.Request
hides favicon housekeeping — avoids sync-TCS / transport-yield deadlocks
that hung locator and navigation error paths under suite load.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
@cursor
cursor Bot force-pushed the cursor/fix-ci-after-relicense-d391 branch from 9d3f0b2 to fcb636f Compare October 3, 2026 05:58
cursoragent and others added 3 commits October 3, 2026 07:26
Fire-and-forget Page.getFrameTree after GoTo ran SendAsync on the CDP
receive thread when the lifecycle TCS was already completed, stalling
HAR abort fetch and CSS screencast on Windows headful. Task.Run the
sync. Write a .webm placeholder at RecordVideo start so two empty
pages still leave files when ffmpeg image2pipe races on Windows.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
A placeholder at RecordVideo start made HasUsableWebm true, so
WriteWhiteVideo skipped the real encode. ffprobe then failed on
EmptyVideo and ShouldEmulateAnIphone across the matrix. Keep
Task.Run getFrameTree off the CDP receive thread.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Task.Run raced AdoptFrameTreeChildren with live frameAttached after
GoTo (drag-in-iframe miss, click evaluate on a page with no button).
Yield first so SendAsync is not started on the CDP receive thread,
which had stalled HAR abort fetch and CSS screencast on Windows.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
@kblok
kblok merged commit 691963d into main Oct 3, 2026
20 of 21 checks passed
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.

2 participants