test: add regression tests for hyphenated folder sidebar duplicates

- Sidebar unit test: entries with isA 'Monday Ideas' produce exactly
  one section header (not two)
- Playwright smoke test: verify no duplicate section labels in sidebar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Test
2026-03-06 16:09:29 +01:00
parent 900ce7f66f
commit bbb29857b8
2 changed files with 74 additions and 0 deletions

View File

@@ -893,4 +893,42 @@ describe('Sidebar', () => {
expect(screen.queryByRole('textbox', { name: 'Section name' })).not.toBeInTheDocument()
})
})
it('renders exactly one section for a hyphenated custom type like Monday Ideas', () => {
const entriesWithMondayIdeas: VaultEntry[] = [
...mockEntries,
{
path: '/vault/monday-ideas/standup-bingo.md',
filename: 'standup-bingo.md',
title: 'Standup Bingo',
isA: 'Monday Ideas',
aliases: [], belongsTo: [], relatedTo: [],
status: null, owner: null, cadence: null,
archived: false, trashed: false, trashedAt: null,
modifiedAt: 1700000000, createdAt: null,
fileSize: 310, snippet: '', wordCount: 120,
relationships: {}, icon: null, color: null, order: null,
sidebarLabel: null, template: null, sort: null, view: null,
outgoingLinks: [], properties: {},
},
{
path: '/vault/monday-ideas/theme-days.md',
filename: 'theme-days.md',
title: 'Theme Days',
isA: 'Monday Ideas',
aliases: [], belongsTo: [], relatedTo: [],
status: null, owner: null, cadence: null,
archived: false, trashed: false, trashedAt: null,
modifiedAt: 1700000000, createdAt: null,
fileSize: 280, snippet: '', wordCount: 95,
relationships: {}, icon: null, color: null, order: null,
sidebarLabel: null, template: null, sort: null, view: null,
outgoingLinks: [], properties: {},
},
]
render(<Sidebar entries={entriesWithMondayIdeas} selection={defaultSelection} onSelect={() => {}} />)
// "Monday Ideas" pluralized → "Monday Ideases" (the pluralizeType function)
const mondaySections = screen.getAllByText(/Monday Ideas/i)
expect(mondaySections).toHaveLength(1)
})
})

View File

@@ -0,0 +1,36 @@
import { test, expect } from '@playwright/test'
test.describe('Sidebar duplicate sections', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/')
await page.waitForLoadState('networkidle')
})
test('no duplicate sidebar section headers', async ({ page }) => {
// Verify that every section label in the sidebar is unique.
// Before the fix, hyphenated folder names (e.g. monday-ideas/)
// would produce a different isA than the Type file title,
// resulting in two sidebar sections for the same type.
const sidebar = page.locator('.app__sidebar')
// Wait for at least one Expand/Collapse button (indicates sections rendered)
await sidebar.locator('button[aria-label*="Collapse"], button[aria-label*="Expand"]').first().waitFor({ timeout: 5000 })
// Extract section labels from the Expand/Collapse aria-labels
const buttons = sidebar.locator('button[aria-label*="Collapse"], button[aria-label*="Expand"]')
const count = await buttons.count()
const labels: string[] = []
for (let i = 0; i < count; i++) {
const ariaLabel = await buttons.nth(i).getAttribute('aria-label')
// aria-label is like "Collapse Projects" or "Expand Projects"
const label = ariaLabel?.replace(/^(Collapse|Expand)\s+/, '') ?? ''
if (label) labels.push(label)
}
// Every label should be unique — no duplicates
const uniqueLabels = [...new Set(labels)]
expect(labels).toEqual(uniqueLabels)
expect(labels.length).toBeGreaterThan(0)
})
})