Title: [176239] trunk
Revision
176239
Author
[email protected]
Date
2014-11-17 17:14:46 -0800 (Mon, 17 Nov 2014)

Log Message

Add initial layout testing coverage for timer throttling
https://bugs.webkit.org/show_bug.cgi?id=138809

Reviewed by Simon Fraser.

Source/WebCore:

Add isTimerThrottled() API to Internals so that we can add layout test
coverage for timer throttling.

Tests: fast/dom/nested-timer-invisible-element-throttling.html
       fast/dom/nested-timer-visible-element-throttling.html
       fast/dom/repeating-timer-invisible-element-throttling.html
       fast/dom/repeating-timer-visible-element-throttling.html

* page/DOMTimer.h:
* testing/Internals.cpp:
(WebCore::Internals::isTimerThrottled):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

Add initial layout test coverage for timer throttling. It currently
covers the following cases:
- Repeating timer changes the style of an Element that is visible
- Repeating timer changes the style of an Element that is not visible
  (i.e. "display: none").
- Repeating timer doing DOM mutations
- Nested timer changes the style of an Element that is visible
- Nested timer changes the style of an Element that is not visible
  (i.e. "display: none").
- Nested timer doing DOM mutations

More layout tests are coming. In particular, we should add coverage for
changing the style of an Element outside the viewport. We should also
Test that the timer gets unthrottled if necessary on scrolling / layout.

* fast/dom/nested-timer-invisible-element-throttling-expected.txt: Added.
* fast/dom/nested-timer-invisible-element-throttling.html: Added.
* fast/dom/nested-timer-visible-element-throttling-expected.txt: Added.
* fast/dom/nested-timer-visible-element-throttling.html: Added.
* fast/dom/repeating-timer-invisible-element-throttling-expected.txt: Added.
* fast/dom/repeating-timer-invisible-element-throttling.html: Added.
* fast/dom/repeating-timer-visible-element-throttling-expected.txt: Added.
* fast/dom/repeating-timer-visible-element-throttling.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (176238 => 176239)


--- trunk/LayoutTests/ChangeLog	2014-11-18 01:13:16 UTC (rev 176238)
+++ trunk/LayoutTests/ChangeLog	2014-11-18 01:14:46 UTC (rev 176239)
@@ -1,3 +1,34 @@
+2014-11-17  Chris Dumez  <[email protected]>
+
+        Add initial layout testing coverage for timer throttling
+        https://bugs.webkit.org/show_bug.cgi?id=138809
+
+        Reviewed by Simon Fraser.
+
+        Add initial layout test coverage for timer throttling. It currently
+        covers the following cases:
+        - Repeating timer changes the style of an Element that is visible
+        - Repeating timer changes the style of an Element that is not visible
+          (i.e. "display: none").
+        - Repeating timer doing DOM mutations
+        - Nested timer changes the style of an Element that is visible
+        - Nested timer changes the style of an Element that is not visible
+          (i.e. "display: none").
+        - Nested timer doing DOM mutations
+
+        More layout tests are coming. In particular, we should add coverage for
+        changing the style of an Element outside the viewport. We should also
+        Test that the timer gets unthrottled if necessary on scrolling / layout.
+
+        * fast/dom/nested-timer-invisible-element-throttling-expected.txt: Added.
+        * fast/dom/nested-timer-invisible-element-throttling.html: Added.
+        * fast/dom/nested-timer-visible-element-throttling-expected.txt: Added.
+        * fast/dom/nested-timer-visible-element-throttling.html: Added.
+        * fast/dom/repeating-timer-invisible-element-throttling-expected.txt: Added.
+        * fast/dom/repeating-timer-invisible-element-throttling.html: Added.
+        * fast/dom/repeating-timer-visible-element-throttling-expected.txt: Added.
+        * fast/dom/repeating-timer-visible-element-throttling.html: Added.
+
 2014-11-17  Alexey Proskuryakov  <[email protected]>
 
         media/track/track-in-band-cues-added-once.html fails sometimes

