blob: edbbf9e4e2d4e816df1006f7f52de8ee0a9dd915 [file] [log] [blame]
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<style>
.outer {
height: 400px;
width: 1000px;
}
.content {
height: 1000px;
width: 1200px;
}
#container {
overflow: scroll;
}
#non_scrollable {
overflow: none;
}
</style>
<div id='non_scrollable' class='outer'>
<div class='content'></div>
</div>
<div id='container' class='outer'>
<div class='content'></div>
</div>
<script>
const container = document.getElementById('container');
const non_scrollable = document.getElementById('non_scrollable');
function setUpForWindow() {
window.scrollTo(100, 100);
container.scrollTo(0, 0);
assert_equals(window.scrollY, 100);
assert_equals(window.scrollX, 100);
}
function setUpForContainer() {
window.scrollTo(0, 0);
container.scrollTo(100, 100);
assert_equals(container.scrollTop, 100);
assert_equals(container.scrollLeft, 100);
}
function smoothScroll(pixels_to_scroll, start_x, start_y, gesture_source_type, direction, speed_in_pixels_s) {
return new Promise((resolve, reject) => {
chrome.gpuBenchmarking.smoothScrollBy(pixels_to_scroll, resolve, start_x, start_y, gesture_source_type, direction, speed_in_pixels_s);
});
}
function waitForAnimationEnd() {
const MAX_FRAME = 500;
var last_changed_frame = 0;
var last_window_x = window.scrollX;
var last_window_y = window.scrollY;
var last_container_x = container.scrollLeft;
var last_container_y = container.scrollTop;
return new Promise((resolve, reject) => {
function tick(frames) {
// We requestAnimationFrame either for 500 frames or until 5 frames with
// no change have been observed.
if (frames >= MAX_FRAME || frames - last_changed_frame > 5) {
resolve();
} else {
if (window.scrollX != last_window_x ||
window.scrollY != last_window_y ||
container.scrollLeft != last_container_x ||
container.scrollTop != last_container_y) {
last_changed_frame = frames;
last_window_x = window.scrollX;
last_window_y = window.scrollY;
last_container_x = container.scrollLeft;
last_container_y = container.scrollTop;
}
requestAnimationFrame(tick.bind(this, frames + 1));
}
}
tick(0);
});
}
function test_boundary_prevents_y(source_type) {
container.style.overscrollBehaviorX = 'auto';
container.style.overscrollBehaviorY = 'none';
setUpForWindow();
return smoothScroll(200, 200, 500, source_type, "up", 4000)
.then(waitForAnimationEnd)
.then(() => {
assert_equals(window.scrollY, 100);})
.then(
smoothScroll.bind(this, 200, 200, 500, source_type, "left", 4000))
.then(waitForAnimationEnd)
.then(() => {
assert_equals(window.scrollX, 0);
});
}
function test_boundary_prevents_x(source_type) {
container.style.overscrollBehaviorX = 'none';
container.style.overscrollBehaviorY = 'auto';
setUpForWindow();
return smoothScroll(200, 200, 500, source_type, 'left', 4000)
.then(waitForAnimationEnd)
.then(() => {
assert_equals(window.scrollX, 100);})
.then(
smoothScroll.bind(this, 200, 200, 500, source_type, 'up', 4000))
.then(waitForAnimationEnd)
.then(() => {
assert_equals(window.scrollY, 0);
});
}
function test_boundary_allows_inner(source_type) {
container.style.overscrollBehaviorX = 'none';
container.style.overscrollBehaviorY = 'none';
setUpForContainer();
return smoothScroll(200, 200, 500, source_type, 'upleft', 4000)
.then(waitForAnimationEnd)
.then(() => {
assert_equals(container.scrollTop, 0);
assert_equals(container.scrollLeft, 0);
});
}
function test_boundary_on_nonscrollable_allows_propagation(source_type) {
non_scrollable.style.overscrollBehaviorX = 'none';
non_scrollable.style.overscrollBehaviorY = 'none';
window.scrollTo(0, 0);
return smoothScroll(200, 200, 300, source_type, 'right', 4000)
.then(waitForAnimationEnd)
.then(() => {
assert_greater_than(window.scrollX, 100);})
.then(
smoothScroll.bind(this, 200, 200, 300, source_type, 'down', 4000))
.then(waitForAnimationEnd)
.then(() => {
assert_greater_than(window.scrollY, 100);
});
}
const TOUCH_SOURCE_TYPE = 1; // TOUCH_INPUT from synthetic_gesture_params.h
const WHEEL_SOURCE_TYPE = 2; // TOUCH_INPUT from synthetic_gesture_params.h
promise_test(t => {
return test_boundary_prevents_y(WHEEL_SOURCE_TYPE);
}, 'overscroll-behavior-y: none should only prevent scroll propagation on y axis with: wheel.');
promise_test(t => {
return test_boundary_prevents_x(WHEEL_SOURCE_TYPE);
}, 'overscroll-behavior-x: none should only prevent scroll propagation on x axis with: wheel.');
promise_test(t => {
return test_boundary_allows_inner(WHEEL_SOURCE_TYPE);
}, 'overscroll-behavior should not affect scrolling inside the applied container with: wheel.');
promise_test(t => {
return test_boundary_on_nonscrollable_allows_propagation(WHEEL_SOURCE_TYPE);
}, 'overscroll-behavior on non-scrollable area should not affect scroll propagation with: wheel.');
const IS_MAC = navigator.platform.indexOf('Mac') == 0;
if (!IS_MAC) {
promise_test(t => {
return test_boundary_prevents_y(TOUCH_SOURCE_TYPE);
}, 'overscroll-behavior-y: none should only prevent scroll propagation on y axis with: touch.');
promise_test(t => {
return test_boundary_prevents_x(TOUCH_SOURCE_TYPE);
}, 'overscroll-behavior-x: none should only prevent scroll propagation on x axis with: touch.');
promise_test(t => {
return test_boundary_on_nonscrollable_allows_propagation(TOUCH_SOURCE_TYPE);
}, 'overscroll-behavior on non-scrollable area should not affect scroll propagation with: touch.');
}
</script>