From 9b92cf40c49389c8faa46f594df48adfab7ccc8b Mon Sep 17 00:00:00 2001 From: Test Date: Wed, 18 Mar 2026 15:57:44 +0100 Subject: [PATCH] test: update smoke tests to use TitleField instead of H1 sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .../smoke/fix-note-filename-on-rename.spec.ts | 44 +++++++++---------- tests/smoke/title-filename-sync.spec.ts | 39 ++++++++-------- 2 files changed, 40 insertions(+), 43 deletions(-) diff --git a/tests/smoke/fix-note-filename-on-rename.spec.ts b/tests/smoke/fix-note-filename-on-rename.spec.ts index ee43e9af..e85a74f5 100644 --- a/tests/smoke/fix-note-filename-on-rename.spec.ts +++ b/tests/smoke/fix-note-filename-on-rename.spec.ts @@ -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 }) diff --git a/tests/smoke/title-filename-sync.spec.ts b/tests/smoke/title-filename-sync.spec.ts index c67c3da9..1786f2a5 100644 --- a/tests/smoke/title-filename-sync.spec.ts +++ b/tests/smoke/title-filename-sync.spec.ts @@ -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