A real Obsidian, not a mock
Tests run against a live Obsidian process, so they exercise the real App, the real vault, the real
workspace — including the internal APIs no mock reproduces.
A real Obsidian, not a mock
Tests run against a live Obsidian process, so they exercise the real App, the real vault, the real
workspace — including the internal APIs no mock reproduces.
Isolated by default
The harness launches and owns a throwaway Obsidian in its own --user-data-dir. Your config, your
vault registry and your running window are never touched.
Desktop and Android
The same test code runs over CDP against Obsidian Desktop and over Appium against Obsidian Mobile
on an Android emulator or device.
Vitest and Jest
Ready-made global setups for both runners, plus a manual path for tools that are not plugins at all.
Trusted user input
Type, press keys and hover through Chromium’s real input pipeline, so focus and :hover behave the
way they do for a human — no isTrusted: false false positives.
Version pinning
Pin the app version, the installer shell, or run the whole suite across the supported range with
runObsidianVersionMatrix.
Getting started
Install the package and write your first test against a real Obsidian.
Writing tests
How evalInObsidian works — arguments, results, context, internal APIs.
Simulating user input
Trusted keyboard and pointer input, and waiting for the effect to settle.
The lib bag
Share helpers with your callbacks instead of hand-rolling them in every closure.
Vaults and fixtures
Transport modes
The owned CDP instance — version pinning, visibility, attaching.
Android testing
Obsidian Mobile over Appium, including the AVD provisioning that decides whether your runs are stable.
Version matrix
Run the suites across the supported version range without double-running a converged one.
Leftover cleanup
What a dead run leaks, and how the sweeps deal with it.
Ad-hoc debugging
connectToCdp and the CLI for reproducing behavior outside a test run.