WIP: Add test

This commit is contained in:
vorotamoroz
2026-05-14 16:06:17 +01:00
parent 02580b2cad
commit bba0a27735
9 changed files with 268 additions and 98 deletions
+59 -3
View File
@@ -1,3 +1,8 @@
/* eslint-disable obsidianmd/prefer-window-timers */
// This file is a test helper and is allowed to use Node.js modules.
/* eslint-disable obsidianmd/hardcoded-config-path */
// This file is a test helper and is allowed to use Node.js modules.
/* eslint-disable import/no-nodejs-modules */
/**
* helpers/vault.ts
*
@@ -24,6 +29,7 @@ import path from "node:path";
import os from "node:os";
/** Absolute path to the repository root (two levels above helpers/). */
// eslint-disable-next-line no-undef
const REPO_ROOT = path.resolve(__dirname, "../..");
export interface VaultSetupResult {
@@ -38,6 +44,15 @@ export interface VaultSetupResult {
cleanup: () => void;
}
export interface VaultSettingsOptions {
/** Optional custom app.json content under <vault>/.obsidian/app.json */
appJson?: Record<string, unknown>;
/** Community plugin IDs to mark as enabled. */
communityPlugins?: string[];
/** Per-plugin configuration keyed by plugin ID. */
pluginData?: Record<string, unknown>;
}
/**
* Creates a throw-away vault with the built plugin pre-installed and
* registered in an isolated Obsidian configuration directory.
@@ -45,6 +60,16 @@ export interface VaultSetupResult {
* Call `cleanup()` (or use `test.afterAll`) to delete the temporary files.
*/
export function setupTestVault(): VaultSetupResult {
return setupTestVaultWithSettings({});
}
/**
* Creates a throw-away vault with optional initial Obsidian/plugin settings.
*
* This helper is intended for real-Obsidian e2e tests that need to open a
* vault in a known configuration state.
*/
export function setupTestVaultWithSettings(options: VaultSettingsOptions = {}): VaultSetupResult {
const id = randomBytes(4).toString("hex");
const baseDir = path.join(os.tmpdir(), `livesync-e2e-${id}`);
const fakeAppData = baseDir;
@@ -66,15 +91,29 @@ export function setupTestVault(): VaultSetupResult {
}
// Disable Obsidian safe mode so community plugins are allowed to load.
writeFileSync(path.join(dotObsidian, "app.json"), JSON.stringify({ promptDelete: false }, null, 2), "utf-8");
writeFileSync(
path.join(dotObsidian, "app.json"),
JSON.stringify({ promptDelete: false, ...(options.appJson ?? {}) }, null, 2),
"utf-8"
);
// Tell Obsidian which community plugins are enabled.
writeFileSync(
path.join(dotObsidian, "community-plugins.json"),
JSON.stringify(["obsidian-livesync"], null, 2),
// JSON.stringify(options.communityPlugins ?? ["obsidian-livesync"], null, 2),
// You should enable the plugin(s) explicitly
JSON.stringify(options.communityPlugins ?? [], null, 2),
"utf-8"
);
if (options.pluginData) {
for (const [pluginId, value] of Object.entries(options.pluginData)) {
const target = path.join(dotObsidian, "plugins", pluginId, "data.json");
mkdirSync(path.dirname(target), { recursive: true });
writeFileSync(target, JSON.stringify(value, null, 2), "utf-8");
}
}
// ------------------------------------------------ Obsidian global config
// With --user-data-dir=<fakeAppData>, Obsidian reads its vault registry
// directly from <fakeAppData>/obsidian.json.
@@ -104,6 +143,23 @@ export function setupTestVault(): VaultSetupResult {
return {
vaultDir,
fakeAppData,
cleanup: () => rmSync(baseDir, { recursive: true, force: true }),
cleanup: () =>
void (async () => {
for (let attempt = 1; attempt <= 5; attempt++) {
try {
rmSync(baseDir, { recursive: true, force: true });
console.log(`[vault cleanup] Successfully removed temporary directory: ${baseDir}`);
return;
} catch {
console.warn(
`[vault cleanup] Attempt ${attempt} failed to remove temporary directory: ${baseDir}`
);
await new Promise((resolve) => setTimeout(resolve, 500 * attempt));
}
}
console.error(
`[vault cleanup] Failed to remove temporary directory after multiple attempts: ${baseDir}`
);
})(),
};
}