新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
108 lines
3.6 KiB
TypeScript
108 lines
3.6 KiB
TypeScript
/* @vitest-environment jsdom */
|
|
|
|
import { fireEvent, render, screen, within } from '@testing-library/react';
|
|
import type { HTMLAttributes, ReactNode } from 'react';
|
|
import { expect, test, vi } from 'vitest';
|
|
|
|
import { getCustomWorldSceneRelativePositionLabel } from '../data/customWorldSceneGraph';
|
|
import {
|
|
getConnectedScenePresets,
|
|
getWorldCampScenePreset,
|
|
} from '../data/scenePresets';
|
|
import { WorldType } from '../types';
|
|
import { MapModal } from './MapModal';
|
|
|
|
vi.mock('motion/react', () => ({
|
|
AnimatePresence: ({ children }: { children: ReactNode }) => <>{children}</>,
|
|
motion: {
|
|
div: ({
|
|
animate: _animate,
|
|
children,
|
|
exit: _exit,
|
|
initial: _initial,
|
|
transition: _transition,
|
|
...props
|
|
}: HTMLAttributes<HTMLDivElement> & {
|
|
animate?: unknown;
|
|
exit?: unknown;
|
|
initial?: unknown;
|
|
transition?: unknown;
|
|
}) => <div {...props}>{children}</div>,
|
|
},
|
|
}));
|
|
|
|
test('目标场景确认面板复用暗色琥珀 PlatformSubpanel 和胶囊标签', () => {
|
|
const currentScene = getWorldCampScenePreset(WorldType.WUXIA);
|
|
if (!currentScene) {
|
|
throw new Error('测试需要武侠营地场景');
|
|
}
|
|
|
|
const destination = getConnectedScenePresets(
|
|
WorldType.WUXIA,
|
|
currentScene.id,
|
|
)[0];
|
|
if (!destination) {
|
|
throw new Error('测试需要至少一个相邻场景');
|
|
}
|
|
|
|
const connection = currentScene.connections.find(
|
|
(item) => item.sceneId === destination.id,
|
|
);
|
|
const destinationLabel = connection
|
|
? getCustomWorldSceneRelativePositionLabel(connection.relativePosition)
|
|
: '前方';
|
|
|
|
render(
|
|
<MapModal
|
|
isOpen
|
|
currentScenePreset={currentScene}
|
|
worldType={WorldType.WUXIA}
|
|
onClose={vi.fn()}
|
|
onTravelToScene={vi.fn()}
|
|
/>,
|
|
);
|
|
|
|
const destinationNameNode = screen.getAllByText(destination.name)[0];
|
|
if (!destinationNameNode) {
|
|
throw new Error('测试需要展示目标场景名称');
|
|
}
|
|
|
|
const destinationButton = destinationNameNode.closest('button');
|
|
if (!destinationButton) {
|
|
throw new Error('测试需要可点击的目标场景节点');
|
|
}
|
|
|
|
const mapNodeLabelBadge =
|
|
within(destinationButton).getByText(destinationLabel);
|
|
expect(mapNodeLabelBadge.className).toContain('bg-emerald-500/10');
|
|
expect(mapNodeLabelBadge.className).toContain('rounded-full');
|
|
|
|
fireEvent.click(destinationButton);
|
|
|
|
const panel = screen.getByTestId('map-target-scene-panel');
|
|
const currentSummary = screen.getByTestId('map-current-scene-summary');
|
|
const nextSummary = screen.getByTestId('map-next-scene-summary');
|
|
const labelBadge = within(panel).getByText(destinationLabel);
|
|
const cancelButton = screen.getByRole('button', { name: '取消' });
|
|
const confirmButton = screen.getByRole('button', { name: '确认前往' });
|
|
|
|
expect(panel.className).toContain('border-amber-300/18');
|
|
expect(panel.className).toContain('bg-amber-500/8');
|
|
expect(panel.className).toContain('rounded-xl');
|
|
expect(panel.className).toContain('p-4');
|
|
expect(labelBadge.className).toContain('rounded-full');
|
|
expect(labelBadge.className).toContain('bg-amber-500/10');
|
|
expect(currentSummary.className).toContain('border-white/10');
|
|
expect(currentSummary.className).toContain('bg-black/25');
|
|
expect(nextSummary.className).toContain('border-white/10');
|
|
expect(nextSummary.className).toContain('bg-black/25');
|
|
expect(cancelButton.className).toContain(
|
|
'platform-action-button--editor-dark',
|
|
);
|
|
expect(cancelButton.className).toContain('bg-black/20');
|
|
expect(confirmButton.className).toContain(
|
|
'platform-action-button--editor-dark',
|
|
);
|
|
expect(confirmButton.className).toContain('bg-amber-500/20');
|
|
});
|