Skip to content

Commit

Permalink
Re-sync web-platform-tests/uievents/mouse from upstream
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=263043
rdar://116832525

Reviewed by Megan Gardner.

This patch imports web-platform-tests/uievents/mouse from upstream
(revision 08b5fe94e3503a012eb261e6ab353053f579ed37).

The uievents/mouse/mousemove_prevent_default_action.tentative.html test
has been revamped in said commit, and will allow us to update our local
test expectations for this test to fully passing once the fix for bug
262878 lands.

* LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/mousemove_prevent_default_action.tentative-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/mousemove_prevent_default_action.tentative.html:
* LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative_buttonType=LEFT&button=0&buttons=1-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative_buttonType=MIDDLE&button=1&buttons=4-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/w3c-import.log:
* LayoutTests/platform/glib/imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative_buttonType=MIDDLE&button=1&buttons=4-expected.txt: Added.
* LayoutTests/platform/ios/TestExpectations:
* LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/uievents/mouse/mousemove_prevent_default_action.tentative-expected.txt:
* LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative_buttonType=LEFT&button=0&buttons=1-expected.txt: Added.
* LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative_buttonType=MIDDLE&button=1&buttons=4-expected.txt: Added.
* LayoutTests/tests-options.json:

Canonical link: https://commits.webkit.org/269248@main
  • Loading branch information
aprotyas committed Oct 12, 2023
1 parent 9ea9298 commit 9111663
Show file tree
Hide file tree
Showing 12 changed files with 305 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ div b
div c

FAIL selectionchange event firing when mousemove event is prevented assert_equals: received events expected "mousemove,mousedown,selectionchange,mousemove,selectionchange" but got "mousemove,mousedown,selectionchange,mousemove"
FAIL dragstart event firing when mousemove event is prevented assert_equals: received events expected "mousemove,mousedown,mousemove,dragstart" but got "mousemove,mousedown,selectionchange,mousemove"
FAIL dragstart event firing when mousemove event is prevented assert_equals: received events expected "mousemove,mousedown,mousemove,dragstart" but got "mousemove,mousedown,mousemove"

Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@

// Deliberately avoiding mouseup here because the last selectionchange
// may be fired before or after the mouseup.
["mousedown", "mousemove", "selectionchange", "dragstart"].forEach(ename => {
document.addEventListener(ename, logEvents);
});
document.addEventListener("mousedown", logEvents);
document.addEventListener("mousemove", logEvents);
document.addEventListener("mousemove", e => e.preventDefault());

