Skip to content

fix: keep CI green after relicense - #7

Open
kblok wants to merge 456 commits into
mainfrom
cursor/fix-ci-after-relicense-d391
Open

kblok wants to merge 456 commits into
mainfrom
cursor/fix-ci-after-relicense-d391

Conversation

@kblok

@kblok kblok commented Sep 2, 2026 •

Copy link
Copy Markdown
Member

Summary

Keep hardkoded/playwright-native CI fully green after the relicense with product-only fixes (no skipped tests, no TestExpectations expected failures, no tests modified to match local code).

Latest tip

  • Chromium data: GoTo land gate (55b853e): do not treat leftover LifecycleEvents commit from about:blank as evidence the new document landed (PressAsyncDispatchesKey on Windows headful). Land evidence is DocumentId/URL match or evaluate location.href + document.readyState.
  • WebKit clock poll backoff: further increase settle/poll delays after scheduling runFor/pauseAt on builtins.setTimeout so Darwin suite load cannot starve embedder timers (RunForShouldAcceptMinuteSecondString hang cascading into later Launch/Click timeouts on mac shard3).

Prior tip fixes (still on branch)

  • WebKit deferred-nav inflight idempotency + reset on cross-document navigations
  • Chromium data: GoTo lifecycle replay gated on real land evidence + readyState confirm fallback
  • Screenshot guards, SSL timing snap, redirect DONE ordering, concurrent GoTo latch, etc.

Test plan

  • Local Chromium: PressAsyncDispatchesKey, FillAsyncSetsInputValue, DialogAcceptShouldWork (stress)
  • Local WebKit: ClockTests + BackgroundPage + Click/Hover across contexts (stress)
  • Await full CI matrix on tip — every check green via gh
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 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

