070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
// Plugins-home HTML preview surface — reachability fallback.
|
|
//
|
|
// The home gallery used to render a permanently-blank tile when a
|
|
// plugin declared an `od.preview.entry` that 404'd on the daemon
|
|
// (the iframe quietly painted the JSON error envelope as white).
|
|
// The HtmlSurface now probes the URL once per session and swaps
|
|
// in a typographic fallback tile when the URL is unreachable.
|
|
//
|
|
// This file:
|
|
// - asserts the iframe is mounted when the probe succeeds;
|
|
// - asserts the typographic fallback renders (and the iframe is
|
|
// skipped) when the probe reports the URL is unreachable.
|
|
|
|
import { describe, expect, it, afterEach, beforeEach, vi } from 'vitest';
|
|
import { cleanup, render, waitFor } from '@testing-library/react';
|
|
import {
|
|
HtmlSurface,
|
|
__resetHtmlSurfaceProbeCacheForTests,
|
|
} from '../../src/components/plugins-home/cards/HtmlSurface';
|
|
import type { HtmlPreviewSpec } from '../../src/components/plugins-home/preview';
|
|
|
|
const PREVIEW: HtmlPreviewSpec = {
|
|
kind: 'html',
|
|
src: '/api/plugins/example-html-ppt/preview',
|
|
label: 'index.html',
|
|
source: 'preview',
|
|
};
|
|
|
|
const okResponse = (): Response =>
|
|
({ ok: true, status: 200 } as unknown as Response);
|
|
const notFoundResponse = (): Response =>
|
|
({ ok: false, status: 404 } as unknown as Response);
|
|
|
|
beforeEach(() => {
|
|
__resetHtmlSurfaceProbeCacheForTests();
|
|
});
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
__resetHtmlSurfaceProbeCacheForTests();
|
|
vi.unstubAllGlobals();
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
describe('HtmlSurface reachability probe', () => {
|
|
it('renders the iframe once the URL probes OK and the auto-arm window elapses', async () => {
|
|
vi.stubGlobal('fetch', vi.fn().mockResolvedValue(okResponse()));
|
|
const { container } = render(
|
|
<HtmlSurface
|
|
preview={PREVIEW}
|
|
pluginId="example-html-ppt"
|
|
pluginTitle="Html Ppt"
|
|
inView
|
|
/>,
|
|
);
|
|
// First the skeleton frame should appear, then after the 280ms
|
|
// arm timer the iframe should mount.
|
|
await waitFor(
|
|
() => {
|
|
expect(container.querySelector('iframe')).toBeTruthy();
|
|
},
|
|
{ timeout: 2000 },
|
|
);
|
|
expect(
|
|
container.querySelector('[data-testid="plugins-home-html-fallback"]'),
|
|
).toBeNull();
|
|
});
|
|
|
|
it('renders the typographic fallback (no iframe) when the URL 404s', async () => {
|
|
vi.stubGlobal('fetch', vi.fn().mockResolvedValue(notFoundResponse()));
|
|
const { container } = render(
|
|
<HtmlSurface
|
|
preview={PREVIEW}
|
|
pluginId="example-html-ppt"
|
|
pluginTitle="Html Ppt"
|
|
inView
|
|
/>,
|
|
);
|
|
await waitFor(
|
|
() => {
|
|
expect(
|
|
container.querySelector('[data-testid="plugins-home-html-fallback"]'),
|
|
).toBeTruthy();
|
|
},
|
|
{ timeout: 2000 },
|
|
);
|
|
expect(container.querySelector('iframe')).toBeNull();
|
|
expect(
|
|
container.querySelector('.plugins-home__html-fallback-glyph')?.textContent,
|
|
).toBe('H');
|
|
});
|
|
});
|