Added: trunk/LayoutTests/fast/dom/nested-timer-invisible-element-throttling-expected.txt (0 => 176239)


--- trunk/LayoutTests/fast/dom/nested-timer-invisible-element-throttling-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/nested-timer-invisible-element-throttling-expected.txt	2014-11-18 01:14:46 UTC (rev 176239)
@@ -0,0 +1,18 @@
+Tests that a nested timer changing the style of a non-visible element gets throttled.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+The timer should initially not be throttled.
+PASS internals.isTimerThrottled(timeoutId) is false
+5th iteration, timer should have been throttled.
+PASS wasThrottled is true
+6th iteration, timer should still be throttled.
+PASS internals.isTimerThrottled(timeoutId) is true
+Timer mutated the DOM tree.
+7th iteration, timer should no longer be throttled.
+PASS internals.isTimerThrottled(timeoutId) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/nested-timer-invisible-element-throttling.html (0 => 176239)


--- trunk/LayoutTests/fast/dom/nested-timer-invisible-element-throttling.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/nested-timer-invisible-element-throttling.html	2014-11-18 01:14:46 UTC (rev 176239)
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<body>
+<script src=""
+<div id="testElement" style="display: none">Test</div>
+<script>
+description("Tests that a nested timer changing the style of a non-visible element gets throttled.");
+jsTestIsAsync = true;
+
+var iterationCount = 0;
+var timeoutId;
+var testElement = document.getElementById("testElement");
+var wasThrottled = false;
+
+function checkTimerThrottleState()
+{
+  if (iterationCount == 5) {
+    // Do not use shouldBeTrue() here because it would cause a DOM tree mutation and
+    // unthrottle the DOM Timer.
+    wasThrottled = internals.isTimerThrottled(timeoutId);
+  } else if (iterationCount == 6) {
+    debug("5th iteration, timer should have been throttled.");
+    shouldBeTrue("wasThrottled");
+    debug("6th iteration, timer should still be throttled.");
+    shouldBeTrue("internals.isTimerThrottled(timeoutId)");
+  } else if (iterationCount >= 6) {
+    // Timer should be unthrottled due to the DOM tree mutation caused by shouldBeTrue() in
+    // the previous iteration.
+    debug("" + iterationCount + "th iteration, timer should no longer be throttled.");
+    shouldBeFalse("internals.isTimerThrottled(timeoutId)");
+    clearTimeout(timeoutId);
+    finishJSTest();
+  }
+}
+
+function timerCallback()
+{
+  ++iterationCount;
+  // Interact with the style of the element.
+  testElement.style["left"] = "" + iterationCount + "px";
+
+  // 5 iterations should be sufficient to throttle the timer.
+  if (iterationCount >= 5) {
+    setTimeout(checkTimerThrottleState, 0);
+    if (iterationCount == 7) {
+      // The call to debug() mutates the DOM tree.
+      debug("Timer mutated the DOM tree.");
+    }
+  }
+
+  timeoutId = setTimeout(timerCallback, 0);
+}
+
+timeoutId = setTimeout(timerCallback, 0);
+debug("The timer should initially not be throttled.");
+shouldBeFalse("internals.isTimerThrottled(timeoutId)");
+</script>
+<script src=""
+</body>

Added: trunk/LayoutTests/fast/dom/nested-timer-visible-element-throttling-expected.txt (0 => 176239)


--- trunk/LayoutTests/fast/dom/nested-timer-visible-element-throttling-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/nested-timer-visible-element-throttling-expected.txt	2014-11-18 01:14:46 UTC (rev 176239)
@@ -0,0 +1,15 @@
+Tests that a nested timer changing the style of a visible element does not get throttled.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+The timer should initially not be throttled.
+PASS internals.isTimerThrottled(timeoutId) is false
+5th iteration, timer should not have been throttled.
+PASS wasThrottled is false
+6th iteration, timer should still be unthrottled.
+PASS internals.isTimerThrottled(timeoutId) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Test

