import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; import vm from 'node:vm'; import vue from '@vitejs/plugin-vue'; import { createServer } from 'vite'; import { createSSRApp, h } from 'vue'; import { renderToString } from 'vue/server-renderer'; const server = await createServer({ configFile: false, plugins: [vue()], resolve: { alias: { '@': fileURLToPath(new URL('../../resources/js', import.meta.url)), }, }, server: { middlewareMode: true, hmr: false, watch: null }, appType: 'custom', }); function browserState(cookie, stored, dark, storageDenied = false) { const root = { dataset: { appearance: cookie }, style: {}, dark: false }; root.classList = { toggle: (_, value) => { root.dark = value; }, }; const listeners = new Map(); const storage = new Map(stored === null ? [] : [['appearance', stored]]); const media = { matches: dark, addEventListener: (_, listener) => listeners.set('media', listener), removeEventListener: () => listeners.delete('media'), }; return { document: { documentElement: root, cookie: '' }, window: { matchMedia: () => media, localStorage: { getItem: (key) => { if (storageDenied) { throw new Error('Storage denied'); } return storage.get(key) ?? null; }, setItem: (key, value) => { if (storageDenied) { throw new Error('Storage denied'); } storage.set(key, value); }, }, addEventListener: (_, listener) => listeners.set('storage', listener), removeEventListener: () => listeners.delete('storage'), }, root, media, listeners, storage, }; } try { const { createAppearance, normalizeAppearance } = await server.ssrLoadModule( '/resources/js/composables/useAppearance.ts', ); const { createLocalization } = await server.ssrLoadModule( '/resources/js/lib/localization.ts', ); const { default: AppearanceTabs } = await server.ssrLoadModule( '/resources/js/components/AppearanceTabs.vue', ); const renderTheme = (value) => renderToString( createSSRApp({ render: () => h(AppearanceTabs) }) .use(createLocalization()) .use(createAppearance(value)), ); const [light, dark] = await Promise.all([ renderTheme('light'), renderTheme('dark'), ]); assert.match(light, /value="light"[^>]*checked/); assert.match(dark, /value="dark"[^>]*checked/); assert.match(light, /Color theme<\/legend>/); assert.equal((light.match(/type="radio"/g) ?? []).length, 3); assert.equal((dark.match(/ checked/g) ?? []).length, 1); assert.equal(normalizeAppearance('unexpected'), 'system'); const blade = await readFile('resources/views/app.blade.php', 'utf8'); const bootstrap = blade.match(/