This commit is contained in:
87
src/routing/RouteImageReadyGate.test.ts
Normal file
87
src/routing/RouteImageReadyGate.test.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { act, render, screen } from '@testing-library/react';
|
||||
import { createElement } from 'react';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
collectRouteImageUrls,
|
||||
extractCssImageUrls,
|
||||
normalizePreloadImageUrl,
|
||||
} from './routeImageReadyGateUtils';
|
||||
import { RouteImageReadyGate } from './RouteImageReadyGate';
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
describe('RouteImageReadyGate image url helpers', () => {
|
||||
it('extracts urls from layered CSS image values', () => {
|
||||
expect(
|
||||
extractCssImageUrls(
|
||||
'linear-gradient(#000,#111), url("/hero.png"), url("icons/card.webp")',
|
||||
),
|
||||
).toEqual(['/hero.png', 'icons/card.webp']);
|
||||
});
|
||||
|
||||
it('normalizes preloadable urls against the current document', () => {
|
||||
expect(normalizePreloadImageUrl('/cover.png')).toBe(
|
||||
new URL('/cover.png', document.baseURI).href,
|
||||
);
|
||||
expect(normalizePreloadImageUrl('data:image/png;base64,abc')).toBe(
|
||||
'data:image/png;base64,abc',
|
||||
);
|
||||
expect(normalizePreloadImageUrl('')).toBeNull();
|
||||
});
|
||||
|
||||
it('collects img and CSS background urls from a route root', () => {
|
||||
const root = document.createElement('section');
|
||||
root.innerHTML = `
|
||||
<img src="/images/card.png" />
|
||||
<div style='background-image: url("/images/bg.webp")'></div>
|
||||
<div style='border-image-source: url("/ui/frame.png")'></div>
|
||||
`;
|
||||
|
||||
expect(collectRouteImageUrls(root)).toEqual([
|
||||
new URL('/images/card.png', document.baseURI).href,
|
||||
new URL('/images/bg.webp', document.baseURI).href,
|
||||
new URL('/ui/frame.png', document.baseURI).href,
|
||||
]);
|
||||
});
|
||||
|
||||
it('reveals route content after a short cap when images stay pending', () => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
render(
|
||||
createElement(
|
||||
RouteImageReadyGate,
|
||||
{
|
||||
eyebrow: '正在载入游戏',
|
||||
text: '正在载入冒险...',
|
||||
},
|
||||
createElement(
|
||||
'section',
|
||||
{
|
||||
'data-testid': 'route-content',
|
||||
},
|
||||
createElement('img', {
|
||||
src: '/generated-characters/slow-cover.png',
|
||||
alt: 'slow cover',
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const content = screen.getByTestId('route-content');
|
||||
const visibilityGate = content.parentElement;
|
||||
expect(visibilityGate?.getAttribute('aria-hidden')).toBe('true');
|
||||
expect(visibilityGate?.style.visibility).toBe('hidden');
|
||||
|
||||
act(() => {
|
||||
vi.advanceTimersByTime(1600);
|
||||
});
|
||||
|
||||
expect(visibilityGate?.getAttribute('aria-hidden')).toBe('false');
|
||||
expect(visibilityGate?.style.visibility).toBe('visible');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user