Files
Genarrative/apps/ai-game-creator-shell/tests/previewRightPanGesture.test.ts
k88936 d5e06de33e
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m58s
Project CI / Backend tests (pull_request) Failing after 12s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 3m57s
Project CI / Frontend tests (pull_request) Successful in 3m6s
Project CI / Repository checks (pull_request) Failing after 11s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m41s
Project CI / Native shell tests (pull_request) Successful in 6m13s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 9m32s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 10m50s
固化键盘菜单键不被右键手势拦截的口径
- 实测 Chromium 151 下键盘菜单键触发的是 button: -1,previewRightPanGesture 注释写明只认按钮 2 的原因
- previewRightPanGesture.test.ts 增加 button: -1 不拦截的判据用例
- previewRightPanDrag.test.tsx 增加键盘菜单键仍走原有节点菜单路径的集成用例
- decision-log 条目补上该实测结论与新增用例的验证口径

验证:npx vitest run previewRightPanDrag.test.tsx previewRightPanGesture.test.ts(13 passed)
2026-09-22 15:35:51 +08:00

107 lines
2.8 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
createPreviewRightPanGesture,
movePreviewRightPanGesture,
resolvePreviewRightPanRelease,
shouldInterceptRightContextMenu,
} from '../src/view/ui-editor/components/preview/previewRightPanGesture';
const startViewport = { x: 10, y: -20, scale: 0.75 };
function pressAt(x: number, y: number) {
return createPreviewRightPanGesture({
pointerId: 7,
pointer: { x, y },
viewport: startViewport,
});
}
describe('preview right-button pan gesture', () => {
it('starts as a click until the pointer passes the drag threshold', () => {
const gesture = pressAt(100, 100);
expect(gesture.panning).toBe(false);
expect(movePreviewRightPanGesture(gesture, { x: 101, y: 100 })).toBe(
gesture,
);
expect(
movePreviewRightPanGesture(gesture, { x: 102, y: 100 }).panning,
).toBe(true);
});
it('keeps panning once engaged, even when the pointer returns to the start', () => {
const engaged = movePreviewRightPanGesture(pressAt(100, 100), {
x: 130,
y: 140,
});
expect(engaged.panning).toBe(true);
expect(
movePreviewRightPanGesture(engaged, { x: 100, y: 100 }).panning,
).toBe(true);
});
it('pans by the full delta from the press point without touching the scale', () => {
const gesture = movePreviewRightPanGesture(pressAt(100, 100), {
x: 140,
y: 70,
});
const release = resolvePreviewRightPanRelease({
gesture,
pointer: { x: 140, y: 70 },
isInsidePreview: true,
});
expect(release.viewport).toEqual({ x: 50, y: -50, scale: 0.75 });
expect(release.openNodeMenu).toBe(false);
});
it('opens the node menu only for a clean release inside the preview', () => {
const gesture = pressAt(100, 100);
expect(
resolvePreviewRightPanRelease({
gesture,
pointer: { x: 101, y: 100 },
isInsidePreview: true,
}),
).toEqual({ viewport: null, openNodeMenu: true });
expect(
resolvePreviewRightPanRelease({
gesture,
pointer: { x: 101, y: 100 },
isInsidePreview: false,
}),
).toEqual({ viewport: null, openNodeMenu: false });
});
it('intercepts only the right button of the preview right-press sequence', () => {
expect(
shouldInterceptRightContextMenu({
button: 2,
withinRightPressSequence: true,
}),
).toBe(true);
expect(
shouldInterceptRightContextMenu({
button: 2,
withinRightPressSequence: false,
}),
).toBe(false);
expect(
shouldInterceptRightContextMenu({
button: 0,
withinRightPressSequence: true,
}),
).toBe(false);
expect(
shouldInterceptRightContextMenu({
button: -1,
withinRightPressSequence: true,
}),
).toBe(false);
});
});