<!doctype html>
<meta charset=utf-8>
<title>Tests for CSS animation event order</title>
<link rel="help" href="https://drafts.csswg.org/css-animations-2/#event-dispatch"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/testcommon.js"></script>
<style>
@keyframes anim {
  from { margin-left: 0px; }
  to { margin-left: 100px; }
}
@keyframes color-anim {
  from { color: red; }
  to { color: green; }
}
</style>
<div id="log"></div>
<script type='text/javascript'>
'use strict';

/**
 * Asserts that the set of actual and received events match.
 * @param actualEvents   An array of the received AnimationEvent objects.
 * @param expectedEvents A series of array objects representing the expected
 *        events, each having the form:
 *          [ event type, target element, [pseudo type], elapsed time ]
 */
const checkEvents = (actualEvents, ...expectedEvents) => {
  const actualTypeSummary = actualEvents.map(event => event.type).join(', ');
  const expectedTypeSummary = expectedEvents.map(event => event[0]).join(', ');

  assert_equals(
    actualEvents.length,
    expectedEvents.length,
    `Number of events received (${actualEvents.length}) \
should match expected number (${expectedEvents.length}) \
(expected: ${expectedTypeSummary}, actual: ${actualTypeSummary})`
  );

  for (const [index, actualEvent] of actualEvents.entries()) {
    const expectedEvent = expectedEvents[index];
    const [type, target] = expectedEvent;
    const pseudoElement = expectedEvent.length === 4 ? expectedEvent[2] : '';
    const elapsedTime = expectedEvent[expectedEvent.length - 1];

    assert_equals(
      actualEvent.type,
      type,
      `Event #${index + 1} types should match \
(expected: ${expectedTypeSummary}, actual: ${actualTypeSummary})`
    );
    assert_equals(
      actualEvent.target,
      target,
      `Event #${index + 1} targets should match`
    );
    assert_equals(
      actualEvent.pseudoElement,
      pseudoElement,
      `Event #${index + 1} pseudoElements should match`
    );
    assert_equals(
      actualEvent.elapsedTime,
      elapsedTime,
      `Event #${index + 1} elapsedTimes should match`
    );
  }
};

const setupAnimation = (t, animationStyle, receiveEvents) => {
  const div = addDiv(t, { style: 'animation: ' + animationStyle });

  for (const name of ['start', 'iteration', 'end']) {
    div['onanimation' + name] = evt => {
      receiveEvents.push({
        type: evt.type,
        target: evt.target,
        pseudoElement: evt.pseudoElement,
        elapsedTime: evt.elapsedTime,
      });
    };
  }

  const watcher = new EventWatcher(t, div, [
    'animationstart',
    'animationiteration',
    'animationend',
  ]);

  const animation = div.getAnimations()[0];

  return [animation, watcher, div];
};

promise_test(async t => {
  let events = [];
  const [animation1, watcher1, div1] =
    setupAnimation(t, 'anim 100s 2 paused', events);
  const [animation2, watcher2, div2] =
    setupAnimation(t, 'anim 100s 2 paused', events);

  await Promise.all([ watcher1.wait_for('animationstart'),
                      watcher2.wait_for('animationstart') ]);

  checkEvents(events, ['animationstart', div1, 0],
                      ['animationstart', div2, 0]);

  events.length = 0;  // Clear received event array

  animation1.currentTime = 100 * MS_PER_SEC;
  animation2.currentTime = 100 * MS_PER_SEC;

  await Promise.all([ watcher1.wait_for('animationiteration'),
                      watcher2.wait_for('animationiteration') ]);

  checkEvents(events, ['animationiteration', div1, 100],
                      ['animationiteration', div2, 100]);

  events.length = 0;  // Clear received event array

  animation1.finish();
  animation2.finish();

  await Promise.all([ watcher1.wait_for('animationend'),
                      watcher2.wait_for('animationend') ]);

  checkEvents(events, ['animationend', div1, 200],
                      ['animationend', div2, 200]);
}, 'Same events are ordered by elements');

