/**
* Tests for scripts/dashboard-web.js
*/
const assert = require('assert');
const fs = require('fs');
const os = require('os');
const path = require('path');
const http = require('http');
const net = require('net');
const vm = require('vm');
const SCRIPT = path.join(__dirname, '..', '..', 'scripts', 'dashboard-web.js');
let testRoot;
let testPassed = 0;
let testFailed = 0;
const asyncTests = [];
const REQUEST_TIMEOUT_MS = 5000;
for (const override of ['ECC_AGENT_DATA_HOME', 'CLAUDE_CONFIG_DIR']) {
asyncTest(`activity HTTP feed reads real hook output with ${override}`, async () => {
const { spawnSync } = require('child_process');
const dir = createTempDir('ecc-activity-override-');
const saved = Object.fromEntries(['ECC_AGENT_DATA_HOME', 'CLAUDE_CONFIG_DIR', 'CURSOR_VERSION', 'CURSOR_PROJECT_DIR'].map(key => [key, process.env[key]]));
try {
for (const key of Object.keys(saved)) delete process.env[key];
process.env[override] = dir;
const payload = { session_id: `override-${override}`, tool_name: 'Read', tool_input: { file_path: 'fixture.txt' } };
const result = spawnSync(process.execPath, [path.resolve(__dirname, '../../scripts/hooks/session-activity-tracker.js')], {
input: JSON.stringify(payload), encoding: 'utf8', timeout: 10000, env: process.env,
});
assert.strictEqual(result.status, 0, result.stderr);
assert.ok(fs.existsSync(path.join(dir, 'metrics', 'tool-usage.jsonl')));
await withDashboardServer(async port => {
const response = await requestDashboard(port, { path: '/api/activity' });
assert.strictEqual(response.statusCode, 200);
const { entries } = JSON.parse(response.body);
assert.strictEqual(entries.length, 1);
assert.strictEqual(entries[0].session_id, payload.session_id);
assert.strictEqual(entries[0].tool_name, 'Read');
});
} finally {
for (const [key, value] of Object.entries(saved)) {
if (value === undefined) delete process.env[key];
else process.env[key] = value;
}
cleanup(dir);
}
});
}
test('renderHTML emits executable scripts without syntax errors', () => {
const { renderHTML } = require(SCRIPT);
const html = renderHTML({ agents: [], skills: [], commands: [], rules: [], mcps: [], hooks: [] });
const scripts = [...html.matchAll(/', d: 'Skill & description', b: '' }],
commands: [],
rules: [],
mcps: [],
hooks: [],
};
const html = renderHTML(data);
// The JSON serialization with .replace(/ not