test: add Playwright smoke test for visible type property

Also updates vite.config.ts vault API parser to include all VaultEntry
fields (visible, icon, color, order, etc.) so the dev server returns
complete entries for sidebar filtering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
lucaronin
2026-03-06 21:52:40 +01:00
parent 486b0e9ed1
commit 78c45970bf
3 changed files with 81 additions and 2 deletions

View File

@@ -681,7 +681,7 @@ export const MOCK_ENTRIES: VaultEntry[] = [
color: null,
order: 3,
sidebarLabel: null,
template: null, sort: null, view: null, visible: null,
template: null, sort: null, view: null, visible: false,
outgoingLinks: [],
properties: {},
},

View File

@@ -0,0 +1,39 @@
import { test, expect } from '@playwright/test'
test.describe('Type visibility in sidebar', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/')
await page.waitForLoadState('networkidle')
})
test('sections with visible:false Type entries are hidden from sidebar', async ({
page,
}) => {
const sidebar = page.locator('.app__sidebar')
// Wait for sections to render
await sidebar
.locator('button[aria-label*="Collapse"], button[aria-label*="Expand"]')
.first()
.waitFor({ timeout: 5000 })
// Extract section labels from Expand/Collapse buttons
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')
const label = ariaLabel?.replace(/^(Collapse|Expand)\s+/, '') ?? ''
if (label) labels.push(label)
}
// Verify that at least some sections render (sanity check)
expect(labels.length).toBeGreaterThan(3)
// All visible section labels should be unique (regression check)
const uniqueLabels = [...new Set(labels)]
expect(labels).toEqual(uniqueLabels)
})
})

View File

@@ -19,11 +19,25 @@ interface VaultEntry {
status: string | null
owner: string | null
cadence: string | null
archived: boolean
trashed: boolean
trashedAt: number | null
modifiedAt: number | null
createdAt: number | null
fileSize: number
snippet: string
wordCount: number
relationships: Record<string, string[]>
icon: string | null
color: string | null
order: number | null
sidebarLabel: string | null
template: string | null
sort: string | null
view: string | null
visible: boolean | null
outgoingLinks: string[]
properties: Record<string, string | number | boolean | null>
}
/** Extract all [[wiki-links]] from a string. */
@@ -115,22 +129,48 @@ function parseMarkdownFile(filePath: string): VaultEntry | null {
}
}
// Boolean field helper
const getBool = (...keys: string[]): boolean | null => {
for (const k of keys) {
for (const fk of Object.keys(fm)) {
if (fk.toLowerCase() === k.toLowerCase() && typeof fm[fk] === 'boolean') {
return fm[fk]
}
}
}
return null
}
return {
path: filePath,
filename,
title,
isA: getString('is_a', 'is a'),
isA: getString('is_a', 'is a', 'type'),
aliases,
belongsTo,
relatedTo,
status: getString('status'),
owner: getString('owner'),
cadence: getString('cadence'),
archived: getBool('archived') ?? false,
trashed: getBool('trashed') ?? false,
trashedAt: null,
modifiedAt: stats.mtimeMs,
createdAt,
fileSize: stats.size,
snippet,
wordCount: bodyText.split(/\s+/).filter(Boolean).length,
relationships,
icon: getString('icon'),
color: getString('color'),
order: fm.order != null ? Number(fm.order) : null,
sidebarLabel: getString('sidebar label', 'sidebar_label'),
template: getString('template'),
sort: getString('sort'),
view: getString('view'),
visible: getBool('visible'),
outgoingLinks: [],
properties: {},
}
} catch {
return null