-
{
- it('hides the legacy title section when loaded content contains a top-level H1', () => {
+ it('marks loaded content with a top-level H1 as titled', () => {
const state = deriveState({
entry: baseEntry,
content: '---\ntitle: Legacy Project\n---\n# Legacy Project\n\nBody',
})
expect(state.hasH1).toBe(true)
- expect(state.showTitleSection).toBe(false)
+ expect(state.showEditor).toBe(true)
})
- it('keeps the title section for notes without an H1', () => {
+ it('keeps editor content visible for notes without an H1', () => {
const state = deriveState({
entry: baseEntry,
content: '---\ntitle: Legacy Project\n---\nBody without a heading',
})
expect(state.hasH1).toBe(false)
- expect(state.showTitleSection).toBe(false)
+ expect(state.showEditor).toBe(true)
})
- it('hides the legacy title section when a frontmatter title drives the display title', () => {
+ it('keeps editor content visible when a legacy frontmatter title exists', () => {
const state = deriveState({
entry: baseEntry,
content: '---\ntitle: Spring 2026\nstatus: Active\n---\n## Goals',
})
expect(state.hasH1).toBe(false)
- expect(state.showTitleSection).toBe(false)
+ expect(state.showEditor).toBe(true)
})
- it('keeps the title section when the document title still comes from the filename', () => {
+ it('does not fall back to a separate title section when the filename drives the display title', () => {
const state = deriveState({
entry: baseEntry,
content: '---\nstatus: Active\n---\nBody without a heading',
})
expect(state.hasH1).toBe(false)
- expect(state.showTitleSection).toBe(true)
+ expect(state.showEditor).toBe(true)
})
- it('hides the title section for untitled drafts before they get an H1', () => {
+ it('keeps untitled drafts in the editor even before they get an H1', () => {
const draftEntry = {
...baseEntry,
path: '/vault/untitled-note-1700000000.md',
@@ -105,6 +105,6 @@ describe('deriveEditorContentState', () => {
})
expect(state.hasH1).toBe(false)
- expect(state.showTitleSection).toBe(false)
+ expect(state.showEditor).toBe(true)
})
})
diff --git a/src/components/editor-content/editorContentState.ts b/src/components/editor-content/editorContentState.ts
index e4332c4e..23d79e40 100644
--- a/src/components/editor-content/editorContentState.ts
+++ b/src/components/editor-content/editorContentState.ts
@@ -1,5 +1,5 @@
import type { NoteStatus, VaultEntry } from '../../types'
-import { contentDefinesDisplayTitle, extractH1TitleFromContent } from '../../utils/noteTitle'
+import { extractH1TitleFromContent } from '../../utils/noteTitle'
import { countWords } from '../../utils/wikilinks'
export interface EditorContentTab {
@@ -14,17 +14,11 @@ interface EditorContentStateInput {
activeStatus: NoteStatus
}
-interface TitleSectionState {
- hasDisplayTitle: boolean
- hasH1: boolean
-}
-
interface VisibilityState {
effectiveRawMode: boolean
isDeletedPreview: boolean
isNonMarkdownText: boolean
showEditor: boolean
- showTitleSection: boolean
}
export interface EditorContentState {
@@ -35,7 +29,6 @@ export interface EditorContentState {
isNonMarkdownText: boolean
effectiveRawMode: boolean
showEditor: boolean
- showTitleSection: boolean
path: string
wordCount: number
}
@@ -49,38 +42,18 @@ function contentHasTopLevelH1(activeTab: EditorContentTab | null): boolean {
return activeTab ? extractH1TitleFromContent(activeTab.content) !== null : false
}
-function contentDefinesTitle(activeTab: EditorContentTab | null): boolean {
- return activeTab ? contentDefinesDisplayTitle(activeTab.content) : false
-}
-
function resolveHasH1(activeTab: EditorContentTab | null, freshEntry: VaultEntry | undefined): boolean {
return contentHasTopLevelH1(activeTab) || freshEntry?.hasH1 === true || activeTab?.entry.hasH1 === true
}
-function resolveHasDisplayTitle(activeTab: EditorContentTab | null, hasH1: boolean): boolean {
- return hasH1 || contentDefinesTitle(activeTab)
-}
-
-function deriveTitleSectionState(activeTab: EditorContentTab | null, freshEntry: VaultEntry | undefined): TitleSectionState {
- const hasH1 = resolveHasH1(activeTab, freshEntry)
- return {
- hasDisplayTitle: resolveHasDisplayTitle(activeTab, hasH1),
- hasH1,
- }
-}
-
function deriveVisibilityState(input: {
- activeStatus: NoteStatus
activeTab: EditorContentTab | null
freshEntry: VaultEntry | undefined
- hasDisplayTitle: boolean
rawMode: boolean
}): VisibilityState {
const {
- activeStatus,
activeTab,
freshEntry,
- hasDisplayTitle,
rawMode,
} = input
const isDeletedPreview = !!activeTab && !freshEntry
@@ -92,36 +65,23 @@ function deriveVisibilityState(input: {
isNonMarkdownText,
effectiveRawMode,
showEditor: !effectiveRawMode,
- showTitleSection: !isDeletedPreview && !hasDisplayTitle && !isUnsavedUntitledDraft(activeTab, activeStatus),
}
}
-function isUnsavedUntitledDraft(activeTab: EditorContentTab | null, activeStatus: NoteStatus): boolean {
- if (!activeTab) return false
- if (!activeTab.entry.filename.startsWith('untitled-')) return false
- return activeStatus === 'new' || activeStatus === 'unsaved' || activeStatus === 'pendingSave'
-}
-
-export function deriveEditorContentState({
- activeTab,
- entries,
- rawMode,
- activeStatus,
-}: EditorContentStateInput): EditorContentState {
+export function deriveEditorContentState(input: EditorContentStateInput): EditorContentState {
+ const { activeTab, entries, rawMode } = input
const freshEntry = findFreshEntry(activeTab, entries)
- const titleState = deriveTitleSectionState(activeTab, freshEntry)
+ const hasH1 = resolveHasH1(activeTab, freshEntry)
const visibilityState = deriveVisibilityState({
- activeStatus,
activeTab,
freshEntry,
- hasDisplayTitle: titleState.hasDisplayTitle,
rawMode,
})
return {
freshEntry,
isArchived: freshEntry?.archived ?? activeTab?.entry.archived ?? false,
- hasH1: titleState.hasH1,
+ hasH1,
...visibilityState,
path: activeTab?.entry.path ?? '',
wordCount: activeTab ? countWords(activeTab.content) : 0,
diff --git a/src/components/editor-content/useEditorContentModel.ts b/src/components/editor-content/useEditorContentModel.ts
index b4944dcf..f79fd546 100644
--- a/src/components/editor-content/useEditorContentModel.ts
+++ b/src/components/editor-content/useEditorContentModel.ts
@@ -1,9 +1,8 @@
import type React from 'react'
-import { useEffect, useRef } from 'react'
+import { useRef } from 'react'
import type { useCreateBlockNote } from '@blocknote/react'
import type { NoteStatus, VaultEntry } from '../../types'
import { useEditorTheme } from '../../hooks/useTheme'
-import { resolveNoteIcon } from '../../utils/noteIcon'
import { deriveEditorContentState } from './editorContentState'
export interface Tab {
@@ -39,61 +38,17 @@ export interface EditorContentProps {
onUnarchiveNote?: (path: string) => void
vaultPath?: string
rawLatestContentRef?: React.MutableRefObject
- onTitleChange?: (path: string, newTitle: string) => void
onRenameFilename?: (path: string, newFilenameStem: string) => void
isConflicted?: boolean
onKeepMine?: (path: string) => void
onKeepTheirs?: (path: string) => void
}
-function useBreadcrumbTitleVisibility({
- showEditor,
- showTitleSection,
- path,
- breadcrumbBarRef,
- titleSectionRef,
-}: {
- showEditor: boolean
- showTitleSection: boolean
- path: string
- breadcrumbBarRef: React.RefObject
- titleSectionRef: React.RefObject
-}) {
- useEffect(() => {
- if (!showEditor) return
-
- const bar = breadcrumbBarRef.current
- const titleSection = titleSectionRef.current
- if (!bar || !titleSection) return
-
- if (!showTitleSection) {
- bar.setAttribute('data-title-hidden', '')
- return () => {
- bar.removeAttribute('data-title-hidden')
- }
- }
-
- const observer = new IntersectionObserver(
- ([entry]) => {
- if (entry.isIntersecting) bar.removeAttribute('data-title-hidden')
- else bar.setAttribute('data-title-hidden', '')
- },
- { threshold: 0 },
- )
- observer.observe(titleSection)
- return () => {
- observer.disconnect()
- bar.removeAttribute('data-title-hidden')
- }
- }, [path, showEditor, showTitleSection, breadcrumbBarRef, titleSectionRef])
-}
-
export function useEditorContentModel(props: EditorContentProps) {
const {
activeTab,
entries,
rawMode,
- activeStatus,
diffMode,
} = props
@@ -105,29 +60,17 @@ export function useEditorContentModel(props: EditorContentProps) {
effectiveRawMode,
showEditor: showContentEditor,
path,
- showTitleSection,
wordCount,
} = deriveEditorContentState({
activeTab,
entries,
rawMode,
- activeStatus,
+ activeStatus: props.activeStatus,
})
const showEditor = !diffMode && showContentEditor
- const entryIcon = activeTab?.entry.icon ?? null
- const hasDisplayIcon = resolveNoteIcon(entryIcon).kind !== 'none'
- const titleSectionRef = useRef(null)
const breadcrumbBarRef = useRef(null)
- useBreadcrumbTitleVisibility({
- showEditor,
- showTitleSection,
- path,
- breadcrumbBarRef,
- titleSectionRef,
- })
-
return {
...props,
cssVars,
@@ -136,11 +79,7 @@ export function useEditorContentModel(props: EditorContentProps) {
effectiveRawMode,
forceRawMode: isNonMarkdownText || isDeletedPreview,
showEditor,
- entryIcon,
- hasDisplayIcon,
path,
- showTitleSection,
- titleSectionRef,
breadcrumbBarRef,
wordCount,
}
diff --git a/tests/integration/vault-workflows.spec.ts b/tests/integration/vault-workflows.spec.ts
index 5f7ab264..17f563b7 100644
--- a/tests/integration/vault-workflows.spec.ts
+++ b/tests/integration/vault-workflows.spec.ts
@@ -56,8 +56,7 @@ test('vault loads entries from fixture files @smoke', async ({ page }) => {
// Open a note and verify editor shows its content from disk
await openNote(page, 'Alpha Project')
- // Verify the stable title field rather than the editor heading rendering.
- await expect(page.getByTestId('title-field-input')).toHaveValue('Alpha Project', { timeout: 5_000 })
+ await expect(page.getByRole('heading', { name: 'Alpha Project', level: 1 })).toBeVisible({ timeout: 5_000 })
})
// ---------------------------------------------------------------------------
diff --git a/tests/smoke/create-note-crash.spec.ts b/tests/smoke/create-note-crash.spec.ts
index 7c9d4eec..3c0108ed 100644
--- a/tests/smoke/create-note-crash.spec.ts
+++ b/tests/smoke/create-note-crash.spec.ts
@@ -30,12 +30,10 @@ test('create note via sidebar + button does not crash', async ({ page }) => {
await page.waitForSelector('[data-testid="sidebar-top-nav"]', { timeout: 10000 })
await page.waitForTimeout(500)
- const plusButtons = page.locator('button[aria-label*="Create new"]')
- if (await plusButtons.count() > 0) {
- await plusButtons.first().click()
- await page.waitForTimeout(2000)
- }
+ await page.locator('button[title="Create new note"]').first().click()
+ await page.waitForTimeout(2000)
expect(errors).toHaveLength(0)
- await expect(page.locator('[data-testid="title-field-input"]')).toBeVisible()
+ await expect(page.locator('.bn-editor')).toBeVisible({ timeout: 5_000 })
+ await expect(page.getByTestId('breadcrumb-filename-trigger')).toContainText(/untitled-note-\d+/i)
})
diff --git a/tests/smoke/fix-note-filename-on-rename.spec.ts b/tests/smoke/fix-note-filename-on-rename.spec.ts
deleted file mode 100644
index e85a74f5..00000000
--- a/tests/smoke/fix-note-filename-on-rename.spec.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { test, expect } from '@playwright/test'
-import { sendShortcut } from './helpers'
-
-/** Known BlockNote/ProseMirror error that fires during editor re-mount after rename. */
-const KNOWN_EDITOR_ERRORS = ['isConnected']
-
-function isKnownEditorError(msg: string): boolean {
- return KNOWN_EDITOR_ERRORS.some(k => msg.includes(k))
-}
-
-/**
- * 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"
- await page.locator('body').click()
- await sendShortcut(page, 'n', ['Control'])
- await expect(page.getByText(/Untitled note/).first()).toBeVisible({ 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. 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 to dismiss
- await page.waitForTimeout(2500)
- })
-
- 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')
-
- // The toast should show "Renamed" after the TitleField commit
- const toast = page.locator('.fixed.bottom-8')
- await expect(toast).toContainText('Renamed', { timeout: 5000 })
-
- // Breadcrumb should show the new title
- const breadcrumb = page.locator('span.truncate.font-medium')
- await expect(breadcrumb.first()).toContainText('Test Note ABC', { timeout: 2000 })
-
- // Cmd+S should NOT trigger another rename (filename already matches)
- await sendShortcut(page, 's', ['Control'])
- await page.waitForTimeout(500)
-
- // No unexpected JS errors
- expect(errors).toEqual([])
- })
-
- test('saving a note whose filename already matches does not trigger rename', async ({ page }) => {
- // Click "All Notes" to show all notes regardless of section grouping
- const allNotes = page.locator('text=All Notes').first()
- await allNotes.click()
- await page.waitForTimeout(500)
- // Click on the first note in the note list
- const noteListContainer = page.locator('[data-testid="note-list-container"]')
- await noteListContainer.waitFor({ timeout: 5000 })
- const noteItem = noteListContainer.locator('.cursor-pointer').first()
- await noteItem.click()
- await page.waitForTimeout(500)
-
- // Cmd+S — should show "Saved" or "Nothing to save", NOT "Renamed"
- await sendShortcut(page, 's', ['Control'])
-
- const toast = page.locator('.fixed.bottom-8')
- await expect(toast).toBeVisible({ timeout: 3000 })
- const toastText = await toast.textContent()
- expect(toastText).not.toContain('Renamed')
- })
-
- 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')
-
- // 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 })
-
- expect(errors).toEqual([])
- })
-})
diff --git a/tests/smoke/h1-title-decoupled.spec.ts b/tests/smoke/h1-title-decoupled.spec.ts
index 16b648cd..39750ca4 100644
--- a/tests/smoke/h1-title-decoupled.spec.ts
+++ b/tests/smoke/h1-title-decoupled.spec.ts
@@ -86,6 +86,23 @@ test('@smoke older notes with a document title do not render the legacy title se
await expect(page.locator('.title-section[data-title-ui-visible]')).toHaveCount(0)
})
+test('deleting the H1 does not resurrect the legacy title section', async ({ page }) => {
+ await openNote(page, 'Alpha Project')
+ await openRawMode(page)
+
+ const rawContent = await getRawEditorContent(page)
+ expect(rawContent).toContain('# Alpha Project')
+
+ await setRawEditorContent(page, rawContent.replace('# Alpha Project\n\n', ''))
+ await page.keyboard.press('Meta+s')
+ await openBlockNoteMode(page)
+
+ await expect(page.locator('.bn-editor')).toBeVisible({ timeout: 5_000 })
+ await expect(page.getByTestId('title-field-input')).toHaveCount(0)
+ await expect(page.locator('.title-section')).toHaveCount(0)
+ await expect(page.getByRole('heading', { name: 'Alpha Project', level: 1 })).toHaveCount(0)
+})
+
test('@smoke edited H1 titles drive note list, search, and wikilink autocomplete', async ({ page }) => {
const updatedTitle = 'Updated Display Title'
const noteList = page.locator('[data-testid="note-list-container"]')
diff --git a/tests/smoke/rename-wikilink-update.spec.ts b/tests/smoke/rename-wikilink-update.spec.ts
deleted file mode 100644
index f65cded3..00000000
--- a/tests/smoke/rename-wikilink-update.spec.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { test, expect } from '@playwright/test'
-
-test.describe('Renaming a note updates wikilinks across the vault', () => {
- test.beforeEach(async ({ page }) => {
- await page.setViewportSize({ width: 1600, height: 900 })
- await page.goto('/')
- await page.waitForLoadState('networkidle')
- })
-
- test('title field rename triggers rename flow and shows toast', async ({ page }) => {
- // 1. Click the first note in the list to open it
- const noteListContainer = page.locator('[data-testid="note-list-container"]')
- await noteListContainer.waitFor({ timeout: 5000 })
- const firstNote = noteListContainer.locator('.cursor-pointer').first()
- await firstNote.click()
- await page.waitForTimeout(500)
-
- // 2. Find the title field in the editor
- const titleField = page.locator('[data-testid="title-field"] input, [data-testid="title-field"]')
- await expect(titleField.first()).toBeVisible({ timeout: 5000 })
- const originalTitle = await titleField.first().inputValue().catch(() => titleField.first().textContent())
- expect(originalTitle).toBeTruthy()
-
- // 3. Click the title field and change the title
- await titleField.first().click()
- await page.keyboard.press('Meta+a')
- const newTitle = `${originalTitle} Renamed`
- await page.keyboard.type(newTitle)
- await page.keyboard.press('Tab') // blur to trigger rename
-
- await page.waitForTimeout(1500)
-
- // 4. Verify the toast message appeared (confirms rename flow ran)
- const toast = page.getByText('Renamed', { exact: true })
- await expect(toast).toBeVisible({ timeout: 5000 })
- })
-})
diff --git a/tests/smoke/title-filename-sync.spec.ts b/tests/smoke/title-filename-sync.spec.ts
deleted file mode 100644
index 1786f2a5..00000000
--- a/tests/smoke/title-filename-sync.spec.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import { test, expect } from '@playwright/test'
-import { sendShortcut } from './helpers'
-
-/** Known BlockNote/ProseMirror error that fires during editor re-mount after rename. */
-const KNOWN_EDITOR_ERRORS = ['isConnected']
-
-function isKnownEditorError(msg: string): boolean {
- return KNOWN_EDITOR_ERRORS.some(k => msg.includes(k))
-}
-
-test.describe('Title/filename sync', () => {
- test.beforeEach(async ({ page }) => {
- await page.goto('/')
- await page.waitForLoadState('networkidle')
- await page.waitForTimeout(2500)
- })
-
- 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) })
-
- // Create note via Cmd+N
- await page.locator('body').click()
- await sendShortcut(page, 'n', ['Control'])
- await expect(page.getByText(/Untitled note/).first()).toBeVisible({ timeout: 3000 })
-
- // 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 async rename
- const toast = page.locator('.fixed.bottom-8')
- await expect(toast).toContainText('Renamed', { timeout: 5000 })
-
- // Breadcrumb should show the new title
- const breadcrumb = page.locator('span.truncate.font-medium')
- await expect(breadcrumb.first()).toContainText('Career Tracks Depend on Company Shape', { timeout: 2000 })
-
- expect(errors).toEqual([])
- })
-
- test('opening a note shows title from frontmatter in tab/breadcrumb', async ({ page }) => {
- // Click "All Notes" to see all notes
- const allNotes = page.locator('text=All Notes').first()
- await allNotes.click()
- await page.waitForTimeout(500)
-
- // Click on the first note in the note list
- const noteListContainer = page.locator('[data-testid="note-list-container"]')
- await noteListContainer.waitFor({ timeout: 5000 })
- const noteItem = noteListContainer.locator('.cursor-pointer').first()
- const noteTitle = await noteItem.locator('.font-medium, .text-sm').first().textContent()
- await noteItem.click()
- await page.waitForTimeout(500)
-
- // Breadcrumb should show the note title
- if (noteTitle) {
- const breadcrumb = page.locator('span.truncate.font-medium')
- await expect(breadcrumb.first()).toContainText(noteTitle.trim(), { timeout: 2000 })
- }
- })
-
- 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) })
-
- // Create a note
- await page.locator('body').click()
- await sendShortcut(page, 'n', ['Control'])
- await expect(page.getByText(/Untitled note/).first()).toBeVisible({ timeout: 3000 })
-
- // 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 expect(page.locator('.fixed.bottom-8')).toContainText('Renamed', { timeout: 5000 })
-
- // Second rename via TitleField
- await titleInput.click()
- await titleInput.fill('Renamed Title XYZ')
- await titleInput.press('Enter')
-
- // Wait for second rename
- await expect(page.locator('.fixed.bottom-8')).toContainText('Renamed', { timeout: 5000 })
-
- // Breadcrumb should show the new title
- const breadcrumb = page.locator('span.truncate.font-medium')
- await expect(breadcrumb.first()).toContainText('Renamed Title XYZ', { timeout: 2000 })
-
- expect(errors).toEqual([])
- })
-})
diff --git a/tests/smoke/type-create-note.spec.ts b/tests/smoke/type-create-note.spec.ts
index ed0f97aa..5128c510 100644
--- a/tests/smoke/type-create-note.spec.ts
+++ b/tests/smoke/type-create-note.spec.ts
@@ -1,4 +1,5 @@
import { test, expect } from '@playwright/test'
+import { executeCommand, openCommandPalette } from './helpers'
test('clicking + in type section creates note with that type', async ({ page }) => {
await page.goto('/')
@@ -11,26 +12,19 @@ test('clicking + in type section creates note with that type', async ({ page })
// Click the "+" button to create a new note
await page.click('[title="Create new note"]')
- await page.waitForTimeout(1000)
+ await expect(page.locator('.bn-editor')).toBeVisible({ timeout: 5000 })
- // The new note should have type-based naming (e.g., "Untitled project N")
- const titleInput = page.locator('[data-testid="title-field-input"]')
- if (await titleInput.count() > 0) {
- const value = await titleInput.inputValue()
- console.log('New note title:', value)
- expect(value.toLowerCase()).toContain('project')
- }
+ // The new note should use a type-specific untitled filename.
+ await expect(page.getByTestId('breadcrumb-filename-trigger')).toContainText(/untitled-project-\d+/i)
// Toggle raw editor to see frontmatter
- await page.keyboard.press('Meta+Shift+m')
- await page.waitForTimeout(500)
+ await openCommandPalette(page)
+ await executeCommand(page, 'Toggle Raw')
+ await expect(page.locator('.cm-content')).toBeVisible({ timeout: 5000 })
const rawEditor = page.locator('.cm-content')
- if (await rawEditor.count() > 0) {
- const content = await rawEditor.textContent()
- console.log('Raw content:', content?.substring(0, 200))
- expect(content).toContain('type: Project')
- }
+ const content = await rawEditor.textContent()
+ expect(content).toContain('type: Project')
})
test('clicking + in All Notes creates generic note', async ({ page }) => {
@@ -43,14 +37,9 @@ test('clicking + in All Notes creates generic note', async ({ page }) => {
// Click the "+" button
await page.click('[title="Create new note"]')
- await page.waitForTimeout(1000)
+ await expect(page.locator('.bn-editor')).toBeVisible({ timeout: 5000 })
- // The new note should be a generic "Note" type
- const titleInput = page.locator('[data-testid="title-field-input"]')
- if (await titleInput.count() > 0) {
- const value = await titleInput.inputValue()
- console.log('New note title:', value)
- expect(value.toLowerCase()).toContain('note')
- expect(value.toLowerCase()).not.toContain('project')
- }
+ // The new note should be a generic untitled note, not a typed one.
+ await expect(page.getByTestId('breadcrumb-filename-trigger')).toContainText(/untitled-note-\d+/i)
+ await expect(page.getByTestId('breadcrumb-filename-trigger')).not.toContainText(/untitled-project-\d+/i)
})
diff --git a/tests/smoke/wikilink-path-fix.spec.ts b/tests/smoke/wikilink-path-fix.spec.ts
index b5fa8773..d00d86ec 100644
--- a/tests/smoke/wikilink-path-fix.spec.ts
+++ b/tests/smoke/wikilink-path-fix.spec.ts
@@ -75,8 +75,6 @@ test.describe('Wikilink insertion and navigation', () => {
const expected = targetTitle?.substring(0, 4) ?? ''
await expect.poll(async () => {
- const titleInput = page.getByTestId('title-field-input')
- if (await titleInput.count()) return await titleInput.inputValue()
const heading = page.locator('.bn-editor h1').first()
if (await heading.count()) return (await heading.textContent()) ?? ''
return ''