A calm place to write long-form, and publish it to the open social web. skypress.blog/
0

Configure Feed

Select the types of activity you want to include in your feed.

at trunk 3.1 kB View raw
1/** 2 * Source-level guard for the client:only island loading fallback. 3 * 4 * `dashboard.astro` and `editor.astro` mount browser-only React islands 5 * (`client:only`). Until their JS bundle loads, Astro shows the `slot="fallback"` 6 * markup. That fallback must carry the durable page chrome — a logo-only header 7 * (matching AppBar's `status === 'loading'` state) plus a content skeleton — so 8 * the page has shape before hydration instead of a bare, left-aligned "Loading…". 9 * 10 * Rendering the pages through astro/container isn't viable here (the runner is 11 * pinned to jsdom for the WordPress block suites), so these assertions pin the 12 * wiring at the source level — same approach as `_index.phase.test.ts`. 13 */ 14import { readFileSync } from 'node:fs'; 15import { fileURLToPath } from 'node:url'; 16import { describe, expect, it } from 'vitest'; 17 18const read = ( rel: string ) => 19 readFileSync( fileURLToPath( new URL( rel, import.meta.url ) ), 'utf8' ); 20 21describe( 'LoadingScene fallback', () => { 22 const scene = read( './LoadingScene.astro' ); 23 24 it( 'renders the durable logo header using the shared app-bar classes', () => { 25 expect( scene ).toMatch( /class="app-bar"/ ); 26 expect( scene ).toMatch( /class="app-bar__home"/ ); 27 expect( scene ).toMatch( /class="app-bar__word"/ ); 28 expect( scene ).toMatch( /SkyPress/ ); 29 } ); 30 31 it( 'omits the dynamic nav + identity (auth state is unknown pre-hydration)', () => { 32 expect( scene ).not.toMatch( /app-bar__nav/ ); 33 expect( scene ).not.toMatch( /app-bar__identity/ ); 34 expect( scene ).not.toMatch( /app-bar__signout/ ); 35 } ); 36 37 it( 'renders shimmering skeleton placeholders', () => { 38 expect( scene ).toMatch( /class="sk\b/ ); 39 expect( scene ).toMatch( /@keyframes/ ); 40 } ); 41 42 it( 'flags the region as busy and keeps an accessible loading label', () => { 43 expect( scene ).toMatch( /aria-busy="true"/ ); 44 expect( scene ).toMatch( /Loading…/ ); 45 } ); 46 47 it( 'stills the shimmer for reduced-motion users', () => { 48 expect( scene ).toMatch( /prefers-reduced-motion/ ); 49 } ); 50 51 it( 'offers distinct dashboard and editor variants', () => { 52 expect( scene ).toMatch( /'dashboard'\s*\|\s*'editor'/ ); 53 expect( scene ).toMatch( /variant === 'dashboard'/ ); 54 } ); 55} ); 56 57describe( 'island fallbacks use LoadingScene', () => { 58 const dashboard = read( '../pages/dashboard.astro' ); 59 const editor = read( '../pages/editor.astro' ); 60 61 it( 'dashboard fallback renders LoadingScene, not a bare "Loading…"', () => { 62 expect( dashboard ).toMatch( /import LoadingScene from '[^']*LoadingScene.astro'/ ); 63 expect( dashboard ).toMatch( /<LoadingScene[\s\S]*?slot="fallback"/ ); 64 expect( dashboard ).toMatch( /variant="dashboard"/ ); 65 expect( dashboard ).not.toMatch( /class="dash__loading">Loading…/ ); 66 } ); 67 68 it( 'editor fallback renders LoadingScene, not a bare "Loading…"', () => { 69 expect( editor ).toMatch( /import LoadingScene from '[^']*LoadingScene.astro'/ ); 70 expect( editor ).toMatch( /<LoadingScene[\s\S]*?slot="fallback"/ ); 71 expect( editor ).toMatch( /variant="editor"/ ); 72 expect( editor ).not.toMatch( /class="editor-shell__loading">Loading…/ ); 73 } ); 74} );