Bug 1139155 - Add a basic sanity test to exercise touch-based scrolling on B2G. r=botond

This commit is contained in:
Kartikaya Gupta 2015-06-19 22:52:07 -04:00
Родитель 0584aa026d
Коммит 08ead0c1ca
7 изменённых файлов: 229 добавлений и 0 удалений

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

@ -124,3 +124,30 @@ function synthesizeNativeMouseMoveAndWaitForMoveEvent(aElement, aX, aY, aCallbac
});
return synthesizeNativeMouseMove(aElement, aX, aY);
}
// Synthesizes a native touch event and dispatches it. aX and aY in CSS pixels
// relative to the top-left of |aElement|'s bounding rect.
function synthesizeNativeTouch(aElement, aX, aY, aType, aObserver = null, aTouchId = 0) {
var targetWindow = aElement.ownerDocument.defaultView;
var scale = targetWindow.devicePixelRatio;
var rect = aElement.getBoundingClientRect();
var x = targetWindow.mozInnerScreenX + ((rect.left + aX) * scale);
var y = targetWindow.mozInnerScreenY + ((rect.top + aY) * scale);
var utils = SpecialPowers.getDOMWindowUtils(targetWindow);
utils.sendNativeTouchPoint(aTouchId, aType, x, y, 1, 90, aObserver);
return true;
}
function synthesizeNativeDrag(aElement, aX, aY, aDeltaX, aDeltaY, aObserver = null, aTouchId = 0) {
synthesizeNativeTouch(aElement, aX, aY, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
var steps = Math.max(Math.abs(aDeltaX), Math.abs(aDeltaY));
for (var i = 1; i < steps; i++) {
var dx = i * (aDeltaX / steps);
var dy = i * (aDeltaY / steps);
synthesizeNativeTouch(aElement, aX + dx, aY + dy, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
}
synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
return synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, aObserver, aTouchId);
}

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

@ -99,3 +99,20 @@ function buildApzcTree(paint) {
}
return root;
}
function flushApzRepaints(aCallback, aWindow = window) {
if (!aCallback) {
throw "A callback must be provided!";
}
var repaintDone = function() {
SpecialPowers.Services.obs.removeObserver(repaintDone, "apz-repaints-flushed", false);
setTimeout(aCallback, 0);
};
SpecialPowers.Services.obs.addObserver(repaintDone, "apz-repaints-flushed", false);
if (SpecialPowers.getDOMWindowUtils(aWindow).flushApzRepaints()) {
dump("Flushed APZ repaints, waiting for callback...\n");
} else {
dump("Flushing APZ repaints was a no-op, triggering callback directly...\n");
repaintDone();
}
}

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

@ -0,0 +1,38 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<title>Sanity panning test</title>
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script type="application/javascript">
function scrollPage() {
SpecialPowers._addMessageListener("APZ:TransformEnd", function() {
dump("Transform complete; flushing repaints...\n");
flushApzRepaints(checkScroll);
});
const TOUCH_SLOP = 1;
synthesizeNativeDrag(document.body, 10, 100, 0, -(50 + TOUCH_SLOP));
dump("Finished native drag, waiting for transform-end observer...\n");
}
function checkScroll() {
window.opener.is(window.scrollY, 50, "check that the window scrolled");
window.opener.testDone();
}
window.onload = function() {
setTimeout(scrollPage, 0);
}
</script>
</head>
<body>
<div style="height: 5000px; background-color: lightgreen;">
This div makes the page scrollable.
</div>
</body>
</html>

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

@ -0,0 +1,44 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<title>Sanity panning test for scrollable div</title>
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script type="application/javascript">
function scrollOuter() {
SpecialPowers._addMessageListener("APZ:TransformEnd", function() {
dump("Transform complete; flushing repaints...\n");
flushApzRepaints(checkScroll);
});
const TOUCH_SLOP = 1;
synthesizeNativeDrag(document.getElementById('outer'), 10, 100, 0, -(50 + TOUCH_SLOP));
dump("Finished native drag, waiting for transform-end observer...\n");
}
function checkScroll() {
var outerScroll = document.getElementById('outer').scrollTop;
window.opener.is(outerScroll, 50, "check that the div scrolled");
window.opener.testDone();
}
window.onload = function() {
setTimeout(scrollOuter, 0);
}
</script>
</head>
<body>
<div id="outer" style="height: 250px; border: solid 1px black; overflow:scroll">
<div style="height: 5000px; background-color: lightblue">
This div makes the |outer| div scrollable.
</div>
</div>
<div style="height: 5000px; background-color: lightgreen;">
This div makes the top-level page scrollable.
</div>
</body>
</html>

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

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<title>Sanity panning test for scrollable div</title>
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script type="application/javascript">
function scrollOuter() {
var outer = document.getElementById('outer');
SpecialPowers._addMessageListener("APZ:TransformEnd", function() {
dump("Transform complete; flushing repaints...\n");
flushApzRepaints(checkScroll, outer.contentWindow);
});
const TOUCH_SLOP = 1;
synthesizeNativeDrag(outer.contentDocument.body, 10, 100, 0, -(50 + TOUCH_SLOP));
dump("Finished native drag, waiting for transform-end observer...\n");
}
function checkScroll() {
var outerScroll = document.getElementById('outer').contentWindow.scrollY;
window.opener.is(outerScroll, 50, "check that the iframe scrolled");
window.opener.testDone();
}
window.onload = function() {
setTimeout(scrollOuter, 0);
}
</script>
</head>
<body>
<iframe id="outer" style="height: 250px; border: solid 1px black" src="data:text/html,<body style='height:5000px'>"></iframe>
<div style="height: 5000px; background-color: lightgreen;">
This div makes the top-level page scrollable.
</div>
</body>
</html>

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

@ -7,6 +7,9 @@ support-files =
helper_iframe1.html
helper_iframe2.html
helper_subframe_style.css
helper_basic_pan.html
helper_div_pan.html
helper_iframe_pan.html
tags = apz
[test_bug982141.html]
skip-if = toolkit != 'gonk' # bug 991198
@ -18,3 +21,5 @@ skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel ev
skip-if = (os == 'android') || (os == 'b2g') # wheel events not supported on mobile
[test_layerization.html]
skip-if = (os == 'android') || (os == 'b2g') # uses wheel events which are not supported on mobile
[test_basic_pan.html]
skip-if = toolkit != 'gonk'

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

@ -0,0 +1,57 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Sanity panning test</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.testInChaosMode();
// this page just serially loads each one of the following test helper pages in
// a new window and waits for it to call testDone()
var tests = [
'helper_basic_pan.html',
'helper_div_pan.html',
'helper_iframe_pan.html',
];
var testIndex = -1;
var w = null;
function testDone() {
if (w) {
w.close();
}
testIndex++;
if (testIndex < tests.length) {
w = window.open(tests[testIndex], "_blank");
} else {
SimpleTest.finish();
}
}
window.onload = function() {
SpecialPowers.pushPrefEnv(
{ "set":
[
// Dropping the touch slop to 0 makes the tests easier to write because
// we can just do a one-pixel drag to get over the pan threshold rather
// than having to hard-code some larger value.
["apz.touch_start_tolerance", "0.0"],
// The B2G emulator is hella slow, and needs more than 300ms to run the
// main-thread code that deals with layerizing subframes and running
// touch listeners. In my local runs this needs to be at least 1000.
["apz.content_response_timeout", "5000"]
]
}, testDone);
};
</script>
</head>
<body>
</body>
</html>