import { dirname, join } from 'node:path' import { mkdtempSync, readFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { fileURLToPath } from 'node:url' import { _electron as electron, expect, test } from '@playwright/test' const here = dirname(fileURLToPath(import.meta.url)) const MAIN = join(here, '..', 'out', 'main', 'index.js') /** Read the real token from .env.local (walking up) so the test can fill the form. */ function readToken(): string | null { let dir = here for (let i = 0; i < 6; i++) { try { const m = /^GITEA_TOKEN\s*=\s*(.+?)\s*$/m.exec(readFileSync(join(dir, '.env.local'), 'utf8')) if (m) return m[1].trim() } catch { /* keep walking */ } dir = dirname(dir) } return null } // Opt-in (GITEA_LIVE=1). Forces the onboarding path (COMMITEA_NO_ENV_LOCAL) with a // fresh userData, fills the real connection form, and asserts it lands on real data. test.describe('live onboarding', () => { test('connect form → real board', async () => { const token = process.env.GITEA_LIVE ? readToken() : null test.skip(!token, 'GITEA_LIVE + a .env.local token required') test.setTimeout(90_000) const app = await electron.launch({ args: [MAIN], env: { ...process.env, COMMITEA_NO_ENV_LOCAL: '1', COMMITEA_USERDATA: mkdtempSync(join(tmpdir(), 'commitea-')) }, }) const win = await app.firstWindow() await win.waitForLoadState('domcontentloaded') // the connection gate, not the app await expect(win.getByText(/Connect your Gitea/)).toBeVisible({ timeout: 15000 }) await win.getByPlaceholder('your-org').fill('christian') await win.getByPlaceholder('your-repo').fill('commitea') await win.getByPlaceholder(/gitea PAT/).fill(token!) await win.getByRole('button', { name: 'Connect' }).click() // it validated + saved + reconciled into the real board — real issue titles prove it const rail = win.getByRole('navigation', { name: 'Primary' }) await rail.getByRole('button', { name: 'The pot' }).click() await expect(win.getByText(/Model router|SQLite cache bootstrap|Purity\/rebuild/).first()).toBeVisible({ timeout: 30000 }) await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-onboarding.png'), fullPage: true, animations: 'disabled' }) await app.close() }) })