| <!DOCTYPE html> |
| <html> |
| <meta charset=utf-8 /> |
| <title>Event Timing: pointerdown and pointerup should not overlap when there is a paint in between</title> |
| <script src=/resources/testharness.js></script> |
| <script src=/resources/testharnessreport.js></script> |
| <script src=/resources/testdriver.js></script> |
| <script src=/resources/testdriver-vendor.js></script> |
| <script src=/resources/testdriver-actions.js></script> |
| <script src=resources/event-timing-test-utils.js></script> |
| <button id='button'>Click me.</button> |
| <script> |
| promise_test(async t => { |
| assert_implements(window.PerformanceEventTiming, 'Event Timing is not supported.'); |
| const button = document.getElementById('button'); |
| const observedEntries = []; |
| |
| button.addEventListener('pointerdown', () => { |
| mainThreadBusy(30); |
| }); |
| button.addEventListener('pointerup', () => { |
| mainThreadBusy(30); |
| }); |
| button.addEventListener('click', () => { |
| mainThreadBusy(150); |
| }); |
| |
| const observerPromise = new Promise(resolve => { |
| new PerformanceObserver(entryList => { |
| observedEntries.push(...entryList.getEntries().filter(entry => |
| entry.name === 'pointerdown' || entry.name === 'pointerup' || entry.name === 'click' |
| )); |
| |
| // We expect pointerdown, pointerup, and click. |
| if (observedEntries.length >= 3) { |
| resolve(); |
| } |
| }).observe({type: 'event', durationThreshold: 16, buffered: true}); |
| }); |
| |
| const actions1 = new test_driver.Actions(); |
| await actions1 |
| .addPointer("testPointer", "mouse") |
| .pointerMove(0, 0, {origin: button}) |
| .pointerDown({button: actions1.ButtonType.LEFT}) |
| .pause(50) |
| .send(); |
| |
| // Wait for a paint to occur |
| await afterNextPaint(); |
| |
| // Perform pointerup |
| const actions2 = new test_driver.Actions(); |
| await actions2 |
| .addPointer("testPointer", "mouse") |
| .pointerMove(0, 0, {origin: button}) |
| .pointerUp({button: actions2.ButtonType.LEFT}) |
| .send(); |
| |
| await observerPromise; |
| |
| const pointerdownEntry = observedEntries.find(e => e.name === 'pointerdown'); |
| const pointerupEntry = observedEntries.find(e => e.name === 'pointerup'); |
| const clickEntry = observedEntries.find(e => e.name === 'click'); |
| |
| assert_true(!!pointerdownEntry, 'Should have pointerdown entry'); |
| assert_true(!!pointerupEntry, 'Should have pointerup entry'); |
| assert_true(!!clickEntry, 'Should have click entry'); |
| |
| // Calculate end times: startTime + duration. |
| const pointerdownEndTime = pointerdownEntry.startTime + pointerdownEntry.duration; |
| const pointerupStartTime = pointerupEntry.startTime; |
| |
| // pointerdown should complete BEFORE pointerup starts. |
| assert_less_than_equal(pointerdownEndTime, pointerupStartTime, |
| 'pointerdown should end before or when pointerup starts (no overlap)'); |
| }, 'pointerdown and pointerup should not overlap when there is no pointerdown handler'); |
| </script> |
| </html> |