from __future__ import annotations from pathlib import Path ROOT = Path(__file__).resolve().parents[2] def source(name: str) -> str: return (ROOT / "apps" / "web-console" / name).read_text(encoding="utf-8") def test_frontend_only_exposes_user_orchestration_and_extension() -> None: web_root = ROOT / "apps" / "web-console" html = source("index.html") console = source("console-v2.js") for removed in ( "self-calibration.js", "self-calibration.css", "self-repair.js", "self-repair.css", "self-repair-seat3d.js", "self-evolution.js", "self-evolution.css", ): assert not (web_root / removed).exists() assert removed not in html assert "511工程-智能座舱" in console assert '["self-orchestration", "self-extension"]' in console assert 'id="vehicleExtensionSync"' in console assert 'getRole: () => "user"' in console assert '"admin"' not in console assert "v2RoleSelect" not in console def test_extension_pet_and_transient_vehicle_state_restart_contract() -> None: extension = source("self-extension.js") styles = source("self-extension.css") assert 'id="extensionDesktopPet"' in extension assert "function initializeDesktopPet()" in extension assert "saved.vehicleExecutions = {};" in extension assert "saved.lastProtocol = null;" in extension assert 'src="/assets/pets/self-extension-cat.png?v=3"' in extension assert 'class="v2-extension-pet-entrance-canvas"' in extension assert '"/assets/pets/self-extension-cat-entrance.png?v=3"' in extension assert "const ENTRANCE_KEYFRAME_COUNT = 12" in extension assert "const ENTRANCE_DURATION_MS = 2300" in extension assert "const ENTRANCE_WALK_STEPS = 5" in extension assert "const ENTRANCE_SETTLE_START_FRAME = 5" in extension assert "0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4" in extension assert "const easedStepProgress = 0.5 - (Math.cos(Math.PI * stepProgress) / 2)" in extension assert "function playEntrance()" in extension assert 'pet.dataset.entering = "true"' in extension assert "const drawEntrancePose =" in extension assert "window.requestAnimationFrame(renderEntrance)" in extension assert "function createThemedPetDataUrl(" in extension assert "blueDominance < 24" in extension assert 'window.addEventListener("cognitive-agent:demo-role-change"' not in extension assert 'class="v2-extension-pet-blink"' in extension assert "const scheduleBlink =" in extension assert 'pet.dataset.blinking = "true"' in extension assert 'class="v2-extension-pet-mouth-closed"' in extension assert "const animateMouth = () =>" in extension assert "mouth.animate?.(" in extension assert "{ opacity: 0, offset: 0.09 }" in extension assert "{ opacity: 0, offset: 0.41 }" in extension assert "{ opacity: 0, offset: 0.73 }" in extension assert "{ duration: 1260" in extension assert 'class="v2-extension-pet-tail-canvas"' in extension assert "const runTailWave =" in extension assert "const requestTailWave =" in extension assert 'prefers-reduced-motion: reduce' not in extension assert "tailWaveQueued = true" in extension assert "window.setTimeout(() => runTailWave(true), 180)" in extension assert "scheduleTailWave" not in extension assert 'pet.dataset.tailWaving = "true"' in extension assert "const tailMotionFrames = [" in extension assert "const sampleTailOffset =" in extension assert "sampleTailOffset(tailPose, distanceFromBase)" in extension assert "clampToSegment = false" in extension assert "Math.max(Math.min(start, end)" in extension assert "const sampleTravelingTailOffset =" not in extension assert 'document.visibilityState !== "visible"' in extension assert ".v2-extension-pet-body" in styles assert ".v2-extension-pet-entrance-canvas" in styles assert '.v2-extension-pet[data-entering="true"] .v2-extension-pet-image' in styles assert '.v2-extension-pet[data-blinking="true"] .v2-extension-pet-blink' in styles assert ".v2-extension-pet-mouth-closed" in styles assert "width: 176px;" in styles assert "font-size: 13px;" in styles assert '.v2-extension-pet[data-tail-waving="true"] .v2-extension-pet-tail-canvas' in styles assert '.v2-extension-pet[data-tail-waving="true"] .v2-extension-pet-image' in styles assert "position: fixed;" in styles assert "extension-pet-float" not in styles assert '[data-module="self-extension"][data-demo-role="admin"] .v2-sidebar' not in styles assert '[data-module="self-extension"][data-demo-role="admin"] .v2-avatar' not in styles def test_orchestration_session_reset_remains_available() -> None: orchestration = source("app.js") assert 'sessionStorage.removeItem("cognitive-agent.conversation-id")' in orchestration def test_vehicle_device_status_cards_prioritize_seats_and_expose_manual_controls() -> None: console = source("console-v2.js") styles = source("console-v2.css") passenger = console.index('id: "passenger", name: "副驾座椅"') driver = console.index('id: "driver", name: "主驾座椅"') windows = console.index('id: "windows", name: "车窗"') assert passenger < driver < windows for key_status in ( '["左前窗", readText("#frontLeftWindow")]', '["右前窗", readText("#frontRightWindow")]', '["左后窗", readText("#rearLeftWindow")]', '["右后窗", readText("#rearRightWindow")]', '["当前位置", readText("#shadePositionValue")]', '["按摩模式", massageMode]', '["按摩强度", massageStrength]', '["前排亮度", frontBrightness]', '["前排颜色", frontColor]', '["后排亮度", rearBrightness]', '["后排颜色", rearColor]', ): assert key_status in console assert 'data-device-control-toggle="${device.id}"' in console assert 'data-device-control-apply="${device.id}"' in console assert 'new CustomEvent("cognitive-agent:vehicle-control-request"' in console assert "window.CognitiveAgentConsole?.executeUtterance?.(utterance" in console assert '.v2-device-control-row input[type="range"]' in styles assert ".v2-device-control-select" in styles assert ".v2-device-control-apply" in styles def test_interactive_console_keeps_actions_inside_composer_and_collapsed_rails_aligned() -> None: console = source("console-v2.js") styles = source("console-v2.css") assert 'const resetButton = $("#newConversation", originalForm);' in console assert 'const runButton = $("#runButton", originalForm);' in console assert "if (resetButton) composer.append(resetButton);" in console assert "if (runButton) composer.append(runButton);" in console assert ".v2-request-form .command-composer" in styles assert "overflow: hidden;" in styles assert "transform: translateY(-50%);" in styles assert '.joint-twin-shell[data-open-panels="none"]' in styles assert "grid-template-columns: 48px minmax(520px, 1fr) 48px;" in styles assert "writing-mode: horizontal-tb;" in styles assert "writing-mode: vertical-rl;" in styles def test_left_sync_rail_can_collapse_and_log_aligns_with_lower_workspace() -> None: console = source("console-v2.js") styles = source("console-v2.css") assert 'make("section", "v2-sync-sidebar"' in console assert '