Added: trunk/LayoutTests/fast/dom/nested-timer-visible-element-throttling.html (0 => 176239)


--- trunk/LayoutTests/fast/dom/nested-timer-visible-element-throttling.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/nested-timer-visible-element-throttling.html	2014-11-18 01:14:46 UTC (rev 176239)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<body>
+<script src=""
+<div id="testElement">Test</div>
+<script>
+description("Tests that a nested timer changing the style of a visible element does not get throttled.");
+jsTestIsAsync = true;
+
+var iterationCount = 0;
+var timeoutId;
+var testElement = document.getElementById("testElement");
+var wasThrottled = false;
+
+function checkTimerThrottlingState() {
+  if (iterationCount == 5) {
+    // Do not use shouldBeTrue() here because it would cause a DOM tree mutation and
+    // unthrottle the DOM Timer.
+    wasThrottled = internals.isTimerThrottled(timeoutId);
+  } else if (iterationCount == 6) {
+    debug("5th iteration, timer should not have been throttled.");
+    shouldBeFalse("wasThrottled");
+    debug("6th iteration, timer should still be unthrottled.");
+    shouldBeFalse("internals.isTimerThrottled(timeoutId)");
+    clearTimeout(timeoutId);
+    finishJSTest();
+  }
+}
+
+function timerCallback()
+{
+  ++iterationCount;
+  // Interact with the style of the element.
+  testElement.style["left"] = "" + iterationCount + "px";
+
+  // 5 iterations should suffice to throttle the timer.
+  if (iterationCount >= 5)
+    setTimeout(checkTimerThrottlingState, 0);
+
+  timeoutId = setTimeout(timerCallback, 0);
+}
+
+timeoutId = setTimeout(timerCallback, 0);
+debug("The timer should initially not be throttled.");
+shouldBeFalse("internals.isTimerThrottled(timeoutId)");
+</script>
+<script src=""
+</body>

Added: trunk/LayoutTests/fast/dom/repeating-timer-invisible-element-throttling-expected.txt (0 => 176239)


--- trunk/LayoutTests/fast/dom/repeating-timer-invisible-element-throttling-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/repeating-timer-invisible-element-throttling-expected.txt	2014-11-18 01:14:46 UTC (rev 176239)
@@ -0,0 +1,18 @@
+Tests that a repeating timer changing the style of a non-visible element gets throttled.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+The timer should initially not be throttled.
+PASS internals.isTimerThrottled(timeoutId) is false
+5th iteration, timer should have been throttled.
+PASS wasThrottled is true
+6th iteration, timer should still be throttled.
+PASS internals.isTimerThrottled(timeoutId) is true
+Timer mutated the DOM tree.
+7th iteration, timer should no longer be throttled.
+PASS internals.isTimerThrottled(timeoutId) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/repeating-timer-invisible-element-throttling.html (0 => 176239)


--- trunk/LayoutTests/fast/dom/repeating-timer-invisible-element-throttling.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/repeating-timer-invisible-element-throttling.html	2014-11-18 01:14:46 UTC (rev 176239)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<body>
+<script src=""
+<div id="testElement" style="display: none">Test</div>
+<script>
+description("Tests that a repeating timer changing the style of a non-visible element gets throttled.");
+jsTestIsAsync = true;
+
+var iterationCount = 0;
+var timeoutId;
+var testElement = document.getElementById("testElement");
+var wasThrottled = false;
+
+function timerCallback()
+{
+  ++iterationCount;
+  // Interact with the style of the element.
+  testElement.style["left"] = "" + iterationCount + "px";
+
+  // 5 iterations should suffice to throttle the timer.
+  if (iterationCount == 5) {
+    // Do not use shouldBeTrue() here because it would cause a DOM tree mutation and
+    // unthrottle the DOM Timer.
+    wasThrottled = internals.isTimerThrottled(timeoutId);
+  } else if (iterationCount == 6) {
+    debug("5th iteration, timer should have been throttled.");
+    shouldBeTrue("wasThrottled");
+    debug("6th iteration, timer should still be throttled.");
+    shouldBeTrue("internals.isTimerThrottled(timeoutId)");
+    debug("Timer mutated the DOM tree.");
+  } else if (iterationCount >= 6) {
+    // Timer should be unthrottled due to the DOM tree mutation caused by shouldBeTrue() in
+    // the previous iteration.
+    debug("" + iterationCount + "th iteration, timer should no longer be throttled.");
+    shouldBeFalse("internals.isTimerThrottled(timeoutId)");
+    clearInterval(timeoutId);
+    finishJSTest();
+  }
+}
+
+timeoutId = setInterval(timerCallback, 0);
+debug("The timer should initially not be throttled.");
+shouldBeFalse("internals.isTimerThrottled(timeoutId)");
+</script>
+<script src=""
+</body>

