Skip to content

Commit

Permalink
[Interop] Fix PointerEvent WPT for pointer-capture in iframe
Browse files Browse the repository at this point in the history
The test is changed in 3 ways:

- All browsers are failing the 4th promise_test here [1] because
the test was wrongly making a pointer-capture request for the
`<iframe>` element on the top frame instead of an element inside
the iframe.  This is fixed.

- Removed the id `innerFrameElement` from all promise_tests to
avoid possible confusion along the same line.

- When the pointer-capture request is expected to fail, dragging
the pointer into or out-of an iframe activates a iframe-capture
behavior, probably on most browsers, that is not defined in the
PointerEvent spec.  Removed pointer dragging in these cases to keep
the tests focused on well-defined behaviors.

[1] https://wpt.fyi/results/pointerevents/pointerevent_pointercapture_in_frame.html%3Fmouse?label=experimental&label=master&aligned

Bug: 357041460
Change-Id: Ibda5890f5d7d2feb90868aa8e4e99a30ae51a180
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6150548
Commit-Queue: Mustaq Ahmed <[email protected]>
Reviewed-by: Robert Flack <[email protected]>
Auto-Submit: Mustaq Ahmed <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1404203}
  • Loading branch information
mustaqahmed authored and sadym-chromium committed Jan 14, 2025
1 parent 360c368 commit efee0e8
Showing 1 changed file with 33 additions and 23 deletions.
56 changes: 33 additions & 23 deletions pointerevents/pointerevent_pointercapture_in_frame.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
</style>
<body id="outerFrame body" onload="run()">
<div id='outerFrame'>
<iframe id='innerFrameElement' src="resources/pointerevent_pointercapture-iframe.html"></iframe>
<iframe src="resources/pointerevent_pointercapture-iframe.html"></iframe>
</div>
</body>
<script>
Expand Down Expand Up @@ -59,8 +59,24 @@
function handleEvent(event) {
if (event.type == 'pointerdown') {
start_logging = true;
const target = document.captureTargetOverride || event.target;
target.setPointerCapture(event.pointerId);
const capture_target = document.captureTargetOverride || event.target;
try {
capture_target.setPointerCapture(event.pointerId);
} catch (error) {
// The promise_tests below look into logged events to assert capture
// failures without logging the exception here.
//
// Logging the exception here is not interoperable because the pointer
// capture algorithm [1] may fail silently at Step 5 instead of throwing
// at Step 1 in certain cases related to optional requirements for
// `event.pointerId`. Below are two such cases:
// - The user agent has a reserved constant pointerId for pointerType
// "mouse".
// - The user agent exposes the same pointerId for a pointer dragged
// across a same-origin iframe boundary.
//
// [1] https://w3c.github.io/pointerevents/#setting-pointer-capture
}
}

// Only log the first pointermove event after pointerdown. We need to account
Expand Down Expand Up @@ -93,6 +109,7 @@
function run() {
Reset();
var pointerType = location.search.substring(1);

promise_test (async(t) => {
t.add_cleanup(Reset);
expectedEventList = ["innerFrame received pointerdown",
Expand All @@ -102,8 +119,7 @@
"innerFrame received lostpointercapture"];
var pointerId = pointerType + "Pointer1";

var innerFrame = document.getElementById('innerFrameElement');
var innerFrameDocument = innerFrame.contentDocument;
var innerFrameDocument = frames[0].document;
// We are interested in tracking events only after pointerdown
var pointerdown_happened = new Promise((resolve, reject)=>{innerFrameDocument.addEventListener("pointerdown",resolve);});
var watcher_promise = pointerdown_happened.then(()=>{
Expand All @@ -118,7 +134,6 @@
.pointerMove(150, 150)
.pointerMove(50, 50)
.pointerUp()
.pointerMove(75, 75)
.send();
// Wait for lostpointercapture to fire.
await watcher_promise;
Expand All @@ -130,11 +145,10 @@
document.captureTargetOverride = document.getElementById('outerFrame');
expectedEventList = ["innerFrame received pointerdown",
"innerFrame received pointermove",
"innerFrameDocument received pointerup"];
"innerFrame received pointerup"];
var pointerId = pointerType + "Pointer1";

var innerFrame = document.getElementById('innerFrameElement');
var innerFrameDocument = innerFrame.contentDocument;
var innerFrameDocument = frames[0].document;
// We are interested in tracking events only after pointerdown
var pointerdown_happened = new Promise((resolve, reject)=>{innerFrameDocument.addEventListener("pointerdown",resolve);});

Expand All @@ -148,10 +162,12 @@
.pointerMove(200, 200)
.pointerDown()
.pointerMove(150, 150)
.pointerMove(50, 50)
.pointerUp()
.pointerMove(75, 75)
.send();
// Interestingly, a drag out of the iframe behaves consitently between
// Chrome, Firefox and Safari even though this is not spec-ed: the
// `pointerup` always goes to innerFrameDocument.

// Wait for pointerup to fire.
await watcher_promise;
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
Expand Down Expand Up @@ -182,16 +198,15 @@
.pointerDown()
.pointerMove(200, 200)
.pointerUp()
.pointerMove(25, 25)
.send();
// Wait for lostpointercapture to fire.
// Wait for pointerup or lostpointercapture to fire.
await watcher_promise;
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
}, "Test " + pointerType + "pointer capture in same-origin frame: Pointer down at outer frame body and set pointer capture.");

promise_test (async(t) => {
t.add_cleanup(Reset);
document.captureTargetOverride = document.getElementById('innerFrameElement');
document.captureTargetOverride = frames[0].document.body;
expectedEventList = ["outerFrame received pointerdown",
"outerFrame received pointermove",
"outerFrame received pointerup"];
Expand All @@ -208,11 +223,10 @@
.addPointer(pointerId, pointerType)
.pointerMove(25, 25)
.pointerDown()
.pointerMove(200, 200)
.pointerMove(75, 75)
.pointerUp()
.pointerMove(25, 25)
.send();
// Wait for lostpointercapture to fire.
// Wait for pointerup to fire.
await watcher_promise;
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
}, "Test " + pointerType + "pointer capture in same-origin frame: Pointer down at outer frame body and set pointer capture in inner frame should not capture.");
Expand All @@ -229,8 +243,7 @@
(pointerType == "touch" ? "outerFrame": "innerFrameDocument") + " received pointerup",];
var pointerId = pointerType + "Pointer1";

var innerFrame = document.getElementById('innerFrameElement');
var innerFrameDocument = innerFrame.contentDocument;
var innerFrameDocument = frames[0].document;
// We are interested in tracking events only after pointerdown
var pointerdown_happened = new Promise((resolve, reject)=>{innerFrameDocument.addEventListener("pointerdown",resolve);});
var watcher_promise = pointerdown_happened.then(()=>{
Expand All @@ -250,15 +263,13 @@
.pointerMove(150, 150)
.pointerMove(50, 50)
.pointerUp()
.pointerMove(150, 150)
.send();
// Wait for pointerup to fire.
await watcher_promise;
assert_array_equals(receivedEventList, expectedEventList, "Received events: " + receivedEventList);
document.releasePointerCaptureOnFirstMove = false;
}, "Test " + pointerType + "pointer capture in same-origin frame: Pointerdown with set capture at inner frame, then release on next pointermove.");


promise_test (async(t) => {
t.add_cleanup(Reset);
document.releasePointerCaptureOnFirstMove = true;
Expand All @@ -269,8 +280,7 @@
"innerFrame received pointerup"];
var pointerId = pointerType + "Pointer1";

var innerFrame = document.getElementById('innerFrameElement');
var innerFrameDocument = innerFrame.contentDocument;
var innerFrameDocument = frames[0].document;
// We are interested in tracking events only after pointerdown
var pointerdown_happened = new Promise((resolve, reject)=>{document.getElementById('outerFrame').addEventListener("pointerdown",resolve);});
var watcher_promise = pointerdown_happened.then(()=>{
Expand Down

0 comments on commit efee0e8

Please sign in to comment.