<!DOCTYPE HTML>
<script src="../../resources/gesture-util.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../resources/compositor-controls.js"></script>
<style>
body {
margin: 0px;
height: 3000px;
width: 3000px;
}
p {
width: 750px;
}
#scrollable {
height: 400px;
width: 400px;
}
</style>
<p>
This test ensures that autoscrolling doesn't scroll an iframe that's marked
as unscrollable via `scrolling="no"`. To test manually, fully scroll the blue
inner scroller and use middle click autoscroll (Windows feature) from the
inner blue scroller or the rest of the iframe to scroll downwards. This test
passes if the iframe that contains the blue scroller doesn't scroll.
</p>
<iframe id="scrollable" scrolling="no" srcdoc="
<!DOCTYPE html>
<style>
body {
width: 410px;
height: 410px;
margin: 0px;
}
#scroller {
width: 300px;
height: 300px;
overflow: scroll;
background-color: blue;
}
#space {
width: 400px;
height: 400px;
}
</style>
<div id='scroller'>
<div id='space'></div>
</div>
"></iframe>
<script>
setAnimationRequiresRaster();
var scrollable = document.getElementById('scrollable');
function autoScroll(start_x, start_y, end_x, end_y) {
return new Promise((resolve, reject) => {
if (!window.eventSender) {
reject();
} else {
const MIDDLE_BUTTON = 1;
eventSender.mouseMoveTo(start_x, start_y);
eventSender.mouseDown(MIDDLE_BUTTON);
eventSender.mouseUp(MIDDLE_BUTTON);
eventSender.mouseMoveTo(end_x, end_y);
resolve();
}
});
}
function cancelAutoScroll() {
return new Promise((resolve, reject) => {
if (!window.eventSender) {
reject();
} else {
const LEFT_BUTTON = 0;
eventSender.mouseDown(LEFT_BUTTON);
eventSender.mouseUp(LEFT_BUTTON);
resolve();
}
});
}
scrollable.addEventListener('load', () => {
var inner_scroller = frames[0].document.getElementById('scroller');
inner_scroller.scrollTop = 1000;
promise_test(async t => {
await waitForCompositorReady();
const MIDDLE_CLICK_AUTOSCROLL_RADIUS = 15; // from blink::kNoMiddleClickAutoscrollRadius
var rect = scrollable.getBoundingClientRect();
var startX = rect.left + inner_scroller.clientWidth / 3;
var startY = rect.top + inner_scroller.clientHeight / 3;
var endX = startX;
var endY = startY + window.visualViewport.height * 0.75;
assert_equals(inner_scroller.scrollTop,
inner_scroller.scrollHeight - inner_scroller.clientHeight,
"Inner scroller starts fully scrolled.");
assert_equals(window.scrollY, 0, "Main window starts unscrolled.");
assert_equals(frames[0].window.scrollY, 0, "IFrame starts unscrolled.");
// Autoscroll over the inner scroller.
let scrollEventPromise = waitForScrollEvent(document);
let scrollEndPromise = waitForScrollendEvent(document);
await autoScroll(startX, startY, endX, endY);
await scrollEventPromise;
await cancelAutoScroll();
await scrollEndPromise;
assert_true(window.scrollY > 0, "Main frame should have scrolled for the first scroll.");
assert_equals(frames[0].window.scrollY, 0, "Iframe frame should not scroll");
// Reset the scroll offset of the document so that the events in the next phase
// of the test are sent to a consistent target for each test iteration.
await waitForScrollReset();
assert_equals(window.scrollY, 0, "Scroll should be reset.");
// Autoscroll over the iframe. Ensure the pointer is over the iframe and not the inner
// scroller.
startX = rect.right - (rect.width - inner_scroller.clientWidth) / 2;
endX = startX;
scrollEventPromise = waitForScrollEvent(document);
scrollEndPromise = waitForScrollendEvent(document);
await autoScroll(startX, startY, endX, endY);
await scrollEventPromise;
await cancelAutoScroll();
await scrollEndPromise;
assert_true(window.scrollY > 0, "Main frame should have scrolled for the second scroll.");
assert_equals(frames[0].window.scrollY, 0, "Iframe frame should not scroll");
});
});
</script>