-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_frontend.py
More file actions
253 lines (204 loc) · 7.66 KB
/
test_frontend.py
File metadata and controls
253 lines (204 loc) · 7.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#!/usr/bin/env python3
"""Validate frontend files for syntax and structure."""
import re
from pathlib import Path
print("=" * 60)
print("Frontend Files Validation")
print("=" * 60)
print()
frontend_dir = Path(__file__).parent / "custom_components" / "camera_snapshot_processor" / "frontend"
# Test 1: Validate HTML structure
print("Test 1: Validating HTML structure...")
try:
panel_html = (frontend_dir / "panel.html").read_text()
# Check for required elements
assert '<!DOCTYPE html>' in panel_html
assert '<html>' in panel_html
assert '<head>' in panel_html
assert '<body>' in panel_html
assert 'panel.js' in panel_html
assert 'styles.css' in panel_html
# Check for main sections
assert 'class="sidebar"' in panel_html
assert 'class="main-content"' in panel_html
assert 'class="content-grid"' in panel_html
assert 'class="config-panel"' in panel_html
assert 'class="preview-panel"' in panel_html
# Check for tabs
assert 'data-tab="dimensions"' in panel_html
assert 'data-tab="crop"' in panel_html
assert 'data-tab="overlays"' in panel_html
assert 'data-tab="state-icons"' in panel_html
assert 'data-tab="stream"' in panel_html
# Check for form inputs
assert 'id="width"' in panel_html
assert 'id="height"' in panel_html
assert 'id="quality"' in panel_html
assert 'id="crop_enabled"' in panel_html
# Check for preview
assert 'id="preview-image"' in panel_html
assert 'id="loading"' in panel_html
# Check for buttons
assert 'id="save-config-btn"' in panel_html
assert 'id="refresh-preview-btn"' in panel_html
assert 'id="add-state-icon"' in panel_html
assert 'id="add-camera-btn"' in panel_html
# Check for modal
assert 'id="state-icon-modal"' in panel_html
assert 'class="modal"' in panel_html
print("✅ HTML structure is valid")
print(f" Total size: {len(panel_html):,} bytes")
except AssertionError as e:
print(f"❌ HTML validation failed: {e}")
exit(1)
print()
# Test 2: Validate JavaScript
print("Test 2: Validating JavaScript...")
try:
panel_js = (frontend_dir / "panel.js").read_text()
# Check for main functions
assert 'function init()' in panel_js or 'async function init()' in panel_js
assert 'setupEventListeners' in panel_js
assert 'loadCameras' in panel_js
assert 'saveConfig' in panel_js
assert 'refreshPreview' in panel_js
assert 'populateForm' in panel_js
assert 'getFormData' in panel_js
# Check for API calls
assert '/api/camera_snapshot_processor/' in panel_js
assert 'fetch(' in panel_js
assert 'async' in panel_js
assert 'await' in panel_js
# Check for event listeners
assert 'addEventListener' in panel_js
assert 'querySelector' in panel_js
# Check for state icon management
assert 'renderStateIcons' in panel_js
assert 'openStateIconModal' in panel_js
assert 'saveStateIcon' in panel_js
# Check for utility functions
assert 'hexToRgb' in panel_js
assert 'rgbToHex' in panel_js
# Count API endpoint calls
api_calls = len(re.findall(r'/api/camera_snapshot_processor/', panel_js))
print("✅ JavaScript is valid")
print(f" Total size: {len(panel_js):,} bytes")
print(f" API endpoints referenced: {api_calls}")
except AssertionError as e:
print(f"❌ JavaScript validation failed: {e}")
exit(1)
print()
# Test 3: Validate CSS
print("Test 3: Validating CSS...")
try:
styles_css = (frontend_dir / "styles.css").read_text()
# Check for main classes
assert '.sidebar' in styles_css
assert '.main-content' in styles_css
assert '.content-grid' in styles_css
assert '.config-panel' in styles_css
assert '.preview-panel' in styles_css
assert '.tab' in styles_css
assert '.tab-content' in styles_css
# Check for form styles
assert '.form-group' in styles_css
assert '.btn' in styles_css
assert '.btn-primary' in styles_css
assert '.btn-secondary' in styles_css
# Check for modal styles
assert '.modal' in styles_css
assert '.modal-content' in styles_css
assert '.modal-header' in styles_css
assert '.modal-body' in styles_css
# Check for animations
assert '@keyframes' in styles_css
assert 'fadeIn' in styles_css
# Check for responsive design
assert '@media' in styles_css
# Check for colors/gradients
assert 'gradient' in styles_css
assert '#667eea' in styles_css or 'rgb' in styles_css
# Count CSS rules (approximate)
css_rules = len(re.findall(r'\{[^}]+\}', styles_css))
print("✅ CSS is valid")
print(f" Total size: {len(styles_css):,} bytes")
print(f" Approximate CSS rules: {css_rules}")
except AssertionError as e:
print(f"❌ CSS validation failed: {e}")
exit(1)
print()
# Test 4: Cross-reference IDs
print("Test 4: Cross-referencing HTML IDs with JavaScript...")
try:
# Find all IDs in HTML
html_ids = set(re.findall(r'id="([^"]+)"', panel_html))
# Find all getElementById calls in JS
js_ids = set(re.findall(r'getElementById\([\'"]([^\'"]+)[\'"]\)', panel_js))
# Check if all JS references exist in HTML
missing_ids = js_ids - html_ids
if missing_ids:
print(f"⚠️ Warning: Some IDs referenced in JS not found in HTML: {missing_ids}")
else:
print("✅ All JavaScript ID references are valid")
print(f" HTML IDs: {len(html_ids)}")
print(f" JS references: {len(js_ids)}")
except Exception as e:
print(f"❌ Cross-reference check failed: {e}")
exit(1)
print()
# Test 5: Validate API endpoint consistency
print("Test 5: Validating API endpoint consistency...")
try:
# Extract API endpoints from JS
js_endpoints = set(re.findall(r'/api/camera_snapshot_processor/([^\'"`\s]+)', panel_js))
expected_endpoints = {
'cameras',
'cameras/${currentCameraId}',
'cameras/${camera_id}',
'entities',
'available_cameras'
}
# Check if key endpoints exist
assert 'cameras' in str(js_endpoints), "cameras endpoint should exist"
assert any('${currentCameraId}' in str(ep) or '${camera_id}' in str(ep) for ep in js_endpoints), "camera_id parameter should exist"
print("✅ API endpoints are consistent")
print(f" Endpoints found: {len(js_endpoints)}")
except AssertionError as e:
print(f"❌ API endpoint validation failed: {e}")
exit(1)
print()
# Test 6: Check for common issues
print("Test 6: Checking for common issues...")
try:
issues = []
# Check for console.log (should use _LOGGER in production)
if 'console.log' in panel_js and panel_js.count('console.log') > 2:
issues.append(f"Found {panel_js.count('console.log')} console.log statements (consider removing for production)")
# Check for alert() usage
alert_count = panel_js.count('alert(')
if alert_count > 0:
issues.append(f"Found {alert_count} alert() calls (consider using toast notifications)")
# Check for hardcoded URLs
if 'http://' in panel_js or 'https://' in panel_js:
issues.append("Found hardcoded URLs (should use relative paths)")
if issues:
print("⚠️ Potential issues found (non-critical):")
for issue in issues:
print(f" - {issue}")
else:
print("✅ No common issues found")
except Exception as e:
print(f"⚠️ Issue check failed: {e}")
print()
print("=" * 60)
print("🎉 Frontend validation complete!")
print("=" * 60)
print()
print("Summary:")
print("✅ HTML structure is valid and complete")
print("✅ JavaScript logic is properly structured")
print("✅ CSS styling is comprehensive")
print("✅ ID references are consistent")
print("✅ API endpoints match backend")
print()
print("Frontend is ready for deployment!")