KanbanBoard's board tabs implemented roving tabindex but never wired up arrow-key navigation, making inactive tabs keyboard-unreachable. Adds ArrowLeft/ArrowRight/Home/End handling that moves both selection and focus between tabs, closing an unmet requirement from the original design doc. Also adds aria-pressed to App's List/Board toggle buttons so their active state is exposed to assistive technology, not just conveyed visually via CSS class.
54 lines
2 KiB
JavaScript
54 lines
2 KiB
JavaScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { mount, flushPromises } from '@vue/test-utils'
|
|
import App from '../src/App.vue'
|
|
|
|
vi.mock('../src/api.js', () => ({
|
|
fetchItems: vi.fn(async () => []),
|
|
fetchItem: vi.fn(async (id) => ({ id })),
|
|
}))
|
|
|
|
beforeEach(() => {
|
|
localStorage.clear()
|
|
})
|
|
|
|
describe('App view mode', () => {
|
|
it('defaults to list view when nothing is stored', async () => {
|
|
const wrapper = mount(App)
|
|
await flushPromises()
|
|
const listButton = wrapper.findAll('.view-toggle button').find((b) => b.text() === 'List')
|
|
expect(listButton.classes()).toContain('active')
|
|
})
|
|
|
|
it('honors a stored board view mode on mount', async () => {
|
|
localStorage.setItem('chorus_view_mode', 'board')
|
|
const wrapper = mount(App)
|
|
await flushPromises()
|
|
const boardButton = wrapper.findAll('.view-toggle button').find((b) => b.text() === 'Board')
|
|
expect(boardButton.classes()).toContain('active')
|
|
})
|
|
|
|
it('defaults to list view for an invalid stored value', async () => {
|
|
localStorage.setItem('chorus_view_mode', 'garbage')
|
|
const wrapper = mount(App)
|
|
await flushPromises()
|
|
const listButton = wrapper.findAll('.view-toggle button').find((b) => b.text() === 'List')
|
|
expect(listButton.classes()).toContain('active')
|
|
})
|
|
|
|
it('clicking Board writes the choice to localStorage', async () => {
|
|
const wrapper = mount(App)
|
|
await flushPromises()
|
|
const boardButton = wrapper.findAll('.view-toggle button').find((b) => b.text() === 'Board')
|
|
await boardButton.trigger('click')
|
|
expect(localStorage.getItem('chorus_view_mode')).toBe('board')
|
|
})
|
|
|
|
it('sets aria-pressed correctly on the view toggle buttons', async () => {
|
|
const wrapper = mount(App)
|
|
await flushPromises()
|
|
const listButton = wrapper.findAll('.view-toggle button').find((b) => b.text() === 'List')
|
|
const boardButton = wrapper.findAll('.view-toggle button').find((b) => b.text() === 'Board')
|
|
expect(listButton.attributes('aria-pressed')).toBe('true')
|
|
expect(boardButton.attributes('aria-pressed')).toBe('false')
|
|
})
|
|
})
|