Let runAfterDisplay ensure the callback is called after a paint

The previous version of runAfterDisplay seems not to ensure a paint
when content_shell runs headlessly. This causes less coverage of
tests in slimming paint mode about display item caching because the
many tested results are of the first paint, not the incremental
paint that the tests are intended to test.

Use testRunner.displayAsyncThen() instead to ensure the paint.

Also added autoNotifyDone mode, so that the test doesn't need to
call testRunner.notifyDone(), and ensures that the test finishes only
after the second paint.

BUG=449628, 450725

Review URL: https://codereview.chromium.org/959783002

git-svn-id: svn://svn.chromium.org/blink/trunk@190875 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/third_party/WebKit/LayoutTests/resources/run-after-display.js b/third_party/WebKit/LayoutTests/resources/run-after-display.js
index f4056c0..41ce79b 100644
--- a/third_party/WebKit/LayoutTests/resources/run-after-display.js
+++ b/third_party/WebKit/LayoutTests/resources/run-after-display.js
@@ -1,9 +1,43 @@
-function runAfterDisplay(callback) {
-    window.requestAnimationFrame(function() {
-        // At this point, only the animate has happened, but no compositing
-        // or layout.  Use a timeout for the callback so that notifyDone
-        // can be called inside of it.
-        // FIXME: we need a better way of waiting for chromium events to happen
-        window.setTimeout(callback, 1);
+// Run a callback after layout and paint of all pending document changes.
+//
+// It has two modes:
+// - traditional mode, for existing tests, and tests needing customized notifyDone timing:
+//   Usage:
+//     if (window.testRunner)
+//       testRunner.waitUntilDone();
+//     runAfterDisplay(function() {
+//       ... // some code which modifies style/layout
+//       if (window.testRunner)
+//         testRunner.notifyDone();
+//       // Or to ensure the next paint is executed before the test finishes:
+//       // if (window.testRunner)
+//       //   runAfterDisplay(function() { testRunner.notifyDone() });
+//       // Or notifyDone any time later if needed.
+//     });
+//
+// - autoNotifyDone mode, for new tests which just need to change style/layout and finish:
+//   Usage:
+//     runAfterDisplay(function() {
+//       ... // some code which modifies style/layout
+//     }, true);
+
+function runAfterDisplay(callback, autoNotifyDone) {
+    if (!window.testRunner) {
+        // For manual test. Delay 500ms to allow us to see the visual change
+        // caused by the callback.
+        setTimeout(callback, 500);
+        return;
+    }
+
+    if (autoNotifyDone)
+        testRunner.waitUntilDone();
+
+    testRunner.displayAsyncThen(function() {
+        callback();
+        if (autoNotifyDone) {
+            testRunner.displayAsyncThen(function() {
+                testRunner.notifyDone();
+            });
+        }
     });
 }