diff --git a/apps/viewer/src/__tests__/ad-carousel.spec.ts b/apps/viewer/src/__tests__/ad-carousel.spec.ts index 24596f5..88f6919 100644 --- a/apps/viewer/src/__tests__/ad-carousel.spec.ts +++ b/apps/viewer/src/__tests__/ad-carousel.spec.ts @@ -38,7 +38,8 @@ function currentSrc(wrapper: VueWrapper): string | null { /** 图加载失败(含现签 URL 过期)→ emit imageError(adId)(2026-09-29 裂图自愈)。 */ function triggerImgError(wrapper: VueWrapper): void { - wrapper.find('.ad-slide img').trigger('error'); + // 触发活跃帧的图错误(头/尾克隆帧常驻轨道,首个 .ad-slide 是头克隆)。 + wrapper.find('.ad-slide.active img').trigger('error'); } describe('AdCarousel', () => { @@ -81,7 +82,7 @@ describe('AdCarousel', () => { it('opens the current ad link in a new tab via window.open', async () => { const wrapper = mountCarousel(); - await wrapper.get('.ad-slide').trigger('click'); + await wrapper.get('.ad-slide.active').trigger('click'); expect(openSpy).toHaveBeenCalledWith('https://link.test/a', '_blank', 'noopener,noreferrer'); }); @@ -128,4 +129,19 @@ describe('AdCarousel', () => { expect(emitted).toHaveLength(1); expect(emitted![0]).toEqual(['a']); // 当前帧(index 0)的 adId }); + + it('wraps last→first as one natural leftward slide then a silent snap', async () => { + const wrapper = mountCarousel(ADS); + await vi.advanceTimersByTimeAsync(8000); // a→b→c(真实末帧) + expect(currentSrc(wrapper)).toBe('https://ad.test/c.jpg'); + expect(wrapper.find('.ad-slides').attributes('style')).toContain('translateX(-300%)'); + await vi.advanceTimersByTimeAsync(4000); // 环回:a 经尾克隆右→左滑入 + expect(currentSrc(wrapper)).toBe('https://ad.test/a.jpg'); // 活跃真实帧已回 a + let track = wrapper.find('.ad-slides'); + expect(track.attributes('style')).toContain('translateX(-400%)'); // 视觉在尾克隆位 + expect(track.classes()).not.toContain('no-transition'); + await vi.advanceTimersByTimeAsync(600); // 过渡结束 → 关过渡瞬时回位 + track = wrapper.find('.ad-slides'); + expect(track.attributes('style')).toContain('translateX(-100%)'); // 等视觉真实首帧 + }); }); diff --git a/apps/viewer/src/components/ads/AdCarousel.vue b/apps/viewer/src/components/ads/AdCarousel.vue index c6c7826..d1cb670 100644 --- a/apps/viewer/src/components/ads/AdCarousel.vue +++ b/apps/viewer/src/components/ads/AdCarousel.vue @@ -1,5 +1,5 @@