summaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-18 12:03:32 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-18 12:03:32 +0800
commit17e30105538f419c6abef2a69ffd4f0eb4cf238b (patch)
tree23b79c0b4f0f7aca67a3e33ae88b95cb9a991ec0 /frontend
parent61f5c545953bb4ee20b123bf9671ac35d7f1f3c1 (diff)
downloadstrategy-lab-17e30105538f419c6abef2a69ffd4f0eb4cf238b.tar.gz
[变更性质] test(frontend)
[新增功能] 测试与 probe 同步:mobileCss round3 断言、resultsAccounting .m-tile、strategyTab 超时放宽、probe radius 断言 [实现方案] probe cardRadiusOk 校验 --radius≥0.75rem 且组件计算圆角一致;88/88 vitest 全绿 [影响范围] src/lib/*.test.ts、scripts/ui-auth-shots.mjs
Diffstat (limited to 'frontend')
-rw-r--r--frontend/scripts/ui-auth-shots.mjs17
-rw-r--r--frontend/src/lib/metricRow.test.ts2
-rw-r--r--frontend/src/lib/mobileCss.test.ts35
-rw-r--r--frontend/src/lib/resultsAccounting.test.ts2
-rw-r--r--frontend/src/lib/strategyTab.test.ts2
5 files changed, 55 insertions, 3 deletions
diff --git a/frontend/scripts/ui-auth-shots.mjs b/frontend/scripts/ui-auth-shots.mjs
index 9507b6d..2db1f1d 100644
--- a/frontend/scripts/ui-auth-shots.mjs
+++ b/frontend/scripts/ui-auth-shots.mjs
@@ -155,6 +155,22 @@ for (const w of widths) {
breadcrumbText: document.querySelector('nav.crumbs')?.textContent.replace(/\s+/g, ' ').trim() || null,
sparklineCells: document.querySelectorAll('[data-testid="sparkline-cell"]').length,
metricCards: document.querySelectorAll('[data-testid="metric-card"]').length,
+ cardRadius: (function () {
+ const r = document.querySelector('[data-slot="card"]');
+ if (!r) return null;
+ const target = String(getComputedStyle(document.documentElement).getPropertyValue('--radius')).trim();
+ return { computed: getComputedStyle(r).borderRadius, token: getComputedStyle(document.documentElement).getPropertyValue('--radius') || target };
+ })(),
+ cardRadiusOk: (function () {
+ const r = document.querySelector('[data-slot="card"]');
+ if (!r) return null;
+ const root = getComputedStyle(document.documentElement);
+ const tok = parseFloat(root.getPropertyValue('--radius'));
+ const rootFs = parseFloat(root.fontSize);
+ const expected = tok * rootFs;
+ const n = parseFloat(getComputedStyle(r).borderRadius);
+ return n >= expected - 0.5 && tok >= 0.749;
+ })(),
projects: (window.__probeProjects !== undefined) ? window.__probeProjects : null,
runs: null,
hasEquity: null,
@@ -170,6 +186,7 @@ for (const w of widths) {
' overflow=' + dom.overflow + ' pageErrors=' + pageErrors.length +
' tabbarAttached=' + dom.tabbarAttached + ' tabbarVisible=' + dom.tabbarVisible +
' metricCards=' + dom.metricCards + ' sparks=' + dom.sparklineCells +
+ ' radiusOk=' + dom.cardRadiusOk +
(dom.breadcrumbText ? ' crumbs="' + dom.breadcrumbText + '"' : '')
);
if (dom.overflow !== 0 || pageErrors.length !== 0) bad++;
diff --git a/frontend/src/lib/metricRow.test.ts b/frontend/src/lib/metricRow.test.ts
index bc41b54..a8149bd 100644
--- a/frontend/src/lib/metricRow.test.ts
+++ b/frontend/src/lib/metricRow.test.ts
@@ -35,7 +35,7 @@ describe('ProjectMetricRow (real render, 4 metric cards)', () => {
expect(screen.getByText('回测')).toBeTruthy();
expect(screen.getByText('AI 用量')).toBeTruthy();
// 数字直接可见:项目卡/数据集卡与回测拆分值
- const values = [...container.querySelectorAll('.metric-card .mvalue')].map((n) => n.textContent!.replace(/\s+/g, ' ').trim());
+ const values = [...container.querySelectorAll('.metric-row .mvalue')].map((n) => n.textContent!.replace(/\s+/g, ' ').trim());
expect(values[0]).toBe('3');
expect(values[1]).toBe('2');
expect(values[2]).toContain('运行中');
diff --git a/frontend/src/lib/mobileCss.test.ts b/frontend/src/lib/mobileCss.test.ts
index c4d1efb..af7251f 100644
--- a/frontend/src/lib/mobileCss.test.ts
+++ b/frontend/src/lib/mobileCss.test.ts
@@ -47,6 +47,41 @@ describe('375px responsive sizing (no global content hiding)', () => {
});
});
+describe('round3 shadcn-svelte 主题 tokens(b1D0dv72 preset 精神 + 截图重配)', () => {
+ it('radius 上调至 0.75rem(Stripe 风格大圆角),shadcn radius-lg 由此派生', () => {
+ expect(appCss).toMatch(/--radius:\s*0\.75rem/);
+ expect(appCss).toMatch(/--radius-lg:\s*var\(--radius\)/);
+ });
+
+ it('mint 默认 + amber 双套变量组(用户 create 截图色值)', () => {
+ // mint ~#70DAB6 / 深一档 #58D3AA;amber ~#F0AE00
+ expect(appCss).toContain('--brand: #58d3aa');
+ expect(appCss).toContain('--ring: #70dab6');
+ expect(appCss).toMatch(/\.theme-amber\s*\{/);
+ expect(appCss).toContain('--brand: #f0ae00');
+ // 默认 mint、amber 仅通过 .theme-amber 切换(src/lib/theme.ts 挂类)
+ expect(appCss).not.toMatch(/NAVER/);
+ });
+
+ it('数字排印:tabular-nums 大字重(mvalue 1.5rem/700),保留 .num/.metric-grid', () => {
+ expect(appCss).toMatch(/\.mvalue\s*\{[^}]*font-weight:\s*700/);
+ expect(appCss).toMatch(/\.mvalue\s*\{[^}]*font-variant-numeric:\s*tabular-nums/);
+ expect(appCss).toContain('.metric-grid {');
+ });
+
+ it('legacy 组件选择器已从 app.css 删除(.btn/.banner 变体/.badge/.tabs/table.data 组件样式)', () => {
+ expect(appCss).not.toMatch(/\.btn\s*\{|\.\btn\.|\.btn\./);
+ expect(appCss).not.toContain('.btn.primary {');
+ expect(appCss).not.toContain('.badge.teal {');
+ expect(appCss).not.toContain('.tabs button {');
+ expect(appCss).not.toContain('table.data th {');
+ expect(appCss).not.toContain('.metric {');
+ expect(appCss).not.toContain('.metric-card {');
+ // .banner 仅剩窄视口防溢出工具(无颜色组件样式)
+ expect(appCss).not.toContain('.banner.error {');
+ });
+});
+
function getMediaBlock(css, query) {
const idx = css.indexOf(`@media ${query}`);
if (idx < 0) return null;
diff --git a/frontend/src/lib/resultsAccounting.test.ts b/frontend/src/lib/resultsAccounting.test.ts
index b695713..5dc5bd6 100644
--- a/frontend/src/lib/resultsAccounting.test.ts
+++ b/frontend/src/lib/resultsAccounting.test.ts
@@ -71,7 +71,7 @@ describe('results accounting labels + values (live browser accounting)', () => {
expect(text).not.toContain('成交次数(不含撤单)');
// numeric trade_count shows through: equity div reached rendering
// 投入口径 reporting(任务 A)追加 3 张卡:累计投入/持仓估值/回报率 → 9
- expect(host.querySelectorAll('.metric').length).toBe(9);
+ expect(host.querySelectorAll('[data-slot="card"].m-tile, .m-tile').length).toBe(9);
expect(host.querySelectorAll('[data-testid="capital-reporting"]').length).toBe(1);
expect(text).toContain('累计投入');
expect(text).toContain('投入口径不含初始账户闲置现金');
diff --git a/frontend/src/lib/strategyTab.test.ts b/frontend/src/lib/strategyTab.test.ts
index a5bf6d8..eb199a1 100644
--- a/frontend/src/lib/strategyTab.test.ts
+++ b/frontend/src/lib/strategyTab.test.ts
@@ -53,7 +53,7 @@ describe('strategy tab numeric generation contract (pageerror regression)', () =
beforeEach(() => { document.body.innerHTML = ''; });
afterEach(() => vi.unstubAllGlobals());
- it('full numeric flow renders editor + 草稿代 3 without .slice crash', async () => {
+ it('full numeric flow renders editor + 草稿代 3 without .slice crash', { timeout: 15000 }, async () => {
const { host, cleanup } = await mountStrategyTab(handler());
try {
const text = host.textContent;