import { test, expect } from '@playwright/test' import { signIn, OWNER_EMAIL } from './lib/auth.js' import { dismissCookies } from './lib/ui.js' // §22.4a Configurable Collection Metadata — end-to-end browser coverage for the // three UI slices, against the Tier-1 stack's faceted `bdd` collection (seeded // in testing/seed-gitea.sh with a fields: schema of priority(enum) + tags, and // three entries: checkout-guest [P0], checkout-returning [P1], search-facets [P0]). // // Tests run in order against a freshly-seeded stack: SLICE-3 reads first, then // SLICE-4 edits `checkout-returning`, then SLICE-5 bulk-edits the two P0 entries // (distinct rows — no cross-test interference within one run). const BDD = '/p/ohm/c/bdd' // SLICE-3 (PUC-3) — faceted left-pane filtering, anonymous/read-only. test('SLICE-3: faceted filter narrows the catalog by Priority', async ({ page }) => { await page.goto(BDD) await dismissCookies(page) const catalog = page.locator('aside.catalog') // All three entries are listed initially. await expect(catalog.getByText('Guest checkout')).toBeVisible() await expect(catalog.getByText('Returning-customer checkout')).toBeVisible() await expect(catalog.getByText('Faceted search')).toBeVisible() // The Priority facet renders with the seeded P0 count (2 entries). const p0 = catalog.locator('.facet-value', { hasText: 'P0' }) await expect(p0.locator('.facet-count')).toHaveText('2') // Selecting P0 re-fetches server-side and drops the lone P1 entry. await p0.getByRole('checkbox').check() await expect(catalog.getByText('Returning-customer checkout')).toHaveCount(0) await expect(catalog.getByText('Guest checkout')).toBeVisible() await expect(catalog.getByText('Faceted search')).toBeVisible() }) // SLICE-4 (PUC-1) — single-entry metadata edit via the detail panel (authed). test('SLICE-4: edit one entry\'s priority from the detail panel', async ({ page }) => { await signIn(page, OWNER_EMAIL) await page.goto(`${BDD}/e/checkout-returning`) await dismissCookies(page) const panel = page.locator('.metadata-fields-panel') await expect(panel).toBeVisible() // Seeded at P1; change to P2 and save (direct sidecar commit, D7). await expect(panel.locator('#mf-priority')).toHaveValue('P1') await panel.locator('#mf-priority').selectOption('P2') await panel.getByRole('button', { name: 'Save' }).click() await expect(panel.getByText('Saved')).toBeVisible() // Persisted across a reload (read back from the committed sidecar). await page.reload() await expect(page.locator('.metadata-fields-panel #mf-priority')).toHaveValue('P2') }) // SLICE-5 (PUC-2) — multi-select + bulk action bar, one commit (authed). test('SLICE-5: bulk-set priority on multiple selected entries', async ({ page }) => { await signIn(page, OWNER_EMAIL) await page.goto(BDD) await dismissCookies(page) const catalog = page.locator('aside.catalog') await expect(catalog.getByText('Guest checkout')).toBeVisible() // Select the two P0 entries. await catalog.getByLabel('select Guest checkout').check() await catalog.getByLabel('select Faceted search').check() // The sticky bulk bar appears with the selected count. const bar = page.locator('.bulk-action-bar') await expect(bar.getByText('2 selected')).toBeVisible() // Set priority P1 across both → one commit; a toast reports the result. await bar.getByLabel('Set Priority').selectOption('P1') await expect(page.getByText(/2 updated/)).toBeVisible() // The change is reflected server-side: the Priority P1 facet now counts the // two newly-updated entries plus the pre-existing P1 (checkout-returning was // P1 at seed; SLICE-4 may have moved it — assert at least the two we set). await expect(catalog.locator('.facet-value', { hasText: 'P1' }).locator('.facet-count')) .not.toHaveText('0') })