<!doctype html>
<html>
  <head>
    <meta charset=utf-8>
    <title>Tests for the effect of setting a CSS transition's
           Animation.currentTime</title>
    <style>

.animated-div {
  margin-left: 100px;
  transition: margin-left 1000s linear 1000s;
}

    </style>
    <script src="../../../resources/testharness.js"></script>
    <script src="../../../resources/testharnessreport.js"></script>
    <script src="../resources/testcommon.js"></script>
  </head>
  <body>
    <div id="log"></div>
    <script type="text/javascript">

'use strict';

// TODO: Once the computedTiming property is implemented, add checks to the
// checker helpers to ensure that computedTiming's properties are updated as
// expected.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1108055


const ANIM_DELAY_MS = 1000000; // 1000s
const ANIM_DUR_MS = 1000000; // 1000s

/**
 * These helpers get the value that the currentTime needs to be set to, to put
 * an animation that uses the above ANIM_DELAY_MS and ANIM_DUR_MS values into
 * the middle of various phases or points through the active duration.
 */
function currentTimeForBeforePhase() {
  return ANIM_DELAY_MS / 2;
}
function currentTimeForActivePhase() {
  return ANIM_DELAY_MS + ANIM_DUR_MS / 2;
}
function currentTimeForAfterPhase() {
  return ANIM_DELAY_MS + ANIM_DUR_MS + ANIM_DELAY_MS / 2;
}
function currentTimeForStartOfActiveInterval() {
  return ANIM_DELAY_MS;
}
function currentTimeForFiftyPercentThroughActiveInterval() {
  return ANIM_DELAY_MS + ANIM_DUR_MS * 0.5;
}
function currentTimeForEndOfActiveInterval() {
  return ANIM_DELAY_MS + ANIM_DUR_MS;
}


// Expected computed 'margin-left' values at points during the active interval:
// When we assert_between_inclusive using these values we could in theory cause
// intermittent failure due to very long delays between paints, but since the
// active duration is 1000s long, a delay would need to be around 100s to cause
// that. If that's happening then there are likely other issues that should be
// fixed, so a failure to make us look into that seems like a good thing.
const INITIAL_POSITION = 100;
const TEN_PCT_POSITION = 110;
const FIFTY_PCT_POSITION = 150;
const END_POSITION = 200;


// The terms used for the naming of the following helper functions refer to
// terms used in the Web Animations specification for specific phases of an
// animation. The terms can be found here:
//
//   http://drafts.csswg.org/web-animations/#animation-effect-phases-and-states

// Called when currentTime is set to zero (the beginning of the start delay).
function checkStateOnSettingCurrentTimeToZero(animation)
{
  // We don't test animation.currentTime since our caller just set it.

  assert_equals(animation.playState, 'running',
    'Animation.playState should be "running" at the start of ' +
    'the start delay');

  assert_equals(animation.effect.target.style.animationPlayState, 'running',
    'Animation.effect.target.style.animationPlayState should be ' +
    '"running" at the start of the start delay');

  var div = animation.effect.target;
  var marginLeft = parseFloat(getComputedStyle(div).marginLeft);
  assert_equals(marginLeft, UNANIMATED_POSITION,
                'the computed value of margin-left should be unaffected ' +
                'at the beginning of the start delay');
}

// Called when the ready Promise's callbacks should happen
function checkStateOnReadyPromiseResolved(animation)
{
  // the 0.0001 here is for rounding error
  assert_less_than_equal(animation.currentTime,
    animation.timeline.currentTime - animation.startTime + 0.0001,
    'Animation.currentTime should be less than the local time ' +
    'equivalent of the timeline\'s currentTime on the first paint tick ' +
    'after animation creation');

  assert_equals(animation.playState, 'running',
    'Animation.playState should be "running" on the first paint ' +
    'tick after animation creation');

  var div = animation.effect.target;
  var marginLeft = parseFloat(getComputedStyle(div).marginLeft);
  assert_equals(marginLeft, INITIAL_POSITION,
                'the computed value of margin-left should be unaffected ' +
                'by an animation with a delay on ready Promise resolve');
}

// Called when currentTime is set to the time the active interval starts.
function checkStateAtActiveIntervalStartTime(animation)
{
  // We don't test animation.currentTime since our caller just set it.

  assert_equals(animation.playState, 'running',
    'Animation.playState should be "running" at the start of ' +
    'the active interval');

  var div = animation.effect.target;
  var marginLeft = parseFloat(getComputedStyle(div).marginLeft);
  assert_between_inclusive(marginLeft, INITIAL_POSITION, TEN_PCT_POSITION,
    'the computed value of margin-left should be close to the value at the ' +
    'beginning of the animation');
}

function checkStateAtFiftyPctOfActiveInterval(animation)
{
  // We don't test animation.currentTime since our caller just set it.

  var div = animation.effect.target;
  var marginLeft = parseFloat(getComputedStyle(div).marginLeft);
  assert_equals(marginLeft, FIFTY_PCT_POSITION,
    'the computed value of margin-left should be half way through the ' +
    'animation at the midpoint of the active interval');
}

