import { test, expect } from './lib/fixtures.js' import { signIn, OWNER_EMAIL } from './lib/auth.js' import { dismissCookies } from './lib/ui.js' // §8.12 Option B — asking-while-reading on the canonical `main` view. // // Before this fix, the AI "Ask" affordance had no chat surface on main (the // human-discussion panel renders there, not the chat panel), so asking from the // reading view silently did nothing. Option B transparently cuts an edit branch, // navigates to it, and runs the question there. // // This spec asserts the model-independent core: the branch cut + navigation // (old code did NOTHING here — the silent no-op), and that the question turn // actually FIRED against the branch. The turn's outcome is environment-specific // — PPE/prod (a model is configured) streams an answer and the optimistic // question persists; the Tier-1 stack has no AI provider, so the turn errors // with "Chat failed". Either outcome proves the turn fired; we match both so the // one spec passes in both environments. The quote-passthrough + answer rendering // are covered deterministically by the RFCView unit tests (model mocked). // // Driven through the prompt bar, which shares handlePrompt → handleMainAsk with // the selection tooltip's onAsk. Runs against the faceted `bdd` collection entry // (collection-scoped — the same three-tier path G-15 hardened). const ENTRY = '/p/ohm/c/bdd/e/checkout-returning' test('Ask from the canonical view cuts an edit branch and lands the question in chat', async ({ page }) => { await signIn(page, OWNER_EMAIL) await page.goto(ENTRY) await dismissCookies(page) // We start on the canonical (main) view: read-only, no chat surface — the // discuss-mode banner is the canonical-view tell, and the URL has no branch. await expect(page.locator('.discuss-mode-banner')).toContainText('read-only') expect(new URL(page.url()).searchParams.get('branch')).toBeNull() // Ask a question from the prompt bar. const question = `What problem does this entry solve? (${Date.now()})` await page.locator('.prompt-input').fill(question) await page.getByRole('button', { name: 'Ask', exact: true }).click() // Option B: an edit branch is cut and we navigate onto it (no silent no-op). await expect(async () => { expect(new URL(page.url()).searchParams.get('branch')).toMatch(/^edit/) }).toPass({ timeout: 30_000 }) // The question turn fired against the new branch: either the optimistic // question is showing (model answered / answering) or the turn surfaced a // chat error (no AI provider in Tier-1). Both prove it ran — the pre-fix // silent no-op showed neither. await expect( page.getByText(question).or(page.getByText(/Chat failed|No AI providers/i)), ).toBeVisible({ timeout: 30_000 }) })