commit 6f5eca3c03871900231431b411cb995ecf1a248f parent 8b2f53ecf8b5e185d1ab831082202cad8213f220 Author: Makoto Kato <m_kato@ga2.so-net.ne.jp> Date: Thu, 9 Oct 2025 13:59:27 +0000 Bug 1993223 - Use document.notifyUserGestureActivation to open pickers on gv-junit. r=geckoview-reviewers,ohall We have bugs that user activation is failed when showing pickers such as bug 1956913, bug 1961352, bug 1961358 and bug 1961940. Actually, although we use a tap to simulate user gesture activation, it is better to use `document.notifyUserGestureActivation` that is chrome privilege API. Differential Revision: https://phabricator.services.mozilla.com/D267945 Diffstat:
7 files changed, 43 insertions(+), 19 deletions(-)
diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/TestSupportChild.sys.mjs b/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/TestSupportChild.sys.mjs @@ -88,6 +88,10 @@ export class TestSupportChild extends GeckoViewActorChild { } return Promise.resolve(); } + case "NotifyUserGestureActivation": { + this.document.notifyUserGestureActivation(); + return Promise.resolve(); + } } return null; } diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/background.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/background.js @@ -104,6 +104,9 @@ const APIS = { TeardownAlertsService() { return browser.test.teardownAlertsService(); }, + NotifyUserGestureActivation({ tab }) { + return browser.test.notifyUserGestureActivation(tab.id); + }, }; port.onMessage.addListener(async message => { diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-api.js b/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-api.js @@ -285,6 +285,12 @@ this.test = class extends ExtensionAPI { ); alertsService.teardown(); }, + + async notifyUserGestureActivation(tabId) { + return getActorForTab(tabId, "TestSupport").sendQuery( + "NotifyUserGestureActivation" + ); + }, }, }; } diff --git a/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-schema.json b/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-schema.json @@ -364,6 +364,19 @@ "async": true, "description": "Triggers teardown on Alerts Service so that it can clear all notification information.", "parameters": [] + }, + + { + "name": "notifyUserGestureActivation", + "type": "function", + "async": true, + "description": "Invokes document.notifyUserGestureActivation to simulate user gesture activation.", + "parameters": [ + { + "type": "number", + "name": "tabId" + } + ] } ] } 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 @@ -324,6 +324,8 @@ open class BaseSessionTest( fun GeckoSession.teardownAlertsService() = sessionRule.teardownAlertsService(this) + fun GeckoSession.notifyUserGestureActivation() = sessionRule.notifyUserGestureActivation(this) + var GeckoSession.active: Boolean get() = sessionRule.getActive(this) set(value) = setActive(value) diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PromptDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/PromptDelegateTest.kt @@ -16,7 +16,6 @@ import org.hamcrest.Matchers.isEmptyOrNullString import org.hamcrest.Matchers.notNullValue import org.hamcrest.Matchers.nullValue import org.junit.Assert -import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mozilla.geckoview.AllowOrDeny @@ -834,8 +833,8 @@ class PromptDelegateTest : BaseSessionTest( """.trimIndent(), ) - mainSession.evaluateJS("document.addEventListener('click', () => this.c.click(), { once: true });") - mainSession.synthesizeTap(1, 1) + mainSession.notifyUserGestureActivation() + mainSession.evaluateJS("document.getElementById('colorexample').showPicker()") assertThat( "Value should match", @@ -844,23 +843,15 @@ class PromptDelegateTest : BaseSessionTest( ) } - @Ignore("https://bugzilla.mozilla.org/show_bug.cgi?id=1988041") @WithDisplay(width = 100, height = 100) @Test fun dateTest() { mainSession.loadTestPath(PROMPT_HTML_PATH) mainSession.waitForPageStop() - mainSession.evaluateJS( - """ - document.documentElement.style.paddingTop = "50px"; - document.addEventListener("click", () => { - document.getElementById('dateexample').showPicker(); - }); - """.trimIndent(), - ) + mainSession.notifyUserGestureActivation() + mainSession.evaluateJS("document.getElementById('dateexample').showPicker()") - mainSession.synthesizeTap(1, 1) // Provides user activation. sessionRule.waitUntilCalled(object : PromptDelegate { @AssertCalled(count = 1) override fun onDateTimePrompt(session: GeckoSession, prompt: PromptDelegate.DateTimePrompt): GeckoResult<PromptDelegate.PromptResponse> { @@ -1101,8 +1092,8 @@ class PromptDelegateTest : BaseSessionTest( mainSession.loadTestPath(PROMPT_HTML_PATH) mainSession.waitForPageStop() - mainSession.evaluateJS("document.addEventListener('click', () => document.getElementById('fileexample').click(), { once: true });") - mainSession.synthesizeTap(1, 1) + mainSession.notifyUserGestureActivation() + mainSession.evaluateJS("document.getElementById('fileexample').showPicker()") sessionRule.waitUntilCalled(object : PromptDelegate { @AssertCalled(count = 1) @@ -1125,8 +1116,8 @@ class PromptDelegateTest : BaseSessionTest( mainSession.loadTestPath(PROMPT_HTML_PATH) mainSession.waitForPageStop() - mainSession.evaluateJS("document.addEventListener('click', () => document.getElementById('filemultipleexample').click(), { once: true });") - mainSession.synthesizeTap(1, 1) + mainSession.notifyUserGestureActivation() + mainSession.evaluateJS("document.getElementById('filemultipleexample').showPicker()") sessionRule.waitUntilCalled(object : PromptDelegate { @AssertCalled(count = 1) @@ -1167,8 +1158,8 @@ class PromptDelegateTest : BaseSessionTest( } }) - mainSession.evaluateJS("document.addEventListener('click', () => document.getElementById('direxample').click(), { once: true });") - mainSession.synthesizeTap(1, 1) + mainSession.notifyUserGestureActivation() + mainSession.evaluateJS("document.getElementById('direxample').showPicker()") sessionRule.waitUntilCalled(object : PromptDelegate { @AssertCalled(count = 1) diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java @@ -2829,6 +2829,11 @@ public class GeckoSessionTestRule implements TestRule { return (Boolean) webExtensionApiCall("IsFissionRunning", null); } + /** Simulate user gesture activation */ + public void notifyUserGestureActivation(final GeckoSession session) { + webExtensionApiCall(session, "NotifyUserGestureActivation", null); + } + /** * Gets all the permission names defined in the WebExtensions API JSONSchema given an array of * type names.