| Index: third_party/WebKit/LayoutTests/intersection-observer/timestamp.html | 
| diff --git a/third_party/WebKit/LayoutTests/intersection-observer/timestamp.html b/third_party/WebKit/LayoutTests/intersection-observer/timestamp.html | 
| index 8d061a94337a050d3f07bf4cb2d395a763fedb7a..6667f546c4831a54e5ff91d1175d3e569f3541c7 100644 | 
| --- a/third_party/WebKit/LayoutTests/intersection-observer/timestamp.html | 
| +++ b/third_party/WebKit/LayoutTests/intersection-observer/timestamp.html | 
| @@ -1,79 +1,98 @@ | 
| <!DOCTYPE html> | 
| -<script src="../resources/js-test.js"></script> | 
| -<script src="../resources/intersection-observer-helper-functions.js"></script> | 
| -<div id="beforeFrame" style="width:100%; height:700px;"></div> | 
| -<div id="afterFrame" style="width:100%; height:700px;"></div> | 
| +<script src="../resources/testharness.js"></script> | 
| +<script src="../resources/testharnessreport.js"></script> | 
| +<script src="./resources/intersection-observer-test-utils.js"></script> | 
| + | 
| +<style> | 
| +pre, #log { | 
| +  position: absolute; | 
| +  top: 0; | 
| +  left: 200px; | 
| +} | 
| +.spacer { | 
| +  height: 700px; | 
| +} | 
| + | 
| +</style> | 
| +<div id="leading-space" class="spacer"></div> | 
| +<div id="trailing-space" class="spacer"></div> | 
|  | 
| <script> | 
| -description("Test that intersection observer time is relative to time in the callback context."); | 
| +// Pick this number to be comfortably greater than the length of two frames at 60Hz. | 
| +var timeSkew = 40; | 
| + | 
| var topWindowEntries = []; | 
| var iframeWindowEntries = []; | 
| -var topWindowObserver; | 
| -var iframeWindowObserver; | 
| var targetIframe; | 
| -var iframeScroller; | 
| -var topWindowTime; | 
| -var iframeWindowTime; | 
| -var timestampTolerance = 24; | 
| +var topWindowTimeBeforeNotification; | 
| +var iframeWindowTimeBeforeNotification; | 
|  | 
| -function step0() { | 
| -  // Test results are only significant if there's a sufficient gap between | 
| -  // top window time and iframe window time. | 
| -  topWindowTime = performance.now(); | 
| -  iframeWindowTime = targetIframe.contentWindow.performance.now(); | 
| -  shouldBeGreaterThan("topWindowTime - iframeWindowTime", "2.5 * timestampTolerance"); | 
| +async_test(function(t) { | 
| +  assert_equals(window.innerWidth, 800, "Window must be 800 pixels wide."); | 
| +  assert_equals(window.innerHeight, 600, "Window must be 600 pixels high."); | 
|  | 
| -  shouldBeEqualToNumber("topWindowEntries.length", 0); | 
| -  shouldBeEqualToNumber("iframeWindowEntries.length", 0); | 
| -  document.scrollingElement.scrollTop = 200; | 
| -  iframeScroller.scrollTop = 250; | 
| -  waitForNotification(step1); | 
| -} | 
| +  setTimeout(function() { | 
| +    targetIframe = document.createElement("iframe"); | 
| +    assert_true(!!targetIframe, "iframe exists"); | 
| +    targetIframe.src = "resources/timestamp-subframe.html"; | 
| +    var trailingSpace = document.getElementById("trailing-space"); | 
| +    assert_true(!!trailingSpace, "trailing-space exists"); | 
| +    trailingSpace.parentNode.insertBefore(targetIframe, trailingSpace); | 
| +    targetIframe.onload = function() { | 
| +      var target = targetIframe.contentDocument.getElementById("target"); | 
| +      var iframeScroller = targetIframe.contentDocument.scrollingElement; | 
|  | 
| -function step1() { | 
| -  topWindowTime = performance.now(); | 
| -  iframeWindowTime = targetIframe.contentWindow.performance.now(); | 
| -  shouldBeEqualToNumber("topWindowEntries.length", 1); | 
| -  if (topWindowEntries.length) | 
| -    shouldBeCloseTo("topWindowEntries[0].time", "topWindowTime", timestampTolerance); | 
| +      // Observer created here, callback created in iframe context.  Timestamps should be | 
| +      // from this window. | 
| +      var observer = new IntersectionObserver( | 
| +          targetIframe.contentDocument.createObserverCallback(topWindowEntries), {}); | 
| +      assert_true(!!observer, "Observer exists"); | 
| +      observer.observe(target); | 
|  | 
| -  shouldBeEqualToNumber("iframeWindowEntries.length", 1); | 
| -  if (iframeWindowEntries.length) { | 
| -    shouldBeCloseTo("iframeWindowEntries[0].time", "iframeWindowTime", timestampTolerance); | 
| -  } | 
| -  waitForNotification(finishJSTest); | 
| -  document.scrollingElement.scrollTop = 0; | 
| +      // Callback created here, observer created in iframe.  Timestamps should be | 
| +      // from iframe window. | 
| +      observer = targetIframe.contentDocument.createObserver(function(newEntries) { | 
| +	iframeWindowEntries = iframeWindowEntries.concat(newEntries); | 
| +      }); | 
| +      observer.observe(target); | 
| +      runTestCycle(step1, "First rAF after iframe is loaded."); | 
| +      t.done(); | 
| +    }; | 
| +  }, timeSkew); | 
| +}, "Check that timestamps correspond to the to execution context that created the observer."); | 
| + | 
| +function step1() { | 
| +  document.scrollingElement.scrollTop = 200; | 
| +  targetIframe.contentDocument.scrollingElement.scrollTop = 250; | 
| +  topWindowTimeBeforeNotification = performance.now(); | 
| +  iframeWindowTimeBeforeNotification = targetIframe.contentWindow.performance.now(); | 
| +  runTestCycle(step2, "Generate notifications."); | 
| +  assert_equals(topWindowEntries.length, 0, "No notifications to top window observer."); | 
| +  assert_equals(iframeWindowEntries.length, 0, "No notifications to iframe observer."); | 
| } | 
|  | 
| -function runTest() { | 
| -  var target = targetIframe.contentDocument.getElementById("target"); | 
| -  iframeScroller = targetIframe.contentDocument.scrollingElement; | 
| +function step2() { | 
| +  document.scrollingElement.scrollTop = 0; | 
| +  var topWindowTimeAfterNotification = performance.now(); | 
| +  var iframeWindowTimeAfterNotification = targetIframe.contentWindow.performance.now(); | 
|  | 
| -  // Observer created here, callback created in iframe context.  Timestamps should be | 
| -  // from this window. | 
| -  topWindowObserver = new IntersectionObserver(targetIframe.contentDocument.createObserverCallback(topWindowEntries), {}); | 
| -  topWindowObserver.observe(target); | 
| +  // Test results are only significant if there's a gap between | 
| +  // top window time and iframe window time. | 
| +  assert_greater_than(topWindowTimeBeforeNotification, iframeWindowTimeAfterNotification, | 
| +		      "Time ranges for top and iframe windows are disjoint."); | 
|  | 
| -  // Callback created here, observer created in iframe.  Timestamps should be | 
| -  // from iframe window. | 
| -  iframeWindowObserver = targetIframe.contentDocument.createObserver(function(newEntries) { | 
| -    for (var i = 0; i < newEntries.length; i++) | 
| -      iframeWindowEntries.push(newEntries[i]); | 
| -  }); | 
| -  iframeWindowObserver.observe(target); | 
| +  assert_equals(topWindowEntries.length, 1, "Top window observer has one notification."); | 
| +  assert_between_inclusive( | 
| +      topWindowEntries[0].time, | 
| +      topWindowTimeBeforeNotification, | 
| +      topWindowTimeAfterNotification, | 
| +      "Notification to top window observer is within the expected range."); | 
|  | 
| -  waitForNotification(step0); | 
| +  assert_equals(iframeWindowEntries.length, 1, "Iframe observer has one notification."); | 
| +  assert_between_inclusive( | 
| +      iframeWindowEntries[0].time, | 
| +      iframeWindowTimeBeforeNotification, | 
| +      iframeWindowTimeAfterNotification, | 
| +      "Notification to iframe observer is within the expected range."); | 
| } | 
| - | 
| -onload = function() { | 
| -  setTimeout(function() { | 
| -    targetIframe = document.createElement("iframe"); | 
| -    targetIframe.src = "../resources/intersection-observer-timestamp-subframe.html"; | 
| -    targetIframe.style = "height: 100px; overflow-y: scroll"; | 
| -    var afterFrame = document.getElementById("afterFrame"); | 
| -    afterFrame.parentNode.insertBefore(targetIframe, afterFrame); | 
| -    targetIframe.onload = runTest; | 
| -  }, 2.5 * timestampTolerance); | 
| -}; | 
| - | 
| </script> | 
|  |