Added: trunk/LayoutTests/fast/dom/repeating-timer-visible-element-throttling-expected.txt (0 => 176239)


--- trunk/LayoutTests/fast/dom/repeating-timer-visible-element-throttling-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/repeating-timer-visible-element-throttling-expected.txt	2014-11-18 01:14:46 UTC (rev 176239)
@@ -0,0 +1,15 @@
+Tests that a repeating timer changing the style of a visible element does not get throttled.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+The timer should initially not be throttled.
+PASS internals.isTimerThrottled(timeoutId) is false
+5th iteration, timer should not have been throttled.
+PASS wasThrottled is false
+6th iteration, timer should still be unthrottled.
+PASS internals.isTimerThrottled(timeoutId) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+Test

Added: trunk/LayoutTests/fast/dom/repeating-timer-visible-element-throttling.html (0 => 176239)


--- trunk/LayoutTests/fast/dom/repeating-timer-visible-element-throttling.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/repeating-timer-visible-element-throttling.html	2014-11-18 01:14:46 UTC (rev 176239)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<body>
+<script src=""
+<div id="testElement">Test</div>
+<script>
+description("Tests that a repeating timer changing the style of a visible element does not get throttled.");
+jsTestIsAsync = true;
+
+var iterationCount = 0;
+var timeoutId;
+var testElement = document.getElementById("testElement");
+var wasThrottled = false;
+
+function timerCallback()
+{
+  ++iterationCount;
+  // Interact with the style of the element.
+  testElement.style["left"] = "" + iterationCount + "px";
+
+  // 5 iterations should suffice to throttle the timer.
+  if (iterationCount == 5) {
+    // Do not use shouldBeTrue() here because it would cause a DOM tree mutation and
+    // unthrottle the DOM Timer.
+    wasThrottled = internals.isTimerThrottled(timeoutId);
+  } else if (iterationCount == 6) {
+    debug("5th iteration, timer should not have been throttled.");
+    shouldBeFalse("wasThrottled");
+    debug("6th iteration, timer should still be unthrottled.");
+    shouldBeFalse("internals.isTimerThrottled(timeoutId)");
+    clearInterval(timeoutId);
+    finishJSTest();
+  }
+}
+
+timeoutId = setInterval(timerCallback, 0);
+debug("The timer should initially not be throttled.");
+shouldBeFalse("internals.isTimerThrottled(timeoutId)");
+</script>
+<script src=""
+</body>

Modified: trunk/Source/WebCore/ChangeLog (176238 => 176239)


