fix(e2e): rebuild better-sqlite3 per ABI + select inbox window by title
- Vitest needs the node-ABI prebuilt sqlite binary; Electron 41 needs ABI 145. Add `rebuild:node` / `rebuild:electron` scripts and wire them as pre-hooks for `test`, `test:e2e`, `start`, `dev`, `test:integration`. - Smoke test was racing on `firstWindow()`, which non-deterministically returned the quickcapture window. Strip ELECTRON_RUN_AS_NODE from the launch env, wait for both windows to register, then pick the inbox by title and assert the heading via `getByRole`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,13 @@
|
||||
"dev": "electron-vite dev",
|
||||
"build": "electron-vite build",
|
||||
"start": "electron-vite preview",
|
||||
"rebuild:node": "cd node_modules/better-sqlite3 && prebuild-install",
|
||||
"rebuild:electron": "cd node_modules/better-sqlite3 && prebuild-install --runtime=electron --target=41.3.0",
|
||||
"pretest": "npm run rebuild:node",
|
||||
"pretest:integration": "npm run rebuild:node",
|
||||
"pretest:e2e": "npm run rebuild:electron && npm run build",
|
||||
"prestart": "npm run rebuild:electron",
|
||||
"predev": "npm run rebuild:electron",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"test:integration": "INKLING_INTEGRATION=1 vitest run tests/integration",
|
||||
|
||||
@@ -2,13 +2,30 @@ import { test, expect, _electron as electron } from '@playwright/test';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
test('inbox shell shows v0.2 empty state', async () => {
|
||||
// Strip ELECTRON_RUN_AS_NODE if it leaked in from the parent process
|
||||
// (some harnesses set it for native-module rebuild and forget to clear it).
|
||||
// When set, Electron's main-process module hook is skipped and require('electron')
|
||||
// returns only the binary path, so app.whenReady is undefined.
|
||||
const env: Record<string, string> = {};
|
||||
for (const [k, v] of Object.entries(process.env)) {
|
||||
if (k === 'ELECTRON_RUN_AS_NODE') continue;
|
||||
if (typeof v === 'string') env[k] = v;
|
||||
}
|
||||
env.INKLING_DEBUG = '1';
|
||||
const app = await electron.launch({
|
||||
args: [resolve('out/main/index.js')],
|
||||
env: { ...process.env, INKLING_DEBUG: '1' }
|
||||
env
|
||||
});
|
||||
const inbox = await app.firstWindow();
|
||||
await inbox.waitForLoadState('domcontentloaded');
|
||||
await expect(inbox.getByText('Inkling')).toBeVisible();
|
||||
const first = await app.firstWindow();
|
||||
// Both the inbox and quickcapture windows are created at startup;
|
||||
// firstWindow() may pick either, so select by title.
|
||||
await new Promise((r) => setTimeout(r, 500));
|
||||
let inbox = first;
|
||||
for (const w of app.windows()) {
|
||||
if ((await w.title()) === 'Inkling') { inbox = w; break; }
|
||||
}
|
||||
await inbox.waitForLoadState('load');
|
||||
await expect(inbox.getByRole('heading', { name: 'Inkling' })).toBeVisible();
|
||||
await expect(inbox.getByText('첫 기억을 구출해보세요.')).toBeVisible();
|
||||
await app.close();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user