Skip to content

Commit

Permalink
Bug 1901815 [wpt PR 46694] - WPT coverage for Pointer Events for slot…
Browse files Browse the repository at this point in the history
…ted elements., a=testonly

Automatic update from web-platform-tests
WPT coverage for Pointer Events for slotted elements.

This CL adds tests for two untested aspects of PointerEvents in slots:
- PE event sequence around slots when the shadow DOM remains unchanged.
- Boundary events after modifications to slotted elements.

This covers the last remaining WPT for:
w3c/pointerevents#477

Bug: 40156858

Change-Id: I9823595a0b15672d0395d4e117ccc6462c3e42f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5598510
Commit-Queue: Mustaq Ahmed <mustaq@chromium.org>
Reviewed-by: Robert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1313570}

--

wpt-commits: b8aab6837b61aacee4cbad1fbb6aeb3952af7b60
wpt-pr: 46694
  • Loading branch information
mustaqahmed authored and moz-wptsync-bot committed Jun 14, 2024
1 parent 7bee123 commit 56ef0ea
Show file tree
Hide file tree
Showing 2 changed files with 282 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<!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>
<meta name="variant" content="?mouse">
<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="pointerevent_support.js"></script>

<template id="template">
<style>
div {
width: 100px;
height: 100px;
}
</style>
<div id="parent">
<slot>slot</slot>
</div>
</template>

<style>
div, my-elem {
width: 100px;
height: 100px;
display: block;
}
</style>

<my-elem id="host">
<div id="child">child</div>
</my-elem>
<div id="done">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 slot = parent.firstElementChild;
const slotted_child = document.getElementById("child");
const done = document.getElementById("done");

let event_log = [];
let elem_to_remove;

function logEvent(e) {
if (e.eventPhase == e.AT_TARGET) {
event_log.push(e.type + "@" + e.target.id);
}
}

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);
}
}

function setup() {
const events = ["pointerover", "pointerout",
"pointerenter", "pointerleave", "pointerdown", "pointerup"];
let targets = [parent, slotted_child];
for (let i = 0; i < targets.length; i++) {
events.forEach(event => targets[i].addEventListener(event, logEvent));
}
}

function addPromiseTest(remover_event, tested_elem_to_remove,
expected_events) {
assert_true(["slot", "slotted-child"].includes(tested_elem_to_remove),
"Unexpcted tested_elem_to_remove param");

const test_name = `Pointer events from ${pointer_type} `+
`received before/after ${tested_elem_to_remove} removal `+
`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 });
// 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
// happens even if we make the shadow DOM construction dynamic inside this
// `promise_test`!!!

let done_click_promise = getEvent("click", done);

let actions = new test_driver.Actions()
.addPointer("TestPointer", pointer_type)
.pointerMove(-30, -30, {origin: shadow_host})
.pointerDown()
.pointerUp()
.pointerMove(30, 30, {origin: shadow_host})
.pointerDown()
.pointerUp()
.pointerMove(0, 0, {origin: done})
.pointerDown()
.pointerUp();

await actions.send();
await done_click_promise;

assert_equals(event_log.toString(), expected_events.toString(),
"events received");
}, test_name);
}

setup();

addPromiseTest(
"pointerdown",
"slot",
["pointerover@child", "pointerenter@parent", "pointerenter@child",
"pointerdown@child", "(child-removed)",
"pointerout@child", "pointerleave@child",
"pointerover@parent", "pointerup@parent",
"pointerdown@parent", "pointerup@parent",
"pointerout@parent", "pointerleave@parent"]
);
addPromiseTest(
"pointerdown",
"slotted-child",
["pointerover@child", "pointerenter@parent", "pointerenter@child",
"pointerdown@child", "(child-removed)",
"pointerover@parent", "pointerup@parent",
"pointerdown@parent", "pointerup@parent",
"pointerout@parent", "pointerleave@parent"]
);
addPromiseTest(
"pointerup",
"slot",
["pointerover@child", "pointerenter@parent", "pointerenter@child",
"pointerdown@child", "pointerup@child", "(child-removed)",
"pointerout@child", "pointerleave@child",
"pointerover@parent", "pointerdown@parent", "pointerup@parent",
"pointerout@parent", "pointerleave@parent"]
);
addPromiseTest(
"pointerup",
"slotted-child",
["pointerover@child", "pointerenter@parent", "pointerenter@child",
"pointerdown@child", "pointerup@child", "(child-removed)",
"pointerover@parent", "pointerdown@parent", "pointerup@parent",
"pointerout@parent", "pointerleave@parent"]
);
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<!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>
<meta name="variant" content="?mouse">
<meta name="variant" content="?touch">
<meta name="variant" content="?pen">
<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="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 {
width: 100px;
height: 100px;
display: block;
}
</style>

<my-elem id="host">
<div id="child">child</div>
</my-elem>
<div id="done">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 slot = parent.firstElementChild;
const slotted_child = document.getElementById("child");
const done = document.getElementById("done");

let event_log = [];

function logEvent(e) {
if (e.eventPhase == e.AT_TARGET) {
event_log.push(e.type + "@" + e.target.id);
}
}

function setup() {
const events = ["pointerover", "pointerout",
"pointerenter", "pointerleave", "pointerdown", "pointerup"];
let targets = [shadow_host, parent, slot, slotted_child];
for (let i = 0; i < targets.length; i++) {
events.forEach(event => targets[i].addEventListener(event, logEvent));
}
}

setup();

promise_test(async test => {
event_log = [];

let done_click_promise = getEvent("click", done);

let actions = new test_driver.Actions()
.addPointer("TestPointer", pointer_type)
.pointerMove(0, 0, {origin: shadow_host})
.pointerDown()
.pointerUp()
.pointerMove(0, 0, {origin: done})
.pointerDown()
.pointerUp();

await actions.send();
await done_click_promise;

const expected_events = [
"pointerover@child",
"pointerenter@host", "pointerenter@parent", "pointerenter@slot", "pointerenter@child",
"pointerdown@child", "pointerup@child",
"pointerout@child",
"pointerleave@child", "pointerleave@slot", "pointerleave@parent", "pointerleave@host"
];
assert_equals(event_log.toString(), expected_events.toString(),
"events received");
}, `Pointer events from ${pointer_type} to slotted element and shadow-host`);
</script>

0 comments on commit 56ef0ea

Please sign in to comment.