Bug 1194037 part 6 - Add test for order of mutation observer records; r=heycam
authorBrian Birtles <birtles@gmail.com>
Fri, 11 Sep 2015 15:02:04 +0900
changeset 294507 991e80fcdd03ef4472c8cc0f2bee70fe39f8374a
parent 294506 23b49acf7cc0db646ceab92bb1a739637eb25150
child 294508 b2d47f9818cea6d798c92ff0883fba88d06cd744
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1194037
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1194037 part 6 - Add test for order of mutation observer records; r=heycam
dom/animation/test/chrome/test_animation_observers.html
--- a/dom/animation/test/chrome/test_animation_observers.html
+++ b/dom/animation/test/chrome/test_animation_observers.html
@@ -732,16 +732,82 @@ function assert_records(expected, desc) 
     // And we should get no notifications.
     yield await_frame();
     assert_records([], "records after attempted animation start");
 
     e.style = "";
   });
 });
 
+addAsyncAnimTest("tree_ordering", { observe: div, subtree: true }, function*() {
+
+  // Create a tree with two children:
+  //
+  //         div
+  //        /  \
+  //   childA  childB
+  var childA = document.createElement("div");
+  var childB = document.createElement("div");
+
+  div.appendChild(childA);
+  div.appendChild(childB);
+
+  // Start an animation on each (using order: childB, div, childA)
+  //
+  // We include multiple animations on some nodes so that we can test batching
+  // works as expected later in this test.
+  childB.style = "animation: anim 100s";
+  div.style    = "animation: anim 100s, anim 100s, anim 100s";
+  childA.style = "animation: anim 100s, anim 100s";
+
+  var divAnimations = div.getAnimations();
+  var childAAnimations = childA.getAnimations();
+  var childBAnimations = childB.getAnimations();
+
+  // The order in which we get the corresponding records is currently
+  // based on the order we visit these nodes when updating styles.
+  //
+  // That is because we don't do any document-level batching of animation
+  // mutation records when we flush styles. We may introduce that in the
+  // future but for now all we are interested in testing here is that the order
+  // these records are dispatched is consistent between runs.
+  //
+  // We currently expect to get records in order childA, childB, div
+  yield await_frame();
+  assert_records([{ added: childAAnimations, changed: [], removed: [] },
+                  { added: childBAnimations, changed: [], removed: [] },
+                  { added: divAnimations, changed: [], removed: [] }],
+                 "records after simultaneous animation start");
+
+  // The one case where we *do* currently perform document-level (or actually
+  // timeline-level) batching is when animations are updated from a refresh
+  // driver tick. In particular, this means that when animations finish
+  // naturally the removed records should be dispatched according to the
+  // position of the elements in the tree.
+  //
+  // Fast-forward to *just* before the end of the animation.
+  var fastForward = animation => animation.currentTime = 99999;
+  divAnimations.forEach(fastForward);
+  childAAnimations.forEach(fastForward);
+  childBAnimations.forEach(fastForward);
+
+  yield await_event(div, "animationend");
+
+  // We should get records in order div, childA, childB
+  assert_records([{ added: [], changed: [], removed: divAnimations },
+                  { added: [], changed: [], removed: childAAnimations },
+                  { added: [], changed: [], removed: childBAnimations }],
+                 "records after finishing");
+
+  // Clean up
+  div.style = "";
+  childA.remove();
+  childB.remove();
+});
+
 // Run the tests.
 
 SimpleTest.waitForExplicitFinish();
 
 runAllAsyncTests().then(function() {
   SimpleTest.finish();
 }, function(aError) {
   ok(false, "Something failed: " + aError);