Increase VectorEngine timeouts and add image UI
Add VectorEngine image generation config and raise request timeouts (env + scripts) from 180000 to 1000000ms. Introduce a reusable CreativeImageInputPanel component with tests and wire up mobile keyboard-focus helpers; update generation views and related tests (CustomWorldGenerationView, BarkBattle editor, Match3D, Puzzle flows). Improve API error handling / VectorEngine request guidance (packages/shared http.ts and docs), and apply multiple backend/frontend fixes for puzzle/match3d/prompt handling. Also include extensive docs and decision-log updates describing UI/UX decisions and verification steps.
This commit is contained in:
@@ -165,6 +165,10 @@ function createSession(
|
||||
return session;
|
||||
}
|
||||
|
||||
function openPuzzleLevelsTab() {
|
||||
fireEvent.click(screen.getByRole('button', { name: '拼图关卡' }));
|
||||
}
|
||||
|
||||
describe('PuzzleResultView', () => {
|
||||
test('renders level list and work info tabs', () => {
|
||||
render(
|
||||
@@ -176,14 +180,21 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole('button', { name: '拼图关卡' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '作品信息' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '素材配置' })).toBeTruthy();
|
||||
const workInfoTab = screen.getByRole('button', { name: '作品信息' });
|
||||
const levelsTab = screen.getByRole('button', { name: '拼图关卡' });
|
||||
const assetsTab = screen.getByRole('button', { name: '素材配置' });
|
||||
expect(workInfoTab).toBeTruthy();
|
||||
expect(levelsTab).toBeTruthy();
|
||||
expect(assetsTab).toBeTruthy();
|
||||
expect(
|
||||
workInfoTab.compareDocumentPosition(levelsTab) &
|
||||
Node.DOCUMENT_POSITION_FOLLOWING,
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
levelsTab.compareDocumentPosition(assetsTab) &
|
||||
Node.DOCUMENT_POSITION_FOLLOWING,
|
||||
).toBeTruthy();
|
||||
expect(screen.queryByRole('button', { name: '音乐' })).toBeNull();
|
||||
expect(screen.getByText('雨夜猫街')).toBeTruthy();
|
||||
expect(screen.getByText('获得更多积分激励')).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '作品信息' }));
|
||||
expect(screen.getByLabelText('作品名称')).toHaveProperty(
|
||||
'value',
|
||||
'暖灯猫街作品',
|
||||
@@ -192,6 +203,10 @@ describe('PuzzleResultView', () => {
|
||||
'value',
|
||||
'一套雨夜猫街主题拼图。',
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
expect(screen.getByText('雨夜猫街')).toBeTruthy();
|
||||
expect(screen.getByText('获得更多积分激励')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('result action bar restores draft trial entry', () => {
|
||||
@@ -276,6 +291,7 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByText('雨夜猫街'));
|
||||
const dialog = screen.getByRole('dialog', { name: '关卡详情' });
|
||||
fireEvent.change(within(dialog).getByLabelText('关卡名称'), {
|
||||
@@ -366,6 +382,7 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByRole('button', { name: /新增关卡/u }));
|
||||
const dialog = screen.getByRole('dialog', { name: '关卡详情' });
|
||||
expect(
|
||||
@@ -427,6 +444,7 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByRole('button', { name: /新增关卡/u }));
|
||||
const dialog = screen.getByRole('dialog', { name: '关卡详情' });
|
||||
fireEvent.change(within(dialog).getByLabelText('画面描述'), {
|
||||
@@ -478,6 +496,7 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByText('雨夜猫街'));
|
||||
fireEvent.click(screen.getByRole('button', { name: /重新生成画面/u }));
|
||||
fireEvent.click(
|
||||
@@ -514,6 +533,7 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByText('雨夜猫街'));
|
||||
fireEvent.click(screen.getByRole('button', { name: /重新生成画面/u }));
|
||||
fireEvent.click(
|
||||
@@ -534,6 +554,7 @@ describe('PuzzleResultView', () => {
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByLabelText('关闭'));
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByRole('button', { name: /新增关卡/u }));
|
||||
expect(screen.getByRole('dialog', { name: '关卡详情' })).toBeTruthy();
|
||||
fireEvent.click(screen.getByLabelText('关闭'));
|
||||
@@ -976,8 +997,8 @@ describe('PuzzleResultView', () => {
|
||||
ownerLabel: '账号 user-1',
|
||||
profileId: null,
|
||||
entityId: 'puzzle-session-1',
|
||||
createdAt: '2026-04-27T10:00:00.000Z',
|
||||
updatedAt: '2026-04-27T10:00:00.000Z',
|
||||
createdAt: '1713686400.000000Z',
|
||||
updatedAt: '1713686400.000000Z',
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -989,6 +1010,7 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByText('雨夜猫街'));
|
||||
const dialog = screen.getByRole('dialog', { name: '关卡详情' });
|
||||
const uploadInput = within(dialog).getByLabelText('上传参考图', {
|
||||
@@ -1004,13 +1026,17 @@ describe('PuzzleResultView', () => {
|
||||
const picker = await screen.findByRole('dialog', {
|
||||
name: '选择历史图片',
|
||||
});
|
||||
expect(await within(picker).findByText('image.png')).toBeTruthy();
|
||||
expect(await within(picker).findByText(/2024\/04\/21/u)).toBeTruthy();
|
||||
expect(within(picker).queryByText('账号 user-1')).toBeNull();
|
||||
fireEvent.click(
|
||||
await within(picker).findByRole('button', { name: /账号 user-1/u }),
|
||||
await within(picker).findByRole('button', { name: /image\.png/u }),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole('dialog', { name: '选择历史图片' })).toBeNull();
|
||||
});
|
||||
expect(screen.getByText('历史素材 · image.png')).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /重新生成画面/u }));
|
||||
fireEvent.click(
|
||||
@@ -1057,6 +1083,7 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByText('雨夜猫街'));
|
||||
fireEvent.click(screen.getByRole('button', { name: /重新生成画面/u }));
|
||||
fireEvent.click(
|
||||
@@ -1087,6 +1114,7 @@ describe('PuzzleResultView', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
openPuzzleLevelsTab();
|
||||
fireEvent.click(screen.getByText('雨夜猫街'));
|
||||
const dialog = screen.getByRole('dialog', { name: '关卡详情' });
|
||||
fireEvent.click(within(dialog).getByRole('button', { name: '图片模型' }));
|
||||
|
||||
Reference in New Issue
Block a user