summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/test/mochitest/helper_relative_scroll_smoothness.html
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/apz/test/mochitest/helper_relative_scroll_smoothness.html')
-rw-r--r--gfx/layers/apz/test/mochitest/helper_relative_scroll_smoothness.html156
1 files changed, 156 insertions, 0 deletions
diff --git a/gfx/layers/apz/test/mochitest/helper_relative_scroll_smoothness.html b/gfx/layers/apz/test/mochitest/helper_relative_scroll_smoothness.html
new file mode 100644
index 0000000000..3f895c37d8
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_relative_scroll_smoothness.html
@@ -0,0 +1,156 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<script src="/tests/SimpleTest/NativeKeyCodes.js"></script>
+<script src="/tests/SimpleTest/paint_listener.js"></script>
+<script src="apz_test_utils.js"></script>
+<script src="apz_test_native_event_utils.js"></script>
+<title>What happens if main thread scrolls?</title>
+<style>
+html, body { margin: 0; }
+
+html {
+ background:
+ repeating-linear-gradient(45deg, transparent 0, transparent 100px, rgba(0,0,0,0.1) 0, rgba(0,0,0,0.1) 200px),
+ repeating-linear-gradient(-45deg, transparent 0, transparent 100px, rgba(0,0,0,0.1) 0, rgba(0,0,0,0.1) 200px),
+ repeating-linear-gradient(to bottom, transparent 0, transparent 500px, rgba(0,0,0,0.4) 0, rgba(0,0,0,0.4) 1000px),
+ repeating-linear-gradient(to bottom, hsl(0, 60%, 80%), hsl(0, 60%, 80%) 200px, hsl(70, 60%, 80%) 0, hsl(70, 60%, 80%) 400px, hsl(140, 60%, 80%) 0, hsl(140, 60%, 80%) 600px, hsl(210, 60%, 80%) 0, hsl(210, 60%, 80%) 800px),
+ white;
+ background-size:
+ 283px 283px,
+ 283px 283px,
+ 100px 1000px,
+ 100px 800px;
+}
+
+body {
+ height: 10000px;
+}
+</style>
+
+<script>
+const searchParams = new URLSearchParams(location.search);
+let strict = searchParams.get("strict") == "true";
+
+var intervalId;
+// Start periodic content expansions after we get a scroll event triggered by
+// a key press in test() function below, otherwise we may have same scroll
+// offsets caused by this script before we start scrolling.
+window.addEventListener("scroll", () => {
+ var offset = 0;
+ var initialBodyHeight = 10000;
+ intervalId = setInterval(() => {
+ // "Add content" at the top. We do this by making the body longer and adjusting the background position.
+ offset += 10;
+ document.documentElement.style.backgroundPosition = `0px ${offset}px`;
+ document.body.style.height = `${initialBodyHeight + offset}px`;
+
+ switch (searchParams.get("scroll-method")) {
+ case "scrollBy":
+ window.scrollBy(0, 10);
+ break;
+ case "scrollTop":
+ document.scrollingElement.scrollTop += 10;
+ break;
+ case "scrollTo":
+ window.scrollTo(0, window.scrollY + 10);
+ break;
+ default:
+ ok(false, "Unsupported scroll method: " + searchParams.get("scroll-method"));
+ break;
+ }
+
+ // Simulate some jank.
+ var freezeDurationInMilliseconds = 100;
+ var startTime = Date.now();
+ while (Date.now() - startTime < freezeDurationInMilliseconds) {} // eslint-disable-line no-empty
+ }, 300);
+}, { once: true });
+
+
+async function test() {
+ // Once this content starts scrolling, it triggers a 100ms jank every 300ms so
+ // sending arrow down keys for 1500ms will cause some jank.
+ const TEST_DURATION_MS = 1500;
+ const timeAtStart = performance.now();
+ while (performance.now() - timeAtStart < TEST_DURATION_MS) {
+ switch (searchParams.get("input-type")) {
+ case "key":
+ synthesizeKey("KEY_ArrowDown");
+ break;
+ case "native-key":
+ const DownArrowKeyCode = nativeArrowDownKey();
+ ok(synthesizeNativeKey(KEYBOARD_LAYOUT_EN_US,
+ DownArrowKeyCode, {} /* no modifier */,
+ "", ""),
+ "Dispatched an down arrow key event");
+ break;
+ case "wheel":
+ await synthesizeNativeWheel(window, 50, 50, 0, -50);
+ break;
+ default:
+ ok(false, "Unsupported input type: " + searchParams.get("input-type"));
+ break;
+ }
+ await promiseFrame(window);
+ }
+
+ // Stop the periodic expansions.
+ clearInterval(intervalId);
+
+ const records = collectSampledScrollOffsets(document.scrollingElement);
+
+ let previousRecord = { scrollOffsetY: 0, sampledTimeStamp: 0 };
+ let scrollStartTime = null;
+ for (const record of records) {
+ // Ignore offsets before scrolling.
+ if (record.scrollOffsetY == 0) {
+ continue;
+ }
+ // Ignore offsets after TEST_DURATION_MS has elapsed since the
+ // start of scrolling. Note that the sampled timestamps are
+ // in microseconds.
+ if (!scrollStartTime) {
+ scrollStartTime = record.sampledTimeStamp;
+ } else if (((record.sampledTimeStamp - scrollStartTime) / 1000) > TEST_DURATION_MS) {
+ break;
+ }
+ ok(
+ strict
+ ? (record.scrollOffsetY > previousRecord.scrollOffsetY)
+ : (record.scrollOffsetY >= previousRecord.scrollOffsetY),
+ "scroll offset should be " +
+ (strict ? "strictly monotonically increasing " : "nondecreasing ") +
+ "previous offset: " + previousRecord.scrollOffsetY +
+ ", offset: " + record.scrollOffsetY
+ );
+ ok(
+ record.sampledTimeStamp > previousRecord.sampledTimeStamp,
+ "sampled time stamp should be strictly monotonically increasing " +
+ "previous timestamp: " + previousRecord.sampledTimeStamp +
+ ", timestamp: " + record.sampledTimeStamp
+ );
+ previousRecord = record;
+ }
+}
+
+function isOnChaosMode() {
+ return SpecialPowers.Services.env.get("MOZ_CHAOSMODE");
+}
+
+if (searchParams.get("input-type") == "native-key" &&
+ getPlatform() != "mac" && getPlatform() != "windows") {
+ ok(true, "Skipping test because native key events are not supported on " +
+ getPlatform());
+ subtestDone();
+} else if (searchParams.get("input-type") == "native-key" &&
+ getPlatform() == "mac" && isOnChaosMode()) {
+ ok(true, "Skipping native-key tests on verify runs on Mac");
+ subtestDone();
+} else {
+ waitUntilApzStable()
+ .then(test)
+ .then(subtestDone, subtestFailed);
+}
+</script>