diff options
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.html | 156 |
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> |