promise_test(async () => {
promise_test(async test => {
document.addEventListener("selectionchange", logEvents);
test.add_cleanup(() => { document.removeEventListener("selectionchange", logEvents); });
event_log = [];

const a = document.getElementById("a");
Expand Down Expand Up @@ -60,7 +61,9 @@
"received events");
}, "selectionchange event firing when mousemove event is prevented");

promise_test(async () => {
promise_test(async test => {
document.addEventListener("dragstart", logEvents);
test.add_cleanup(() => { document.removeEventListener("dragstart", logEvents); });
event_log = [];

const b = document.getElementById("b");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="variant" content="?buttonType=LEFT&button=0&buttons=1">
<meta name="variant" content="?buttonType=MIDDLE&button=1&buttons=4">
<title>Testing button state of synthesized mouse(out|over|leave|enter) events</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>
<style>
#parent {
background-color: lightseagreen;
padding: 0;
height: 40px;
width: 40px;
}
#child {
background-color: red;
margin: 0;
height: 30px;
width: 30px;
}
</style>
</head>
<body>
<div id="parent"><div id="child">abc</div></div>
<script>
const searchParams = new URLSearchParams(document.location.search);
const buttonType = searchParams.get("buttonType");
const button = parseInt(searchParams.get("button"));
const buttons = parseInt(searchParams.get("buttons"));

let events = [];
function eventToString(data) {
if (!data) {
return "{}";
}
return `{ '${data.type}' on '${data.target}': button=${data.button}, buttons=${data.buttons} }`;
}

function eventsToString(events) {
if (!events.length) {
return "[]";
}
let ret = "[";
for (const data of events) {
if (ret != "[") {
ret += ", ";
}
ret += eventToString(data);
}
return ret + "]";
}

function removeEventsBefore(eventType) {
while (events[0]?.type != eventType) {
events.shift();
}
}

const parentElement = document.getElementById("parent");
const childElement = document.getElementById("child");

function promiseLayout() {
return new Promise(resolve => {
(childElement.isConnected ? childElement : parentElement).getBoundingClientRect();
requestAnimationFrame(() => requestAnimationFrame(resolve));
});
}

promise_test(async () => {
await new Promise(resolve => {
addEventListener("load", resolve, { once: true });
});

["mouseout", "mouseover", "mouseleave", "mouseenter", "mousemove", "mousedown"].forEach(eventType => {
parentElement.addEventListener(eventType, event => {
if (event.target != parentElement) {
return;
}
events.push({
type: event.type,
target: "parent",
button: event.button,
buttons: event.buttons,
});
});
childElement.addEventListener(eventType, event => {
if (event.target != childElement) {
return;
}
events.push({
type: event.type,
target: "child",
button: event.button,
buttons: event.buttons,
});
});
});
}, "Setup event listeners and wait for load");

promise_test(async t => {
events = [];
await promiseLayout();
childElement.addEventListener("mousedown", () => childElement.remove(), {once: true});
const {x, y} = (function () {
const rect = childElement.getBoundingClientRect();
return { x: rect.left, y: rect.top };
})();
const actions = new test_driver.Actions();
await actions.pointerMove(10, 10, {origin: childElement})
.pointerDown({button: actions.ButtonType[buttonType]})
.pause(100) // Allow browsers to synthesize mouseout, etc
.pointerUp({button: actions.ButtonType[buttonType]})
.send();
await promiseLayout();
removeEventsBefore("mousedown");
test(() => {
const maybeMouseDownEvent =
events.length && events[0].type == "mousedown" ? events.shift() : undefined;
assert_equals(
eventToString(maybeMouseDownEvent),
eventToString({ type: "mousedown", target: "child", button, buttons })
);
}, `${t.name}: mousedown should've been fired`);
assert_true(events.length > 0, `${t.name}: Some events should've been fired after mousedown`);
test(() => {
// Before `mousedown` is fired, both parent and child must have received
// `mouseenter`, only the child must have received `mouseover`. Then, the
// child is now moved away by the `mousedown` listener. Therefore,
// `mouseout` and `mouseleave` should be fired on the child as the spec of
// UI Events defines. Then, they are not a button press events. Therefore,
// the `button` should be 0, but buttons should be set to 4 because of
// pressing the middle button.
let mouseOutOrLeave = [];
while (events[0]?.type == "mouseout" || events[0]?.type == "mouseleave") {
mouseOutOrLeave.push(events.shift());
}
assert_equals(
eventsToString(mouseOutOrLeave),
eventsToString([
{ type: "mouseout", target: "child", button: 0, buttons },
{ type: "mouseleave", target: "child", button: 0, buttons },
])
);
}, `${t.name}: mouseout and mouseleave should've been fired on the removed child`);
test(() => {
// And `mouseover` should be fired on the parent as the spec of UI Events
// defines.
let mouseOver = [];
while (events[0]?.type == "mouseover") {
mouseOver.push(events.shift());
}
assert_equals(
eventsToString(mouseOver),
eventsToString([{ type: "mouseover", target: "parent", button: 0, buttons }])
);
}, `${t.name}: mouseover should've been fired on the parent`);
test(() => {
// On the other hand, it's unclear about `mouseenter`. The mouse cursor has
// never been moved out from the parent. Therefore, it shouldn't be fired
// on the parent ideally, but all browsers do not pass this test and there
// is no clear definition about this case.
let mouseEnter = [];
while (events.length && events[0].type == "mouseenter") {
mouseEnter.push(events.shift());
}
assert_equals(eventsToString(mouseEnter), eventsToString([]));
}, `${t.name}: mouseenter should not have been fired on the parent`);
assert_equals(eventsToString(events), eventsToString([]), "All events should've been checked");
parentElement.appendChild(childElement);
}, "Removing an element at mousedown");

promise_test(async t => {
events = [];
await promiseLayout();
childElement.addEventListener("mouseup", () => childElement.remove(), {once: true});
const {x, y} = (function () {
const rect = childElement.getBoundingClientRect();
return { x: rect.left, y: rect.top };
})();
const actions = new test_driver.Actions();
await actions.pointerMove(10, 10, {origin: childElement})
.pointerDown({button: actions.ButtonType[buttonType]})
.pointerUp({button: actions.ButtonType[buttonType]})
.send();
await promiseLayout();
removeEventsBefore("mousedown");
test(() => {
const maybeMouseDownEvent =
events.length && events[0].type == "mousedown" ? events.shift() : undefined;
assert_equals(
eventToString(maybeMouseDownEvent),
eventToString({ type: "mousedown", target: "child", button, buttons })
);
}, `${t.name}: mousedown should've been fired`);
assert_true(events.length > 0, `${t.name}: Some events should've been fired after mousedown`);
// Same as the `mousedown` case except `buttons` value because `mouseout`,
// `mouseleave`, `mouseover` and `mouseenter` should (or may) be fired
// after the `mouseup`. Therefore, `.buttons` should not have the button
// flag.
test(() => {
let mouseOutOrLeave = [];
while (events[0]?.type == "mouseout" || events[0]?.type == "mouseleave") {
mouseOutOrLeave.push(events.shift());
}
assert_equals(
eventsToString(mouseOutOrLeave),
eventsToString([
{ type: "mouseout", target: "child", button: 0, buttons: 0 },
{ type: "mouseleave", target: "child", button: 0, buttons: 0 },
])
);
}, `${t.name}: mouseout and mouseleave should've been fired on the removed child`);
test(() => {
let mouseOver = [];
while (events[0]?.type == "mouseover") {
mouseOver.push(events.shift());
}
assert_equals(
eventsToString(mouseOver),
eventsToString([{ type: "mouseover", target: "parent", button: 0, buttons: 0 }])
);
}, `${t.name}: mouseover should've been fired on the parent`);
test(() => {
let mouseEnter = [];
while (events[0]?.type == "mouseenter") {
mouseEnter.push(events.shift());
}
assert_equals(eventsToString(mouseEnter), eventsToString([]));
}, `${t.name}: mouseenter should not have been fired on the parent`);
assert_equals(eventsToString(events), eventsToString([]), "All events should've been checked");
parentElement.appendChild(childElement);
}, "Removing an element at mouseup");
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

PASS Setup event listeners and wait for load
FAIL Removing an element at mousedown assert_true: Removing an element at mousedown: Some events should've been fired after mousedown expected true got false
FAIL Removing an element at mouseup assert_true: Removing an element at mouseup: Some events should've been fired after mousedown expected true got false
PASS Removing an element at mousedown: mousedown should've been fired
FAIL Removing an element at mouseup: mousedown should've been fired assert_equals: expected "{ 'mousedown' on 'child': button=0, buttons=1 }" but got "{ 'mousedown' on 'parent': button=0, buttons=1 }"

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

PASS Setup event listeners and wait for load
FAIL Removing an element at mousedown assert_true: Removing an element at mousedown: Some events should've been fired after mousedown expected true got false
FAIL Removing an element at mouseup assert_true: Removing an element at mouseup: Some events should've been fired after mousedown expected true got false
FAIL Removing an element at mousedown: mousedown should've been fired assert_equals: expected "{ 'mousedown' on 'child': button=1, buttons=4 }" but got "{ 'mousedown' on 'child': button=1, buttons=2 }"
FAIL Removing an element at mouseup: mousedown should've been fired assert_equals: expected "{ 'mousedown' on 'child': button=1, buttons=4 }" but got "{ 'mousedown' on 'parent': button=1, buttons=2 }"

Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ List of files:
/LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/mouseenter-mouseleave-on-drag.html
/LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/mouseevent_move_button.html
/LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/mousemove_prevent_default_action.tentative.html
/LayoutTests/imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

PASS Setup event listeners and wait for load
FAIL Removing an element at mousedown assert_true: Removing an element at mousedown: Some events should've been fired after mousedown expected true got false
FAIL Removing an element at mouseup assert_true: Removing an element at mouseup: Some events should've been fired after mousedown expected true got false
PASS Removing an element at mousedown: mousedown should've been fired
FAIL Removing an element at mouseup: mousedown should've been fired assert_equals: expected "{ 'mousedown' on 'child': button=1, buttons=4 }" but got "{ 'mousedown' on 'parent': button=1, buttons=4 }"

4 changes: 4 additions & 0 deletions LayoutTests/platform/ios/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -3376,6 +3376,10 @@ webkit.org/b/221466 imported/w3c/web-platform-tests/uievents/keyboard/modifier-k
webkit.org/b/221465 imported/w3c/web-platform-tests/uievents/keyboard/modifier-keys-combinations.html [ Skip ]
webkit.org/b/262723 imported/w3c/web-platform-tests/uievents/mouse/cancel-mousedown-in-subframe.html [ Skip ]

# https://webkit.org/b/263067 ([iOS] uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html WPT consistently times out in iOS 16 open source config)
imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html?buttonType=LEFT&button=0&buttons=1 [ Skip ]
imported/w3c/web-platform-tests/uievents/mouse/synthetic-mouse-enter-leave-over-out-button-state-after-target-removed.tentative.html?buttonType=MIDDLE&button=1&buttons=4 [ Skip ]

# iOS15 supports this emoji.
fast/text/mending-heart.html [ Pass ]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ div b
div c

FAIL selectionchange event firing when mousemove event is prevented assert_equals: received events expected "mousemove,mousedown,selectionchange,mousemove,selectionchange" but got "mousemove,mousedown,selectionchange,mousemove,mousemove"
FAIL dragstart event firing when mousemove event is prevented assert_equals: received events expected "mousemove,mousedown,mousemove,dragstart" but got "mousemove,mousedown,selectionchange,mousemove,mousemove"
FAIL dragstart event firing when mousemove event is prevented assert_equals: received events expected "mousemove,mousedown,mousemove,dragstart" but got "mousemove,mousedown,mousemove,mousemove"

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

PASS Setup event listeners and wait for load
FAIL Removing an element at mousedown assert_equals: All events should've been checked expected "[]" but got "[{ 'mousemove' on 'parent': button=0, buttons=0 }]"
FAIL Removing an element at mouseup assert_equals: All events should've been checked expected "[]" but got "[{ 'mousemove' on 'parent': button=0, buttons=0 }]"
PASS Removing an element at mousedown: mousedown should've been fired
FAIL Removing an element at mousedown: mouseout and mouseleave should've been fired on the removed child assert_equals: expected "[{ 'mouseout' on 'child': button=0, buttons=1 }, { 'mouseleave' on 'child': button=0, buttons=1 }]" but got "[{ 'mouseout' on 'child': button=0, buttons=0 }, { 'mouseleave' on 'child': button=0, buttons=0 }]"
FAIL Removing an element at mousedown: mouseover should've been fired on the parent assert_equals: expected "[{ 'mouseover' on 'parent': button=0, buttons=1 }]" but got "[{ 'mouseover' on 'parent': button=0, buttons=0 }]"
FAIL Removing an element at mousedown: mouseenter should not have been fired on the parent assert_equals: expected "[]" but got "[{ 'mouseenter' on 'parent': button=0, buttons=0 }]"
FAIL Removing an element at mouseup: mousedown should've been fired assert_equals: expected "{ 'mousedown' on 'child': button=0, buttons=1 }" but got "{ 'mousedown' on 'parent': button=0, buttons=1 }"
FAIL Removing an element at mouseup: mouseout and mouseleave should've been fired on the removed child assert_equals: expected "[{ 'mouseout' on 'child': button=0, buttons=0 }, { 'mouseleave' on 'child': button=0, buttons=0 }]" but got "[]"
FAIL Removing an element at mouseup: mouseover should've been fired on the parent assert_equals: expected "[{ 'mouseover' on 'parent': button=0, buttons=0 }]" but got "[]"
PASS Removing an element at mouseup: mouseenter should not have been fired on the parent

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

PASS Setup event listeners and wait for load
FAIL Removing an element at mousedown assert_equals: All events should've been checked expected "[]" but got "[{ 'mousemove' on 'parent': button=0, buttons=0 }]"
FAIL Removing an element at mouseup assert_equals: All events should've been checked expected "[]" but got "[{ 'mousemove' on 'parent': button=0, buttons=0 }]"
FAIL Removing an element at mousedown: mousedown should've been fired assert_equals: expected "{ 'mousedown' on 'child': button=1, buttons=4 }" but got "{ 'mousedown' on 'child': button=1, buttons=2 }"
FAIL Removing an element at mousedown: mouseout and mouseleave should've been fired on the removed child assert_equals: expected "[{ 'mouseout' on 'child': button=0, buttons=4 }, { 'mouseleave' on 'child': button=0, buttons=4 }]" but got "[{ 'mouseout' on 'child': button=0, buttons=0 }, { 'mouseleave' on 'child': button=0, buttons=0 }]"
FAIL Removing an element at mousedown: mouseover should've been fired on the parent assert_equals: expected "[{ 'mouseover' on 'parent': button=0, buttons=4 }]" but got "[{ 'mouseover' on 'parent': button=0, buttons=0 }]"
FAIL Removing an element at mousedown: mouseenter should not have been fired on the parent assert_equals: expected "[]" but got "[{ 'mouseenter' on 'parent': button=0, buttons=0 }]"
FAIL Removing an element at mouseup: mousedown should've been fired assert_equals: expected "{ 'mousedown' on 'child': button=1, buttons=4 }" but got "{ 'mousedown' on 'parent': button=1, buttons=2 }"
FAIL Removing an element at mouseup: mouseout and mouseleave should've been fired on the removed child assert_equals: expected "[{ 'mouseout' on 'child': button=0, buttons=0 }, { 'mouseleave' on 'child': button=0, buttons=0 }]" but got "[]"
FAIL Removing an element at mouseup: mouseover should've been fired on the parent assert_equals: expected "[{ 'mouseover' on 'parent': button=0, buttons=0 }]" but got "[]"
PASS Removing an element at mouseup: mouseenter should not have been fired on the parent

3 changes: 3 additions & 0 deletions LayoutTests/tests-options.json
Original file line number Diff line number Diff line change
Expand Up @@ -5519,6 +5519,9 @@
"imported/w3c/web-platform-tests/svg/animations/svglengthlist-animation-3.html": [
"slow"
],
"imported/w3c/web-platform-tests/uievents/mouse/mouseevent_move_button.html": [
"slow"
],
"imported/w3c/web-platform-tests/upgrade-insecure-requests/gen/iframe-blank-inherit.meta/unset/fetch.https.html": [
"slow"
],
Expand Down

0 comments on commit 9111663

Please sign in to comment.