feat(sense): add loopback NVR management console
Harness governance / validate (pull_request) Has been cancelled
Harness governance / validate (pull_request) Has been cancelled
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import re
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
ASSETS = ROOT / "Sense" / "internal" / "console" / "assets"
|
||||
|
||||
|
||||
class SenseConsoleContractTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.html = (ASSETS / "index.html").read_text(encoding="utf-8")
|
||||
cls.css = (ASSETS / "app.css").read_text(encoding="utf-8")
|
||||
cls.javascript = (ASSETS / "app.js").read_text(encoding="utf-8")
|
||||
|
||||
def test_console_is_self_contained_and_preserves_five_entry_ia(self):
|
||||
self.assertIn('href="/sense-console/app.css"', self.html)
|
||||
self.assertIn('src="/sense-console/app.js"', self.html)
|
||||
self.assertNotRegex(self.html, r"https?://")
|
||||
self.assertNotIn("<script>", self.html)
|
||||
self.assertNotIn("<style>", self.html)
|
||||
for view in ("overview", "monitor", "devices", "onboarding", "operations"):
|
||||
self.assertGreaterEqual(self.html.count(f'data-view="{view}"'), 2)
|
||||
self.assertIn(f'data-page="{view}"', self.html)
|
||||
|
||||
def test_capacity_and_preview_bounds_are_explicit(self):
|
||||
self.assertIn('params.set("limit", String(state.config.page_size))', self.javascript)
|
||||
self.assertIn("state.selected.size >= state.config.max_active_previews", self.javascript)
|
||||
self.assertIn('state.config.page_size !== 16', self.javascript)
|
||||
self.assertIn('state.config.max_active_previews !== 4', self.javascript)
|
||||
self.assertIn('state.config.recording_and_playback !== false', self.javascript)
|
||||
self.assertIn('$("#nextPage").disabled = loading || !state.nextCursor', self.javascript)
|
||||
self.assertIn('$("#prevPage").disabled = loading || state.pageIndex === 0', self.javascript)
|
||||
self.assertNotRegex(self.javascript, r"\.slice\(\s*0\s*,\s*16\s*\)")
|
||||
|
||||
def test_token_is_memory_only_and_sensitive_addresses_are_not_rendered(self):
|
||||
for forbidden in ("local" + "Storage", "session" + "Storage", "document.cookie"):
|
||||
self.assertNotIn(forbidden, self.javascript)
|
||||
self.assertIn('state.token = ""', self.javascript)
|
||||
self.assertIn('tokenInput.value = ""', self.javascript)
|
||||
self.assertNotRegex(self.html, r"rtsp://|onvif://|/whep")
|
||||
self.assertNotRegex(self.javascript, r"rtsp://|onvif://")
|
||||
self.assertNotIn("innerHTML", self.javascript)
|
||||
|
||||
def test_accessibility_and_responsive_guards_are_present(self):
|
||||
self.assertIn('href="#main-content"', self.html)
|
||||
self.assertIn('aria-live="polite"', self.html)
|
||||
self.assertIn('aria-current="page"', self.html)
|
||||
self.assertIn("@media (max-width: 760px)", self.css)
|
||||
self.assertIn("min-height: 44px", self.css)
|
||||
self.assertIn("prefers-reduced-motion", self.css)
|
||||
self.assertIn(":focus-visible", self.css)
|
||||
ids = re.findall(r'\bid="([^"]+)"', self.html)
|
||||
self.assertEqual(len(ids), len(set(ids)))
|
||||
for attributes, content in re.findall(r"<button\b([^>]*)>(.*?)</button>", self.html, re.S):
|
||||
visible_text = re.sub(r"<[^>]+>", "", content).strip()
|
||||
self.assertTrue(
|
||||
"aria-label=" in attributes or visible_text,
|
||||
f"button lacks an accessible name: {attributes}",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user