Files

131 lines
3.9 KiB
Python

"""
Frontend smoke tests — lightweight checks via curl + grep.
Verifies the server serves correct HTML, CSS, and tab structure.
Playwright is unavailable due to snap chromium incompatibility.
"""
import os
import sys
import subprocess
import pytest
BASE_URL = "https://canteen.ourpad.casa"
def _curl(path):
"""Fetch a URL and return (status_code, body)."""
url = f"{BASE_URL}{path}"
result = subprocess.run(
["curl", "-sk", "-w", "\n%{http_code}", url],
capture_output=True, text=True, timeout=10
)
lines = result.stdout.strip().split("\n")
status = int(lines[-1])
body = "\n".join(lines[:-1])
return status, body
class TestFrontendServes:
"""Basic server serving tests."""
def test_html_returns_200(self):
"""Homepage returns 200."""
status, _ = _curl("/")
assert status == 200
def test_has_title(self):
"""Page has correct title."""
_, body = _curl("/")
assert "<title>Canteen Asset Tracker</title>" in body
def test_has_doctype(self):
"""Returns valid HTML5."""
_, body = _curl("/")
assert body.strip().startswith("<!DOCTYPE html>")
def test_has_viewport_meta(self):
"""Has mobile viewport meta tag."""
_, body = _curl("/")
assert 'name="viewport"' in body
assert "user-scalable=no" in body
class TestFrontendUIElements:
"""Key UI elements present in the HTML."""
def test_has_hamburger_menu(self):
"""Header has hamburger menu button."""
_, body = _curl("/")
assert 'class="hamburger"' in body or "hamburger" in body
def test_has_tab_bar(self):
"""Has tab navigation."""
_, body = _curl("/")
# Check for tab-related class names
assert "tab" in body.lower()
def test_dark_theme(self):
"""Dark theme CSS variables are defined."""
_, body = _curl("/")
assert "var(--bg)" in body
def test_has_leaflet_js(self):
"""Leaflet map library is loaded."""
_, body = _curl("/")
assert "leaflet.js" in body or "leaflet" in body
def test_has_zxing_barcode(self):
"""Barcode scanning library is loaded."""
_, body = _curl("/")
assert "zxing" in body
def test_mobile_layout(self):
"""Page uses mobile-first max-width layout."""
_, body = _curl("/")
assert "max-width: 480px" in body
def test_has_drawer(self):
"""Has drawer/sidebar component."""
_, body = _curl("/")
assert "drawer" in body
class TestAPIEndpoints:
"""Key API endpoints are reachable."""
def test_health_endpoint(self):
"""Health check works."""
status, body = _curl("/health")
assert status == 200
assert '"status":"ok"' in body
def test_login_reachable(self):
"""Login endpoint is reachable (POST)."""
import subprocess
result = subprocess.run(
["curl", "-sk", "-o", "/dev/null", "-w", "%{http_code}",
"-X", "POST", "-H", "Content-Type: application/json",
"-d", '{"username":"admin","password":"changeme"}',
f"{BASE_URL}/api/auth/login"],
capture_output=True, text=True, timeout=10
)
status = int(result.stdout.strip())
assert status == 200, f"Login returned {status}"
def test_assets_listable(self):
"""Assets endpoint is reachable."""
status, _ = _curl("/api/assets")
assert status in (200, 401) # 401=needs auth, but reachable
def test_static_files(self):
"""Static asset files are served."""
status, _ = _curl("/static/index.html")
assert status == 404 # index.html is at root, not /static/
def test_frontend_loads_fast(self):
"""Frontend loads in under 2 seconds."""
import time
start = time.time()
_curl("/")
elapsed = time.time() - start
assert elapsed < 2.0, f"Frontend took {elapsed:.2f}s to load"