import type { ComponentProps } from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; import type { SimulationSnapshot } from '../../simulation/SimulationSession'; import { WorkspaceToolsPanel } from './WorkspaceToolsPanel'; const snapshot = { actuators: [], joints: [], controller: { enabled: true }, rlPolicy: { enabled: false }, } as unknown as SimulationSnapshot; const noop = () => {}; function props(): ComponentProps { return { active: 'controls', snapshot, loading: false, ignoreJointLimits: false, jointAdvanced: false, angleUnit: 'rad', forceScale: 50, controllerPaths: [], controllerStatus: { enabled: true } as ComponentProps< typeof WorkspaceToolsPanel >['controllerStatus'], policyPaths: [], policyStatus: { enabled: false } as ComponentProps['policyStatus'], onResetJoints: noop, onToggleJointLimits: noop, onToggleAdvanced: noop, onToggleAngleUnit: noop, onActuator: noop, onActuatorParameters: noop, onJoint: noop, onForceScale: noop, onSelectControllerPath: noop, onLoadControllerPath: noop, onImportController: noop, onToggleController: noop, onControllerCommand: noop, onRemoveController: noop, onSelectPolicyPath: noop, onLoadPolicyPath: noop, onImportPolicy: noop, onTogglePolicy: noop, onPolicyCommand: noop, onRemovePolicy: noop, onDataRecorderConfigure: noop, onDataRecordingStart: noop, onDataRecordingStop: noop, onDataRecordingClear: noop, onDataRecordingExport: noop, }; } describe('WorkspaceToolsPanel', () => { it('首次展开后折叠训练组不丢连接凭据与状态', () => { render(); expect(screen.queryByLabelText('训练服务访问令牌')).not.toBeInTheDocument(); const section = screen.getByRole('button', { name: '强化学习任务' }); fireEvent.click(section); fireEvent.change(screen.getByLabelText('训练服务访问令牌'), { target: { value: 'session-only' }, }); fireEvent.click(section); expect(screen.getByLabelText('训练服务访问令牌')).not.toBeVisible(); expect(section).toHaveTextContent('离线'); fireEvent.click(section); expect(screen.getByLabelText('训练服务访问令牌')).toHaveValue('session-only'); }); it('按实时控制到自动化流程排序,并默认折叠所有控制台组件', () => { render(); const sections = screen .getAllByRole('button') .filter((button) => button.hasAttribute('aria-expanded')); const expected = [ ['执行器实时控制'], ['关节姿态调试'], ['外力交互参数'], ['Python 脚本控制', '运行'], ['ONNX 策略运行', '停止'], ['强化学习任务'], ]; expect(sections).toHaveLength(expected.length); sections.forEach((section, index) => { expect(section).toHaveAttribute('aria-expanded', 'false'); expected[index].forEach((label) => expect(section).toHaveTextContent(label)); }); }); });