Skip to content

obsidian/mobile-trusted-input

Mobile-only trusted input helpers. There is no in-renderer route to a trusted event on a phone — webContents.sendInputEvent is Electron-only and a dispatched event is untrusted — so the injection has to be a round-trip: the request goes to the host over the obsidian-integration-testing harness’s binding channel, and the host injects it into the WebView over CDP.

That channel is installed by the harness’s Appium transport, so these helpers delegate to the harness rather than reimplementing the wire format: they call window.__obsidianIntegrationTesting.trustedInput.*, which holds the very function objects the harness seeds into an evalInObsidian closure’s lib bag. Delegating is what keeps the mobile semantics — tap, long-press for button: 'right', a throw for 'middle', the pressKey key set, and the throws for the :hover helpers — identical to the harness’s own copy for free, instead of a second implementation to hand-sync (see the project AGENTS.md L4).

The namespace shape is declared locally: the harness must never be a dependency of this library, in either direction, at runtime or in types.

Consequence, and it is deliberate: these helpers only work inside an app the harness bootstrapped. Outside one they throw a message saying so, rather than silently doing nothing — a no-op would recreate exactly the false-confidence failure trusted input exists to end. Consumers wanting the platform-correct helper should import the trusted-input facade instead of this module.

FunctionDescription
clickElementClicks the center of an element using trusted touch input — a CDP tap in the WebView, injected by the host. The element-relative counterpart of clickMouse. button: 'right' is the long-press that opens Obsidian Mobile’s context menu; 'middle' throws, because touch has no gesture for it and inventing one would be worse than saying so.
clickMouseClicks at the given viewport coordinates using trusted touch input, injected by the host over CDP. The coordinates are CSS pixels in the WebView’s own viewport — which is what CDP takes — so devicePixelRatio never enters the picture.
hoverElementAlways throws: :hover has no touch equivalent. A silent no-op here would let a hover test pass on a phone without hovering anything, so the mobile arm refuses instead. Gate the assertion on Platform.isDesktopApp, or drive the element with clickElement.
moveMouseAlways throws: a touch screen has no persistent pointer to move.
pressKeyPresses a single key using trusted keyboard input, injected by the host over CDP. Named keys ('Enter', 'Escape', 'Tab', 'Backspace', 'Delete', the arrows) and single printable characters are supported; anything else throws rather than pressing nothing.
typeIntoEditorTypes text into a CodeMirror editor using trusted keyboard input, injected by the host over CDP. Focuses the editor (caret to the end), presses every code point of the text, then polls until the document reflects the input or a bounded timeout elapses.
unhoverElementAlways throws, for the same reason as hoverElement: there is no :hover state to clear.