Automatic update from web-platform-tests WebKit export of https://bugs.webkit.org/show_bug.cgi?id=300102 (#55577) Verifies that `pointerdown`/`keydown` event timing entries can have their durations set before the matching `*up` event is fired. Original patch was modified to resolve a potential race in browsers in which `await afterNextPaint()` does not guarantee the dispatch of event timing entries. To make sure the pointerdown/keydown's event timing entry had its duration set, we now produce an interleaving event and await until its event timing entry is observed. This ensures that the "Dispatch pending Event Timing entries" step ran. -- wpt-commits: f77e140355cde2fac3c8c9f1a16a154a34fda15c wpt-pr: 55577
63 lines
2.5 KiB
HTML
63 lines
2.5 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<meta charset=utf-8 />
|
|
<title>Event Timing: keydown/up gap.</title>
|
|
<script src=/resources/testharness.js></script>
|
|
<script src=/resources/testharnessreport.js></script>
|
|
<script src=/resources/testdriver.js></script>
|
|
<script src=/resources/testdriver-actions.js></script>
|
|
<script src=/resources/testdriver-vendor.js></script>
|
|
<script src=resources/event-timing-test-utils.js></script>
|
|
<div id='target'>Click me</div>
|
|
<script>
|
|
promise_test(async t => {
|
|
const keyDowns = []
|
|
const keyUps = []
|
|
blockNextEventListener(window, 'keydown', 30)
|
|
blockNextEventListener(window, 'keyup', 30)
|
|
|
|
// A pointerdown is used as an interleaving event, to make sure the keydown's
|
|
// timing entry had it's duration set before triggering the keyup. Using
|
|
// only `await afterNextPaint()` after the first event is not enough to
|
|
// guarantee this in all browsers. See discussion in
|
|
// https://github.com/web-platform-tests/wpt/pull/55577#discussion_r2466579023
|
|
blockNextEventListener(window, 'pointerdown', 30)
|
|
const {promise: interleavingEventTimingEntryObserved, resolve: resolveInterleaving } = Promise.withResolvers();
|
|
new PerformanceObserver( (entries) => {
|
|
entries.getEntries().forEach( (e) => {
|
|
if (e.name == 'keydown')
|
|
keyDowns.push(e)
|
|
if (e.name =='keyup')
|
|
keyUps.push(e)
|
|
if (e.name == 'pointerdown')
|
|
resolveInterleaving()
|
|
})
|
|
}).observe({type: 'event', durationThreshold: 16})
|
|
const keyDownHandled = new Promise( resolve => window.addEventListener('keydown', e => resolve(), true) )
|
|
const keyUpHandled = new Promise( resolve => window.addEventListener('keyup', e => resolve(), true) )
|
|
|
|
await new test_driver.Actions()
|
|
.keyDown('a')
|
|
.send()
|
|
await keyDownHandled
|
|
await afterNextPaint()
|
|
await new test_driver.Actions()
|
|
.pointerMove(0, 0)
|
|
.pointerDown()
|
|
.pointerUp()
|
|
.send()
|
|
await interleavingEventTimingEntryObserved
|
|
const waitStart = performance.now()
|
|
await t.step_wait(() => (performance.now() - waitStart > 50))
|
|
await new test_driver.Actions()
|
|
.keyUp('a')
|
|
.send()
|
|
await keyUpHandled
|
|
await t.step_wait(() => (keyDowns.length != 0 && keyUps.length != 0), 'Wait for the event timing entries to be processed.')
|
|
assert_equals(keyDowns.length, 1)
|
|
assert_equals(keyUps.length, 1)
|
|
assert_greater_than(keyUps[0].startTime, keyDowns[0].startTime + keyDowns[0].duration)
|
|
}, "keydown duration shouldn't wait for keyup.")
|
|
</script>
|
|
</html>
|