import { dirname, join } from 'node:path' 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') // Opt-in only (GITEA_LIVE=1). Launches WITHOUT COMMITEA_E2E so the main process // reconciles the real repo via .env.local, and asserts real data renders. test.describe('live backlog', () => { test('The pot + Focus render real gitea data', async () => { test.skip(!process.env.GITEA_LIVE, 'GITEA_LIVE not set — opt-in live test') const app = await electron.launch({ args: [MAIN], env: { ...process.env } }) const win = await app.firstWindow() await win.waitForLoadState('domcontentloaded') const rail = win.getByRole('navigation', { name: 'Primary' }) // The pot — waiting here also lets the reconcile (issues + deps) complete await rail.getByRole('button', { name: 'The pot' }).click() await expect(win.getByText('Gitea read client behind an injected fetch')).toBeVisible({ timeout: 20000 }) await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-board.png'), fullPage: true, animations: 'disabled' }) // Back to Focus — the deterministic scheduler's real Now/Next/Later. These // rationale phrases are emitted only by the scheduler, never by the demo fixture. await rail.getByRole('button', { name: 'Morning service' }).click() await expect(win.getByText(/on the critical path|unblocks #|waits on #|· ready/).first()).toBeVisible() // Real Monte Carlo cone — this headline is emitted only for real forecasts. await expect(win.getByText(/80% of the open backlog lands by/)).toBeVisible() await expect(win.getByText(/Cold-start priors/)).toBeVisible() await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-focus.png'), fullPage: true, animations: 'disabled' }) await app.close() }) })