// @vitest-environment node import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { describe, expect, it } from "vitest"; const TEST_DIR = path.dirname(fileURLToPath(import.meta.url)); const PROJECT_ROOT = path.resolve(TEST_DIR, "../.."); const readProjectFile = (relativePath) => fs.readFileSync(path.join(PROJECT_ROOT, relativePath), "utf8"); describe("app loading shell", () => { it("renders a branded bootstrap loader before Vue mounts", () => { const indexHtml = readProjectFile("index.html"); expect(indexHtml).toContain("__TW_LOADER_STARTED_AT__"); expect(indexHtml).toContain(''); expect(indexHtml).toContain('
'); expect(indexHtml).not.toContain('
'); expect(indexHtml).toContain(''); expect(indexHtml).toContain("html.tw-bootstrap-loading"); expect(indexHtml).toContain("font-size: 16px !important"); expect(indexHtml).toContain("background: #fff"); expect(indexHtml).toContain("body.tw-bootstrap-loading"); expect(indexHtml).toContain("background: #041f32"); expect(indexHtml).toContain("html.tw-loader-scroll-lock"); expect(indexHtml).toContain("body.tw-loader-scroll-lock"); expect(indexHtml).toContain('data-testid="app-bootstrap-loading"'); expect(indexHtml).toContain('data-testid="app-bootstrap-loading-status"'); expect(indexHtml).toContain('role="status"'); expect(indexHtml).toContain('aria-live="polite"'); expect(indexHtml).toContain("Indlæser..."); expect(indexHtml).toContain("Vi gør kundeportalen klar"); expect(indexHtml).toContain("usesSessionLoader"); expect(indexHtml).toContain("hasStoredSession"); expect(indexHtml).toContain("usesGuestSessionLoader"); expect(indexHtml).toContain("Bekræfter bruger..."); expect(indexHtml).toContain("Vi indlæser din session"); expect(indexHtml).toContain("--tw-loader-spin-delay"); expect(indexHtml).toContain("--tw-loader-sweep-delay"); expect(indexHtml).toContain("--tw-loader-dot-three-delay"); expect(indexHtml).toContain("%BASE_URL%assets/branding/truckwash-banner-white-compressed.png"); expect(indexHtml).toContain("@media (prefers-reduced-motion: reduce)"); expect(indexHtml).not.toContain('src="/assets/'); }); it("keeps the bootstrap logo available as a public asset", () => { const sourceLogo = fs.readFileSync( path.join(PROJECT_ROOT, "src/assets/branding/truckwash-banner-white-compressed.png") ); const publicLogo = fs.readFileSync( path.join(PROJECT_ROOT, "public/assets/branding/truckwash-banner-white-compressed.png") ); expect(publicLogo.equals(sourceLogo)).toBe(true); }); it("uses the branded Vue fallback for async app routes", () => { const appVue = readProjectFile("src/App.vue"); const mainJs = readProjectFile("src/main.js"); const routerJs = readProjectFile("src/router.js"); const brandedLoaderVue = readProjectFile("src/components/global/BrandedLoadingScreen.vue"); expect(appVue).toContain('import BrandedLoadingScreen from "@/components/global/BrandedLoadingScreen.vue"'); expect(appVue).toContain("sessionRouteLoadingProps"); expect(appVue).toContain("sessionLoaderRoutePattern"); expect(appVue).toContain("guestSessionLoaderRoutePattern"); expect(appVue).toContain("currentBrowserPath"); expect(appVue).toContain("hasRouteMiddleware"); expect(appVue).toContain("shouldUseGuestSessionPathLoader"); expect(appVue).toContain("shouldUseSessionRouteLoader"); expect(appVue).toContain('hasRouteMiddleware("guestMiddleware")'); expect(appVue).toContain('testId: "app-route-loading"'); expect(appVue).toContain('statusTestId: "app-route-loading-status"'); expect(appVue.match(/')).toHaveLength(5); expect(brandedLoaderVue).toContain("font-family: Avenir, system-ui"); expect(brandedLoaderVue).toContain("font-size: 16px !important"); expect(brandedLoaderVue).toContain("__TW_LOADER_STARTED_AT__"); expect(brandedLoaderVue).toContain("--branded-loader-spin-delay"); expect(brandedLoaderVue).toContain("--branded-loader-dot-three-delay"); expect(brandedLoaderVue.match(/box-sizing: border-box;/g) || []).toHaveLength(2); expect(routerJs).toContain("name: 'landing'"); expect(routerJs).toContain("meta: { template: 'with-header', middleware: guestMiddleware }"); expect(mainJs).toContain('document.documentElement?.classList.remove("tw-bootstrap-loading")'); expect(mainJs).toContain('classList.remove("tw-bootstrap-loading")'); expect(mainJs).toContain("window.setTimeout(releaseBootstrapScrollLock, 0)"); }); });