diff --git a/mobile/src/browser/use-mobile-browser-commands-click-fallback.test.tsx b/mobile/src/browser/use-mobile-browser-commands-click-fallback.test.tsx index 1159c529400..2fec0fb223c 100644 --- a/mobile/src/browser/use-mobile-browser-commands-click-fallback.test.tsx +++ b/mobile/src/browser/use-mobile-browser-commands-click-fallback.test.tsx @@ -11,17 +11,21 @@ import type { RpcClient } from '../transport/rpc-client' import { useMobileBrowserCommands } from './use-mobile-browser-commands' import { useMobileBrowserRequest } from './use-mobile-browser-request' -const { sent, clickFailure } = vi.hoisted(() => { +const { sent, clickFailure, clickReply } = vi.hoisted(() => { const failure: { current: Error | null } = { current: null } - return { sent: new Array(), clickFailure: failure } + const reply: { current: unknown } = { current: {} } + return { sent: new Array(), clickFailure: failure, clickReply: reply } }) vi.mock('./mobile-browser-command-operations', () => { const command = (method: string) => ({ request: vi.fn(async () => { sent.push(method) - if (method === 'browser.mouseClick' && clickFailure.current) { - throw clickFailure.current + if (method === 'browser.mouseClick') { + if (clickFailure.current) { + throw clickFailure.current + } + return clickReply.current } return {} }), @@ -85,6 +89,7 @@ describe('tap fallback', () => { beforeEach(() => { sent.length = 0 clickFailure.current = null + clickReply.current = {} }) it('does not replay a click whose delivery is unknown', async () => { @@ -100,6 +105,18 @@ describe('tap fallback', () => { expect(sent).toEqual(['browser.mouseClick']) }) + // The external-Chromium provider answers a delivered click with agent-browser's `data`, which can be null. + it('does not replay a click the host answered, whatever the answer', async () => { + clickReply.current = null + const commands = mountCommands() + + await act(async () => { + await commands.sendPointerClick({ x: 10, y: 20 }, 'right') + }) + + expect(sent).toEqual(['browser.mouseClick']) + }) + it('replays a click the host refused as move, down and up', async () => { clickFailure.current = new Error('Unknown method: browser.mouseClick') const commands = mountCommands() diff --git a/mobile/src/browser/use-mobile-browser-commands.ts b/mobile/src/browser/use-mobile-browser-commands.ts index 46a7b0d42f5..0881688622d 100644 --- a/mobile/src/browser/use-mobile-browser-commands.ts +++ b/mobile/src/browser/use-mobile-browser-commands.ts @@ -119,7 +119,7 @@ export function useMobileBrowserCommands(args: MobileBrowserCommandArgs) { return } try { - const reply = browserPointerClick.interpret( + browserPointerClick.interpret( await browserPointerClick.request( client, { @@ -143,18 +143,13 @@ export function useMobileBrowserCommands(args: MobileBrowserCommandArgs) { ) ) setError(null) - if (reply !== null) { - return - } + return } catch (error) { // Why: a timed-out click may still run on the host; replaying it as move/down/up double-taps. - if (isRpcDeliveryUnknown(error)) { + if (isRpcDeliveryUnknown(error) || pointerModifiers.length > 0) { return } } - if (pointerModifiers.length > 0) { - return - } try { const moveReply = await browserPointerMove.request(client, { ...base,