feat: add child motion entry and fix auth env
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-05-10 18:27:51 +08:00
parent 86fc382413
commit 46a254f142
22 changed files with 2868 additions and 58 deletions

View File

@@ -0,0 +1,96 @@
/* @vitest-environment jsdom */
import { fireEvent, render, screen } from '@testing-library/react';
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
import { ChildMotionWarmupDemo } from './ChildMotionWarmupDemo';
import {
markChildMotionWarmupCompletedInRuntime,
resetChildMotionWarmupRuntimeSession,
} from './childMotionWarmupModel';
beforeEach(() => {
resetChildMotionWarmupRuntimeSession();
vi.restoreAllMocks();
Object.defineProperty(navigator, 'mediaDevices', {
configurable: true,
value: undefined,
});
});
afterEach(() => {
vi.restoreAllMocks();
});
test('renders the warmup stage and starts with the center ring step', () => {
render(<ChildMotionWarmupDemo />);
expect(screen.getByTestId('child-motion-demo')).toBeTruthy();
expect(screen.getByText('来到圆圈这里')).toBeTruthy();
expect(screen.getByLabelText('绿色圆环')).toBeTruthy();
expect(screen.getByText('请横屏体验')).toBeTruthy();
});
test('re-entering within the same runtime session opens the start button', () => {
markChildMotionWarmupCompletedInRuntime();
render(<ChildMotionWarmupDemo />);
expect(screen.getByRole('button', { name: '开始游戏' })).toBeTruthy();
});
test('developer keyboard input moves the avatar and triggers jump state', () => {
render(<ChildMotionWarmupDemo />);
const avatar = screen.getByTestId('child-motion-avatar');
fireEvent.keyDown(window, { key: 'a', code: 'KeyA' });
expect(avatar.getAttribute('style')).toContain('left: 34%');
fireEvent.keyDown(window, { key: 'd', code: 'KeyD' });
expect(avatar.getAttribute('style')).toContain('left: 66%');
fireEvent.keyUp(window, { key: 'd', code: 'KeyD' });
expect(avatar.getAttribute('style')).toContain('left: 50%');
fireEvent.keyDown(window, { key: ' ', code: 'Space' });
expect(avatar.className).toContain('child-motion-avatar--jumping');
});
test('connects camera stream and releases it on unmount', async () => {
const stopTrack = vi.fn();
const stream = {
getTracks: () => [
{
stop: stopTrack,
},
],
} as unknown as MediaStream;
const getUserMedia = vi.fn().mockResolvedValue(stream);
const play = vi
.spyOn(HTMLMediaElement.prototype, 'play')
.mockResolvedValue(undefined);
Object.defineProperty(navigator, 'mediaDevices', {
configurable: true,
value: {
getUserMedia,
},
});
const { unmount } = render(<ChildMotionWarmupDemo />);
expect(await screen.findByText('正在连接摄像头')).toBeTruthy();
await vi.waitFor(() => {
expect(getUserMedia).toHaveBeenCalledWith({
audio: false,
video: {
facingMode: 'user',
},
});
expect(play).toHaveBeenCalled();
});
unmount();
expect(stopTrack).toHaveBeenCalled();
});