Skip to content

ObsidianCdpTransportOptions

Transport options for desktop testing via Chrome DevTools Protocol.

This is the default desktop transport. By default the harness launches and owns an isolated Obsidian instance in a temporary user-data dir (never touching the user’s Obsidian), connected over a free CDP port. Provide ObsidianCdpTransportOptions.port to instead attach to an already-running Obsidian.

Import:

import type { ObsidianCdpTransportOptions } from 'obsidian-integration-testing';

Signature:

export interface ObsidianCdpTransportOptions

Properties

PropertyTypeDescription
commandTimeoutInMilliseconds?numberTimeout in milliseconds for individual CDP commands.

A test's closure travels as one Runtime.evaluate command, so this is also the desktop per-eval cap. The default is DEFAULT_EVAL_CAP_IN_MILLISECONDS, exported from the package root — import it rather than restating the number, so a closure sized against the cap follows it if it ever moves.
configDirectory?stringThe vault's **config folder** — Obsidian's per-vault *Override config folder* setting, e.g. '.obsidian-desktop'. Must start with a dot, must not be the bare dot, and must not contain a path separator; anything else throws before Obsidian is launched, because Obsidian itself would silently substitute .obsidian.

Needed to open a vault that keeps its settings somewhere other than .obsidian — a vault with a stale .obsidian beside the real folder would otherwise open successfully against the wrong settings and report success. The override lives in localStorage, keyed by vault id, and so is scoped to a user-data directory: an owned instance gets a fresh temp one and therefore inherits nothing from the user's Obsidian, however that vault is configured there.

Setting it costs one extra boot phase: the instance is launched to the starter screen, the override is written in that renderer, and the vault is then opened over IPC. After the vault is ready its actual app.vault.configDir is read back and any mismatch throws ConfigDirectoryFallbackError — there is no knob to downgrade that, because a vault opened against the wrong config folder is silently the wrong vault.

Only meaningful in owned mode; **ignored in attach mode** (ObsidianCdpTransportOptions.port set), where the vault is opened by the user's own Obsidian under its own config.
deadBootGraceInMilliseconds?numberGrace window in milliseconds for fast-failing a **dead boot** of the owned instance.

When an asar cannot run on the launched Electron shell (the installer version is too old for the app version), the renderer loads but never bootstraps: document.body stays empty and window.app remains undefined — a black screen. Rather than waiting out the full readiness timeout, the owned-vault readiness poll concludes the boot is dead once the renderer has been document.readyState 'complete' for this long with no window.app and an empty <body>, and throws a RendererFailedToInitializeError. Only applies to an owned instance (ignored in attach mode, port set). Set 0 to disable fast-fail and restore the plain wait-out-the-readiness-timeout behavior.
host?stringCDP host. Defaults to 'localhost'
isHarnessOwnedInstance?boolean | undefinedMarks port as the CDP port of a **harness-owned, isolated instance** that the global setup already launched and prepared (vault registered, plugin enabled).

Populated automatically by the global setup and provided to test workers via the framework's context mechanism (e.g. Vitest provide/inject). When set, the worker **attaches** to the owned instance on port instead of launching its own, and skips the user-scope vault-registration preflight — the owned instance's vault lives in an isolated user-data config, not the user-scope registry. Do not set this manually; for plain attach mode use port alone.
isObsidianAppVisible?booleanWhether the owned desktop Obsidian window is shown on screen.

When false, the harness launches the owned instance with keep-alive Chromium flags and moves its window **off-screen** once Electron's remote bridge is available, so the run never steals focus or pops a window in front of you. Off-screen (not minimized) keeps the renderer live, so setTimeout, requestAnimationFrame, :hover, and trusted input behave identically to a visible window. Defaults to true; integration setup explicitly passes false to avoid stealing focus. Ignored in attach mode (port set) — the harness never moves the user's own running window.
leftoverMaxAgeInMilliseconds?numberHow old a leftover directory must be before shouldSweepLeftovers removes it.

The gate matters most on desktop: runs are deliberately **not** serialized (each owns an isolated instance), and every project on the machine shares one temp directory, so a young temp-vault-* / userdata-* directory may well belong to a run that is still in flight. Raise it if a run of yours can outlive the default; set 0 to remove every match regardless of age.
obsidianInstallerVersion?string | undefinedPins the **Electron shell** (installer build) the owned instance runs.

