mirror of
https://github.com/Quad4-Software/MeshChatX.git
synced 2026-08-18 09:49:09 -04:00
127 lines
5.7 KiB
JavaScript
127 lines
5.7 KiB
JavaScript
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
import { readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import {
|
|
MESHCHAT_THEME_VARIABLES_LIGHT,
|
|
MESHCHAT_THEME_VARIABLES_DARK,
|
|
injectMeshchatThemeVariables,
|
|
} from "../../meshchatx/src/frontend/theme/designTokens.js";
|
|
|
|
const ROOT = resolve(import.meta.dirname, "../..");
|
|
|
|
describe("boot and load smoothness", () => {
|
|
beforeEach(() => {
|
|
document.head.innerHTML = "";
|
|
document.body.innerHTML = "";
|
|
document.documentElement.className = "";
|
|
});
|
|
|
|
afterEach(() => {
|
|
document.head.innerHTML = "";
|
|
document.body.innerHTML = "";
|
|
document.documentElement.className = "";
|
|
});
|
|
|
|
it("index.html uses canvas-colored body instead of gray-100 flash", () => {
|
|
const html = readFileSync(resolve(ROOT, "meshchatx/src/frontend/index.html"), "utf8");
|
|
const bootTheme = readFileSync(resolve(ROOT, "meshchatx/src/frontend/public/boot-theme.js"), "utf8");
|
|
expect(html).not.toMatch(/body class="bg-gray-100"/);
|
|
expect(html).toContain("background-color: #f8fafc");
|
|
expect(html).toContain("background-color: #09090b");
|
|
expect(html).toContain('src="/boot-theme.js"');
|
|
expect(html).not.toMatch(/<script(?![^>]*\bsrc=)[^>]*>/);
|
|
expect(bootTheme).toContain("meshchatx_ui_theme");
|
|
expect(bootTheme).toContain("getPreferredUiTheme");
|
|
expect(html).toContain('id="meshchatx-boot-splash"');
|
|
expect(html).toContain('id="app"');
|
|
});
|
|
|
|
it("style.css paints html/body/#app with semantic canvas", () => {
|
|
const css = readFileSync(resolve(ROOT, "meshchatx/src/frontend/style.css"), "utf8");
|
|
expect(css).toContain("background-color: var(--mc-canvas");
|
|
expect(css).toContain("#app");
|
|
expect(css).toContain(".route-view-fade-enter-active");
|
|
});
|
|
|
|
it("main.js defers splash removal and preloads critical routes", () => {
|
|
const main = readFileSync(resolve(ROOT, "meshchatx/src/frontend/main.js"), "utf8");
|
|
expect(main).toContain("removeBootSplash");
|
|
expect(main).toContain("requestAnimationFrame");
|
|
expect(main).toContain("preloadCriticalRouteChunks");
|
|
expect(main).toContain('import("./components/messages/MessagesPage.vue")');
|
|
expect(main).toContain("ElectronUtils.isElectron()");
|
|
expect(main).toContain("serviceWorkerRegisterOptions");
|
|
expect(main).toContain("decideControllerChangeReload");
|
|
expect(main).toContain("shouldRegisterServiceWorker");
|
|
expect(main).toContain("import.meta.env.DEV");
|
|
});
|
|
|
|
it("App.vue fades non-keepAlive route swaps on canvas background", () => {
|
|
const app = readFileSync(resolve(ROOT, "meshchatx/src/frontend/components/App.vue"), "utf8");
|
|
expect(app).toContain('name="route-view-fade"');
|
|
expect(app).toContain("bg-sem-canvas");
|
|
expect(app).toContain("setUiTheme");
|
|
expect(app).toContain("meshchatx_ui_theme");
|
|
});
|
|
|
|
it("Android theme and WebView use meshchat canvas color", () => {
|
|
const colors = readFileSync(resolve(ROOT, "android/app/src/main/res/values/colors.xml"), "utf8");
|
|
const themes = readFileSync(resolve(ROOT, "android/app/src/main/res/values/themes.xml"), "utf8");
|
|
const layout = readFileSync(resolve(ROOT, "android/app/src/main/res/layout/activity_main.xml"), "utf8");
|
|
const activity = readFileSync(
|
|
resolve(ROOT, "android/app/src/main/java/com/meshchatx/MainActivity.java"),
|
|
"utf8"
|
|
);
|
|
|
|
expect(colors).toContain("meshchat_canvas");
|
|
expect(colors).toContain("#FF09090B");
|
|
expect(colors).toContain("meshchat_canvas_light");
|
|
expect(colors).toContain("#FFF8FAFC");
|
|
expect(themes).toContain("android:windowBackground");
|
|
expect(layout).toContain("@color/meshchat_canvas");
|
|
expect(activity).toContain("applyShellCanvasTheme");
|
|
expect(activity).toContain("setUiTheme");
|
|
expect(activity).toContain("setLocalNightMode");
|
|
});
|
|
|
|
it("injectMeshchatThemeVariables keeps light/dark canvas tokens aligned", () => {
|
|
injectMeshchatThemeVariables(document);
|
|
const style = document.getElementById("meshchat-design-tokens");
|
|
expect(style).toBeTruthy();
|
|
expect(style.textContent).toContain(MESHCHAT_THEME_VARIABLES_LIGHT["--mc-canvas"]);
|
|
expect(style.textContent).toContain(MESHCHAT_THEME_VARIABLES_DARK["--mc-canvas"]);
|
|
expect(MESHCHAT_THEME_VARIABLES_LIGHT["--mc-canvas"]).toBe("#f8fafc");
|
|
expect(MESHCHAT_THEME_VARIABLES_DARK["--mc-canvas"]).toBe("#09090b");
|
|
});
|
|
|
|
it("removeBootSplash fades then removes without leaving white gap", async () => {
|
|
vi.useFakeTimers();
|
|
const splash = document.createElement("div");
|
|
splash.id = "meshchatx-boot-splash";
|
|
splash.setAttribute("aria-busy", "true");
|
|
document.body.appendChild(splash);
|
|
|
|
function removeBootSplash(el) {
|
|
if (!el || !el.isConnected) {
|
|
return;
|
|
}
|
|
el.setAttribute("aria-busy", "false");
|
|
el.style.transition = "opacity 140ms ease";
|
|
el.style.opacity = "0";
|
|
window.setTimeout(() => {
|
|
if (el.isConnected) {
|
|
el.remove();
|
|
}
|
|
}, 160);
|
|
}
|
|
|
|
removeBootSplash(splash);
|
|
expect(splash.getAttribute("aria-busy")).toBe("false");
|
|
expect(splash.style.opacity).toBe("0");
|
|
expect(document.getElementById("meshchatx-boot-splash")).toBeTruthy();
|
|
|
|
vi.advanceTimersByTime(160);
|
|
expect(document.getElementById("meshchatx-boot-splash")).toBeNull();
|
|
vi.useRealTimers();
|
|
});
|
|
});
|