commit b3cf5553a09c3d6cb39393902b933b636a6f2caa
parent aaa64225d8a56bf94bd2ea57bf2b41ca4a09a7a7
Author: Mustaq Ahmed <mustaq@google.com>
Date: Fri, 7 Nov 2025 09:03:07 +0000
Bug 1998593 [wpt PR 55894] - Fix pointerevent_after_target_removed_from_slot.html asserts, a=testonly
Automatic update from web-platform-tests
Fix pointerevent_after_target_removed_from_slot.html asserts
This CL updates the test its and expectations to match the event hittest
behavior in practice after either the slot or the element placed in the
slot is removed. To avoid boundary event complications caused by layout
changes, all relevant elements are made same sized.
The expectations are written based on the following observations: each
test starts with `host` containing the shadow-root containing `parent`
containing `slot` in which `child` is placed; `child` remains hidden as
a a sibling of the shadow-root until placed in `slot`.
- Removing `slot` returns `child` back to the hidden position.
- Removing `child` exposes the subtree of `slot`.
Manual testing: https://codepen.io/mustaqahmed/full/LEGgpMQ
Bug: 404479707
Change-Id: I2ce50112f7f1bdb2a4cb6417e7477f59be5e1b89
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7107458
Reviewed-by: Robert Flack <flackr@chromium.org>
Commit-Queue: Mustaq Ahmed <mustaq@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1541198}
--
wpt-commits: a9f4351e61506bfec0a0c111f22d164cf213aa1c
wpt-pr: 55894
Diffstat:
1 file changed, 103 insertions(+), 81 deletions(-)
diff --git a/testing/web-platform/tests/pointerevents/pointerevent_after_target_removed_from_slot.html b/testing/web-platform/tests/pointerevents/pointerevent_after_target_removed_from_slot.html
@@ -1,6 +1,7 @@
<!DOCTYPE HTML>
-<link rel="help" href="https://w3c.github.io/pointerevents/#firing-events-using-the-pointerevent-interface">
-<title>Enter/leave events fired to parent after child is removed from slot</title>
+<link rel="help"
+ href="https://w3c.github.io/pointerevents/#firing-events-using-the-pointerevent-interface">
+<title>Pointerevents fired after a slotted element is removed</title>
<meta name="variant" content="?mouse">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
@@ -9,56 +10,45 @@
<script src="/resources/testdriver-vendor.js"></script>
<script src="pointerevent_support.js"></script>
-<template id="template">
- <style>
- div {
- width: 100px;
- height: 100px;
- }
- </style>
- <div id="parent">
- <slot id="slot">slot</slot>
- </div>
-</template>
-
<style>
- div, my-elem {
+ div {
width: 100px;
height: 100px;
display: block;
}
</style>
-<my-elem id="host">
- <div id="child">child</div>
-</my-elem>
-<div id="done">done</div>
+<div id="host">
+ <template id="template" shadowrootmode="open">
+ <style>
+ div {
+ width: 100px;
+ height: 100px;
+ }
+ </style>
+ <div id="parent">
+ <slot id="slot">
+ <div></div>
+ </slot>
+ </div>
+ </template>
+
+ <div id="filler"></div>
+</div>
+<div id="done"></div>
<script>
"use strict";
- customElements.define(
- "my-elem",
- class extends HTMLElement {
- constructor() {
- super();
- let content = document.getElementById("template").content;
- const shadowRoot = this.attachShadow({ mode: "open" });
- shadowRoot.appendChild(content.cloneNode(true));
- }
- },
- );
-
const pointer_type = location.search.substring(1);
- const shadow_host = document.getElementById("host");
- const parent = shadow_host.shadowRoot.getElementById("parent");
+ const host = document.getElementById("host");
+ const parent = host.shadowRoot.getElementById("parent");
const slot = parent.firstElementChild;
- const slotted_child = document.getElementById("child");
+ const filler = document.getElementById("filler");
const done = document.getElementById("done");
let event_log = [];
- let elem_to_remove;
function logEvent(e) {
if (e.eventPhase == e.AT_TARGET) {
@@ -66,48 +56,49 @@
}
}
- function removeChildFromSlot() {
- elem_to_remove.remove();
- event_log.push("(child-removed)");
- }
-
- function restoreChildInSlot() {
- if (!slotted_child.parentElement) {
- shadow_host.appendChild(slotted_child);
- }
- if (!slot.parentElement) {
- parent.appendChild(slot);
+ const modifier_methods = {
+ "remove-slot": {
+ "remover": () => { slot.remove(); event_log.push("(removed)"); },
+ "restorer": () => { parent.appendChild(slot); }
+ },
+ "remove-filler": {
+ "remover": () => { filler.remove(); event_log.push("(removed)"); },
+ "restorer": () => { host.appendChild(filler); }
+ },
+ "change-slotname": {
+ "remover": () => { filler.slot = "xyz"; event_log.push("(removed)"); },
+ "restorer": () => { filler.slot = ""; }
}
}
function setup() {
const events = ["pointerover", "pointerout",
"pointerenter", "pointerleave", "pointerdown", "pointerup"];
- let targets = [shadow_host, parent, slot, slotted_child];
+ let targets = [host, parent, slot, filler];
for (let i = 0; i < targets.length; i++) {
events.forEach(event => targets[i].addEventListener(event, logEvent));
}
}
- function addPromiseTest(remover_event, tested_elem_to_remove,
+ function addPromiseTest(remover_event, removal_type,
expected_events) {
- assert_true(["slot", "slotted-child"].includes(tested_elem_to_remove),
- "Unexpcted tested_elem_to_remove param");
+ assert_true(Object.keys(modifier_methods).includes(removal_type),
+ "[sanity check] Unknown removal_type param");
- const test_name = `Pointer events from ${pointer_type} `+
- `received before/after ${tested_elem_to_remove} removal `+
+ const test_name = `${pointer_type} events with ${removal_type} ` +
`at ${remover_event}`;
promise_test(async test => {
event_log = [];
- elem_to_remove = (tested_elem_to_remove == "slot" ? slot : slotted_child);
- restoreChildInSlot();
- child.addEventListener(remover_event, removeChildFromSlot,
- { once: true });
+ filler.addEventListener(remover_event,
+ modifier_methods[removal_type].remover,
+ { once: true });
+ test.add_cleanup(modifier_methods[removal_type].restorer);
+
// TODO(mustaq@chromium.org): It would be more robust if we could remove
// the event listener above through `test.add_cleanup()` but strangely the
- // cleanup call fails after the test that removes the slotted-child! This
+ // cleanup call fails after the test that removes the filler! This
// happens even if we make the shadow DOM construction dynamic inside this
// `promise_test`!!!
@@ -115,10 +106,10 @@
let actions = new test_driver.Actions()
.addPointer("TestPointer", pointer_type)
- .pointerMove(-30, -30, {origin: shadow_host})
+ .pointerMove(-30, -30, {origin: host})
.pointerDown()
.pointerUp()
- .pointerMove(30, 30, {origin: shadow_host})
+ .pointerMove(30, 30, {origin: host})
.pointerDown()
.pointerUp()
.pointerMove(0, 0, {origin: done})
@@ -128,10 +119,13 @@
await actions.send();
await done_click_promise;
- let removal_in_event_log = event_log.indexOf("(child-removed)");
- let removal_in_expected_list = expected_events.indexOf("(child-removed)");
- assert_true(removal_in_event_log != -1 && removal_in_expected_list != -1,
- "(child-removed) expected in both lists");
+ let removal_in_event_log = event_log.indexOf("(removed)");
+ assert_true(removal_in_event_log != -1,
+ "(removed) in event log");
+
+ let removal_in_expected_list = expected_events.indexOf("(removed)");
+ assert_true(removal_in_expected_list != -1,
+ "[sanity check] (removed) in expected events");
assert_equals(event_log.slice(0, removal_in_event_log).toString(),
expected_events.slice(0, removal_in_expected_list).toString(),
@@ -146,11 +140,12 @@
addPromiseTest(
"pointerdown",
- "slot",
+ "remove-slot",
[
- "pointerover@child",
- "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
- "pointerdown@child", "(child-removed)",
+ "pointerover@filler",
+ "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
+ "pointerdown@filler", "(removed)",
+ "pointerout@filler", "pointerleave@filler",
"pointerover@parent", "pointerover@host", "pointerup@parent", "pointerup@host",
"pointerdown@parent", "pointerdown@host", "pointerup@parent", "pointerup@host",
"pointerout@parent", "pointerout@host",
@@ -159,12 +154,25 @@
);
addPromiseTest(
"pointerdown",
- "slotted-child",
+ "remove-filler",
+ [
+ "pointerover@filler",
+ "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
+ "pointerdown@filler", "(removed)",
+ "pointerover@slot", "pointerup@slot",
+ "pointerdown@slot", "pointerup@slot",
+ "pointerout@slot",
+ "pointerleave@slot", "pointerleave@parent", "pointerleave@host"
+ ]
+ );
+ addPromiseTest(
+ "pointerdown",
+ "change-slotname",
[
- "pointerover@child",
- "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
- "pointerdown@child", "(child-removed)",
- "pointerleave@slot",
+ "pointerover@filler",
+ "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
+ "pointerdown@filler", "(removed)",
+ "pointerout@filler", "pointerleave@filler",
"pointerover@parent", "pointerover@host", "pointerup@parent", "pointerup@host",
"pointerdown@parent", "pointerdown@host", "pointerup@parent", "pointerup@host",
"pointerout@parent", "pointerout@host",
@@ -173,11 +181,12 @@
);
addPromiseTest(
"pointerup",
- "slot",
+ "remove-slot",
[
- "pointerover@child",
- "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
- "pointerdown@child", "pointerup@child", "(child-removed)",
+ "pointerover@filler",
+ "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
+ "pointerdown@filler", "pointerup@filler", "(removed)",
+ "pointerout@filler", "pointerleave@filler",
"pointerover@parent", "pointerover@host",
"pointerdown@parent", "pointerdown@host", "pointerup@parent", "pointerup@host",
"pointerout@parent", "pointerout@host",
@@ -186,12 +195,25 @@
);
addPromiseTest(
"pointerup",
- "slotted-child",
+ "remove-filler",
+ [
+ "pointerover@filler",
+ "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
+ "pointerdown@filler", "pointerup@filler", "(removed)",
+ "pointerover@slot",
+ "pointerdown@slot", "pointerup@slot",
+ "pointerout@slot",
+ "pointerleave@slot", "pointerleave@parent", "pointerleave@host"
+ ]
+ );
+ addPromiseTest(
+ "pointerup",
+ "change-slotname",
[
- "pointerover@child",
- "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
- "pointerdown@child", "pointerup@child", "(child-removed)",
- "pointerleave@slot",
+ "pointerover@filler",
+ "pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@filler",
+ "pointerdown@filler", "pointerup@filler", "(removed)",
+ "pointerout@filler", "pointerleave@filler",
"pointerover@parent", "pointerover@host",
"pointerdown@parent", "pointerdown@host", "pointerup@parent", "pointerup@host",
"pointerout@parent", "pointerout@host",