Accepts an explicit 'x.y.z', 'public-latest', or 'catalyst-latest'. The matching GitHub release installer is downloaded and extracted to a portable shell (cached for reuse). Public releases only — catalyst builds have no public installer. Ignored when port (attach mode) is set.
obsidianVersion?string | undefinedPins the **Obsidian app version** (asar) the owned instance runs.

Accepts an explicit 'x.y.z', 'public-latest', or 'catalyst-latest'. Versions at or above the shell version are applied as a cheap asar swap; older versions transparently use the matching installer shell. When omitted, the user's currently-installed version is used. Ignored when port (attach mode) is set.
port?numberCDP port of an already-running Obsidian to **attach** to (the --remote-debugging-port it was launched with). When set, the harness attaches instead of owning an instance, and the version knobs are ignored. When omitted, an owned isolated instance is launched on an automatically chosen free port (no port is hardcoded).
shouldDisableSandbox?booleanWhether to launch the owned instance with Chromium's sandbox disabled (--no-sandbox).

Needed to boot an owned instance on Linux when there is no correctly-configured setuid chrome-sandbox helper — e.g. a portable shell extracted from an installer, or a CI runner launching as a non-root user, in which case the renderer otherwise refuses to start. Harmless on Windows/macOS. Ignored in attach mode (port set) — the harness never relaunches the user's running instance.
shouldFailOnStaleBuild?booleanWhether a dist/ older than the sources it was built from fails the run.

When true (the default) the global setup compares main.js in the dist folder it is about to install against the newest file under src/ (tests excluded), plus manifest.json and styles.css, and throws StaleBuildError when the build is older — before the owned instance is launched, so a stale build costs a stat rather than a boot.

Set it to false for a project that deliberately tests a shipped artifact. Doing so downgrades the failure to a warning — it never goes silent, because a suite that PASSES against a stale build proves nothing and says so to nobody. For a single run, OBSIDIAN_TEST_ALLOW_STALE_BUILD=1 does the same without editing a tracked file, and takes precedence over this option.
shouldSweepLeftovers?booleanWhether the harness removes the temporary directories earlier runs leaked.

When true (the default), each run sweeps at start and at end for temp-vault-* staging directories and owned userdata-* instance profiles older than leftoverMaxAgeInMilliseconds. A run killed mid-flight never reaches its own cleanup, so without this the temp directory grows without bound.
shouldThrowOnIncompatibleInstaller?booleanWhether an **unrunnable** installer↔app version pair fails fast before launch.

When true (the default), an installer below the app's run floor (the oldest installer the app's asar can boot on) throws IncompatibleInstallerVersionError from version resolution, before anything is downloaded or launched. Set false to let the pin proceed to launch instead — where the reactive dead-boot fast-fail (RendererFailedToInitializeError, see deadBootGraceInMilliseconds) still catches the black-screen boot, and the 'unrunnable' verdict is surfaced as data rather than thrown. Only applies to an owned instance (ignored in attach mode, port set).
shouldThrowOnSilentAsarFallback?booleanWhether a **silent asar fallback** fails fast after boot.

When an asar is swapped onto an installer shell too old for it, the instance may not dead-boot — it can silently revert to the installer's own bundled asar and run the **wrong (older)** version behind a healthy UI. When true (the default), the transport verifies the running app version against the pin post-boot and throws SilentAsarFallbackError on a mismatch. Set false to let the boot proceed — the mismatch is then surfaced as data (the fallback verdict) rather than thrown. Only applies to an owned instance running a swapped-in asar (ignored in attach mode, port set, and when no asar is swapped — there is nothing to verify).
shouldWarnOnCompatibilityIssues?booleanWhether the owned-instance compatibility **nag warnings** are emitted.

Covers **both** compatibility nags: the offline installer↔app warning (a runnable installer below the recommended floor) and the post-boot runtime-Electron warning (a live Electron below the app's recommended minimum). When true (the default) each fires via the harness log; set false to silence both — the verdicts are still computed and surfaced as data (compatibility / electronCompatibility), only the log is suppressed. Does not affect the 'unrunnable' throw (see shouldThrowOnIncompatibleInstaller). Only applies to an owned instance (ignored in attach mode, port set).
type'obsidian-cdp'Discriminant for the transport type.

Links to this page: