test: update smoke tests to use TitleField instead of H1 sync

Old tests typed into the H1 heading to trigger title rename — now
that H1 is decoupled from title, all rename flows go through TitleField.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Test
2026-03-18 15:57:44 +01:00
parent e8ace69bb0
commit 9b92cf40c4
2 changed files with 40 additions and 43 deletions

View File

@@ -9,43 +9,40 @@ function isKnownEditorError(msg: string): boolean {
}
/**
* Helper: create a new note, select the existing H1 heading text,
* replace it with a new title, then wait for the 500 ms title-sync debounce.
* Helper: create a new note and rename it via TitleField.
*/
async function createNoteWithTitle(page: import('@playwright/test').Page, title: string) {
// 1. Cmd+N → new "Untitled note" (creates heading with "Untitled note")
// 1. Cmd+N → new "Untitled note"
await page.locator('body').click()
await sendShortcut(page, 'n', ['Control'])
await expect(page.getByText(/Untitled note/).first()).toBeVisible({ timeout: 3000 })
// 2. Wait for the heading to render in BlockNote
const heading = page.locator('[data-content-type="heading"] h1')
await heading.waitFor({ timeout: 3000 })
// 2. Edit the title via TitleField
const titleInput = page.getByTestId('title-field-input')
await titleInput.waitFor({ timeout: 3000 })
await titleInput.click()
await titleInput.fill(title)
await titleInput.press('Enter')
// 3. Triple-click the heading to select all its text, then type replacement
await heading.click({ clickCount: 3 })
await page.keyboard.type(title, { delay: 20 })
// 4. Wait for the 500 ms useHeadingTitleSync debounce to fire + React re-render
await page.waitForTimeout(800)
// 3. Wait for async rename to complete
await page.waitForTimeout(1000)
}
test.describe('Note filename updates on title change + save', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/')
await page.waitForLoadState('networkidle')
// Wait for startup toast ("Laputa registered as MCP tool") to dismiss
// Wait for startup toast to dismiss
await page.waitForTimeout(2500)
})
test('Cmd+N creates untitled note, typing new title triggers rename via title sync', async ({ page }) => {
test('Cmd+N creates untitled note, editing TitleField triggers rename', async ({ page }) => {
const errors: string[] = []
page.on('pageerror', (err) => { if (!isKnownEditorError(err.message)) errors.push(err.message) })
await createNoteWithTitle(page, 'Test Note ABC')
// Title sync now triggers a full rename (save + rename + wikilink update).
// The toast should show "Renamed" after the debounce fires.
// The toast should show "Renamed" after the TitleField commit
const toast = page.locator('.fixed.bottom-8')
await expect(toast).toContainText('Renamed', { timeout: 5000 })
@@ -82,20 +79,19 @@ test.describe('Note filename updates on title change + save', () => {
expect(toastText).not.toContain('Renamed')
})
test('rapid title changes only rename to final title', async ({ page }) => {
test('rapid TitleField edits only rename to final title', async ({ page }) => {
const errors: string[] = []
page.on('pageerror', (err) => { if (!isKnownEditorError(err.message)) errors.push(err.message) })
await createNoteWithTitle(page, 'First Title')
// Select heading text again and replace with final title
const heading = page.locator('[data-content-type="heading"] h1')
await heading.click({ clickCount: 3 })
await page.keyboard.type('Final Title', { delay: 20 })
// Wait for debounce to fire — title sync triggers rename automatically
await page.waitForTimeout(800)
// Edit TitleField again with final title
const titleInput = page.getByTestId('title-field-input')
await titleInput.click()
await titleInput.fill('Final Title')
await titleInput.press('Enter')
// Wait for rename
const toast = page.locator('.fixed.bottom-8')
await expect(toast).toContainText('Renamed', { timeout: 5000 })

View File

@@ -15,7 +15,7 @@ test.describe('Title/filename sync', () => {
await page.waitForTimeout(2500)
})
test('new note has title in frontmatter and filename = slug of title', async ({ page }) => {
test('new note renamed via TitleField updates frontmatter and filename', async ({ page }) => {
const errors: string[] = []
page.on('pageerror', (err) => { if (!isKnownEditorError(err.message)) errors.push(err.message) })
@@ -24,14 +24,14 @@ test.describe('Title/filename sync', () => {
await sendShortcut(page, 'n', ['Control'])
await expect(page.getByText(/Untitled note/).first()).toBeVisible({ timeout: 3000 })
// Type a title in the heading
const heading = page.locator('[data-content-type="heading"] h1')
await heading.waitFor({ timeout: 3000 })
await heading.click({ clickCount: 3 })
await page.keyboard.type('Career Tracks Depend on Company Shape', { delay: 15 })
// Edit the title via TitleField (not H1)
const titleInput = page.getByTestId('title-field-input')
await titleInput.waitFor({ timeout: 3000 })
await titleInput.click()
await titleInput.fill('Career Tracks Depend on Company Shape')
await titleInput.press('Enter')
// Wait for debounce + rename
await page.waitForTimeout(800)
// Wait for async rename
const toast = page.locator('.fixed.bottom-8')
await expect(toast).toContainText('Renamed', { timeout: 5000 })
@@ -63,7 +63,7 @@ test.describe('Title/filename sync', () => {
}
})
test('rename via title editing updates both title and filename atomically', async ({ page }) => {
test('rename via TitleField updates both title and filename', async ({ page }) => {
const errors: string[] = []
page.on('pageerror', (err) => { if (!isKnownEditorError(err.message)) errors.push(err.message) })
@@ -72,21 +72,22 @@ test.describe('Title/filename sync', () => {
await sendShortcut(page, 'n', ['Control'])
await expect(page.getByText(/Untitled note/).first()).toBeVisible({ timeout: 3000 })
const heading = page.locator('[data-content-type="heading"] h1')
await heading.waitFor({ timeout: 3000 })
await heading.click({ clickCount: 3 })
await page.keyboard.type('Original Title XYZ', { delay: 15 })
// First rename via TitleField
const titleInput = page.getByTestId('title-field-input')
await titleInput.waitFor({ timeout: 3000 })
await titleInput.click()
await titleInput.fill('Original Title XYZ')
await titleInput.press('Enter')
// Wait for rename
await page.waitForTimeout(800)
await expect(page.locator('.fixed.bottom-8')).toContainText('Renamed', { timeout: 5000 })
// Now rename by editing the heading again
await heading.click({ clickCount: 3 })
await page.keyboard.type('Renamed Title XYZ', { delay: 15 })
// Second rename via TitleField
await titleInput.click()
await titleInput.fill('Renamed Title XYZ')
await titleInput.press('Enter')
// Wait for debounce + rename
await page.waitForTimeout(800)
// Wait for second rename
await expect(page.locator('.fixed.bottom-8')).toContainText('Renamed', { timeout: 5000 })
// Breadcrumb should show the new title