fix(ci): keep CI green after relicense - #7
Merged
Merged
Conversation
kblok
marked this pull request as ready for review
September 2, 2026 20:30
kblok
commented
Sep 11, 2026
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" |
Member
Author
There was a problem hiding this comment.
We can move this to a bash file
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>
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>
kblok
commented
Oct 2, 2026
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' |
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>
kblok
commented
Oct 2, 2026
Member
Author
There was a problem hiding this comment.
Tests on this class don't match upstream. Review
There was a problem hiding this comment.
Removed leftover ClockInstallOptionsTests — coverage lives in LibraryPageClockParityTests (upstream page-clock.spec.ts / playwright-dotnet PageClockTests).
kblok
commented
Oct 2, 2026
| const long frozen = 1_706_871_600_000; | ||
| await page.Clock.InstallAsync(frozen).ConfigureAwait(false); | ||
|
|
||
| await page.Clock.PauseAtAsync(frozen).ConfigureAwait(false); |
Member
Author
There was a problem hiding this comment.
Tests on this class don't match upstream. Review
There was a problem hiding this comment.
Removed leftover ClockTests — same reason; official parity is LibraryPageClockParityTests / LibraryPageClockFrozenParityTests.
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
Bot
force-pushed
the
cursor/fix-ci-after-relicense-d391
branch
from
October 3, 2026 05:58
9d3f0b2 to
fcb636f
Compare
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Keep tip CI green on the post-relicense branch with product-only fixes (no TestExpectations / skip workarounds).
Latest tip (
a0fd549)Page.getFrameTreebut yield first soSendAsyncis not started on the CDP receive thread (Windows headful HAR abort / CSS screencast stalls).Task.Runfor that sync racedAdoptFrameTreeChildrenwith liveframeAttached(should work inside iframe,CRClickTests.ShouldClickTheButton). Skip the tree sync when the page is already closed. FaviconNetwork.*events stay suppressed on user CDP sessions..webmat RecordVideo start (EmptyVideo/ShouldEmulateAnIphoneffprobe). Empty recordings still fall back to ffmpeg white-frame encode on stop.EvaluateInFrameAsyncon TargetClosed from process-swap dispose.getTargets, console wait under tracing, worker attach, TS-title alignment.Note
Tip
9d3f0b2(transportTask.Yield+ sync GoTo TCS + client-root attach) was reverted; it caused widespread 30s hangs on navigation/locator error tests.Test plan
ShouldSendEvents,ShouldReturnPage, HAR abort, CSS/empty ffmpeg,EmptyVideo, iframe drag,CRClickTests.ShouldClickTheButton(10 passed)a0fd549