import { mount } from '@vue/test-utils' import type { Ref } from 'vue' import { beforeEach, describe, expect, it, vi } from 'vitest' import PwaUpdatePrompt from './PwaUpdatePrompt.vue' /** 用 hoisted 持有引用,让测试可以驱动 needRefresh / offlineReady */ const stub = vi.hoisted(() => ({ needRefresh: null as unknown as Ref, offlineReady: null as unknown as Ref, updateServiceWorker: null as unknown as ReturnType, })) vi.mock('virtual:pwa-register/vue', async () => { const { ref } = await import('vue') stub.needRefresh = ref(false) stub.offlineReady = ref(false) stub.updateServiceWorker = vi.fn() return { useRegisterSW: () => stub } }) function mountPrompt() { return mount(PwaUpdatePrompt, { attachTo: document.body }) } describe('PwaUpdatePrompt', () => { beforeEach(() => { stub.needRefresh.value = false stub.offlineReady.value = false stub.updateServiceWorker.mockClear() }) it('无状态时不渲染', () => { const wrapper = mountPrompt() expect(wrapper.find('[role="status"]').exists()).toBe(false) }) it('有新版本时提示并可立即更新', async () => { stub.needRefresh.value = true const wrapper = mountPrompt() await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('有新版本可用') const updateButton = wrapper.findAll('button').find((node) => node.text() === '立即更新') await updateButton?.trigger('click') // 传 true 表示更新后立即刷新页面 expect(stub.updateServiceWorker).toHaveBeenCalledWith(true) }) it('已可离线使用时提示,但不显示更新按钮', async () => { stub.offlineReady.value = true const wrapper = mountPrompt() await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('已缓存,可离线使用') expect(wrapper.findAll('button').map((node) => node.text())).not.toContain('立即更新') }) it('点击关闭后提示消失', async () => { stub.needRefresh.value = true const wrapper = mountPrompt() await wrapper.vm.$nextTick() await wrapper.find('button[aria-label="关闭提示"]').trigger('click') await wrapper.vm.$nextTick() expect(stub.needRefresh.value).toBe(false) expect(wrapper.find('[role="status"]').exists()).toBe(false) }) it('带 role=status 便于读屏播报', async () => { stub.offlineReady.value = true const wrapper = mountPrompt() await wrapper.vm.$nextTick() expect(wrapper.find('[role="status"]').exists()).toBe(true) }) })