function pseudoTest(description, testMarkerPseudos) {
  promise_test(async t => {
    // Setup a hierarchy as follows:
    //
    //              parent
    //                |
    //  (::marker, ::before, ::after) // ::marker optional
    //                |
    //              child
    const parentDiv = addDiv(t, { style: 'animation: anim 100s' });

    parentDiv.id = 'parent-div';
    addStyle(t, {
      '#parent-div::after': "content: ''; animation: anim 100s",
      '#parent-div::before': "content: ''; animation: anim 100s",
    });

    if (testMarkerPseudos) {
      parentDiv.style.display = 'list-item';
      addStyle(t, {
        '#parent-div::marker': "content: ''; animation: color-anim 100s",
      });
    }

    const childDiv = addDiv(t, { style: 'animation: anim 100s' });
    parentDiv.append(childDiv);

    // Setup event handlers
    let events = [];
    for (const name of ['start', 'iteration', 'end', 'cancel']) {
      parentDiv['onanimation' + name] = evt => {
        events.push({
          type: evt.type,
          target: evt.target,
          pseudoElement: evt.pseudoElement,
          elapsedTime: evt.elapsedTime,
        });
      };
    }

    // Wait a couple of frames for the events to be dispatched
    await waitForFrame();
    await waitForFrame();

    const expectedEvents = [
      ['animationstart', parentDiv, 0],
      ['animationstart', parentDiv, '::marker', 0],
      ['animationstart', parentDiv, '::before', 0],
      ['animationstart', parentDiv, '::after', 0],
      ['animationstart', childDiv, 0],
    ];
    if (!testMarkerPseudos) {
      expectedEvents.splice(1, 1);
    }

    checkEvents(events, ...expectedEvents);
  }, description);
}

pseudoTest('Same events on pseudo-elements follow the prescribed order', false);
pseudoTest('Same events on pseudo-elements follow the prescribed order ' +
    '(::marker)', true);

promise_test(async t => {
  let events = [];
  const [animation1, watcher1, div1] =
    setupAnimation(t, 'anim 200s 400s', events);
  const [animation2, watcher2, div2] =
    setupAnimation(t, 'anim 300s 2', events);

  await watcher2.wait_for('animationstart');

  animation1.currentTime = 400 * MS_PER_SEC;
  animation2.currentTime = 400 * MS_PER_SEC;

  events.length = 0;  // Clear received event array

  await Promise.all([ watcher1.wait_for('animationstart'),
                      watcher2.wait_for('animationiteration') ]);

  checkEvents(events, ['animationiteration', div2, 300],
                      ['animationstart',     div1, 0]);
}, 'Start and iteration events are ordered by time');

promise_test(async t => {
  let events = [];
  const [animation1, watcher1, div1] =
    setupAnimation(t, 'anim 150s', events);
  const [animation2, watcher2, div2] =
    setupAnimation(t, 'anim 100s 2', events);

  await Promise.all([ watcher1.wait_for('animationstart'),
                      watcher2.wait_for('animationstart') ]);

  animation1.currentTime = 150 * MS_PER_SEC;
  animation2.currentTime = 150 * MS_PER_SEC;

  events.length = 0;  // Clear received event array

  await Promise.all([ watcher1.wait_for('animationend'),
                      watcher2.wait_for('animationiteration') ]);

  checkEvents(events, ['animationiteration', div2, 100],
                      ['animationend',       div1, 150]);
}, 'Iteration and end events are ordered by time');

promise_test(async t => {
  let events = [];
  const [animation1, watcher1, div1] =
    setupAnimation(t, 'anim 100s 100s', events);
  const [animation2, watcher2, div2] =
    setupAnimation(t, 'anim 100s 2', events);

  animation1.finish();
  animation2.finish();

  await Promise.all([ watcher1.wait_for([ 'animationstart',
                                          'animationend' ]),
                      watcher2.wait_for([ 'animationstart',
                                          'animationend' ]) ]);

  checkEvents(events, ['animationstart', div2, 0],
                      ['animationstart', div1, 0],
                      ['animationend',   div1, 100],
                      ['animationend',   div2, 200]);
}, 'Start and end events are sorted correctly when fired simultaneously');

</script>
