60 lines
2.8 KiB
TypeScript
60 lines
2.8 KiB
TypeScript
import { readFileSync } from 'node:fs'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
const source = readFileSync('src/CountdownPanel.vue', 'utf8')
|
|
|
|
describe('countdown modal accessibility', () => {
|
|
it('names the dialog and supports focus and Escape close', () => {
|
|
expect(source).toContain('aria-labelledby="countdown-dialog-title"')
|
|
expect(source).toContain('id="countdown-dialog-title"')
|
|
expect(source).toContain('@keydown.esc="closeDialog"')
|
|
expect(source).toContain('ref="titleInput"')
|
|
expect(source).toContain('titleInput.value?.focus()')
|
|
expect(source).toContain(':inert="open || Boolean(detailItem)"')
|
|
})
|
|
|
|
it('uses one time-capsule focus and moves row actions into a detail sheet', () => {
|
|
expect(source).toContain('class="countdown-timeline"')
|
|
expect(source).toContain('class="countdown-row"')
|
|
expect(source).toContain('class="countdown-focus"')
|
|
expect(source).toContain('@click="openDetail(focusItem)"')
|
|
expect(source).toContain('item.id !== focusItem.value?.id')
|
|
expect(source).toContain('`kind-${item.kind}`')
|
|
expect(source).toContain(':class="`kind-${focusItem.kind}`"')
|
|
expect(source).toContain('class="countdown-detail-sheet app-sheet app-sheet--detail"')
|
|
expect(source).toContain('ref="detailCloseButton"')
|
|
expect(source).toContain('detailCloseButton.value?.focus()')
|
|
expect(source).toContain('@keydown="trapDetailFocus"')
|
|
expect(source).not.toContain('class="countdown-actions"')
|
|
})
|
|
|
|
it('does not show or edit countdown icons', () => {
|
|
expect(source).not.toContain('countdown-icon')
|
|
expect(source).not.toContain('form.icon')
|
|
expect(source).not.toContain('item.icon')
|
|
expect(source).not.toContain('focusItem.icon')
|
|
expect(source).not.toContain('detailItem.icon')
|
|
expect(source).not.toContain('图标与名称')
|
|
})
|
|
|
|
it('keeps advanced creation fields collapsed behind more settings', () => {
|
|
expect(source).toContain('class="countdown-advanced"')
|
|
expect(source).toContain('<span>更多设置</span>')
|
|
expect(source).toContain('@change="applyKindDefaults"')
|
|
expect(source).toContain(':disabled="form.ignore_year"')
|
|
})
|
|
|
|
it('shows cached countdowns immediately and refreshes active items first', () => {
|
|
expect(source).toContain('readCountdownCache<Countdown>()')
|
|
expect(source).toContain("const active = await request('/countdowns')")
|
|
expect(source).toContain("const archivedItems = await request('/countdowns?archived=true')")
|
|
expect(source).toContain('writeCountdownCache(items.value, archived.value)')
|
|
expect(source).not.toContain("Promise.all([request('/countdowns'),request('/countdowns?archived=true')])")
|
|
})
|
|
|
|
it('keeps the empty state directly actionable', () => {
|
|
expect(source).toContain('添加第一个重要日子')
|
|
expect(source).toContain('@click="openFromEmpty"')
|
|
})
|
|
})
|