refine workbench page usability
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,7 @@
|
||||
<span class="icon">⚙</span>
|
||||
<span>管理员配置台</span>
|
||||
</button>
|
||||
<button class="nav-item">
|
||||
<button class="nav-item" data-screen-target="settings">
|
||||
<span class="icon">☰</span>
|
||||
<span>设置</span>
|
||||
</button>
|
||||
@@ -1915,6 +1915,7 @@
|
||||
</section>
|
||||
|
||||
<section class="screen" data-screen="admin-workbench"></section>
|
||||
<section class="screen" data-screen="settings"></section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
|
||||
49
web/storyforge-web-v4/tests/workbench-pages.test.mjs
Normal file
49
web/storyforge-web-v4/tests/workbench-pages.test.mjs
Normal file
@@ -0,0 +1,49 @@
|
||||
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");
|
||||
|
||||
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"/);
|
||||
});
|
||||
Reference in New Issue
Block a user