test(electron): smoke test as the regression gate for the desktop shell
Phase 1 step 2 of VNCprodbuild. e2e/electron-smoke.spec.ts uses Playwright's
_electron.launch() to boot the real skeleton (dist-electron/main.js from
step 1) and asserts:
- the login screen renders (same input[type="text"]/[type="password"]
selectors as e2e/login.spec.ts's browser-based check)
- zero uncaught page errors fire during load
Sets JMAP_SERVER_URL (any non-empty value) so the app reaches
lib/setup/state.ts's "env-managed" state and serves the normal login screen
instead of 302ing to the first-run /setup wizard - no live mail server or
mock JMAP build flag needed just to prove the shell renders.
playwright.electron.config.ts is deliberately separate from
playwright.config.ts: it has no `webServer` block, since this suite's app
boots its own server and would otherwise race pointlessly with `npm run dev`
starting on :3000 for the browser-based e2e/*.spec.ts suite.
Wired as `npm run test:electron`. Verified green locally (2 passed) after
`npm run build:standalone && npm run build:electron`; every later step in
the Electron rollout must keep this passing before moving on.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { test, expect, _electron as electron } from '@playwright/test';
|
||||
import type { ElectronApplication, Page } from '@playwright/test';
|
||||
import path from 'node:path';
|
||||
|
||||
// Regression gate for the Electron desktop shell (electron/main.ts +
|
||||
// electron/preload.ts). Launches the real skeleton - the same standalone
|
||||
// Next.js server artifact the Dockerfile produces, booted as a child
|
||||
// process by main.ts, with a real BrowserWindow on top - and asserts the
|
||||
// login screen renders with zero uncaught page errors. Every later step in
|
||||
// the Electron rollout (notification bridge, realtime sync, packaging) must
|
||||
// keep this green; run it before touching anything else.
|
||||
//
|
||||
// Requires `npm run build:standalone && npm run build:electron` to have run
|
||||
// first (see package.json's `electron:dev`/`test:electron` scripts, which
|
||||
// this suite assumes but does not itself trigger, matching how
|
||||
// playwright.config.ts's browser suite assumes `npm run build` for its own
|
||||
// prod-mode runs).
|
||||
const projectRoot = path.resolve(__dirname, '..');
|
||||
|
||||
test.describe('Electron desktop shell', () => {
|
||||
let electronApp: ElectronApplication;
|
||||
let window: Page;
|
||||
const pageErrors: Error[] = [];
|
||||
|
||||
test.beforeAll(async () => {
|
||||
electronApp = await electron.launch({
|
||||
args: [projectRoot],
|
||||
env: {
|
||||
...process.env,
|
||||
// Bypass the first-run setup wizard (lib/setup/state.ts's
|
||||
// "bootstrap" state, which 302s everything to /setup) without
|
||||
// needing a reachable JMAP server just to prove the login screen
|
||||
// renders - any non-empty JMAP_SERVER_URL is enough to reach
|
||||
// "env-managed" state and serve the normal app shell.
|
||||
JMAP_SERVER_URL: 'https://stalwart.sandbox.vnc.de',
|
||||
SESSION_SECRET: 'electron-smoke-test-not-for-production',
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
});
|
||||
|
||||
window = await electronApp.firstWindow();
|
||||
window.on('pageerror', (error) => {
|
||||
pageErrors.push(error);
|
||||
});
|
||||
await window.waitForLoadState('domcontentloaded');
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await electronApp?.close();
|
||||
});
|
||||
|
||||
test('boots the standalone server and renders the login screen', async () => {
|
||||
// Same selectors as e2e/login.spec.ts's browser-based check - the
|
||||
// shell should render the identical login form, not a different view.
|
||||
await expect(window.locator('input[type="text"]')).toBeVisible({ timeout: 20000 });
|
||||
await expect(window.locator('input[type="password"]')).toBeVisible();
|
||||
});
|
||||
|
||||
test('produces zero uncaught page errors', () => {
|
||||
expect(pageErrors).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user