Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 1 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /event-timing/gap-keydown-keyup.html - WPT Dashboard Interop Dashboard
<!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
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>