Files
Genarrative/apps/ai-game-creator-shell/tests/uiEditorKeyboardShortcuts.test.ts
k88936 4db6d28603
Project CI / Repository checks (push) Successful in 3m6s
Project CI / Frontend tests (push) Successful in 3m44s
Project CI / Backend tests (push) Successful in 8m16s
Project CI / Native shell tests (push) Successful in 20m48s
UI编辑器一批细节优化 (#278)
* 提示词:完善组件建议,增加容器背景与节点大小一致的实现
* 支持Delete删除节点 ctrl + -缩放
* 步骤结束弹窗提醒
![shotmd-1788599068.jpg](/attachments/99a1e4aa-d778-41bf-9dda-0df703723407)
![shotmd-1788605840.jpg](/attachments/31ab883d-32bc-467b-9308-616b83387a79)

* UI 树快捷删除
![shotmd-1788605655.jpg](/attachments/3d451201-3f68-4eb6-b558-864ecf0cb5a3)

* zoom滑动条样式

before:
![image.png](/attachments/e4a04304-e6eb-4da6-9352-99e093fee42e)
after:
![shotmd-1788606577.jpg](/attachments/6cdc377c-f2a3-4a7e-b78e-772a3fdb13b7)

Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/278
Co-authored-by: 王德宇 <kvtodev@outlook.com>
Co-committed-by: 王德宇 <kvtodev@outlook.com>
2026-09-08 11:56:36 +08:00

110 lines
3.5 KiB
TypeScript

// @vitest-environment jsdom
import { fireEvent } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { handleUiEditorKeyDown } from '../src/view/ui-editor/uiEditorKeyboardShortcuts';
describe('ui editor keyboard shortcuts', () => {
afterEach(() => {
document.body.replaceChildren();
});
it.each([
{ key: 'z', ctrlKey: true },
{ key: 'z', ctrlKey: true, shiftKey: true },
{ key: 'y', ctrlKey: true },
])('does not change history from inside a modal (%o)', (shortcut) => {
const dialog = document.createElement('div');
dialog.setAttribute('role', 'dialog');
const button = document.createElement('button');
dialog.append(button);
document.body.append(dialog);
const historyUndo = vi.fn(() => true);
const historyRedo = vi.fn(() => true);
const listener = (event: KeyboardEvent) =>
handleUiEditorKeyDown(event, {
selectedNodeId: null,
activeImageId: null,
deleteNode: vi.fn(),
historyUndo,
historyRedo,
});
window.addEventListener('keydown', listener);
fireEvent.keyDown(button, shortcut);
expect(historyUndo).not.toHaveBeenCalled();
expect(historyRedo).not.toHaveBeenCalled();
window.removeEventListener('keydown', listener);
});
it('keeps undo available from a non-modal button', () => {
const button = document.createElement('button');
document.body.append(button);
const historyUndo = vi.fn(() => true);
const historyRedo = vi.fn(() => true);
const listener = (event: KeyboardEvent) =>
handleUiEditorKeyDown(event, {
selectedNodeId: null,
activeImageId: null,
deleteNode: vi.fn(),
historyUndo,
historyRedo,
});
window.addEventListener('keydown', listener);
fireEvent.keyDown(button, { key: 'z', ctrlKey: true });
expect(historyUndo).toHaveBeenCalledTimes(1);
window.removeEventListener('keydown', listener);
});
it.each(['Delete', 'Backspace'])(
'does not delete a node when the zoom slider has focus (%s)',
(key) => {
const slider = document.createElement('input');
slider.type = 'range';
document.body.append(slider);
const deleteNode = vi.fn(() => ({ ok: true }));
const listener = (event: KeyboardEvent) =>
handleUiEditorKeyDown(event, {
selectedNodeId: 'node-1',
activeImageId: 'page-1',
deleteNode,
historyUndo: vi.fn(() => true),
historyRedo: vi.fn(() => true),
});
window.addEventListener('keydown', listener);
fireEvent.keyDown(slider, { key });
expect(deleteNode).not.toHaveBeenCalled();
window.removeEventListener('keydown', listener);
},
);
it('keeps node deletion available after zoom button focus is released', () => {
const zoomControls = document.createElement('div');
const zoomIn = document.createElement('button');
zoomControls.append(zoomIn);
document.body.append(zoomControls);
const deleteNode = vi.fn(() => ({ ok: true }));
const listener = (event: KeyboardEvent) =>
handleUiEditorKeyDown(event, {
selectedNodeId: 'node-1',
activeImageId: 'page-1',
deleteNode,
historyUndo: vi.fn(() => true),
historyRedo: vi.fn(() => true),
});
window.addEventListener('keydown', listener);
fireEvent.click(zoomIn);
fireEvent.keyDown(window, { key: 'Delete' });
expect(deleteNode).toHaveBeenCalledWith('node-1', 'page-1');
window.removeEventListener('keydown', listener);
});
});