fieldwitness/tests/e2e/helpers.py
Aaron D. Lee 16318daea3
Some checks failed
CI / lint (push) Failing after 12s
CI / typecheck (push) Failing after 12s
Add comprehensive test suite: integration tests + Playwright e2e
Integration tests (350 passing):
- test_evidence_summary.py: HTML/PDF generation, XSS safety, anchor rendering
- test_tor.py: Tor module unit tests (mocked, no Tor needed)
- test_c2pa_importer.py: Import result dataclass, trust evaluation, graceful degradation
- test_file_attestation.py: All file types (PNG, PDF, CSV, empty, large), determinism
- test_paths.py: Registry correctness, env var override, all paths under BASE_DIR
- test_killswitch_coverage.py: Tor keys, trusted keys, carrier history destruction

Playwright e2e infrastructure:
- tests/e2e/ with conftest (live server, auth fixtures), helpers (test file generators)
- test_auth.py: Setup flow, login/logout, protected routes
- test_attest.py: Image/PDF/CSV attestation, verify, attestation log
- test_dropbox.py: Token creation, source upload, branding check
- test_keys.py: Identity display, trust store
- test_fieldkit.py: Status dashboard, killswitch page
- test_navigation.py: All nav links, responsive layout

Run: pytest (unit/integration) or pytest -m e2e tests/e2e/ (browser)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 20:22:12 -04:00

108 lines
3.3 KiB
Python

"""
Test helpers for e2e tests — generate in-memory test files.
All helpers return raw bytes suitable for use with page.set_input_files().
"""
from __future__ import annotations
import io
import struct
import zlib
def create_test_image(width: int = 64, height: int = 64) -> bytes:
"""Generate a minimal valid PNG image in memory.
Returns raw PNG bytes. Does not require Pillow — builds a PNG manually
using only the stdlib so that helpers.py has zero external dependencies.
"""
# PNG signature
png_sig = b"\x89PNG\r\n\x1a\n"
def make_chunk(chunk_type: bytes, data: bytes) -> bytes:
length = struct.pack(">I", len(data))
crc = struct.pack(">I", zlib.crc32(chunk_type + data) & 0xFFFFFFFF)
return length + chunk_type + data + crc
# IHDR: width, height, bit depth=8, color type=2 (RGB), compression=0,
# filter=0, interlace=0
ihdr_data = struct.pack(">IIBBBBB", width, height, 8, 2, 0, 0, 0)
ihdr = make_chunk(b"IHDR", ihdr_data)
# IDAT: raw scanlines (filter byte 0 per row, then RGB pixels)
raw_rows = []
for y in range(height):
row = b"\x00" # filter type None
for x in range(width):
# Vary pixel color so the image is non-trivial
r = (x * 4) & 0xFF
g = (y * 4) & 0xFF
b = ((x + y) * 2) & 0xFF
row += bytes([r, g, b])
raw_rows.append(row)
compressed = zlib.compress(b"".join(raw_rows))
idat = make_chunk(b"IDAT", compressed)
iend = make_chunk(b"IEND", b"")
return png_sig + ihdr + idat + iend
def create_test_pdf() -> bytes:
"""Generate a minimal valid single-page PDF in memory.
The PDF is structurally valid (Acrobat/browsers will accept it) but
contains only a blank page with a text label.
"""
body = b"""%PDF-1.4
1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj
3 0 obj<</Type/Page/MediaBox[0 0 612 792]/Parent 2 0 R/Resources<</Font<</F1 4 0 R>>>>>>endobj
4 0 obj<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>endobj
5 0 obj<</Length 44>>
stream
BT /F1 12 Tf 100 700 Td (FieldWitness test PDF) Tj ET
endstream
endobj
"""
xref_offset = len(body)
body += (
b"xref\n"
b"0 6\n"
b"0000000000 65535 f \n"
b"0000000009 00000 n \n"
b"0000000058 00000 n \n"
b"0000000115 00000 n \n"
b"0000000266 00000 n \n"
b"0000000346 00000 n \n"
b"trailer<</Size 6/Root 1 0 R>>\n"
b"startxref\n"
)
body += str(xref_offset).encode() + b"\n%%EOF\n"
return body
def create_test_csv() -> bytes:
"""Generate a simple CSV file in memory."""
lines = [
"timestamp,sensor_id,value,unit",
"2024-01-15T10:00:00Z,TEMP-001,23.5,celsius",
"2024-01-15T10:01:00Z,TEMP-001,23.7,celsius",
"2024-01-15T10:02:00Z,TEMP-001,23.6,celsius",
"2024-01-15T10:03:00Z,HUMID-001,65.2,percent",
]
return "\n".join(lines).encode("utf-8")
def create_test_txt() -> bytes:
"""Generate a plain-text file in memory."""
content = (
"FieldWitness e2e test document\n"
"===============================\n\n"
"This file was generated by the automated test suite.\n"
"It contains no sensitive information.\n"
)
return content.encode("utf-8")