cursoragent and others added 15 commits September 15, 2026 04:11
Keep fetch() expressions unwrapped so awaitPromise retains a handle instead
of re-running the request, and drop PartitionKey cookies on frozen mac14
WebKit where CHIPS is ignored and they leak into document.cookie.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Emit the canonical "Timeout Nms exceeded." substring for waitForEvent
timeouts while keeping the Node "while waiting for event" call-log line,
and probe candidate ffmpeg binaries for a real libwebp encoder so macOS
WebP screenshots do not pick a screencast-only build.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Queue OnFrame callbacks so ack-based backpressure holds while an async
listener is pending, prefer system ffmpeg for lavfi white-frame empty
videos (bundled build lacks lavfi), and accept macOS Microsoft Edge
paths in the channel resolver unit test.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
macOS requestStorageAccess fails when focus is lost after cross-process
iframe navigations; activate the target and setActiveAndFocused before
child-frame evaluate so storage-access grants succeed.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
The ParentFrame early-return in ShouldSuppressDuplicateNavigationRequest
caused opener pageProxy teardown during target=_blank bring-up, which
broke popup waits and new-window downloads. Same-URL iframe requests
still work via the pending-navigation marker clear on main-frame load.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Homebrew's current ffmpeg bottles omit --enable-libwebp, so macOS WebP
screenshot recoding failed with "Unknown encoder 'libwebp'". Prefer
ffmpeg when it has libwebp, otherwise use cwebp, and install the webp
package in CI alongside ffmpeg.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
WebKit Network interception does not rewrite WS upgrades, and
LocaleHandshakeProxy used <-loopback> bypass so ws://localhost tests
kept the browser default en-US. Disable loopback bypass for WebKit
so the proxy rewrites Accept-Language (and ExtraHTTPHeaders) on
loopback handshakes.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Route value-only handles through the JSON tree revive path because
WebKit rejects {value}/{unserializableValue} on callFunctionOn with
executionContextId. Also read Infinity/NaN/-0 from description when
WebKit returns {value:null,description:...}.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Create-time credentials were stored but never enabled network interception
on new pages, so HeadersWithAuth never ran and auth navigations got 401.
Mirror SetHttpCredentialsAsync in ApplyContextChromeAsync.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Map Meta+C/X/V/Z (and Shift+Meta+Z) to mac editing commands so
contenteditable copy/cut/paste/undo work under Input.dispatchKeyEvent.
Prefer raw upgraded-stream frames in OfficialServerWebSocket so
application close codes are echoed instead of WebKit reporting 1006.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Run animation finish/restore in the same frame world so infinite
animations resume after capture; await fonts.ready under screenshot
timeout. Treat Missing injected script as a destroyed-context race so
clicks retry across navigation. Synthesize loadingFailed for navigation
204 like upstream. Align ShouldWorkWithCsp with upstream swallow-and-
assert-blocked behavior.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Public response body reads throw when the frame has navigated away even
if prefetch cached bytes. Clock embedder performanceNow falls back to
wall-clock elapsed when native Performance.now freezes after replace.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Ignore Target worker targets and use Worker.workerCreated only; clear
workers on provisional commit; map worker Console JS errors to pageerror.
Re-enable file-chooser intercept on provisional sessions and after
main-frame navigations. Dispose locator action handles so RequestGC can
collect detached nodes.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Handshake proxy without loopback bypass makes the browser send
Proxy-Connection; drop those hop-by-hop headers from public request
headers so they match the origin. Lock binding coalesce so concurrent
duplicate Runtime.bindingCalled events share one host invocation.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Keep LocaleHandshakeProxy Latin1-safe so binary/UTF-8 continue postData
survives loopback rewrite; reinject Proxy-Authorization on continue;
omit invented Content-Length on default fulfill; fire-and-forget JSHandle
dispose; stash evaluate results to avoid binding double-fire; reapply
orientation after provisional swaps; rewrite local.playwright for
APIRequest; treat fetcher INSTALLATION_COMPLETE as a cache hit.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
@cursor cursor Bot changed the title Fix CI failures after relicense Fix CI after relicense: WebKit network/bindings/dispose green path Sep 15, 2026
cursoragent and others added 4 commits September 15, 2026 09:05
Remove the injected 20ms ensureOpened fallback that raced Task.Run
handlers and forwarded page frames before OnMessage was registered.
Queue page messages until the handler completes, and wire
HarRecorder.ObserveWebSocket via RoutedHarWebSocket on ConnectToServer
so modified server-side frames are recorded.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Re-assert page focus after child-frame context is ready and after iframe
navigations, and run child-frame thenables via callFunctionOn with
emulateUserGesture so requestStorageAccess sees activation. Prefer
CheckFunction (LABEL→control retarget) before ClickAsync so WebKit
hit-test hangs no longer block check/uncheck.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Match upstream wkPage.ts: release buffered requestWillBeSent on
loadingFailed without attaching a route, and continue orphan
requestIntercepted events with Network.interceptWithRequest instead of
parking them or re-invoking routes on already-materialized requests.
Also skip data:/about: willBeSent and clone buffered payloads.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
cursoragent and others added 3 commits September 26, 2026 01:32
… errors

