Bug 1787560 - Add test for touch drag scrollbar scroll. r=botond

Differential Revision: https://phabricator.services.mozilla.com/D155871
This commit is contained in:
Dan Robertson 2022-09-02 13:36:38 +00:00
Родитель c6fa781bc2
Коммит ea25b2e90a
3 изменённых файлов: 135 добавлений и 36 удалений

Просмотреть файл

@ -1293,6 +1293,25 @@ function promiseMoveMouseAndScrollWheelOver(
return p; return p;
} }
function scrollbarDragStart(aTarget, aScaleFactor) {
var targetElement = elementForTarget(aTarget);
var w = {},
h = {};
utilsForTarget(aTarget).getScrollbarSizes(targetElement, w, h);
var verticalScrollbarWidth = w.value;
if (verticalScrollbarWidth == 0) {
return null;
}
var upArrowHeight = verticalScrollbarWidth; // assume square scrollbar buttons
var startX = targetElement.clientWidth + verticalScrollbarWidth / 2;
var startY = upArrowHeight + 5; // start dragging somewhere in the thumb
startX *= aScaleFactor;
startY *= aScaleFactor;
return { x: startX, y: startY };
}
// Synthesizes events to drag |target|'s vertical scrollbar by the distance // Synthesizes events to drag |target|'s vertical scrollbar by the distance
// specified, synthesizing a mousemove for each increment as specified. // specified, synthesizing a mousemove for each increment as specified.
// Returns null if the element doesn't have a vertical scrollbar. Otherwise, // Returns null if the element doesn't have a vertical scrollbar. Otherwise,
@ -1301,7 +1320,7 @@ function promiseMoveMouseAndScrollWheelOver(
// processed by the widget code can be detected by listening for the mousemove // processed by the widget code can be detected by listening for the mousemove
// events in the caller, or for some other event that is triggered by the // events in the caller, or for some other event that is triggered by the
// mousemove, such as the scroll event resulting from the scrollbar drag. // mousemove, such as the scroll event resulting from the scrollbar drag.
// The scaleFactor argument should be provided if the scrollframe has been // The aScaleFactor argument should be provided if the scrollframe has been
// scaled by an enclosing CSS transform. (TODO: this is a workaround for the // scaled by an enclosing CSS transform. (TODO: this is a workaround for the
// fact that coordinatesRelativeToScreen is supposed to do this automatically // fact that coordinatesRelativeToScreen is supposed to do this automatically
// but it currently does not). // but it currently does not).
@ -1309,31 +1328,22 @@ function promiseMoveMouseAndScrollWheelOver(
// with modifications. Fixes here should be copied there if appropriate. // with modifications. Fixes here should be copied there if appropriate.
// |target| can be an element (for subframes) or a window (for root frames). // |target| can be an element (for subframes) or a window (for root frames).
async function promiseVerticalScrollbarDrag( async function promiseVerticalScrollbarDrag(
target, aTarget,
distance = 20, aDistance = 20,
increment = 5, aIncrement = 5,
scaleFactor = 1 aScaleFactor = 1
) { ) {
var targetElement = elementForTarget(target); var startPoint = scrollbarDragStart(aTarget, aScaleFactor);
var w = {}, var targetElement = elementForTarget(aTarget);
h = {}; if (startPoint == null) {
utilsForTarget(target).getScrollbarSizes(targetElement, w, h);
var verticalScrollbarWidth = w.value;
if (verticalScrollbarWidth == 0) {
return null; return null;
} }
var upArrowHeight = verticalScrollbarWidth; // assume square scrollbar buttons
var mouseX = targetElement.clientWidth + verticalScrollbarWidth / 2;
var mouseY = upArrowHeight + 5; // start dragging somewhere in the thumb
mouseX *= scaleFactor;
mouseY *= scaleFactor;
dump( dump(
"Starting drag at " + "Starting drag at " +
mouseX + startPoint.x +
", " + ", " +
mouseY + startPoint.y +
" from top-left of #" + " from top-left of #" +
targetElement.id + targetElement.id +
"\n" "\n"
@ -1341,31 +1351,31 @@ async function promiseVerticalScrollbarDrag(
// Move the mouse to the scrollbar thumb and drag it down // Move the mouse to the scrollbar thumb and drag it down
await promiseNativeMouseEventWithAPZ({ await promiseNativeMouseEventWithAPZ({
target, target: aTarget,
offsetX: mouseX, offsetX: startPoint.x,
offsetY: mouseY, offsetY: startPoint.y,
type: "mousemove", type: "mousemove",
}); });
// mouse down // mouse down
await promiseNativeMouseEventWithAPZ({ await promiseNativeMouseEventWithAPZ({
target, target: aTarget,
offsetX: mouseX, offsetX: startPoint.x,
offsetY: mouseY, offsetY: startPoint.y,
type: "mousedown", type: "mousedown",
}); });
// drag vertically by |increment| until we reach the specified distance // drag vertically by |aIncrement| until we reach the specified distance
for (var y = increment; y < distance; y += increment) { for (var y = aIncrement; y < aDistance; y += aIncrement) {
await promiseNativeMouseEventWithAPZ({ await promiseNativeMouseEventWithAPZ({
target, target: aTarget,
offsetX: mouseX, offsetX: startPoint.x,
offsetY: mouseY + y, offsetY: startPoint.y + y,
type: "mousemove", type: "mousemove",
}); });
} }
await promiseNativeMouseEventWithAPZ({ await promiseNativeMouseEventWithAPZ({
target, target: aTarget,
offsetX: mouseX, offsetX: startPoint.x,
offsetY: mouseY + distance, offsetY: startPoint.y + aDistance,
type: "mousemove", type: "mousemove",
}); });
@ -1373,14 +1383,50 @@ async function promiseVerticalScrollbarDrag(
return async function() { return async function() {
dump("Finishing drag of #" + targetElement.id + "\n"); dump("Finishing drag of #" + targetElement.id + "\n");
await promiseNativeMouseEventWithAPZ({ await promiseNativeMouseEventWithAPZ({
target, target: aTarget,
offsetX: mouseX, offsetX: startPoint.x,
offsetY: mouseY + distance, offsetY: startPoint.y + aDistance,
type: "mouseup", type: "mouseup",
}); });
}; };
} }
// This is similar to promiseVerticalScrollbarDrag except this triggers
// the vertical scrollbar drag with a touch drag input. This function
// returns true if a scrollbar was present and false if no scrollbar
// was found for the given element.
async function promiseVerticalScrollbarTouchDrag(
aTarget,
aDistance = 20,
aScaleFactor = 1
) {
var startPoint = scrollbarDragStart(aTarget, aScaleFactor);
var targetElement = elementForTarget(aTarget);
if (startPoint == null) {
return false;
}
dump(
"Starting touch drag at " +
startPoint.x +
", " +
startPoint.y +
" from top-left of #" +
targetElement.id +
"\n"
);
await promiseNativeTouchDrag(
aTarget,
startPoint.x,
startPoint.y,
0,
aDistance
);
return true;
}
// Synthesizes a native mouse drag, starting at offset (mouseX, mouseY) from // Synthesizes a native mouse drag, starting at offset (mouseX, mouseY) from
// the given target. The drag occurs in the given number of steps, to a final // the given target. The drag occurs in the given number of steps, to a final
// destination of (mouseX + distanceX, mouseY + distanceY) from the target. // destination of (mouseX + distanceX, mouseY + distanceY) from the target.

Просмотреть файл

@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<title>Touch Drag on the viewport's scrollbar</title>
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<style>
.content {
width: 1000px;
height: 5000px;
}
</style>
<script type="text/javascript">
async function test() {
let transformEndPromise = promiseTransformEnd();
let scrollbarPresent = await promiseVerticalScrollbarTouchDrag(window, 20);
if (!scrollbarPresent) {
ok(true, "No scrollbar, can't do this test");
return;
}
await transformEndPromise;
// Flush everything just to be safe
await promiseOnlyApzControllerFlushed();
// After dragging the scrollbar 20px on a 1000px-high viewport, we should
// have scrolled approx 2% of the 5000px high content. There might have been
// scroll arrows and such so let's just have a minimum bound of 50px to be safe.
ok(window.scrollY > 50, "Scrollbar drag resulted in a vertical scroll position of " + window.scrollY);
// Check that we did not get spurious horizontal scrolling, as we might if the
// drag gesture is mishandled by content as a select-drag rather than a scrollbar
// drag.
is(window.scrollX, 0, "Scrollbar drag resulted in a horizontal scroll position of " + window.scrollX);
}
waitUntilApzStable()
.then(test)
.then(subtestDone, subtestFailed);
</script>
</head>
<body>
<div class="content">Some content to ensure the root scrollframe is scrollable</div>
</body>
</html>

Просмотреть файл

@ -13,6 +13,8 @@
var subtests = [ var subtests = [
// tests that scrolling doesn't cause extra SchedulePaint calls // tests that scrolling doesn't cause extra SchedulePaint calls
{"file": "helper_bug1669625.html", "dp_suppression": false}, {"file": "helper_bug1669625.html", "dp_suppression": false},
{"file": "helper_touch_drag_root_scrollbar.html", "prefs": [["apz.allow_zooming", true]]},
{"file": "helper_touch_drag_root_scrollbar.html", "prefs": [["apz.allow_zooming", false]]},
// Add new subtests here. If this starts timing out because it's taking too // Add new subtests here. If this starts timing out because it's taking too
// long, create a test_group_touchevents-6.html file. Refer to 1423011#c57 // long, create a test_group_touchevents-6.html file. Refer to 1423011#c57