// Called when currentTime is set to the time the active interval ends.
function checkStateAtActiveIntervalEndTime(animation)
{
  // We don't test animation.currentTime since our caller just set it.

  assert_equals(animation.playState, 'finished',
    'Animation.playState should be "finished" at the end of ' +
    'the active interval');

  var div = animation.effect.target;
  var marginLeft = parseFloat(getComputedStyle(div).marginLeft);
  assert_equals(marginLeft, END_POSITION,
    'the computed value of margin-left should be the final transitioned-to ' +
    'value at the end of the active duration');
}

test(function(t)
{
  var div = addDiv(t, {'class': 'animated-div'});
  flushComputedStyle(div);
  div.style.marginLeft = '200px'; // initiate transition

  var animation = div.getAnimations()[0];
  assert_equals(animation.currentTime, 0, 'currentTime should be zero');
}, 'currentTime of a newly created transition is zero');


test(function(t)
{
  var div = addDiv(t, {'class': 'animated-div'});
  flushComputedStyle(div);
  div.style.marginLeft = '200px'; // initiate transition

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

  // So that animation is running instead of paused when we set currentTime:
  animation.startTime = animation.timeline.currentTime;

  animation.currentTime = 10;
  assert_equals(animation.currentTime, 10,
    'Check setting of currentTime actually works');
}, 'Sanity test to check round-tripping assigning to new animation\'s ' +
   'currentTime');


async_test(function(t) {
  var div = addDiv(t, {'class': 'animated-div'});
  var eventWatcher = new EventWatcher(t, div, 'transitionend');

  flushComputedStyle(div);
  div.style.marginLeft = '200px'; // initiate transition

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

  animation.ready.then(t.step_func(function() {
    checkStateOnReadyPromiseResolved(animation);

    animation.currentTime = currentTimeForStartOfActiveInterval();
    checkStateAtActiveIntervalStartTime(animation);

    animation.currentTime = currentTimeForFiftyPercentThroughActiveInterval();
    checkStateAtFiftyPctOfActiveInterval(animation);

    animation.currentTime = currentTimeForEndOfActiveInterval();
    return eventWatcher.wait_for('transitionend');
  })).then(t.step_func(function() {
    checkStateAtActiveIntervalEndTime(animation);
  })).catch(t.step_func(function(reason) {
    assert_unreached(reason);
  })).then(function() {
    t.done();
  });
}, 'Skipping forward through transition');


test(function(t) {
  var div = addDiv(t, {'class': 'animated-div'});
  var eventWatcher = new EventWatcher(t, div, 'transitionend');

  flushComputedStyle(div);
  div.style.marginLeft = '200px'; // initiate transition

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

  // Unlike in the case of CSS animations, we cannot skip to the end and skip
  // backwards since when we reach the end the transition effect is removed and
  // changes to the Animation object no longer affect the element. For
  // this reason we only skip forwards as far as the 50% through point.

  animation.ready.then(t.step_func(function() {
    animation.currentTime = currentTimeForFiftyPercentThroughActiveInterval();
    checkStateAtFiftyPctOfActiveInterval(animation);

    animation.currentTime = currentTimeForStartOfActiveInterval();

    // Despite going backwards from being in the active interval to being
    // before it, we now expect a 'transitionend' event because the transition
    // should go from being active to inactive.
    //
    // Calling checkStateAtActiveIntervalStartTime will check computed style,
    // causing computed style to be updated and the 'transitionend' event to
    // be dispatched synchronously. We need to call wait_for first
    // otherwise eventWatcher will assert that the event was unexpected.
    eventWatcher.wait_for('transitionend').then(function() {
      t.done();
    });
    checkStateAtActiveIntervalStartTime(animation);
  }));
}, 'Skipping backwards through transition');


async_test(function(t) {
  var div = addDiv(t, {'class': 'animated-div'});
  flushComputedStyle(div);
  div.style.marginLeft = '200px'; // initiate transition

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

  animation.ready.then(t.step_func(function() {
    var exception;
    try {
      animation.currentTime = null;
    } catch (e) {
      exception = e;
    }
    assert_equals(exception.name, 'TypeError',
      'Expect TypeError exception on trying to set ' +
      'Animation.currentTime to null');
  })).catch(t.step_func(function(reason) {
    assert_unreached(reason);
  })).then(function() {
    t.done();
  });
}, 'Setting currentTime to null');


async_test(function(t) {
  var div = addDiv(t, {'class': 'animated-div'});
  flushComputedStyle(div);
  div.style.marginLeft = '200px'; // initiate transition

  var animation = div.getAnimations()[0];
  var pauseTime;

  animation.ready.then(t.step_func(function() {
    assert_not_equals(animation.currentTime, null,
      'Animation.currentTime not null on ready Promise resolve');
    animation.pause();
    return animation.ready;
  })).then(t.step_func(function() {
    pauseTime = animation.currentTime;
    return waitForFrame();
  })).then(t.step_func(function() {
    assert_equals(animation.currentTime, pauseTime,
      'Animation.currentTime is unchanged after pausing');
  })).catch(t.step_func(function(reason) {
    assert_unreached(reason);
  })).then(function() {
    t.done();
  });
}, 'Animation.currentTime after pausing');

    </script>
  </body>
</html>
