wpt / css / css-pseudo / events-on-pseudo-element.tentative.html

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>