author | Ali Juma <ajuma@chromium.org> |
Thu, 13 Sep 2018 02:51:55 +0000 | |
changeset 436558 | 56c514060216ae984271f9484ea95de37a262599 |
parent 436557 | 9da2c08934b5f527547cc78268d21c9322bd307f |
child 436559 | ebbb8f220ef6b89849281e917179ed551de8eb5c |
push id | 34649 |
push user | aciure@mozilla.com |
push date | Sat, 15 Sep 2018 21:40:43 +0000 |
treeherder | mozilla-central@5d14d1e9f74d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | testonly |
bugs | 1489671, 12901, 1214176, 590195 |
milestone | 64.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
|
--- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -616073,17 +616073,17 @@ "0cc117cb3a69d0f2ed19505f7d14f824cbad6d71", "support" ], "intersection-observer/resources/iframe-no-root-subframe.html": [ "ee63a06ca0ff30eb6bc82d28350cf8d85313251b", "support" ], "intersection-observer/resources/intersection-observer-test-utils.js": [ - "5ad811932f06c34f1bb3bfd70094a0cd5c046c56", + "8683c8b570c8bffbe413315c2b36ec1e47a6d650", "support" ], "intersection-observer/resources/observer-in-iframe-subframe.html": [ "9d0769ae44a1bb4a6195c006999b0959f706330c", "support" ], "intersection-observer/resources/timestamp-subframe.html": [ "143e4f6e23a7688949420a07ccd20e3c211a6f6b",
--- a/testing/web-platform/tests/intersection-observer/resources/intersection-observer-test-utils.js +++ b/testing/web-platform/tests/intersection-observer/resources/intersection-observer-test-utils.js @@ -1,33 +1,83 @@ // Here's how waitForNotification works: // // - myTestFunction0() // - waitForNotification(myTestFunction1) // - requestAnimationFrame() // - Modify DOM in a way that should trigger an IntersectionObserver callback. // - BeginFrame // - requestAnimationFrame handler runs -// - First step_timeout() +// - Second requestAnimationFrame() // - Style, layout, paint // - IntersectionObserver generates new notifications // - Posts a task to deliver notifications -// - First step_timeout handler runs -// - Second step_timeout() // - Task to deliver IntersectionObserver notifications runs // - IntersectionObserver callbacks run -// - Second step_timeout handler runs +// - Second requestAnimationFrameHandler runs +// - step_timeout() +// - step_timeout handler runs // - myTestFunction1() // - [optional] waitForNotification(myTestFunction2) // - requestAnimationFrame() // - Verify newly-arrived IntersectionObserver notifications // - [optional] Modify DOM to trigger new notifications +// +// Ideally, it should be sufficient to use requestAnimationFrame followed +// by two step_timeouts, with the first step_timeout firing in between the +// requestAnimationFrame handler and the task to deliver notifications. +// However, the precise timing of requestAnimationFrame, the generation of +// a new display frame (when IntersectionObserver notifications are +// generated), and the delivery of these events varies between engines, making +// this tricky to test in a non-flaky way. +// +// In particular, in WebKit, requestAnimationFrame and the generation of +// a display frame are two separate tasks, so a step_timeout called within +// requestAnimationFrame can fire before a display frame is generated. +// +// In Gecko, on the other hand, requestAnimationFrame and the generation of +// a display frame are a single task, and IntersectionObserver notifications +// are generated during this task. However, the task posted to deliver these +// notifications can fire after the following requestAnimationFrame. +// +// This means that in general, by the time the second requestAnimationFrame +// handler runs, we know that IntersectionObservations have been generated, +// and that a task to deliver these notifications has been posted (though +// possibly not yet delivered). Then, by the time the step_timeout() handler +// runs, these notifications have been delivered. +// +// Since waitForNotification uses a double-rAF, it is now possible that +// IntersectionObservers may have generated more notifications than what is +// under test, but have not yet scheduled the new batch of notifications for +// delivery. As a result, observer.takeRecords should NOT be used in tests: +// +// - myTestFunction0() +// - waitForNotification(myTestFunction1) +// - requestAnimationFrame() +// - Modify DOM in a way that should trigger an IntersectionObserver callback. +// - BeginFrame +// - requestAnimationFrame handler runs +// - Second requestAnimationFrame() +// - Style, layout, paint +// - IntersectionObserver generates a batch of notifications +// - Posts a task to deliver notifications +// - Task to deliver IntersectionObserver notifications runs +// - IntersectionObserver callbacks run +// - BeginFrame +// - Second requestAnimationFrameHandler runs +// - step_timeout() +// - IntersectionObserver generates another batch of notifications +// - Post task to deliver notifications +// - step_timeout handler runs +// - myTestFunction1() +// - At this point, observer.takeRecords will get the second batch of +// notifications. function waitForNotification(t, f) { requestAnimationFrame(function() { - t.step_timeout(function() { t.step_timeout(f); }); + requestAnimationFrame(function() { t.step_timeout(f); }); }); } // The timing of when runTestCycle is called is important. It should be // called: // // - Before or during the window load event, or // - Inside of a prior runTestCycle callback, *before* any assert_* methods