goal-bar.e2e.ts 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Keyless assembled-browser coverage for the goal bar over the shipped Web
  2. // bundles and FixtureApiClient wire. The command creates a real projected
  3. // goal in the fixture session; the golden pins the active strip, while the
  4. // clear gesture proves the acknowledged tombstone leaves neither stale chrome
  5. // nor a duplicate-mutation error.
  6. import { fileURLToPath } from 'node:url'
  7. import { join } from 'node:path'
  8. import type { Browser, Page } from 'playwright'
  9. import { chromium } from 'playwright'
  10. import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest'
  11. import {
  12. assertFixtureInventory, captureStableAria, compareOrRefreshGolden,
  13. launchWebScaffold, watchConsole, webSnapshotMode, type WebScaffold,
  14. } from './scaffold.ts'
  15. import { newEnglishPage, saveFailureShot } from './support.ts'
  16. const SNAPSHOT_DIR = fileURLToPath(new URL('./snapshots/goal-bar', import.meta.url))
  17. const ACTIVE_EXPECTED = join(SNAPSHOT_DIR, 'active.expected.md')
  18. const OVERLAY = fileURLToPath(new URL('./goal-bar.overlay.yml', import.meta.url))
  19. const MODE = webSnapshotMode()
  20. describe('web e2e: goal bar clear convergence', () => {
  21. let scaffold: WebScaffold
  22. let browser: Browser
  23. let page: Page
  24. let tripwire: ReturnType<typeof watchConsole>
  25. beforeAll(async () => {
  26. scaffold = await launchWebScaffold({ extraOverlayPath: OVERLAY, welcomeNoticePending: true })
  27. browser = await chromium.launch()
  28. page = await newEnglishPage(browser)
  29. tripwire = watchConsole(page)
  30. await page.goto(`${scaffold.baseUrl}?fixture`, { waitUntil: 'load' })
  31. await page.waitForSelector('[class*="frame"]', { timeout: 30_000 })
  32. }, 120_000)
  33. afterAll(async () => {
  34. await browser?.close()
  35. await scaffold?.close()
  36. })
  37. it('renders one active goal and clears it without exposing a stale error', async () => {
  38. onTestFailed(() => saveFailureShot(page, 'web-e2e-goal-bar-clear'))
  39. // Startup reuses the fixture workspace's blank session, keeping this
  40. // command independent of alpha's running replay and pending question.
  41. const input = page.getByPlaceholder('Describe what you want to build')
  42. await input.waitFor({ timeout: 10_000 })
  43. await input.fill('/goal guard rapid clear clicks')
  44. await input.press('Enter')
  45. const bar = page.locator('[data-goal-bar]')
  46. await bar.waitFor({ timeout: 10_000 })
  47. const snapshot = await captureStableAria(page, '[data-goal-bar]', scaffold.workspaceCwd)
  48. await compareOrRefreshGolden(ACTIVE_EXPECTED, snapshot, MODE)
  49. const clear = bar.getByRole('button', { name: 'Clear goal' })
  50. await clear.evaluate((button) => {
  51. const control = button as HTMLButtonElement
  52. control.click()
  53. control.click()
  54. })
  55. await expect.poll(() => page.locator('[data-goal-bar]').count(), { timeout: 10_000 }).toBe(0)
  56. expect(await page.getByText(/no current goal/iu).count()).toBe(0)
  57. expect(tripwire.pageErrors).toEqual([])
  58. expect(tripwire.warnings).toEqual([])
  59. }, 60_000)
  60. it.skipIf(MODE === 'record')('keeps the fixture inventory closed', async () => {
  61. await assertFixtureInventory(SNAPSHOT_DIR, ['active.expected.md'])
  62. })
  63. })