先截图审视现状,再针对性修改。主要问题与改动如下。 工具栏 - 标签筛选从「平铺全部标签」改为下拉面板,标签多时不再换行挤爆工具栏 - 备份与快捷键帮助移到导航栏 —— 它们是应用级操作,不该挤在看板工具栏里, 顺带修好了「? 帮助只在看板可用」的问题 - 到期统计(今日到期 / 逾期)合并为可点击的筛选入口,去掉两个独立控件 - 移动端工具栏从占半屏降到三行紧凑布局 卡片 - 优先级从彩色胶囊改为左侧色条,扫视一列时比读文字更快分辨轻重 - 元信息改为「优先级 · 日期 · 标签」的轻量文本行,不再三种胶囊叠在一起 - 完成态用勾选图标 + 降低不透明度 布局 - 今日视图限宽居中(max-w-3xl):此前 1440px 下卡片被拉满整屏, 标题与元信息之间出现大片空白 - 修复移动端卡片被压成细条:TaskCard 的 overflow-hidden(用于裁切左侧色条) 会让 flex 项的最小尺寸解析为 0,补 shrink-0 修正; 同时改为移动端按内容高度堆叠、桌面端列内滚动 其他 - 导航栏品牌改用看板图标,消除「看板」重复出现两次 - 统一卡片阴影、圆角与键盘焦点样式 - 新增 scripts/screenshot.mjs,便于后续对照审视视觉改动 验证:单元测试 452 个、端到端测试 23 个全部通过,lint 与构建无错误。
87 lines
2.7 KiB
TypeScript
87 lines
2.7 KiB
TypeScript
import { flushPromises, mount } from '@vue/test-utils'
|
|
import { createPinia, setActivePinia } from 'pinia'
|
|
import { createMemoryHistory, createRouter } from 'vue-router'
|
|
import { describe, expect, it } from 'vitest'
|
|
|
|
import { routes } from '@/router'
|
|
import { useUiStore } from '@/stores/ui'
|
|
|
|
import AppNav from './AppNav.vue'
|
|
|
|
async function setup(initialPath = '/') {
|
|
const pinia = createPinia()
|
|
setActivePinia(pinia)
|
|
|
|
const router = createRouter({ history: createMemoryHistory(), routes })
|
|
await router.push(initialPath)
|
|
await router.isReady()
|
|
|
|
const wrapper = mount(AppNav, {
|
|
global: { plugins: [pinia, router] },
|
|
attachTo: document.body,
|
|
})
|
|
|
|
return { wrapper, router, ui: useUiStore() }
|
|
}
|
|
|
|
describe('AppNav 导航', () => {
|
|
it('渲染看板与今日两个入口', async () => {
|
|
const { wrapper } = await setup()
|
|
expect(wrapper.findAll('a').map((node) => node.text())).toEqual(['看板', '今日'])
|
|
})
|
|
|
|
it('当前路由的入口标记 aria-current', async () => {
|
|
const { wrapper } = await setup('/')
|
|
const links = wrapper.findAll('a')
|
|
|
|
expect(links[0]?.attributes('aria-current')).toBe('page')
|
|
expect(links[1]?.attributes('aria-current')).toBeUndefined()
|
|
})
|
|
|
|
it('在今日页时高亮今日入口', async () => {
|
|
const { wrapper } = await setup('/today')
|
|
const links = wrapper.findAll('a')
|
|
|
|
expect(links[0]?.attributes('aria-current')).toBeUndefined()
|
|
expect(links[1]?.attributes('aria-current')).toBe('page')
|
|
})
|
|
|
|
it('点击可切换路由', async () => {
|
|
const { wrapper, router } = await setup('/')
|
|
|
|
await wrapper.findAll('a')[1]?.trigger('click')
|
|
// 路由跳转是异步的,必须等 Promise 落地
|
|
await flushPromises()
|
|
|
|
expect(router.currentRoute.value.path).toBe('/today')
|
|
})
|
|
|
|
it('导航带可访问性标签', async () => {
|
|
const { wrapper } = await setup()
|
|
expect(wrapper.find('nav').attributes('aria-label')).toBe('主导航')
|
|
})
|
|
})
|
|
|
|
describe('AppNav 应用级操作', () => {
|
|
it('点击「备份」打开备份面板', async () => {
|
|
const { wrapper, ui } = await setup()
|
|
expect(ui.backupOpen).toBe(false)
|
|
|
|
const backupButton = wrapper.findAll('button').find((node) => node.text() === '备份')
|
|
await backupButton?.trigger('click')
|
|
|
|
expect(ui.backupOpen).toBe(true)
|
|
})
|
|
|
|
it('点击 ? 打开快捷键帮助', async () => {
|
|
const { wrapper, ui } = await setup()
|
|
await wrapper.find('button[aria-label="快捷键帮助"]').trigger('click')
|
|
expect(ui.helpOpen).toBe(true)
|
|
})
|
|
|
|
it('应用级操作在看板与今日视图下都可用', async () => {
|
|
const { wrapper } = await setup('/today')
|
|
expect(wrapper.findAll('button').map((node) => node.text())).toContain('备份')
|
|
})
|
|
})
|