Files
pleno-vue/tests/unit/app-loading-shell.spec.js
T

89 lines
4.8 KiB
JavaScript

// @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('<html lang="" class="theme-light tw-bootstrap-loading" data-theme="light">');
expect(indexHtml).toContain('<div id="app">');
expect(indexHtml).not.toContain('<div id="app"></div>');
expect(indexHtml).toContain('<body class="tw-bootstrap-loading">');
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(/<Suspense/g) || []).toHaveLength(4);
expect(appVue.split('<BrandedLoadingScreen v-bind="appRouteLoadingProps" />')).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)");
});
});