78 lines
4.1 KiB
JavaScript
78 lines
4.1 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const ROOT = path.resolve(process.cwd(), "web/storyforge-web-v4");
|
|
const HTML = fs.readFileSync(path.join(ROOT, "index.html"), "utf8");
|
|
const APP = fs.readFileSync(path.join(ROOT, "assets/app.js"), "utf8");
|
|
const CSS = fs.readFileSync(path.join(ROOT, "assets/styles.css"), "utf8");
|
|
|
|
function extractBetween(source, startToken, endToken) {
|
|
const start = source.indexOf(startToken);
|
|
assert.notEqual(start, -1, `Missing token: ${startToken}`);
|
|
const end = source.indexOf(endToken, start);
|
|
assert.notEqual(end, -1, `Missing token: ${endToken}`);
|
|
return source.slice(start, end);
|
|
}
|
|
|
|
test("settings navigation and screen are real routes", () => {
|
|
assert.match(HTML, /data-screen-target="settings"/);
|
|
assert.match(HTML, /data-screen="settings"/);
|
|
assert.match(APP, /function renderSettingsScreen\(/);
|
|
assert.match(APP, /screenMap\.settings\.innerHTML = renderSettingsScreen\(\);/);
|
|
assert.match(APP, /window\.addEventListener\("hashchange"/);
|
|
});
|
|
|
|
test("automation screen stays user-facing and excludes admin-only panels", () => {
|
|
const source = extractBetween(APP, "function renderAutomationScreen()", "function renderOwnedScreen()");
|
|
assert.doesNotMatch(source, /renderTenantQuotaPanel\(/);
|
|
assert.doesNotMatch(source, /renderOneLinerActionRegistryPanel\(/);
|
|
assert.doesNotMatch(source, /renderAdminOpsPanel\(/);
|
|
assert.match(source, /renderDetailTabs\("automationDetailTab"/);
|
|
});
|
|
|
|
test("agent screen excludes quota and registry panels and uses page tabs", () => {
|
|
const source = extractBetween(APP, "function renderPlaybookScreen()", "function renderProductionScreen()");
|
|
assert.doesNotMatch(source, /renderTenantQuotaPanel\(/);
|
|
assert.doesNotMatch(source, /renderOneLinerActionRegistryPanel\(/);
|
|
assert.match(source, /renderDetailTabs\("playbookDetailTab"/);
|
|
});
|
|
|
|
test("discovery, production, and admin screens use page tabs for heavy content", () => {
|
|
const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()");
|
|
const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");
|
|
const admin = extractBetween(APP, "function renderAdminWorkbenchScreen()", "function renderDashboardScreen()");
|
|
|
|
assert.match(discovery, /renderDetailTabs\("discoveryDetailTab"/);
|
|
assert.match(production, /renderDetailTabs\("productionDetailTab"/);
|
|
assert.match(admin, /renderDetailTabs\("adminWorkbenchTab"/);
|
|
});
|
|
|
|
test("projects screen uses an adaptive project grid instead of a fixed three-column squeeze", () => {
|
|
const projects = extractBetween(APP, "function renderProjectsScreen()", "function getActiveDetailTab(");
|
|
assert.match(projects, /project-status-grid/);
|
|
assert.match(CSS, /\.project-status-grid\s*\{[\s\S]*repeat\(auto-fit,\s*minmax\(260px,\s*1fr\)\)/);
|
|
assert.match(CSS, /\.entity-card\.pad\s*\{[\s\S]*padding:\s*15px/);
|
|
});
|
|
|
|
test("dashboard and project screens distinguish auto-connecting from truly disconnected", () => {
|
|
const dashboard = extractBetween(APP, "function renderDashboardScreen()", "function renderProjectsScreen()");
|
|
const projects = extractBetween(APP, "function renderProjectsScreen()", "function getActiveDetailTab(");
|
|
const helper = extractBetween(APP, "function isAutoConnectionPending()", "async function refreshFromAuthModal()");
|
|
|
|
assert.match(APP, /function isAutoConnectionPending\(\)/);
|
|
assert.match(APP, /function renderAutoConnectingScreen\(/);
|
|
assert.match(helper, /正在自动连接工作区/);
|
|
assert.match(dashboard, /isAutoConnectionPending\(\)/);
|
|
assert.match(dashboard, /renderAutoConnectingScreen\("项目总台"/);
|
|
assert.match(projects, /isAutoConnectionPending\(\)/);
|
|
assert.match(projects, /renderAutoConnectingScreen\("我的项目"/);
|
|
});
|
|
|
|
test("ensureAutoSession re-renders immediately when auto-connect starts", () => {
|
|
const source = extractBetween(APP, "async function ensureAutoSession(options = {})", "async function refreshFromAuthModal()");
|
|
assert.match(source, /appState\.autoConnectAttempted = true;/);
|
|
assert.match(source, /renderAll\(\);/);
|
|
});
|