Refresh the interface and clarify usage records
Adopt a white theme, add home-page shortcuts, and show usage metrics with color-coded details, automatic units, and explicit estimated-cost coverage. Update the README screenshots.
This commit is contained in:
1 parent
90364e91b4
commit
d6bb29f79f
29 files changed
+954
-67
No files matched your search
@@ -3,20 +3,24 @@ const assert = require('node:assert/strict');
|
||||
const path = require('node:path');
|
||||
|
||||
(async () => {
|
||||
const { createServer } = await import('vite');
|
||||
const react = (await import('@vitejs/plugin-react')).default;
|
||||
const root = path.resolve(__dirname, '..');
|
||||
const server = await createServer({ configFile: false, root, plugins: [react()], logLevel: 'error', server: { host: '127.0.0.1', port: 1421, strictPort: false } });
|
||||
let browser;
|
||||
let server;
|
||||
let base = 'http://127.0.0.1:1420/';
|
||||
try {
|
||||
const response = await fetch(base);
|
||||
if (!response.ok) throw new Error(String(response.status));
|
||||
} catch {
|
||||
const { createServer } = await import('vite');
|
||||
const react = (await import('@vitejs/plugin-react')).default;
|
||||
const root = path.resolve(__dirname, '..');
|
||||
server = await createServer({ configFile: false, root, plugins: [react()], logLevel: 'error', server: { host: '127.0.0.1', port: 1421, strictPort: false } });
|
||||
await server.listen();
|
||||
const address = server.httpServer.address();
|
||||
const base = `http://127.0.0.1:${typeof address === 'object' && address ? address.port : 1421}/`;
|
||||
const response = await fetch(base);
|
||||
assert.equal(response.ok, true, `Vite server failed at ${base}`);
|
||||
await response.text();
|
||||
base = `http://127.0.0.1:${typeof address === 'object' && address ? address.port : 1421}/`;
|
||||
}
|
||||
let browser;
|
||||
try {
|
||||
const channel = process.env.PLAYWRIGHT_CHANNEL || (process.platform === 'win32' ? 'msedge' : undefined);
|
||||
browser = await chromium.launch(channel ? { channel, headless: true } : { headless: true });
|
||||
browser = await chromium.launch(channel ? { channel, headless: true, args: ['--no-proxy-server'] } : { headless: true, args: ['--no-proxy-server'] });
|
||||
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
|
||||
await page.goto(`${base}?mock=running`, { waitUntil: 'commit' });
|
||||
await page.locator('.app-shell').waitFor();
|
||||
@@ -68,7 +72,7 @@ const path = require('node:path');
|
||||
console.log('PASS: page hierarchy, tabs, contextual filters, modal focus and compact shell.');
|
||||
} finally {
|
||||
if (browser) await browser.close();
|
||||
await server.close();
|
||||
if (server) await server.close();
|
||||
}
|
||||
})().catch((error) => {
|
||||
console.error(error);
|
||||
|
||||
@@ -26,7 +26,7 @@ const base = 'http://127.0.0.1:1421';
|
||||
|
||||
assert.equal(statInfo1213.cardCount, 6, 'There are 6 stat cards');
|
||||
assert.equal(statInfo1213.cardRows, 1, 'At 1213px width, all 6 cards fit into a single row');
|
||||
assert.equal(statInfo1213.metaCount, 0, 'Stat cards have no meta subtext displayed');
|
||||
assert.equal(statInfo1213.metaCount, 6, 'Each stat card shows its supporting detail');
|
||||
assert.ok(!statInfo1213.tpsValue.includes('TPS'), `TPS value should not contain TPS unit: ${statInfo1213.tpsValue}`);
|
||||
assert.ok(/^\d+(\.\d+)?$/.test(statInfo1213.tpsValue), `TPS value should be numeric: ${statInfo1213.tpsValue}`);
|
||||
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import { formatUsageNumber } from '../src/services/usageNumber';
|
||||
import { formatDuration, formatUsageNumber } from '../src/services/usageNumber';
|
||||
|
||||
describe('使用统计数量单位', () => {
|
||||
test('百万以下保持普通数字格式', () => {
|
||||
expect(formatUsageNumber(999_999, 'en-US')).toBe('999,999');
|
||||
test('按数量级自动切换 K、M、B', () => {
|
||||
expect(formatUsageNumber(999, 'en-US')).toBe('999');
|
||||
expect(formatUsageNumber(1_000, 'en-US')).toBe('1K');
|
||||
expect(formatUsageNumber(132_000, 'en-US')).toBe('132K');
|
||||
expect(formatUsageNumber(486_500, 'en-US')).toBe('486.5K');
|
||||
expect(formatUsageNumber(999_949, 'en-US')).toBe('999.9K');
|
||||
expect(formatUsageNumber(999_950, 'en-US')).toBe('1M');
|
||||
expect(formatUsageNumber(Number.NaN, 'en-US')).toBe('0');
|
||||
});
|
||||
|
||||
test('延迟在毫秒和秒之间自动切换', () => {
|
||||
expect(formatDuration(842, 'en-US')).toBe('842 ms');
|
||||
expect(formatDuration(1_284, 'en-US')).toBe('1.28 s');
|
||||
expect(formatDuration(12_840, 'en-US')).toBe('12.8 s');
|
||||
expect(formatDuration(Number.NaN, 'en-US')).toBe('0 ms');
|
||||
});
|
||||
|
||||
test('百万级使用 M 并在达到阈值时自动切换为 B', () => {
|
||||
expect(formatUsageNumber(1_000_000, 'en-US')).toBe('1M');
|
||||
expect(formatUsageNumber(12_340_000, 'en-US')).toBe('12.3M');
|
||||
|
||||
Reference in new issue
Block a user