commit 958df829e92fd29a176418df512b9c0ac75ad326
parent 14960bc360198cbb43203d5d5fb27b238a2d6d3c
Author: Blink WPT Bot <blink-w3c-test-autoroller@chromium.org>
Date: Tue, 21 Oct 2025 10:31:10 +0000
Bug 1993639 [wpt PR 55338] - [EventTiming] Add targetIdentifier string in case Node is disconnected, a=testonly
Automatic update from web-platform-tests
[EventTiming] Add targetIdentifier string in case Node is disconnected (#55338)
Long Animation Frame Timing API already provided a utility for
serializing a name for EventTarget, so extracting that to a common
helper and using it also for EventTiming api.
As part of consolidation, the string format for target identifiers is
changed to be a valid querySelector by fixing a tiny error in formatting
which is guarded by a kill switch due to LoAF compat change.
I2P: https://chromestatus.com/feature/5143499213242368
Spec: https://github.com/w3c/event-timing/pull/160
Bug: 40887145
Change-Id: Ibafa01ac4de5f21a5d72a558abcaf0306a351fd0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6967813
Reviewed-by: Noam Rosenthal <nrosenthal@google.com>
Commit-Queue: Michal Mocny <mmocny@chromium.org>
Reviewed-by: Scott Haseley <shaseley@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1528130}
Co-authored-by: Michal Mocny <mmocny@chromium.org>
--
wpt-commits: b84f9bdaa5e087aa5fe434d9c1bbf008176951cf
wpt-pr: 55338
Diffstat:
3 files changed, 106 insertions(+), 7 deletions(-)
diff --git a/testing/web-platform/tests/event-timing/resources/event-timing-test-utils.js b/testing/web-platform/tests/event-timing/resources/event-timing-test-utils.js
@@ -70,8 +70,10 @@ function verifyEvent(entry, eventType, targetId, isFirst=false, minDuration=104,
assert_equals(firstInput.processingEnd, entry.processingEnd);
assert_equals(firstInput.cancelable, entry.cancelable);
}
- if (targetId)
- assert_equals(entry.target, document.getElementById(targetId));
+ if (targetId) {
+ const target = document.getElementById(targetId);
+ assert_equals(entry.target, target);
+ }
}
function verifyClickEvent(entry, targetId, isFirst=false, minDuration=104, event='pointerdown') {
@@ -256,9 +258,9 @@ function testCounts(t, resolve, looseCount, eventType, expectedCount) {
// 'target'. The test assumes that such element already exists. |looseCount| is set for
// eventTypes for which events would occur for other interactions other than the ones being
// specified for the target, so the counts could be larger.
-async function testEventType(t, eventType, looseCount=false) {
+async function testEventType(t, eventType, looseCount=false, targetId='target') {
assert_implements(window.EventCounts, "Event Counts isn't supported");
- const target = document.getElementById('target');
+ const target = document.getElementById(targetId);
if (requiresListener(eventType)) {
target.addEventListener(eventType, () =>{});
}
@@ -293,7 +295,7 @@ async function testEventType(t, eventType, looseCount=false) {
// The other events could also be considered slow. Find the one with the correct
// target.
eventTypeEntries.forEach(e => {
- if (e.target === document.getElementById('target'))
+ if (e.target === document.getElementById(targetId))
entry = e;
});
if (!entry)
@@ -301,7 +303,7 @@ async function testEventType(t, eventType, looseCount=false) {
}
verifyEvent(entry,
eventType,
- 'target',
+ targetId,
false /* isFirst */,
durationThreshold,
notCancelable(eventType));
diff --git a/testing/web-platform/tests/event-timing/target-identifier.html b/testing/web-platform/tests/event-timing/target-identifier.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<meta name="timeout" content="long">
+<title>Event Timing targetIdentifier.</title>
+<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=resources/event-timing-test-utils.js></script>
+<div id='div-with-id'>Target with ID</div>
+<div>Target without ID</div>
+<img id='img-with-id-and-src' src='/images/blue.png'>
+<img src='/images/green.png'>
+<script>
+ function verifyTargetIdentifier(entry, target) {
+ if ('targetIdentifier' in entry) {
+ let expectedIdentifier = target.tagName;
+ if (target.id) {
+ expectedIdentifier += '#' + target.id;
+ } else if (target.hasAttribute('src')) {
+ expectedIdentifier += '[src="' + target.getAttribute('src') + '"]';
+ }
+ assert_equals(entry.targetIdentifier, expectedIdentifier);
+ }
+ }
+
+ function runTest(t, eventType, target) {
+ let entry;
+ const callback = (entryList) => {
+ const entries = entryList.getEntriesByName(eventType);
+ if (entries.length > 0) {
+ entry = entries[0];
+ }
+ };
+ const readyToResolve = () => !!entry;
+ const observerPromise = createPerformanceObserverPromise(['event'], callback, readyToResolve);
+ return interactAndObserve(eventType, target, observerPromise)
+ .then(() => {
+ assert_equals(entry.name, eventType);
+ assert_equals(entry.entryType, 'event');
+ assert_equals(entry.target, target);
+ verifyTargetIdentifier(entry, target);
+ if (entry.target) {
+ const matchingElements = document.querySelectorAll(entry.targetIdentifier);
+ assert_true(Array.from(matchingElements).includes(target));
+ }
+ });
+ }
+
+ promise_test(async t => {
+ // Element with tagName and id.
+ return runTest(t, 'click', document.getElementById('div-with-id'));
+ }, "Test with target that has an ID");
+
+ promise_test(async t => {
+ // Element with tagName only.
+ return runTest(t, 'click', document.querySelector('div:not([id])'));
+ }, "Test with simple target (no id)");
+
+ promise_test(async t => {
+ // Element with tagName, id, and src.
+ return runTest(t, 'click', document.getElementById('img-with-id-and-src'));
+ }, "Test with image target with id and src");
+
+ promise_test(async t => {
+ // Element with tagName and src.
+ return runTest(t, 'click', document.querySelector('img:not([id])'));
+ }, "Test with image target with src only");
+
+ promise_test(async t => {
+ let entry;
+ const callback = (entryList) => {
+ const entries = entryList.getEntriesByName('click');
+ if (entries.length > 0) {
+ entry = entries[0];
+ }
+ };
+ const readyToResolve = () => !!entry;
+ const observerPromise = createPerformanceObserverPromise(['event'], callback, readyToResolve);
+ const parent = document.body;
+ const target = document.createElement('button');
+ target.id = 'temp-target';
+ target.textContent = 'Click Me';
+ parent.appendChild(target);
+ await interactAndObserve('click', target, observerPromise);
+ const expectedIdentifier = target.tagName + '#' + target.id;
+ parent.removeChild(target);
+ // The garbage collector might need some time to collect |target|.
+ await new Promise(r => t.step_timeout(r, 0));
+ assert_equals(entry.target, null);
+ assert_equals(entry.targetIdentifier, expectedIdentifier);
+ }, "Test with disconnected target");
+</script>
+</html>
+\ No newline at end of file
diff --git a/testing/web-platform/tests/long-animation-frame/tentative/loaf-event-listener.html b/testing/web-platform/tests/long-animation-frame/tentative/loaf-event-listener.html
@@ -30,7 +30,7 @@ test_self_event_listener((t, busy_wait) => {
});
document.body.appendChild(img);
t.add_cleanup(() => img.remove());
-}, "IMG[src=/images/green.png].onload");
+}, "IMG[src=\"/images/green.png\"].onload");
test_self_event_listener((t, busy_wait) => {
const xhr = new XMLHttpRequest();