Files
hapi/e2e/file-md-preview.spec.ts
T
a82dd49049 feat(web): markdown Source | Preview toggle in session file pane (#957)
* feat(web): markdown Source | Preview toggle in session file pane

Add Source | Preview toggle for .md/.mdx files in the session file route,
defaulting to preview with localStorage persistence. Reuse chat markdown
pipeline via MarkdownRenderer standalone mode (no assistant-ui thread).

Includes unit tests, Playwright smoke, and e2e fixture.

Closes tiann/hapi#954

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): cast standalone MarkdownRenderer components for react-markdown

Soup verify gate: defaultComponents merge type is wider than
react-markdown Components; standalone file-pane path needs explicit cast.

* fix(web): route file-pane markdown fences through SyntaxHighlighter

Standalone file preview now mirrors chat code-block rendering: fenced
blocks use SyntaxHighlighter and MARKDOWN_COMPONENTS_BY_LANGUAGE (mermaid
included) without requiring ThreadPrimitive context.

Addresses HAPI Bot Major on tiann/hapi#957.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web): detect fenced vs inline code in standalone markdown preview

Move block detection to the pre override (react-markdown v10 does not pass
inline to custom code components). Add inline-code regression test.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 11:06:38 +08:00

34 lines
1.4 KiB
TypeScript

/*
* Playwright smoke for issue #954 — markdown Source | Preview toggle in
* the session file pane. Drives the Vite fixture that mounts the same
* MarkdownRenderer + toggle affordance as production `file.tsx`.
*/
import { test, expect } from '@playwright/test'
import path from 'node:path'
const SCREENSHOT_PATH = path.resolve(
process.env.HOME ?? '',
'coding/hapi/localdocs/playwright-runs/954-file-md-preview.png'
)
test.describe('file markdown preview e2e', () => {
test('preview renders heading and table; source shows raw markdown', async ({ page }) => {
await page.goto('/e2e-fixtures/file-md-preview-fixture.html')
await expect(page.getByTestId('file-md-preview-fixture')).toBeVisible()
await expect(page.getByRole('heading', { name: 'Teams and channels' })).toBeVisible()
await expect(page.getByRole('cell', { name: 'general' })).toBeVisible()
await expect(page.locator('.aui-md-codeblock')).toBeVisible()
await page.getByTestId('markdown-mode-source').click()
await expect(page.getByTestId('markdown-source-view')).toContainText('# Teams and channels')
await expect(page.getByRole('heading', { name: 'Teams and channels' })).toHaveCount(0)
await page.getByTestId('markdown-mode-preview').click()
await expect(page.getByRole('heading', { name: 'Teams and channels' })).toBeVisible()
await page.screenshot({ path: SCREENSHOT_PATH, fullPage: true })
})
})