收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
@@ -18,6 +18,23 @@ vi.mock('../ResolvedAssetImage', () => ({
|
||||
}) => (src ? <img src={src} alt={alt} className={className} /> : null),
|
||||
}));
|
||||
|
||||
function findNearestClassName(
|
||||
element: HTMLElement,
|
||||
classNamePart: string,
|
||||
): HTMLElement | null {
|
||||
let current: HTMLElement | null = element;
|
||||
|
||||
while (current) {
|
||||
if (current.className.includes(classNamePart)) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current = current.parentElement;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function createSession(): BigFishSessionSnapshotResponse {
|
||||
return {
|
||||
sessionId: 'big-fish-session-1',
|
||||
@@ -151,8 +168,65 @@ describe('BigFishResultView', () => {
|
||||
);
|
||||
|
||||
expect(screen.getByText('主图 已生成')).toBeTruthy();
|
||||
expect(screen.getByAltText('荧潮幼体')).toBeTruthy();
|
||||
expect(screen.getByAltText('深海谜境 场地背景')).toBeTruthy();
|
||||
const levelImage = screen.getByAltText('荧潮幼体');
|
||||
expect(levelImage).toBeTruthy();
|
||||
const levelFrame = findNearestClassName(levelImage, 'relative');
|
||||
expect(levelFrame?.className).toContain('aspect-square');
|
||||
expect(levelFrame?.className).toContain('radial-gradient');
|
||||
expect(levelFrame?.className).toContain('linear-gradient');
|
||||
expect(levelFrame?.className).not.toContain(
|
||||
'bg-[var(--platform-subpanel-fill)]',
|
||||
);
|
||||
const backgroundImage = screen.getByAltText('深海谜境 场地背景');
|
||||
expect(backgroundImage).toBeTruthy();
|
||||
const backgroundFrame = findNearestClassName(backgroundImage, 'relative');
|
||||
expect(backgroundFrame?.className).toContain('aspect-[9/16]');
|
||||
expect(backgroundFrame?.className).toContain('radial-gradient');
|
||||
expect(backgroundFrame?.className).toContain('linear-gradient');
|
||||
expect(backgroundFrame?.className).not.toContain(
|
||||
'bg-[var(--platform-subpanel-fill)]',
|
||||
);
|
||||
expect(
|
||||
findNearestClassName(screen.getByText('荧潮幼体'), 'platform-subpanel')
|
||||
?.className,
|
||||
).toContain('rounded-[1.5rem]');
|
||||
expect(
|
||||
findNearestClassName(screen.getByText('场地背景'), 'platform-subpanel')
|
||||
?.className,
|
||||
).toContain('rounded-[1.5rem]');
|
||||
expect(
|
||||
findNearestClassName(screen.getByText('发布校验'), 'platform-subpanel')
|
||||
?.className,
|
||||
).toContain('rounded-[1.5rem]');
|
||||
});
|
||||
|
||||
test('uses platform pill badge for ready publish status', () => {
|
||||
render(
|
||||
<BigFishResultView
|
||||
session={{
|
||||
...createSession(),
|
||||
publishReady: true,
|
||||
assetCoverage: {
|
||||
levelMainImageReadyCount: 1,
|
||||
levelMotionReadyCount: 2,
|
||||
backgroundReady: true,
|
||||
requiredLevelCount: 1,
|
||||
publishReady: true,
|
||||
blockers: [],
|
||||
},
|
||||
}}
|
||||
onBack={() => {}}
|
||||
onExecuteAction={() => {}}
|
||||
onStartTestRun={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
const readyBadge = screen.getByText('已达到发布条件');
|
||||
|
||||
expect(readyBadge.tagName).toBe('SPAN');
|
||||
expect(readyBadge.className).toContain('rounded-full');
|
||||
expect(readyBadge.className).toContain('border-emerald-200');
|
||||
expect(readyBadge.className).toContain('bg-emerald-50');
|
||||
});
|
||||
|
||||
test('uses level descriptions as default prompt content in asset studio', () => {
|
||||
@@ -166,8 +240,21 @@ describe('BigFishResultView', () => {
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '主图' }));
|
||||
expect(screen.getByText('PROMPT').className).toContain('tracking-[0.18em]');
|
||||
const studioPreviewFrame = findNearestClassName(
|
||||
screen.getByAltText('Lv.1 主图工坊'),
|
||||
'relative',
|
||||
);
|
||||
expect(studioPreviewFrame?.className).toContain('aspect-[9/5]');
|
||||
expect(studioPreviewFrame?.className).toContain('border-dashed');
|
||||
expect(studioPreviewFrame?.className).toContain('bg-cyan-50/40');
|
||||
expect(studioPreviewFrame?.className).not.toContain(
|
||||
'bg-[var(--platform-subpanel-fill)]',
|
||||
);
|
||||
expect(
|
||||
screen.getByText('带有浅青色荧光纹路的小型鱼苗,轮廓圆润,呈现弱小但灵动的开局形象。'),
|
||||
screen.getByText(
|
||||
'带有浅青色荧光纹路的小型鱼苗,轮廓圆润,呈现弱小但灵动的开局形象。',
|
||||
),
|
||||
).toBeTruthy();
|
||||
fireEvent.click(screen.getByRole('button', { name: '关闭' }));
|
||||
|
||||
@@ -183,6 +270,33 @@ describe('BigFishResultView', () => {
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
test('uses PlatformActionButton chrome for white surface asset actions', () => {
|
||||
render(
|
||||
<BigFishResultView
|
||||
session={createSession()}
|
||||
onBack={() => {}}
|
||||
onExecuteAction={() => {}}
|
||||
onStartTestRun={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
for (const actionName of ['主图', '待机', '移动', '生成背景']) {
|
||||
const action = screen.getByRole('button', { name: actionName });
|
||||
|
||||
expect(action.className).toContain('platform-button');
|
||||
expect(action.className).toContain('rounded-full');
|
||||
}
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '主图' }));
|
||||
|
||||
for (const actionName of ['关闭', '生成并应用正式图']) {
|
||||
const action = screen.getByRole('button', { name: actionName });
|
||||
|
||||
expect(action.className).toContain('platform-button');
|
||||
expect(action.className).toContain('rounded-full');
|
||||
}
|
||||
});
|
||||
|
||||
test('shows publish failures in a dismissible modal', () => {
|
||||
const onDismissError = vi.fn();
|
||||
|
||||
@@ -202,6 +316,13 @@ describe('BigFishResultView', () => {
|
||||
expect(
|
||||
screen.getByText('big_fish 发布校验未通过:还缺少 16 个基础动作'),
|
||||
).toBeTruthy();
|
||||
const iconBadge = screen.getByLabelText('发布失败提示');
|
||||
expect(iconBadge.className).toContain(
|
||||
'bg-[var(--platform-button-danger-fill)]',
|
||||
);
|
||||
expect(iconBadge.className).toContain(
|
||||
'text-[var(--platform-button-danger-text)]',
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '知道了' }));
|
||||
expect(onDismissError).toHaveBeenCalledTimes(1);
|
||||
@@ -234,6 +355,11 @@ describe('BigFishResultView', () => {
|
||||
const publishedButton = screen.getByRole('button', { name: '已发布' });
|
||||
expect((publishedButton as HTMLButtonElement).disabled).toBe(true);
|
||||
expect(screen.getAllByText('已发布').length).toBeGreaterThan(0);
|
||||
const publishedBadge = screen
|
||||
.getAllByText('已发布')
|
||||
.find((element) => element.tagName === 'SPAN');
|
||||
expect(publishedBadge?.className).toContain('border-emerald-200');
|
||||
expect(publishedBadge?.className).toContain('bg-emerald-50');
|
||||
fireEvent.click(publishedButton);
|
||||
expect(onExecuteAction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user