Files
Cognitive_Agent/tests/unit/test_requested_frontend_enhancements.py
T

216 lines
10 KiB
Python

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 '<div class="v2-sync-sidebar-overview">' in console
assert '$(".v2-sync-sidebar-overview", syncSidebar)?.append(sidebarFooter);' in console
assert '$(".v2-sync-sidebar-heading", syncSidebar)?.append(sidebarToggle);' in console
assert "function syncSidebarLogBaseline()" in console
assert 'sidebar.style.setProperty("--v2-sync-log-top"' in console
assert 'window.addEventListener("resize", syncSidebarLogBaseline);' in console
assert "requestAnimationFrame(syncSidebarLogBaseline);" in console
assert "--v2-sync-log-top: 291px;" in styles
assert "grid-template-rows: calc(var(--v2-sync-log-top) - 10px) minmax(0, 1fr);" in styles
assert ".v2-sync-sidebar > .v2-sync-log" in styles
assert "grid-template-columns: 64px minmax(0, 1fr);" in styles
assert ".v2-sidebar-collapsed #v2SidebarToggle" in styles
def test_twin_device_status_popover_has_clear_close_paths() -> None:
console = source("console-v2.js")
styles = source("console-v2.css")
assert 'data-twin-popover-close aria-label="关闭${escapeHtml(device.name)}状态详情"' in console
assert 'popover.setAttribute("role", "dialog");' in console
assert 'popover.setAttribute("aria-label", "车端设备状态详情");' in console
assert 'event.target.closest("[data-twin-popover-close]")' in console
assert 'event.target.closest("[data-twin-device], #v2TwinDevicePopover")' in console
assert "const samePinned = displaySync.pinnedDevice === focus.dataset.deviceFocus;" in console
assert "clearTwinDevicePreview({ force: true });" in console
assert ".v2-twin-popover-close" in styles
assert ".v2-twin-popover-close:focus-visible" in styles
def test_twin_device_hotspots_use_responsive_hover_and_leader_labels() -> None:
console = source("console-v2.js")
styles = source("console-v2.css")
assert "previewClearTimer: null" in console
assert "hoverSuppressedUntil: 0" in console
assert 'class="v2-twin-hotspot-label"' in console
assert 'button.addEventListener("pointerenter"' in console
assert 'button.addEventListener("pointerleave"' in console
assert "scheduleTwinDevicePreviewClear();" in console
assert "}, 45);" in console
assert "performance.now() + 160" in console
assert 'hotspots.addEventListener("pointerover"' not in console
assert 'hotspots.addEventListener("pointerout"' not in console
assert ".v2-twin-hotspots button::before" in styles
assert ".v2-twin-hotspots button::after" in styles
assert ".v2-twin-hotspot-label" in styles
assert "--v2-hotspot-label-x: -115px" in styles
assert "--v2-hotspot-line-angle: -150deg" in styles
assert '.v2-twin-device-popover[data-pinned="false"]' in styles
assert "pointer-events: none;" in styles