Status: FAIL | Duration: 70ms | Subtests: 0/1 | Open test on wpt.live | wpt.fyi
/css/css-pseudo/events-on-pseudo-element.tentative.html
<!DOCTYPE html> <meta charset="utf-8"> <title>CSS Test: event.pseudoTarget tests with different events </title> <link rel="help" href="https://drafts.csswg.org/css-overflow-5/#scroll-marker-pseudo"> <link rel="help" href="https://drafts.csswg.org/css-pseudo/#CSSPseudoElement-interface"> <script src="/dom/events/scrolling/scroll_support.js"></script> <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> <style> @keyframes slide-in { from { transform: translateX(100%) scaleX(3); } to { transform: translateX(0) scaleX(1); } } div { scroll-marker-group: after links; overflow: scroll; height: 200px; li { height: 200px; background: purple; border: 1px solid black; &::scroll-marker { content: "S"; padding: 10px; color: white; background: red; transition-property: transform, background; transition-duration: 2s; transition-delay: 1s; animation-duration: 2s; animation-name: slide-in; } &::scroll-marker:hover { background: blue; transform: rotate(90deg); } } } </style> <div> <li id="target">1</li> </div> <script> const target = document.getElementById("target"); let animationstartTarget = null; let animationstartPseudoTarget = null; let animationendTarget = null; let animationendPseudoTarget = null; let clickTarget = null; let clickPseudoTarget = null; let dblclickTarget = null; let dblclickPseudoTarget = null; let mouseoverTarget = null; let mouseoverPseudoTarget = null; let mouseoutTarget = null; let mouseoutPseudoTarget = null; let mouseenterTarget = null; let mouseenterPseudoTarget = null; let mouseleaveTarget = null; let mouseleavePseudoTarget = null; let pointeroverTarget = null; let pointeroverPseudoTarget = null; let pointeroutTarget = null; let pointeroutPseudoTarget = null; let pointerenterTarget = null; let pointerenterPseudoTarget = null; let pointerleaveTarget = null; let pointerleavePseudoTarget = null; let wheelTarget = null; let wheelPseudoTarget = null; let scrollTarget = null; let scrollPseudoTarget = null; let focusinTarget = null; let focusinPseudoTarget = null; let focusoutTarget = null; let focusoutPseudoTarget = null; let transitionstartTarget = null; let transitionstartPseudoTarget = null; let transitionendTarget = null; let transitionendPseudoTarget = null; function waitForEvent(element, eventName) { return new Promise(resolve => { element.addEventListener(eventName, resolve, { once: true }); }); } target.addEventListener("animationstart", (e) => { animationstartTarget = e.target; animationstartPseudoTarget = e.pseudoTarget; }); target.addEventListener("animationend", (e) => { animationendTarget = e.target; animationendPseudoTarget = e.pseudoTarget; }); target.addEventListener("click", (e) => { clickTarget = e.target; clickPseudoTarget = e.pseudoTarget; }); target.addEventListener("dblclick", (e) => { dblclickTarget = e.target; dblclickPseudoTarget = e.pseudoTarget; }); target.addEventListener("mouseover", (e) => { mouseoverTarget = e.target; mouseoverPseudoTarget = e.pseudoTarget; }); target.addEventListener("mouseout", (e) => { mouseoutTarget = e.target; mouseoutPseudoTarget = e.pseudoTarget; }); target.addEventListener("mouseenter", (e) => { mouseenterTarget = e.target; mouseenterPseudoTarget = e.pseudoTarget; }); target.addEventListener("mouseleave", (e) => { mouseleaveTarget = e.target; mouseleavePseudoTarget = e.pseudoTarget; }); target.addEventListener("pointerover", (e) => { pointeroverTarget = e.target; pointeroverPseudoTarget = e.pseudoTarget; }); target.addEventListener("pointerout", (e) => { pointeroutTarget = e.target; pointeroutPseudoTarget = e.pseudoTarget; }); target.addEventListener("pointerenter", (e) => { pointerenterTarget = e.target; pointerenterPseudoTarget = e.pseudoTarget; }); target.addEventListener("pointerleave", (e) => { pointerleaveTarget = e.target; pointerleavePseudoTarget = e.pseudoTarget; }); target.addEventListener("focusin", (e) => { focusinTarget = e.target; focusinPseudoTarget = e.pseudoTarget; }); target.addEventListener("focusout", (e) => { focusoutTarget = e.target; focusoutPseudoTarget = e.pseudoTarget; }); target.addEventListener("keydown", (e) => { keydownTarget = e.target; keydownPseudoTarget = e.pseudoTarget; }); target.addEventListener("keyup", (e) => { keyupTarget = e.target; keyupPseudoTarget = e.pseudoTarget; }); target.addEventListener("transitionstart", (e) => { transitionstartTarget = e.target; transitionstartPseudoTarget = e.pseudoTarget; }); target.addEventListener("transitionend", (e) => { transitionendTarget = e.target; transitionendPseudoTarget = e.pseudoTarget; }); target.addEventListener('wheel', (e) => { wheelTarget = e.target; wheelPseudoTarget = e.pseudoTarget; }); target.addEventListener('scroll', (e) => { scrollTarget = e.target; scrollPseudoTarget = e.pseudoTarget; }); const kTab = "\uE004"; const kEnter = "\uE007"; const scrollMarkerX = 20; const scrollMarkerY = 220; const pseudoElement = target.pseudo("::scroll-marker"); const animationStartPromise = waitForEvent(target, "animationstart"); promise_test(async t => { await animationStartPromise; assert_equals(animationstartTarget, target, "event.target is ultimate originating element for animationstart"); assert_equals(animationstartPseudoTarget, pseudoElement, "event.pseudoTarget is ::scroll-marker for animationstart"); await waitForEvent(target, "animationend"); assert_equals(animationendTarget, target, "event.target is ultimate originating element for animationend"); assert_equals(animationendPseudoTarget, pseudoElement, "event.pseudoTarget is ::scroll-marker for animationend"); const transitionStartPromise = waitForEvent(target, "transitionstart"); await new test_driver.Actions() .pointerMove(scrollMarkerX, scrollMarkerY) .pointerDown() .pointerUp() .pointerDown() .pointerUp() .send(); await transitionStartPromise; assert_equals(clickTarget, target, "event.target is ultimate originating element for click"); assert_equals(clickPseudoTarget, pseudoElement, "event.pseudoTarget is ::scroll-marker for click"); assert_equals(dblclickTarget, target, "event.target is ultimate originating element for double click"); assert_equals(dblclickPseudoTarget, pseudoElement, "event.pseudoTarget is ::scroll-marker for double click"); assert_equals(mouseoverTarget, target, "event.target is ultimate originating element for mouseover"); // `mouseover` is a boundary event; currently `pseudoTarget` is not // defined for boundary events, so it should be null. assert_equals(mouseoverPseudoTarget, null, "event.pseudoTarget is null for mouseover (boundary event)"); await new test_driver.Actions() .keyDown(kTab) .keyUp(kTab) .keyDown(kEnter) .keyUp(kEnter) .send(); assert_equals(focusinTarget, target, "event.target is ultimate originating element for focusin"); assert_equals(focusinPseudoTarget, pseudoElement, "event.pseudoTarget is ::scroll-marker for focusin"); assert_equals(focusoutTarget, target, "event.target is ultimate originating element for focusout"); assert_equals(focusoutPseudoTarget, pseudoElement, "event.pseudoTarget is ::scroll-marker for focusout"); assert_equals(transitionstartTarget, target, "event.target is ultimate originating element for transitionstart"); assert_equals(transitionstartPseudoTarget, pseudoElement, "event.pseudoTarget is ::scroll-marker for transitionstart"); await waitForEvent(target, "transitionend"); assert_equals(transitionendTarget, target, "event.target is ultimate originating element for transitionend"); assert_equals(transitionendPseudoTarget, pseudoElement, "event.pseudoTarget is ::scroll-marker for transitionend"); // Move pointer away to trigger boundary events (mouseout / pointerout / leave) const mouseOutPromise = waitForEvent(target, 'mouseout'); const pointerOutPromise = waitForEvent(target, 'pointerout'); const mouseLeavePromise = waitForEvent(target, 'mouseleave'); const pointerLeavePromise = waitForEvent(target, 'pointerleave'); await new test_driver.Actions() .pointerMove(0, 0) .send(); await Promise.all([mouseOutPromise, pointerOutPromise, mouseLeavePromise, pointerLeavePromise]); // Boundary events should not have pseudoTarget set. assert_equals(mouseoutTarget, target, "event.target is ultimate originating element for mouseout"); assert_equals(mouseoutPseudoTarget, null, "event.pseudoTarget is null for mouseout (boundary event)"); assert_equals(pointeroutTarget, target, "event.target is ultimate originating element for pointerout"); assert_equals(pointeroutPseudoTarget, null, "event.pseudoTarget is null for pointerout (boundary event)"); assert_equals(mouseleaveTarget, target, "event.target is ultimate originating element for mouseleave"); assert_equals(mouseleavePseudoTarget, null, "event.pseudoTarget is null for mouseleave (boundary event)"); assert_equals(pointerleaveTarget, target, "event.target is ultimate originating element for pointerleave"); assert_equals(pointerleavePseudoTarget, null, "event.pseudoTarget is null for pointerleave (boundary event)"); // Move pointer back in to trigger enter events; they should also be null const mouseEnterPromise = waitForEvent(target, 'mouseenter'); const pointerEnterPromise = waitForEvent(target, 'pointerenter'); await new test_driver.Actions() .pointerMove(scrollMarkerX, scrollMarkerY) .send(); await Promise.all([mouseEnterPromise, pointerEnterPromise]); assert_equals(mouseenterTarget, target, "event.target is ultimate originating element for mouseenter"); assert_equals(mouseenterPseudoTarget, null, "event.pseudoTarget is null for mouseenter (boundary event)"); assert_equals(pointerenterTarget, target, "event.target is ultimate originating element for pointerenter"); assert_equals(pointerenterPseudoTarget, null, "event.pseudoTarget is null for pointerenter (boundary event)"); // Dispatch some unrelated events and ensure pseudoTarget is null. target.dispatchEvent(new WheelEvent('wheel')); assert_equals(wheelTarget, target, 'wheel event target should be the element'); assert_equals(wheelPseudoTarget, null, 'wheel event pseudoTarget should be null'); target.dispatchEvent(new Event('scroll')); assert_equals(scrollTarget, target, 'scroll event target should be the element'); assert_equals(scrollPseudoTarget, undefined, 'scroll event pseudoTarget should be null'); }); </script>