/** * 页签栏右侧工具区(照 vben 的 TabsTool*):更多 / 刷新当前页 / 内容最大化。 * 挂载真实 App(布局、页签、store、路由全真),覆盖: * 1. 三个工具按钮渲染 * 2. 内容最大化:顶栏摘除 + is-maximized 标记(侧栏由该标记隐藏),页签栏保留;再次点击还原 * 3. 刷新按钮:当前页刷新计数 +1(页面组件重挂载由 keepalive-cache 用例覆盖) * 4. 「更多」菜单 = 当前激活页签的上下文菜单(与右键菜单同源),点击菜单项生效 */ import { describe, it, expect, beforeEach, vi } from 'vitest' import { flushPromises, mount } from '@vue/test-utils' vi.mock('@/views/dashboard/index.vue', () => ({ default: { name: 'Dashboard', template: '
DB
' }, })) vi.mock('@/views/module/module-management/index.vue', () => ({ default: { name: 'ModuleManagement', template: '
MM
' }, })) vi.mock('@/views/module/menu-management/index.vue', () => ({ default: { name: 'MenuManagement', template: '
MENU
' }, })) vi.mock('@/views/detail/DetailPage.vue', () => ({ default: { name: 'DetailPageStub', props: ['id'], template: '
' }, })) vi.mock('@/services/api', () => ({ loadDataApi: vi.fn(() => Promise.resolve({ data: [], code: 0, success: true })), describeApi: vi.fn(() => Promise.resolve({ data: [], code: 0, success: true })), saveObjectApi: vi.fn(() => Promise.resolve({ code: 0, success: true })), nextIdApi: vi.fn(() => Promise.resolve({ data: 1, code: 0, success: true })), })) import App from '@/App.vue' import router from '@/router' import { createTestPinia } from '../helpers/app.js' import { useAuthStore } from '@/stores/auth' import { useAppStore } from '@/stores/app' beforeEach(async () => { localStorage.clear() sessionStorage.clear() createTestPinia() // 模块中心 /module/* 在路由层仅 g3soft 放行 useAuthStore().setSession({ token: 't', user: { id: 1, account: 'g3soft', name: 'U' } }, 'ORG') await router.push('/dashboard') await router.isReady() }) async function mountApp() { const wrapper = mount(App, { global: { plugins: [router] }, attachTo: document.body }) await flushPromises() return wrapper } const TOOL_MORE = 0 const TOOL_REFRESH = 1 const TOOL_MAXIMIZE = 2 describe('页签栏右侧工具区', () => { it('渲染三个工具按钮:更多 / 刷新 / 内容最大化', async () => { const wrapper = await mountApp() expect(wrapper.findAll('.fms-tabs-tool')).toHaveLength(3) wrapper.unmount() }) it('内容最大化:顶栏摘除、侧栏标记隐藏,页签栏保留;再次点击还原', async () => { const wrapper = await mountApp() const app = useAppStore() // 最大化前:顶栏在、无 is-maximized 标记 expect(wrapper.find('.fms-topbar').exists()).toBe(true) expect(wrapper.find('.fms-layout').classes()).not.toContain('is-maximized') await wrapper.findAll('.fms-tabs-tool')[TOOL_MAXIMIZE].trigger('click') expect(app.contentMaximized).toBe(true) // 顶栏由模板 v-if 摘除;侧栏由 .is-maximized 的 display:none 隐藏(jsdom 不算样式,断言标记) expect(wrapper.find('.fms-topbar').exists()).toBe(false) expect(wrapper.find('.fms-layout').classes()).toContain('is-maximized') // 页签栏保留 —— 它是还原入口 expect(wrapper.find('.fms-tabs').exists()).toBe(true) await wrapper.findAll('.fms-tabs-tool')[TOOL_MAXIMIZE].trigger('click') expect(app.contentMaximized).toBe(false) expect(wrapper.find('.fms-topbar').exists()).toBe(true) wrapper.unmount() }) it('刷新按钮:点击后当前页刷新计数 +1', async () => { const wrapper = await mountApp() await router.push('/module/module-management') await flushPromises() const app = useAppStore() const before = app.getRouteRefreshKey('/module/module-management') await wrapper.findAll('.fms-tabs-tool')[TOOL_REFRESH].trigger('click') expect(app.getRouteRefreshKey('/module/module-management')).toBe(before + 1) wrapper.unmount() }) it('更多菜单:为当前激活页签的上下文菜单,点击「关闭其他」生效', async () => { const wrapper = await mountApp() // 制造多个页签:工作台 + 菜单管理 + 模块管理(激活) await router.push('/module/menu-management') await flushPromises() await router.push('/module/module-management') await flushPromises() await wrapper.findAll('.fms-tabs-tool')[TOOL_MORE].trigger('click') await flushPromises() // 浮层经 Teleport 渲染到 body const menuItems = Array.from(document.querySelectorAll('.dropdown-item')) const labels = menuItems.map((el) => el.textContent.trim()) expect(labels).toContain('刷新') expect(labels).toContain('关闭其他') expect(labels).toContain('关闭全部') const closeOthers = menuItems.find((el) => el.textContent.trim() === '关闭其他') closeOthers.click() await flushPromises() // 仅保留工作台与当前激活页签 const app = useAppStore() expect(app.visitedTabs.map((t) => t.key)).toEqual(['/dashboard', '/module/module-management']) wrapper.unmount() }) })