test(plugins): trim redundant refresh/tooltip coverage

Drop the plugin-manager refresh e2e to a single failure round: the store's
success and retry outcomes are covered deterministically by
manager-store.client.spec.ts, while the e2e keeps its unique value — real
500ms tooltip timing, a running spinner animation, aria-busy, and the
portaled failure toast over kept cards. Regenerate refresh.expected.md.

Remove the components spec tooltip-delay case; ui-primitives'
tooltip.client.spec.tsx already covers 499/500ms hover/focus delay, early
cancellation, and portaling. PluginManagerPage.tsx stays at 100% coverage.
This commit is contained in:
Yif committed 2026-09-27 02:28:09 +08:00
1 parent 9c6bdd020c
commit 9fabb67bca
3 files changed
+7 -65

No files matched your search

@@ -4,21 +4,9 @@ Hover at 500ms:
Focus at 499ms: 0 tooltips
Focus at 500ms:
- tooltip "刷新"
success: pending
- button "刷新" [disabled]
{"busy":"true","spinners":1,"cards":11,"skeletons":0,"alerts":[],"retry":0,"toasts":[]}
success: settled
- button "刷新"
{"busy":"false","spinners":0,"cards":11,"skeletons":0,"alerts":[],"retry":0,"toasts":[]}
failure: pending
- button "刷新" [disabled]
{"busy":"true","spinners":1,"cards":11,"skeletons":0,"alerts":[],"retry":0,"toasts":[]}
failure: settled
- button "刷新"
{"busy":"false","spinners":0,"cards":11,"skeletons":0,"alerts":[],"retry":0,"toasts":["刷新失败,请重试"]}
retry: pending
- button "刷新" [disabled]
{"busy":"true","spinners":1,"cards":11,"skeletons":0,"alerts":[],"retry":0,"toasts":[]}
retry: settled
- button "刷新"
{"busy":"false","spinners":0,"cards":11,"skeletons":0,"alerts":[],"retry":0,"toasts":[]}
+7 -10
View File
@@ -283,14 +283,15 @@ describe('web e2e: plugin manager', () => {
await probe.clock.pauseAt(await probe.evaluate(() => Date.now() + 1000))
const spy = vi.spyOn(scaffold.ctx.pluginManager, 'listBundles')
try {
for (const outcome of ['success', 'failure', 'retry'] as const) {
{
// One failure round exercises the full path: kept cards and spinner while pending,
// then the failure toast with no inline error over the stale cards. Success and retry
// outcomes are the store's deterministic concern, covered by manager-store.client.spec.ts.
const outcome = 'failure' as const
const release = Promise.withResolvers<undefined>()
const called = spy.mock.calls.length
spy.mockImplementationOnce(() => {
const read = release.promise.then(() => {
if (outcome === 'failure') throw new Error('Fixture plugin refresh failed')
return listBundles()
})
const read = release.promise.then(() => { throw new Error('Fixture plugin refresh failed') })
reads.push(read)
return read
})
@@ -320,11 +321,7 @@ describe('web e2e: plugin manager', () => {
expect(await panel.getByRole('alert').count()).toBe(0)
expect(await panel.getByRole('button', { name: '重试', exact: true }).count()).toBe(0)
const toasts = probe.locator('body > [role="alert"]')
if (outcome === 'failure') {
await expect.poll(() => toasts.allTextContents()).toEqual(['刷新失败,请重试'])
} else {
expect(await toasts.count()).toBe(0)
}
await expect.poll(() => toasts.allTextContents()).toEqual(['刷新失败,请重试'])
await recordRefresh(`${outcome}: settled`)
} finally {
release.resolve(undefined)
@@ -364,49 +364,6 @@ describe('PluginManagerPage', () => {
}
})
it.each(['hover', 'keyboard'] as const)('shows a portaled refresh tooltip after 500ms of %s and cancels early departure', (trigger) => {
vi.useFakeTimers()
try {
const { unmount } = renderTab()
const refresh = screen.getByRole('button', { name: en.refresh })
const enter = () => {
if (trigger === 'hover') fireEvent.mouseEnter(refresh)
else {
fireEvent.keyDown(document, { key: 'Tab' })
fireEvent.focus(refresh)
}
}
const leave = () => {
if (trigger === 'hover') fireEvent.mouseLeave(refresh)
else fireEvent.blur(refresh)
}
expect(refresh.getAttribute('title')).toBeNull()
enter()
act(() => { vi.advanceTimersByTime(499) })
expect(screen.queryByRole('tooltip', { hidden: true })).toBeNull()
leave()
act(() => { vi.advanceTimersByTime(1) })
expect(screen.queryByRole('tooltip', { hidden: true })).toBeNull()
enter()
act(() => { vi.advanceTimersByTime(499) })
expect(screen.queryByRole('tooltip', { hidden: true })).toBeNull()
act(() => { vi.advanceTimersByTime(1) })
const tooltip = screen.getByRole('tooltip', { hidden: true })
expect(tooltip.textContent).toBe(en.refresh)
expect(tooltip.parentElement).toBe(document.body)
fireEvent.click(refresh)
expect(screen.queryByRole('tooltip', { hidden: true })).toBeNull()
leave()
enter()
unmount()
act(() => { vi.advanceTimersByTime(500) })
expect(screen.queryByRole('tooltip', { hidden: true })).toBeNull()
} finally {
cleanup()
vi.useRealTimers()
}
})
it('keeps the read failure and its retry visible while a detail page is open', () => {
const { actions, set } = renderTab({ packages: [pkg()] })
fireEvent.click(screen.getByRole('button', { name: en.openDetail.replace('{name}', 'dsh-better-sidebar') }))