Skip to content

[macOS release] imported/w3c/web-platform-tests/event-timing/keydown is a flaky text failure.#62323

Open
diegodelatoba wants to merge 1 commit intoWebKit:mainfrom
diegodelatoba:eng/macOS-release-imported-w3c-web-platform-tests-event-timing-keydown-is-a-flaky-text-failure
Open

[macOS release] imported/w3c/web-platform-tests/event-timing/keydown is a flaky text failure.#62323
diegodelatoba wants to merge 1 commit intoWebKit:mainfrom
diegodelatoba:eng/macOS-release-imported-w3c-web-platform-tests-event-timing-keydown-is-a-flaky-text-failure

Conversation

@diegodelatoba
Copy link
Copy Markdown
Contributor

@diegodelatoba diegodelatoba commented Apr 9, 2026

76a95d0

[macOS release] imported/w3c/web-platform-tests/event-timing/keydown is a flaky text failure.
rdar://174354241
https://bugs.webkit.org/show_bug.cgi?id=311759

Reviewed by NOBODY (OOPS!).

The test uses event-timing-test-utils.js to create intentionally "slow" events and verify they are reported.
A PerformanceObserver is set up with durationThreshold: 16 — meaning events with duration ≥ 16ms should be reported.
The test then blocks the main thread for durationThreshold + 4 = 20ms to create a slow event.

The problem is that 20ms sits exactly on an 8ms rounding boundary. The Event Timing spec requires
durations to be rounded to the nearest 8ms for security ("The duration has an 8 millisecond granularity"). The
boundary between rounding to 16ms vs 24ms is at exactly 20.0ms. Additionally, WebKit spec states performance.now()
precision is 1ms. Since mainThreadBusy(20) uses performance.now() in its busy-wait loop, the 1ms floor quantization
means it can block for as little as ~19ms depending on where the initial timestamp falls relative to a 1ms tick. A
raw duration of 19ms rounds to 16ms instead of 24ms.

When the duration rounds to 16ms, the entry is still delivered to the observer (16 ≥ 16 satisfies the threshold),
but the verification assertion entry.duration + 4 >= entry.processingEnd - entry.startTime fails — because 16 + 4 = 20
is not greater than or equal to the actual processing time of ~20+ms (processingEnd - startTime includes more than just
the busy-wait — it also includes the dispatch delay (time from event creation to handler invocation))

The fix is to change the blocking duration from durationThreshold + 4 (20ms) to durationThreshold + 5 (21ms), which
provides enough margin that even with worst-case clock quantization, the raw duration stays above the 20ms rounding
boundary and always rounds to 24ms.

* LayoutTests/imported/w3c/web-platform-tests/event-timing/resources/event-timing-test-utils.js:
* LayoutTests/platform/mac-wk2/TestExpectations:

76a95d0

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win
✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 win-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 api-mac-debug ✅ 🛠 gtk3-libwebrtc
✅ 🧪 api-ios ✅ 🧪 mac-wk1 ✅ 🛠 gtk
✅ 🧪 mac-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 api-gtk
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🛠 playstation
✅ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2
✅ 🛠 tv
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

…is a flaky text failure.

rdar://174354241
https://bugs.webkit.org/show_bug.cgi?id=311759

Reviewed by NOBODY (OOPS!).

The test uses event-timing-test-utils.js to create intentionally "slow" events and verify they are reported.
A PerformanceObserver is set up with durationThreshold: 16 — meaning events with duration ≥ 16ms should be reported.
The test then blocks the main thread for durationThreshold + 4 = 20ms to create a slow event.

The problem is that 20ms sits exactly on an 8ms rounding boundary. The Event Timing spec requires
durations to be rounded to the nearest 8ms for security ("The duration has an 8 millisecond granularity"). The
boundary between rounding to 16ms vs 24ms is at exactly 20.0ms. Additionally, WebKit spec states performance.now()
precision is 1ms. Since mainThreadBusy(20) uses performance.now() in its busy-wait loop, the 1ms floor quantization
means it can block for as little as ~19ms depending on where the initial timestamp falls relative to a 1ms tick. A
raw duration of 19ms rounds to 16ms instead of 24ms.

When the duration rounds to 16ms, the entry is still delivered to the observer (16 ≥ 16 satisfies the threshold),
but the verification assertion entry.duration + 4 >= entry.processingEnd - entry.startTime fails — because 16 + 4 = 20
is not greater than or equal to the actual processing time of ~20+ms (processingEnd - startTime includes more than just
the busy-wait — it also includes the dispatch delay (time from event creation to handler invocation))

The fix is to change the blocking duration from durationThreshold + 4 (20ms) to durationThreshold + 5 (21ms), which
provides enough margin that even with worst-case clock quantization, the raw duration stays above the 20ms rounding
boundary and always rounds to 24ms.

* LayoutTests/imported/w3c/web-platform-tests/event-timing/resources/event-timing-test-utils.js:
* LayoutTests/platform/mac-wk2/TestExpectations:
@diegodelatoba diegodelatoba self-assigned this Apr 9, 2026
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