summaryrefslogtreecommitdiffstats
path: root/layout/generic/test/test_flex_interrupt.html
diff options
context:
space:
mode:
Diffstat (limited to 'layout/generic/test/test_flex_interrupt.html')
-rw-r--r--layout/generic/test/test_flex_interrupt.html107
1 files changed, 107 insertions, 0 deletions
diff --git a/layout/generic/test/test_flex_interrupt.html b/layout/generic/test/test_flex_interrupt.html
new file mode 100644
index 0000000000..dfe4208f93
--- /dev/null
+++ b/layout/generic/test/test_flex_interrupt.html
@@ -0,0 +1,107 @@
+<!doctype html>
+<title>Test for bug 1579929</title>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<style>
+ .container {
+ display: flex;
+ flex-direction: column;
+ overflow-y: scroll;
+ }
+ #outer {
+ width: 500px;
+ height: 300px;
+ }
+</style>
+<div class="container" id="outer">
+ <div class="item" id="firstItem" style="width: 50px">
+ <!--popuplated by script-->
+ </div>
+ <div class="container">
+ <div class="container">
+ <div class="container">
+ <div class="container">
+ <div class="container">
+ <div class="item">Item</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+<script>
+SimpleTest.waitForExplicitFinish();
+
+// Globals/constants:
+
+const gUtils = SpecialPowers.DOMWindowUtils;
+
+// This needs to match/exceed nsPresContext::sInterruptChecksToSkip in order
+// for us to actually be able to trigger the mHasPendingInterrupt=true codepath
+// in this test. Each of these "dummy" blocks will trigger a call to
+// nsPresContext::CheckForInterrupt, and after 200, we'll actually trigger an
+// interrupt.
+const gInterruptCheckThreshold = 200;
+
+// Expected to match the inline style="width:..." for #firstItem (we slowly
+// increment it to trigger reflows):
+let gFirstItemWidthPX = 50;
+
+function main() {
+ const outer = document.getElementById("outer");
+ const firstItem = document.getElementById("firstItem");
+
+ // Insert a bunch of elements to be sure we actually get interrupted.
+ // (See description of gInterruptCheckThreshold above)
+ for (let i = 0; i < gInterruptCheckThreshold; i++) {
+ let dummyBlock = document.createElement("div");
+ dummyBlock.innerText = "dummy";
+ firstItem.appendChild(dummyBlock);
+ }
+
+ // Flush any pending relayout:
+ outer.offsetHeight;
+
+ // Take control of the refresh driver
+ gUtils.advanceTimeAndRefresh(0);
+
+ // Force reflow and store the "cost" (in num-frames-reflowed)
+ const costOfNormalReflow = forceReflow();
+
+ // Sanity-check: do that again and remeasure cost, to be sure it's stable:
+ const costOfNormalReflow2 = forceReflow();
+ is(costOfNormalReflow, costOfNormalReflow2,
+ "Our forceReflow function is expected to reliably trigger " +
+ "the same set of frames to be reflowed. If this fails, there's a " +
+ "bug in the test, or non-determinism in layout code.");
+
+ // Now, we force the next reflow to get interrupted, and then measure the
+ // cost under those conditions:
+ gUtils.forceReflowInterrupt();
+ const costOfInterruptedReflow = forceReflow();
+
+ // Hopefully the interrupted one was less expensive...
+ ok(costOfInterruptedReflow <= costOfNormalReflow,
+ "num frames reflowed in interrupted reflow (" +
+ costOfInterruptedReflow +
+ ") shouldn't exceed the num frames reflowed in normal reflow (" +
+ costOfNormalReflow + ")");
+
+ gUtils.restoreNormalRefresh();
+ SimpleTest.finish();
+}
+
+// This function dirties firstItem's width, forces a reflow, and
+// returns the number of frames that were reflowed as a result.
+function forceReflow() {
+ gFirstItemWidthPX++;
+ firstItem.style.width = gFirstItemWidthPX + "px";
+
+ const origFramesReflowed = gUtils.framesReflowed;
+ gUtils.advanceTimeAndRefresh(0);
+ return gUtils.framesReflowed - origFramesReflowed;
+}
+
+main();
+</script>