import { test, expect } from '@playwright/test'; import { _electron as electron } from 'playwright'; import { promises as fs } from 'node:fs'; import nodePath from 'node:path'; import os from 'node:os'; const MAIN_JS = nodePath.join(process.cwd(), 'dist-electron/main/index.js'); async function launchApp() { const tmp = await fs.mkdtemp(nodePath.join(os.tmpdir(), 'hn-e2e-')); const userData = nodePath.join(tmp, 'userdata'); const vault = nodePath.join(tmp, 'vault'); await fs.mkdir(userData, { recursive: true }); await fs.mkdir(vault, { recursive: true }); // 预置 config,让 app 直接用临时库(FR-V 隔离) await fs.writeFile( nodePath.join(userData, 'config.json'), JSON.stringify({ vault: { currentRoot: vault, recents: [vault], defaultRoot: vault } }), 'utf8', ); const app = await electron.launch({ args: ['--user-data-dir=' + userData, MAIN_JS] }); return { app, tmp, vault }; } test('app launches and renders title bar', async () => { const { app, tmp } = await launchApp(); try { const page = await app.firstWindow(); await page.waitForLoadState('domcontentloaded'); await expect(page.getByText('狩夜人笔记').first()).toBeVisible(); const shot = nodePath.join(tmp, 'smoke.png'); await page.screenshot({ path: shot }); console.log('SHOT=' + shot); } finally { await app.close(); } });