140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
import { expect, test, type Page } from '@playwright/test'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import { createFixtureVaultCopy, openFixtureVault, removeFixtureVaultCopy } from '../helpers/fixtureVault'
|
|
import { executeCommand, openCommandPalette } from './helpers'
|
|
|
|
let tempVaultDir: string
|
|
|
|
const INLINE_LATEX = 'E=mc^2'
|
|
const DISPLAY_LATEX = '\\int_0^1 x^2 \\, dx = \\frac{1}{3}'
|
|
const MALFORMED_LATEX = '\\frac{'
|
|
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
testInfo.setTimeout(90_000)
|
|
tempVaultDir = createFixtureVaultCopy()
|
|
await openFixtureVault(page, tempVaultDir)
|
|
})
|
|
|
|
test.afterEach(async () => {
|
|
removeFixtureVaultCopy(tempVaultDir)
|
|
})
|
|
|
|
async function openNote(page: Page, title: string): Promise<void> {
|
|
await page.locator('[data-testid="note-list-container"]').getByText(title, { exact: true }).click()
|
|
await expect(page.locator('.bn-editor')).toBeVisible({ timeout: 5_000 })
|
|
}
|
|
|
|
async function toggleRawMode(page: Page, visibleSelector: '.bn-editor' | '.cm-content'): Promise<void> {
|
|
await openCommandPalette(page)
|
|
await executeCommand(page, 'Toggle Raw')
|
|
await expect(page.locator(visibleSelector)).toBeVisible({ timeout: 5_000 })
|
|
}
|
|
|
|
async function getRawEditorContent(page: Page): Promise<string> {
|
|
return page.evaluate(() => {
|
|
type CodeMirrorHost = Element & {
|
|
cmTile?: {
|
|
view?: {
|
|
state: {
|
|
doc: {
|
|
toString(): string
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const host = document.querySelector('.cm-content') as CodeMirrorHost | null
|
|
return host?.cmTile?.view?.state.doc.toString() ?? host?.textContent ?? ''
|
|
})
|
|
}
|
|
|
|
async function setRawEditorContent(page: Page, content: string): Promise<void> {
|
|
await page.evaluate((nextContent) => {
|
|
type CodeMirrorHost = Element & {
|
|
cmTile?: {
|
|
view?: {
|
|
state: {
|
|
doc: {
|
|
length: number
|
|
}
|
|
}
|
|
dispatch(update: {
|
|
changes: {
|
|
from: number
|
|
to: number
|
|
insert: string
|
|
}
|
|
}): void
|
|
}
|
|
}
|
|
}
|
|
|
|
const host = document.querySelector('.cm-content') as CodeMirrorHost | null
|
|
const view = host?.cmTile?.view
|
|
if (!view) return
|
|
|
|
view.dispatch({
|
|
changes: { from: 0, to: view.state.doc.length, insert: nextContent },
|
|
})
|
|
}, content)
|
|
}
|
|
|
|
async function expectMathNode(page: Page, selector: string, latex: string): Promise<void> {
|
|
await expect.poll(async () =>
|
|
page.locator(selector).evaluateAll((nodes, expectedLatex) =>
|
|
nodes.some((node) => node.getAttribute('data-latex') === expectedLatex),
|
|
latex),
|
|
).toBe(true)
|
|
}
|
|
|
|
function readNoteBFile(): string {
|
|
return fs.readFileSync(path.join(tempVaultDir, 'note', 'note-b.md'), 'utf8')
|
|
}
|
|
|
|
test('LaTeX math source round-trips through rich mode, save, and reopen @smoke', async ({ page }) => {
|
|
await openNote(page, 'Note B')
|
|
await toggleRawMode(page, '.cm-content')
|
|
|
|
const originalContent = await getRawEditorContent(page)
|
|
const nextContent = `${originalContent.trimEnd()}
|
|
|
|
Inline math $${INLINE_LATEX}$ stays in prose.
|
|
|
|
$$
|
|
${DISPLAY_LATEX}
|
|
$$
|
|
|
|
Malformed math $${MALFORMED_LATEX}$ stays visible.
|
|
`
|
|
|
|
await setRawEditorContent(page, nextContent)
|
|
|
|
await expect.poll(readNoteBFile).toContain(`$${INLINE_LATEX}$`)
|
|
await expect.poll(readNoteBFile).toContain(`$$\n${DISPLAY_LATEX}\n$$`)
|
|
|
|
await toggleRawMode(page, '.bn-editor')
|
|
|
|
await expectMathNode(page, '.math--inline', INLINE_LATEX)
|
|
await expectMathNode(page, '.math--block', DISPLAY_LATEX)
|
|
await expectMathNode(page, '.math--inline', MALFORMED_LATEX)
|
|
await expect(page.locator('.math .katex, .math .katex-error')).toHaveCount(3)
|
|
|
|
await toggleRawMode(page, '.cm-content')
|
|
const rawAfterRichMode = await getRawEditorContent(page)
|
|
expect(rawAfterRichMode).toContain(`$${INLINE_LATEX}$`)
|
|
expect(rawAfterRichMode).toContain(`$$\n${DISPLAY_LATEX}\n$$`)
|
|
expect(rawAfterRichMode).toContain(`$${MALFORMED_LATEX}$`)
|
|
|
|
await toggleRawMode(page, '.bn-editor')
|
|
await openNote(page, 'Note C')
|
|
await openNote(page, 'Note B')
|
|
await toggleRawMode(page, '.cm-content')
|
|
|
|
const reopenedRaw = await getRawEditorContent(page)
|
|
expect(reopenedRaw).toContain(`$${INLINE_LATEX}$`)
|
|
expect(reopenedRaw).toContain(`$$\n${DISPLAY_LATEX}\n$$`)
|
|
expect(reopenedRaw).toContain(`$${MALFORMED_LATEX}$`)
|
|
})
|