feat: validate real-bench seat orchestration and self-repair

This commit is contained in:
vee
2026-08-09 19:00:16 +08:00
parent 3bceb0d5a1
commit 3701192a11
41 changed files with 10403 additions and 3392 deletions
+8 -2
View File
@@ -115,7 +115,7 @@ class SeatWebApiTests(unittest.TestCase):
def test_static_console_and_runtime_endpoint(self) -> None:
with self.opener.open(f"{self.base_url}/", timeout=3) as response:
html = response.read().decode("utf-8")
with self.opener.open(f"{self.base_url}/app.js?v=seat-hil-43", timeout=3) as response:
with self.opener.open(f"{self.base_url}/app.js?v=seat-hil-44", timeout=3) as response:
app_script = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/gesture-control.js?v=android-pad-6", timeout=3
@@ -150,7 +150,7 @@ class SeatWebApiTests(unittest.TestCase):
self.assertIn("整车孪生界面", html)
self.assertIn("<strong>阅读灯</strong>", html)
self.assertNotIn("透明车体 · 实体设备", html)
self.assertIn('src="/app.js?v=seat-hil-43"', html)
self.assertIn('src="/app.js?v=seat-hil-44"', html)
self.assertIn('src="/gesture-control.js?v=android-pad-6"', html)
self.assertNotIn('class="vehicle-system-hud"', html)
self.assertIn('src="/console-v2.js?v=desktop-refactor-28"', html)
@@ -229,6 +229,12 @@ class SeatWebApiTests(unittest.TestCase):
self.assertNotIn('id="releaseHardwareAccess"', html)
self.assertIn('const dynamicModeOrder = ["rocking_horse", "dynamic_cradle"]', app_script)
self.assertIn('divider.className = "mode-group-divider"', app_script)
self.assertIn(
'mode === "hardware" && !state.runtime?.hardware_execution_allowed',
app_script,
)
self.assertIn("hardwareButton.disabled = !hardwareExecutionReady", app_script)
self.assertIn("车端 CAN 未启用,其他领域保持虚拟执行", app_script)
self.assertIn("function extractReferenceWindowPanes", app_script)
self.assertIn("function collectReferenceFrontLampMeshes", app_script)
self.assertIn("function emphasizeReferenceWindowPanes", app_script)
+27 -6
View File
@@ -5,6 +5,7 @@ import threading
import urllib.error
import urllib.request
from http.server import ThreadingHTTPServer
from pathlib import Path
import pytest
@@ -134,15 +135,15 @@ class TestSelfRepairApi:
with urllib.request.urlopen(f"{self.base_url}/", timeout=3) as response:
html = response.read().decode("utf-8")
with urllib.request.urlopen(
f"{self.base_url}/self-repair.js?v=repair-15", timeout=3
f"{self.base_url}/self-repair.js?v=repair-17", timeout=3
) as response:
script = response.read().decode("utf-8")
with urllib.request.urlopen(
f"{self.base_url}/self-repair.css?v=repair-15", timeout=3
f"{self.base_url}/self-repair.css?v=repair-17", timeout=3
) as response:
styles = response.read().decode("utf-8")
with urllib.request.urlopen(
f"{self.base_url}/self-repair-seat3d.js?v=repair-15", timeout=3
f"{self.base_url}/self-repair-seat3d.js?v=repair-17", timeout=3
) as response:
seat3d = response.read().decode("utf-8")
with urllib.request.urlopen(
@@ -150,10 +151,15 @@ class TestSelfRepairApi:
) as response:
console_script = response.read().decode("utf-8")
assert 'href="/self-repair.css?v=repair-15"' in html
assert 'src="/self-repair.js?v=repair-15"' in html
assert 'src="/self-repair-seat3d.js?v=repair-15"' in html
assert 'href="/self-repair.css?v=repair-17"' in html
assert 'src="/self-repair.js?v=repair-17"' in html
assert 'src="/self-repair-seat3d.js?v=repair-17"' in html
assert "量产故障用例" in script
assert 'id="repairConfirmDialog"' in script
assert "confirmAction(" in script
assert "window.confirm" not in script
assert 'hardware.link?.adapter === "OK"' in script
assert 'PASSED: ["21针通过", "online"]' in script
assert "connectorRows" in script
assert "Polling refreshes data only" in script
assert "renderRecords();\n showView(activeView);" not in script
@@ -172,3 +178,18 @@ class TestSelfRepairApi:
assert 'window.addEventListener("self-repair-seat-reset"' in seat3d
assert '["self-calibration", "self-repair"].includes(module)' in console_script
assert 'roleSelect.disabled = ui.activeModule === "self-repair"' in console_script
def test_self_repair_bridge_uses_the_backend_runtime_directory() -> None:
source = (
Path(__file__).resolve().parents[2]
/ "tools"
/ "zcan"
/ "seat_self_repair_bridge.py"
).read_text(encoding="utf-8")
assert '"artifacts", "tmp", "self-repair", "runtime"' in source
assert 'os.path.join(BASE_DIR, "seat_function_runtime")' not in source
assert "A silent or disconnected CAN bus must not kill" in source
assert 'self.message("GUI STOP_ALL发送失败' in source
assert 'self.message("GUI thermal off发送失败' in source