--- trunk/Source/WebCore/ChangeLog	2014-11-18 01:13:16 UTC (rev 176238)
+++ trunk/Source/WebCore/ChangeLog	2014-11-18 01:14:46 UTC (rev 176239)
@@ -1,3 +1,24 @@
+2014-11-17  Chris Dumez  <[email protected]>
+
+        Add initial layout testing coverage for timer throttling
+        https://bugs.webkit.org/show_bug.cgi?id=138809
+
+        Reviewed by Simon Fraser.
+
+        Add isTimerThrottled() API to Internals so that we can add layout test
+        coverage for timer throttling.
+
+        Tests: fast/dom/nested-timer-invisible-element-throttling.html
+               fast/dom/nested-timer-visible-element-throttling.html
+               fast/dom/repeating-timer-invisible-element-throttling.html
+               fast/dom/repeating-timer-visible-element-throttling.html
+
+        * page/DOMTimer.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::isTimerThrottled):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2014-11-17  Zalan Bujtas  <[email protected]>
 
         Simple line layout: Rename FlowContentIterator and move implementation to SimpleLineLayoutFlowContents.cpp

Modified: trunk/Source/WebCore/page/DOMTimer.h (176238 => 176239)


--- trunk/Source/WebCore/page/DOMTimer.h	2014-11-18 01:13:16 UTC (rev 176238)
+++ trunk/Source/WebCore/page/DOMTimer.h	2014-11-18 01:14:46 UTC (rev 176239)
@@ -61,6 +61,8 @@
 
     private:
         DOMTimer(ScriptExecutionContext&, std::unique_ptr<ScheduledAction>, int interval, bool singleShot);
+        friend class Internals;
+
         double intervalClampedToMinimum() const;
 
         bool isIntervalDependentOnViewport() const { return m_throttleState == ShouldThrottle && !m_elementsCausingThrottling.isEmpty(); }

Modified: trunk/Source/WebCore/testing/Internals.cpp (176238 => 176239)


--- trunk/Source/WebCore/testing/Internals.cpp	2014-11-18 01:13:16 UTC (rev 176238)
+++ trunk/Source/WebCore/testing/Internals.cpp	2014-11-18 01:14:46 UTC (rev 176239)
@@ -626,6 +626,16 @@
     return element->setPseudo(id);
 }
 
+bool Internals::isTimerThrottled(int timeoutId, ExceptionCode& ec)
+{
+    DOMTimer* timer = scriptExecutionContext()->findTimeout(timeoutId);
+    if (!timer) {
+        ec = NOT_FOUND_ERR;
+        return false;
+    }
+    return timer->m_throttleState == DOMTimer::ShouldThrottle;
+}
+
 String Internals::visiblePlaceholder(Element* element)
 {
     if (is<HTMLTextFormControlElement>(element)) {

Modified: trunk/Source/WebCore/testing/Internals.h (176238 => 176239)


--- trunk/Source/WebCore/testing/Internals.h	2014-11-18 01:13:16 UTC (rev 176238)
+++ trunk/Source/WebCore/testing/Internals.h	2014-11-18 01:14:46 UTC (rev 176239)
@@ -92,6 +92,9 @@
     String shadowPseudoId(Element*, ExceptionCode&);
     void setShadowPseudoId(Element*, const String&, ExceptionCode&);
 
+    // DOMTimers throttling testing.
+    bool isTimerThrottled(int timeoutId, ExceptionCode&);
+
     // Spatial Navigation testing.
     unsigned lastSpatialNavigationCandidateCount(ExceptionCode&) const;
 

Modified: trunk/Source/WebCore/testing/Internals.idl (176238 => 176239)


--- trunk/Source/WebCore/testing/Internals.idl	2014-11-18 01:13:16 UTC (rev 176238)
+++ trunk/Source/WebCore/testing/Internals.idl	2014-11-18 01:14:46 UTC (rev 176239)
@@ -238,6 +238,9 @@
     [RaisesException] void startTrackingRepaints();
     [RaisesException] void stopTrackingRepaints();
 
+    // Query if a timer is currently throttled, to debug timer throttling.
+    [RaisesException] boolean isTimerThrottled(long timerHandle);
+
     // |node| should be Document, HTMLIFrameElement, or unspecified.
     // If |node| is an HTMLIFrameElement, it assumes node.contentDocument is
     // specified without security checks. Unspecified means this document.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to