Accept Page.navigate ERR_ABORTED when FrameNavigated already committed the
document, and track Fetch-paired / type-omitted main-frame navigations so
the document 200 stays findable under Windows suite load. On MITM handshake
budget expiry, prefer AuthenticationException text so HTTP/2 self-signed
origins still paint "self-signed certificate".

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
After scheduling clock pauseAt/runFor/fastForward on builtins.setTimeout(0),
wait before polling and increase the poll delay so Runtime.evaluate does not
starve embedder timers under macOS WebKit suite load
(RunForShouldAcceptMinuteSecondString).

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Darwin WIP can wedge on Runtime.callFunctionOn awaitPromise:true for
sync STYLE/SCRIPT handle reads (mac shard2 ShouldReturnStyleElementHandle
30s empty-stack timeouts cascading into Launch/GoTo hangs). Evaluate
handles with awaitPromise:false first and only await thenables, matching
GetPropertyOnHandleAsync. Align AddStyleTag inline content with the
AddScriptTag path and bound sentinel polls so hung evaluates cannot
outlive their timeout.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
@cursor cursor Bot changed the title fix CI after relicense fix: keep CI green after relicense Sep 26, 2026
cursoragent and others added 26 commits September 26, 2026 03:53
ThreadPool.QueueUserWorkItem still raced CatchAsync on Darwin under suite
load so anotherPromise stayed null in ShouldFailWhenReplacedByAnotherNavigation.
Await Task.Yield before TrySetException so NavigateAsync returns its Task
to the hanging route callback first.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Darwin ApplyEmulation runs before Target.resume; probing/stamping
navigator.userAgent on a paused target wedges Runtime.evaluate for the
full 20s WKSession timeout and eats LaunchAsyncHandleSIGINTFalse's
NUnit 30s budget. Defer UA probes/stamps until InitializedTask completes,
bound stamp evaluates, and cap EvaluateOnCurrent attempts with WhenAny.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Windows headful shard4 failed ShouldReturnFromGotoIfNewNavigationIsStarted
with ERR_ABORTED when responseReceived beat Fetch Document promotion, so
the committed 200 never entered the recovery ring. Latch the existing
response on promotion, treat main-frame Other/empty-type GETs as document
navigations, and adopt those URL matches in TryFindNavigationRequest.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
GoToFrameAsync only treats lifecycle as ready while currently present and
re-waits after a revoked networkidle, matching SetContent. Trace action
screenshots use raw CDP with a hard budget so abandoned WaitForFonts
cannot deadlock ScreenshotGates across before/action/after phases.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
The previous GoToFrameAsync wait loop treated any lifecycle Contains as
done and skipped waiting when a stale load was still latched, breaking
normal navigations. Scope revoke-safe waiting and Contains-only
fast-path to networkidle; leave load/domcontentloaded on sawTargetLifecycle.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Route bare expressions like `1 + 1` through returnByValue serialize so
Darwin avoids MaterializeAsync awaitPromise wedges. Wait for element
visibility before screenshot decorations/fonts, and shorten the fonts
budget. Retry destroyed-context frame evaluates after iframe goto.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Broad CanWrapExpression wrapping of any semicolon-free expression
routed property-access evaluates (e.g. document.body.textContent)
through returnByValue serialize and caused Darwin WebKit empty-stack
timeouts. Keep wrapping only simple sync expressions like `1 + 1`.

Remove the pre-CaptureAsync Stable wait so infinite CSS/Web animations
can be frozen inside CaptureAsync before visibility/stable checks.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Darwin CFNetwork can leave document.cookie rows after a single
expires:0 setCookies. Re-expire until getAllCookies is clean, expire
leading-dot domain variants, and clear matched non-HttpOnly names via
document.cookie Max-Age=0 on open pages (ShouldRemoveCookiesByNameRegex).

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Treat WebKit "Execution context is not yet available" as a destroyed/
navigating race so screenshot decorations retry and surface the official
navigating error (ShouldWorkWhileNavigating). MaterializeAsync now reads
inline number/boolean/string payloads instead of SerializeAwaitedJs,
avoiding Darwin awaitPromise wedges on Date.now() / matchMedia. Cookie
document.cookie clears use a wrappable IIFE.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Allow CanWrapExpression on sync IIFEs even when the body mentions
Promise/.then so clock kickoff stays on returnByValue and does not
deadlock Darwin awaitPromise. Strip trailing semicolons before
parenthesizing in WithSerializedResult so injectors like
`(() => {…})();` stay valid.

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

Promote and latch main-frame GET document responses even before Fetch
marks TracksDocumentNavigation so concurrent-goto ERR_ABORTED recovery
still finds the committed 200 under Windows suite load.

Never fall back to the page main world for HTML5 drag setup/cleanup —
that drops textarea text selection on headful Chromium.

On Linux WebKit, reconcile empty-name cookie values from live
document.cookie into CookiesAsync so Cookies→AddCookies roundtrips do
not resurrect a stale protocol value.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Under Windows suite load a second Page.navigate can abort the first before
Network.requestWillBeSent / frameNavigated, so concurrent-goto recovery never
sees the committed 200. Track in-flight frame navigations and wait for the
peer to start (and briefly for commit) before sending a superseding navigate;
hung cancel/replace peers still abort after a short grace.

