Files
tolaria/tests/smoke/create-note-backing-file.spec.ts
2026-04-28 15:01:32 +02:00

115 lines
4.1 KiB
TypeScript

import fs from 'fs'
import { test, expect, type Page } from '@playwright/test'
import { createFixtureVaultCopy, openFixtureVaultTauri, removeFixtureVaultCopy } from '../helpers/fixtureVault'
import { triggerMenuCommand } from './testBridge'
interface CreateNoteProbe {
createCalls: string[]
getBeforeCreate: string[]
}
interface ProbeWindow {
__mockHandlers?: Record<string, (args?: unknown) => unknown>
__createNoteBackingFileProbe?: CreateNoteProbe
}
let tempVaultDir: string
async function pinFixtureHandlers(page: Page): Promise<void> {
await page.evaluate(() => {
const probeWindow = window as typeof window & ProbeWindow
const handlers = probeWindow.__mockHandlers
if (!handlers?.create_note_content || !handlers.get_note_content) {
throw new Error('Fixture vault handlers are missing create/read commands')
}
Object.defineProperty(window, '__mockHandlers', {
configurable: true,
get: () => handlers,
set: (nextHandlers) => Object.assign(handlers, nextHandlers),
})
})
}
async function recordCreateNoteCalls(page: Page): Promise<void> {
await page.evaluate(() => {
const probeWindow = window as typeof window & ProbeWindow
const handlers = probeWindow.__mockHandlers as Record<string, (args?: unknown) => unknown>
const originalCreate = handlers.create_note_content.bind(handlers)
const probe: CreateNoteProbe = { createCalls: [], getBeforeCreate: [] }
probeWindow.__createNoteBackingFileProbe = probe
handlers.create_note_content = async (args?: unknown) => {
const notePath = String((args as { path?: unknown } | undefined)?.path ?? '')
await new Promise((resolve) => setTimeout(resolve, 100))
const result = await originalCreate(args)
probe.createCalls.push(notePath)
return result
}
})
}
async function rejectReadsBeforeCreate(page: Page): Promise<void> {
await page.evaluate(() => {
const probeWindow = window as typeof window & ProbeWindow
const handlers = probeWindow.__mockHandlers as Record<string, (args?: unknown) => unknown>
const originalGet = handlers.get_note_content.bind(handlers)
const probe = probeWindow.__createNoteBackingFileProbe as CreateNoteProbe
handlers.get_note_content = (args?: unknown) => {
const notePath = String((args as { path?: unknown } | undefined)?.path ?? '')
if (notePath.includes('untitled-note-') && !probe.createCalls.includes(notePath)) {
probe.getBeforeCreate.push(notePath)
throw new Error(`File does not exist: ${notePath}`)
}
return originalGet(args)
}
})
}
async function installCreateNoteBackingFileProbe(page: Page): Promise<void> {
await pinFixtureHandlers(page)
await recordCreateNoteCalls(page)
await rejectReadsBeforeCreate(page)
}
async function readProbe(page: Page): Promise<CreateNoteProbe> {
return page.evaluate(() => {
const probeWindow = window as typeof window & ProbeWindow
return probeWindow.__createNoteBackingFileProbe ?? { createCalls: [], getBeforeCreate: [] }
})
}
test.beforeEach(async ({ page }, testInfo) => {
testInfo.setTimeout(60_000)
tempVaultDir = createFixtureVaultCopy()
await openFixtureVaultTauri(page, tempVaultDir)
await installCreateNoteBackingFileProbe(page)
})
test.afterEach(() => {
removeFixtureVaultCopy(tempVaultDir)
})
test('@smoke creating a note writes its backing file before reload can read it', async ({ page }) => {
const errors: string[] = []
page.on('pageerror', (error) => errors.push(error.message))
await triggerMenuCommand(page, 'file-new-note')
await triggerMenuCommand(page, 'vault-reload')
await expect(page.getByTestId('breadcrumb-filename-trigger')).toContainText(/untitled-note-\d+/i, {
timeout: 5_000,
})
await expect.poll(() => readProbe(page), { timeout: 5_000 }).toMatchObject({
createCalls: [expect.stringMatching(/untitled-note-\d+\.md$/)],
getBeforeCreate: [],
})
const { createCalls, getBeforeCreate } = await readProbe(page)
expect(getBeforeCreate).toEqual([])
expect(errors.filter((message) => message.includes('File does not exist'))).toEqual([])
expect(fs.readFileSync(createCalls[0], 'utf8')).toContain('type: Note')
})