import { fireEvent, render, screen, waitFor } from '@testing-library/react' import { SWRConfig } from 'swr' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { AgentViewPage } from '../src/pages/AgentViewPage' import { browse } from '../src/api/browse' import type { Snapshot } from '../src/api/browse' /* Page-level wiring: the api module is mocked, everything else (SWR, the markdown renderer, tabs, the ?url= loop) is real. */ vi.mock('../src/api/browse', () => ({ browse: vi.fn(), })) const browseMock = vi.mocked(browse) function snapshot(overrides: Partial = {}): Snapshot { return { requestedUrl: 'https://example.test', finalUrl: 'https://example.test/', status: 200, contentType: 'text/html; charset=utf-8', durationMs: 210, fetchedAt: '2026-09-16T10:00:00Z', page: { title: 'Example Site', description: 'An example.', canonical: '', robotsMeta: '', lang: 'en', h1: 'Welcome', linkCount: 1, deadLinks: 0, scriptCount: 1, imageCount: 0, wordCount: 12, textLength: 80, }, markdown: '# Welcome\n\nRead the [docs](https://example.test/docs).', markdownTruncated: false, files: { llmsTxt: { url: 'https://example.test/llms.txt', status: 200, contentType: 'text/markdown', content: '# Example Site\n\n## Docs\n\n- [Guide](https://example.test/guide): the guide\n', truncated: false, llmsDoc: { title: 'Example Site', description: '', sections: [ { heading: 'Docs', description: '', links: [{ title: 'Guide', url: 'https://example.test/guide', description: 'the guide' }], }, ], linkCount: 1, }, }, llmsFullTxt: null, wellKnownLlmsTxt: null, robotsTxt: { url: 'https://example.test/robots.txt', status: 200, contentType: 'text/plain', content: 'User-agent: *\nAllow: /\n', truncated: false, }, }, checks: [ { id: 'page.status', label: 'Page reachable', severity: 'ok', detail: '200 OK' }, { id: 'llms.txt', label: '/llms.txt', severity: 'ok', detail: 'found' }, { id: 'page.description', label: 'Meta description', severity: 'warn', detail: 'thin' }, ], ...overrides, } } function renderPage() { return render( new Map(), dedupingInterval: 0 }}> , ) } beforeEach(() => { window.history.replaceState(null, '', '/') browseMock.mockReset() }) afterEach(() => { vi.clearAllMocks() }) describe('AgentViewPage', () => { it('stays on the explainer until a domain is submitted', () => { browseMock.mockResolvedValue(snapshot()) renderPage() expect(screen.getByText(/What does your site look like to an LLM/i)).toBeInTheDocument() expect(browseMock).not.toHaveBeenCalled() }) it('fetches the domain and renders the markdown with live links', async () => { browseMock.mockResolvedValue(snapshot()) renderPage() fireEvent.change(screen.getByLabelText(/domain or url/i), { target: { value: 'example.test' } }) fireEvent.click(screen.getByRole('button', { name: /view as agent/i })) await waitFor(() => expect(browseMock).toHaveBeenCalledWith('example.test')) expect(await screen.findByRole('heading', { level: 1, name: 'Welcome' })).toBeInTheDocument() const link = screen.getByRole('link', { name: 'docs' }) expect(link).toHaveAttribute('href', 'https://example.test/docs') expect(screen.getByText(/210 ms/i)).toBeInTheDocument() }) it('re-enters the viewer when a markdown link is clicked', async () => { browseMock.mockResolvedValue(snapshot()) renderPage() fireEvent.change(screen.getByLabelText(/domain or url/i), { target: { value: 'example.test' } }) fireEvent.click(screen.getByRole('button', { name: /view as agent/i })) fireEvent.click(await screen.findByRole('link', { name: 'docs' })) await waitFor(() => expect(browseMock).toHaveBeenCalledWith('https://example.test/docs')) }) it('shows the parsed llms.txt and the checks', async () => { browseMock.mockResolvedValue(snapshot()) renderPage() fireEvent.change(screen.getByLabelText(/domain or url/i), { target: { value: 'example.test' } }) fireEvent.click(screen.getByRole('button', { name: /view as agent/i })) fireEvent.click(await screen.findByRole('tab', { name: /llms\.txt/i })) expect((await screen.findAllByText('Example Site')).length).toBeGreaterThan(0) expect(screen.getByText('Guide')).toBeInTheDocument() fireEvent.click(screen.getByRole('tab', { name: /checks/i })) expect(await screen.findByText('Page reachable')).toBeInTheDocument() expect(screen.getByText(/warnings/)).toBeInTheDocument() }) it('surfaces fetch failures with a retry', async () => { browseMock.mockRejectedValue( new (await import('../src/api/client')).ApiError(502, 'unavailable', 'could not fetch https://down.test/'), ) renderPage() fireEvent.change(screen.getByLabelText(/domain or url/i), { target: { value: 'down.test' } }) fireEvent.click(screen.getByRole('button', { name: /view as agent/i })) expect(await screen.findByText(/the site did not answer/i)).toBeInTheDocument() fireEvent.click(screen.getByRole('button', { name: /try again/i })) await waitFor(() => expect(browseMock).toHaveBeenCalledTimes(2)) }) })