diff --git a/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-on-non-root.html b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-on-non-root.html
new file mode 100644
index 000000000000..422ab3c5680d
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/overscroll-behavior-none-on-non-root.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
index 28e564e59f39..dd23c3f0e1ef 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -96,6 +96,7 @@ open class BaseSessionTest(noErrorCollector: Boolean = false) {
const val OVERSCROLL_BEHAVIOR_AUTO_HTML_PATH = "/assets/www/overscroll-behavior-auto.html"
const val OVERSCROLL_BEHAVIOR_AUTO_NONE_HTML_PATH = "/assets/www/overscroll-behavior-auto-none.html"
const val OVERSCROLL_BEHAVIOR_NONE_AUTO_HTML_PATH = "/assets/www/overscroll-behavior-none-auto.html"
+ const val OVERSCROLL_BEHAVIOR_NONE_NON_ROOT_HTML_PATH = "/assets/www/overscroll-behavior-none-on-non-root.html"
const val SCROLL_HANDOFF_HTML_PATH = "/assets/www/scroll-handoff.html"
const val TEST_ENDPOINT = GeckoSessionTestRule.TEST_ENDPOINT
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/InputResultDetailTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/InputResultDetailTest.kt
index ab9255ddd626..9330db72f031 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/InputResultDetailTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/InputResultDetailTest.kt
@@ -159,20 +159,8 @@ class InputResultDetailTest : BaseSessionTest() {
PanZoomController.OVERSCROLL_FLAG_VERTICAL)
}
- @WithDisplay(width = 100, height = 100)
- @Test
- fun testScrollHandoff() {
- sessionRule.display?.run { setDynamicToolbarMaxHeight(20) }
- setupDocument(SCROLL_HANDOFF_HTML_PATH);
-
- var value = sessionRule.waitForResult(sendDownEvent(50f, 50f))
-
- // There is a child scroll container and its overscroll-behavior is `contain auto`
- assertResultDetail("handoff", value,
- PanZoomController.INPUT_RESULT_HANDLED_CONTENT,
- PanZoomController.SCROLLABLE_FLAG_BOTTOM,
- PanZoomController.OVERSCROLL_FLAG_VERTICAL)
-
+ // NOTE: This function requires #scroll element in the target document.
+ private fun scrollToBottom() {
// Prepare a scroll event listener.
val scrollPromise = mainSession.evaluatePromiseJS("""
new Promise(resolve => {
@@ -188,11 +176,26 @@ class InputResultDetailTest : BaseSessionTest() {
const scroll = document.getElementById('scroll');
scroll.scrollTo(0, scroll.scrollHeight);
""".trimIndent())
-
- // Wait a scroll event to make sure the scroll operation has happened.
assertThat("scroll", scrollPromise.value as Boolean, equalTo(true));
-
sessionRule.session.flushApzRepaints()
+ }
+
+ @WithDisplay(width = 100, height = 100)
+ @Test
+ fun testScrollHandoff() {
+ sessionRule.display?.run { setDynamicToolbarMaxHeight(20) }
+ setupDocument(SCROLL_HANDOFF_HTML_PATH);
+
+ var value = sessionRule.waitForResult(sendDownEvent(50f, 50f))
+
+ // There is a child scroll container and its overscroll-behavior is `contain auto`
+ assertResultDetail("handoff", value,
+ PanZoomController.INPUT_RESULT_HANDLED_CONTENT,
+ PanZoomController.SCROLLABLE_FLAG_BOTTOM,
+ PanZoomController.OVERSCROLL_FLAG_VERTICAL)
+
+ // Scroll to the bottom edge
+ scrollToBottom()
value = sessionRule.waitForResult(sendDownEvent(50f, 50f))
@@ -202,4 +205,66 @@ class InputResultDetailTest : BaseSessionTest() {
PanZoomController.SCROLLABLE_FLAG_BOTTOM,
(PanZoomController.OVERSCROLL_FLAG_HORIZONTAL or PanZoomController.OVERSCROLL_FLAG_VERTICAL))
}
+
+ @WithDisplay(width = 100, height = 100)
+ @Test
+ fun testOverscrollBehaviorNoneOnNonRoot() {
+ var files = arrayOf(
+ OVERSCROLL_BEHAVIOR_NONE_NON_ROOT_HTML_PATH)
+
+ for (file in files) {
+ setupDocument(file)
+
+ var value = sessionRule.waitForResult(sendDownEvent(50f, 50f))
+
+ assertResultDetail("`overscroll-behavior: none` on non root scroll container", value,
+ PanZoomController.INPUT_RESULT_HANDLED_CONTENT,
+ PanZoomController.SCROLLABLE_FLAG_BOTTOM,
+ PanZoomController.OVERSCROLL_FLAG_NONE)
+
+ // Scroll to the bottom edge so that the container is no longer scrollable downwards.
+ scrollToBottom()
+
+ value = sessionRule.waitForResult(sendDownEvent(50f, 50f))
+
+ // The touch event should be handled in the scroll container content.
+ assertResultDetail("`overscroll-behavior: none` on non root scroll container", value,
+ PanZoomController.INPUT_RESULT_HANDLED_CONTENT,
+ PanZoomController.SCROLLABLE_FLAG_TOP,
+ PanZoomController.OVERSCROLL_FLAG_NONE)
+ }
+ }
+
+ @WithDisplay(width = 100, height = 100)
+ @Test
+ fun testOverscrollBehaviorNoneOnNonRootWithDynamicToolbar() {
+ sessionRule.display?.run { setDynamicToolbarMaxHeight(20) }
+
+ var files = arrayOf(
+ OVERSCROLL_BEHAVIOR_NONE_NON_ROOT_HTML_PATH)
+
+ for (file in files) {
+ setupDocument(file)
+
+ var value = sessionRule.waitForResult(sendDownEvent(50f, 50f))
+
+ assertResultDetail("`overscroll-behavior: none` on non root scroll container", value,
+ PanZoomController.INPUT_RESULT_HANDLED_CONTENT,
+ PanZoomController.SCROLLABLE_FLAG_BOTTOM,
+ PanZoomController.OVERSCROLL_FLAG_NONE)
+
+ // Scroll to the bottom edge so that the container is no longer scrollable downwards.
+ scrollToBottom()
+
+ value = sessionRule.waitForResult(sendDownEvent(50f, 50f))
+
+ // Now the touch event should be handed to the root scroller even if
+ // the scroll container's `overscroll-behavior` is none to move
+ // the dynamic toolbar.
+ assertResultDetail("`overscroll-behavior: none, none`", value,
+ PanZoomController.INPUT_RESULT_HANDLED,
+ PanZoomController.SCROLLABLE_FLAG_BOTTOM,
+ (PanZoomController.OVERSCROLL_FLAG_HORIZONTAL or PanZoomController.OVERSCROLL_FLAG_VERTICAL))
+ }
+ }
}