Files
Genarrative/apps/ai-game-creator-shell/tests/gameRunToolbarActionsStyle.test.ts
T
suzmii 6dde321bd1
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m5s
Project CI / Backend tests (pull_request) Failing after 11s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m13s
Project CI / Frontend tests (pull_request) Successful in 3m15s
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m56s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 7m55s
Project CI / AI game creator shell web tests (pull_request) Failing after 3m21s
Project CI / Native shell tests (pull_request) Successful in 8m53s
修 review 发现:运行反馈全面退出对话区,并补齐顶栏与守卫细节
- executeRunLocal 的三条失败路径(缺 Tauri / 缺项目 / 启动预览报错)也改走 onRunNotice 失败色提示,对话区不再出现过程行;随之删除已无调用方的 announceProjectChatMessage 与不再有意义的 announceToChat 参数
- RunNoticeToast 的失败提示延长到 6 秒(成功仍 2.6 秒),避免错误一闪而过
- 版本入口在 UI 编辑器壳里不渲染;版本名改由一层 span 承载省略号,长版本名不再被硬裁
- 视图拿不到 onNotice 时把「在浏览器打开失败」写进 console,不再静默吞掉
- check-native-shells 增加「运行页视图里 openUrl( 只有一个调用点」的判据,堵住自动开浏览器的口子
- 新增外壳级接线用例 runNoticeShellWiring;previewActivation 补「启动失败走失败色提示且不写对话区」;runNoticeToast 补失败时长;样式守卫补省略号
- decision-log 收敛到最终口径(成功与失败都出对话区、失败留 6 秒、编辑器不挂版本入口)
2026-09-22 13:51:30 +08:00

75 lines
3.4 KiB
TypeScript

// @vitest-environment jsdom
import { readFileSync } from 'node:fs';
import { describe, expect, test } from 'vitest';
import { repoPath } from './repoPath';
import {
declaration,
parseStyleSheet,
resolveDeclarations,
} from './styleCascade';
/**
* 运行页顶栏动作区的声明级断言。
*
* jsdom 不加载全局样式表,所以这里按仓库既有做法(`styleCascade`)解析真实生效的声明:
* 「版本入口与「在浏览器打开」跟其他动作按钮同一套皮」只由样式决定,用例必须钉在声明上,
* 否则下一次改动给版本入口单开一套 border / background / hover 时没有任何东西会红。
*/
const GLOBAL_CSS_PATH = repoPath('apps/ai-game-creator-shell/src/styles.css');
const rules = parseStyleSheet(readFileSync(GLOBAL_CSS_PATH, 'utf8'));
// 同一个求值器限制:全局表里也有 `prefers-reduced-motion` 档,求值时先排除掉。
const widthRules = rules.filter(
(rule) => !(rule.media ?? '').includes('prefers-reduced-motion'),
);
function resolved(selectors: readonly string[]): Map<string, string> {
return resolveDeclarations(widthRules, selectors, 1280);
}
function hasRule(selector: string): boolean {
return widthRules.some((rule) => rule.selectors.includes(selector));
}
describe('运行页顶栏动作区样式', () => {
test('运行画面回到两行,页面里不再有预览地址状态行', () => {
const surface = resolved(['.game-run-surface']);
expect(declaration(surface, 'grid-template-rows')).toBe(
'minmax(300px, 1fr) auto',
);
// 状态行与那行小字整体退役:地址不再以文字常驻在页面上。
expect(hasRule('.game-run-status-bar')).toBe(false);
expect(hasRule('.game-run-status-hint')).toBe(false);
});
test('版本入口住进顶栏动作区,皮由那一组的基础规则给', () => {
// 动作区的按钮共用一套基础外观(这一组是「在浏览器打开」与版本入口的共同来源)。
const actionsButton = resolved(['.game-workbench-view-actions button']);
expect(declaration(actionsButton, 'min-height')).toBe('30px');
expect(declaration(actionsButton, 'border-radius')).toBe('999px');
expect(declaration(actionsButton, 'font-size')).toBe('12px');
expect(declaration(actionsButton, 'font-weight')).toBe('700');
// 版本入口只补「版本名可能很长」这一件事,不再自带边框 / 底色 / 文字色 / hover。
const trigger = resolved(['.game-run-version-trigger']);
expect(trigger.has('border')).toBe(false);
expect(trigger.has('background')).toBe(false);
expect(trigger.has('color')).toBe(false);
expect(declaration(trigger, 'min-width')).toBe('0');
// 省略号要真的生效:按钮是 flex 容器,文本必须挂在自带 overflow 的 span 上。
const label = resolved(['.game-run-version-trigger-label']);
expect(declaration(label, 'overflow')).toBe('hidden');
expect(declaration(label, 'text-overflow')).toBe('ellipsis');
expect(declaration(label, 'white-space')).toBe('nowrap');
expect(hasRule('.game-run-version-trigger:hover')).toBe(false);
expect(hasRule('.game-run-version-trigger:focus-visible')).toBe(false);
// 版本入口不再绝对定位压在游戏画面上。
const picker = resolved(['.game-run-version-picker']);
expect(picker.has('position')).toBe(false);
expect(picker.has('top')).toBe(false);
expect(picker.has('right')).toBe(false);
});
});