Also flush handleJavaScriptDialog without an async state machine so
fire-and-forget Accept from Dialog handlers schedules the CDP write promptly.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
sawTargetLifecycle could stay true after a later frameNavigated cleared
LifecycleEvents to only commit, so GoTo returned without load present
(GoToShouldClearLifecycleOnNewNavigation under Windows suite load).

Require the target lifecycle to be currently recorded, reset the mid-
navigate saw flag on new-document commits, and replay DCL/load for data:
URLs that commit without a second loadEventFired.

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

Require live lifecycle only for networkidle; keep sawTargetLifecycle OR
Contains for other events so MITM/TLS and dialog paths do not hang, while
clearing sawTargetLifecycle on new-document FrameNavigated and replaying
data: DOMContentLoaded/load so GoToCannotClearLifecycle flakes stay fixed.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Keep sawTargetLifecycle OR Contains for non-networkidle so MITM/TLS
does not hang, but when GoTo resolves with only {commit} left in
LifecycleEvents, replay DOMContentLoaded/load so EmptyPage assertions
and waitUntil stay honest after a mid-wait FrameNavigated clear.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Skip ClearLifecycleEvents when frameNavigated repeats the same loaderId
so a late re-commit cannot wipe load after GoTo resolved. Also ensure
promised DCL/load is recorded on successful GoTo exit (including MITM).

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Validate full-page/clip dimensions against the 32767 device-pixel cap
(same as WebKit) so a too-tall capture throws PlaywrightException instead
of crashing the page, allowing scale:css retries to succeed.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
loadingFinished can race ahead of responseReceived on redirect hops and
emit DONE before the 302 Response event. Skip the page requestfinished
while Response is null so ShouldSupportRedirects sees GET,302,DONE.

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

loadingFinished removed navigations from the request map before Response
arrived, so deferred requestfinished never resumed after fulfill/redirect
races (RouteRequestUrl hang). Keep the entry until Response is attached.
Also snap RequestStart/ResponseStart forward when WebKit float-rounds SSL
timings a few sub-ms out of order (ShouldWorkForSsl).

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Keeping Response-less finished navigations in _requestsById blocked
WebKit requestId reuse and hung later navigations (macOS IsVisible
data: GoTo timeout). Park them in a side map so late Response/DONE
still attach without colliding with new requests.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Require only a missing waitUntil event — not commit/DocumentId parity —
so persistent+HAR data: navigations under CI load do not hang when
FrameNavigated races Page.navigate (ShouldHavePagesInPersistentContext).

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Deferred navigation requestfinished left requests counted as inflight until
a late Response path ran, which could wedge networkidle / provisional-swap
commit under CI load. Clear inflight on defer, track request ids so finish
is idempotent, and reset page inflight on cross-document navigations.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Replaying load before FrameNavigated could complete GoTo while the browser
was still on about:blank, so QuerySelector returned null
(FillAsyncSetsInputValue on Windows CI). Require commit, DocumentId match,
or a data: frame URL before replaying — without requiring all of them, so
persistent+HAR races that skip a fresh commit still complete.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
After gating lifecycle replay on landed navigation, persistent data: GoTo
under Windows suite load could hang the full timeout when FrameNavigated
and commit never arrived (DialogAcceptShouldWork). Poll location.href and
document.readyState briefly so a usable data: document still completes
GoTo without replaying against about:blank.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
LifecycleEvents still contains commit from about:blank until
FrameNavigated clears it, so treating commit alone as landed made
GoTo return before the data: DOM existed (PressAsyncDispatchesKey).
Require DocumentId/URL match or evaluate readyState confirmation.

Co-authored-by: Darío Kondratiuk <dariokondratiuk@gmail.com>
Increase initial settle and poll delay after scheduling runFor/pauseAt
on builtins.setTimeout so Runtime.evaluate does not starve embedder
timers (RunForShouldAcceptMinuteSecondString hang cascading into
later Launch/Click timeouts on macOS WebKit shards).

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

This branch has not been deployed

No deployments
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