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:
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
36
tests/smoke/sidebar-duplicate-sections.spec.ts
Normal file
36
tests/smoke/sidebar-duplicate-sections.spec.ts
Normal 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)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user