Real Obsidian E2E Runner
This directory contains the experimental real Obsidian end-to-end runner.
The current smoke runner verifies only the launch path:
- create a temporary vault,
- install the built Self-hosted LiveSync plug-in artifacts,
- launch real Obsidian,
- open the temporary vault through
obsidian-cli, - enable Obsidian community plug-ins for the temporary app profile,
- reload Self-hosted LiveSync through
obsidian-cli, - verify through
obsidian-cli evalthat the plug-in is loaded, - optionally drive a real vault or CouchDB workflow through Obsidian's own API,
- terminate Obsidian and remove the temporary vault.
The runner does not require Self-hosted LiveSync to expose an E2E-only bridge. Readiness is checked from outside the plug-in through Obsidian's own CLI.
Obsidian 1.12 stores the global community plug-in switch outside .obsidian/community-plugins.json. The smoke runner enables it through app.plugins.setEnable(true) after the vault window is available.
Future workflows should use startObsidianLiveSyncSession() from runner/session.ts rather than repeating the launch and plug-in readiness sequence.
Local Setup
Set OBSIDIAN_BINARY when Obsidian is not installed in a standard location.
For an AppImage on Linux without FUSE, use the helper script:
npm run test:e2e:obsidian:install-appimage
The script downloads Obsidian 1.12.7 for the current architecture, stores it in _testdata/obsidian, and extracts it to _testdata/obsidian/squashfs-root. The runner checks _testdata/obsidian/squashfs-root/obsidian before the AppImage path.
Do not download the AppImage on every CI run. Prefer one of these approaches:
- set
OBSIDIAN_BINARYto a pre-installed Obsidian executable, - restore
_testdata/obsidian/squashfs-rootfrom a CI cache, or - run
test:e2e:obsidian:install-appimageonly in a manually triggered preparation job.
Commands
npm run test:e2e:obsidian:install-appimage
npm run test:e2e:obsidian:discover
npm run test:e2e:obsidian:cli-help -- vaults verbose
npm run test:e2e:obsidian:smoke
npm run test:e2e:obsidian:vault-reflection
npm run test:e2e:obsidian:couchdb-upload
npm run test:e2e:obsidian:startup-scan
npm run test:e2e:obsidian:hidden-file-snippet-sync
npm run test:e2e:obsidian:setting-markdown-export
test:e2e:obsidian:couchdb-upload reuses the CouchDB variables from .test.env or the process environment. It expects a reachable CouchDB service, creates a unique database, configures Self-hosted LiveSync through obsidian-cli eval, creates a note in real Obsidian, commits the note into the local database, runs one-shot synchronisation, and verifies that the remote database contains both the metadata document and its chunk documents.
test:e2e:obsidian:startup-scan configures a temporary CouchDB database, stops Obsidian, writes a note directly into the vault, restarts Obsidian, and verifies from CouchDB that the boot-time scan picked up the offline file.
test:e2e:obsidian:hidden-file-snippet-sync runs a two-vault hidden file round-trip. It verifies creation and deletion of a real .obsidian/snippets/*.css file, automatic JSON conflict merging for a hidden file with the merged result propagated by a second synchronisation, manual JSON Resolve dialogue application through Obsidian's UI, and per-device target patterns where one vault ignores a hidden file that the other vault synchronises.
test:e2e:obsidian:setting-markdown-export enables setting Markdown export, waits for the generated Markdown file in the vault, and verifies that credentials are omitted when writeCredentialsForSettingSync=false.
Start the local CouchDB fixture first when one is not already running:
npm run test:docker-couchdb:start
Useful environment variables:
OBSIDIAN_BINARY: explicit Obsidian executable path.E2E_OBSIDIAN_VERSION: Obsidian AppImage version fortest:e2e:obsidian:install-appimage; default is1.12.7.E2E_OBSIDIAN_APPIMAGE_ARCH: AppImage architecture override, such asarm64orx86_64.E2E_OBSIDIAN_APPIMAGE_URL: explicit AppImage URL override.E2E_OBSIDIAN_DOWNLOAD_DIR: AppImage download and extraction directory; default is_testdata/obsidian.E2E_OBSIDIAN_FORCE_DOWNLOAD=true: re-download the AppImage even when it exists.E2E_OBSIDIAN_SKIP_EXTRACT=true: download the AppImage without extracting it.E2E_OBSIDIAN_SMOKE_TIMEOUT_MS: smoke timeout in milliseconds.E2E_OBSIDIAN_READY_TIMEOUT_MS: plug-in readiness timeout in milliseconds.E2E_OBSIDIAN_CLI_READY_TIMEOUT_MS: timeout for waiting until the vault-side Obsidian CLI exposes the plug-in catalogue.E2E_OBSIDIAN_CLI_TIMEOUT_MS: timeout for eachobsidian-cliinvocation.E2E_OBSIDIAN_FILE_TIMEOUT_MS: timeout for waiting until a note created through Obsidian's vault API is reflected to disk.E2E_OBSIDIAN_CORE_READY_TIMEOUT_MS: timeout for waiting until Self-hosted LiveSync reports that its core lifecycle and local database are ready.E2E_OBSIDIAN_LOCAL_DB_TIMEOUT_MS: timeout for waiting until a file appears in Self-hosted LiveSync's local database.E2E_OBSIDIAN_COUCHDB_TIMEOUT_MS: timeout for waiting until CouchDB contains uploaded E2E documents.E2E_OBSIDIAN_KEEP_COUCHDB=true: keep the temporary CouchDB database for inspection.E2E_OBSIDIAN_STARTUP_GRACE_MS: early process-exit detection window in milliseconds.E2E_OBSIDIAN_KEEP_VAULT=true: keep the temporary vault for inspection.E2E_OBSIDIAN_USE_XVFB=false: disable automaticxvfb-runon headless Linux.E2E_OBSIDIAN_ARGS: override the default Obsidian launch arguments.
On headless Linux, the runner automatically uses /usr/bin/xvfb-run when no DISPLAY or WAYLAND_DISPLAY is present.