import re import json from datetime import datetime import pytest from playwright.sync_api import expect from helpers import app_url, login_as_admin, skip_without_admin_credentials def drone_payload(operator_name): return { "operator_name": operator_name, "operator_id": "E2E-OP", "flyer_name": "E2E Remote Pilot", "flyer_id": "E2E-FLYER", "email": "drone-e2e@example.com", "phone": "0123456789", "flight_date": "2026-06-21", "estimated_takeoff_time": "10:00", "estimated_completion_time": "10:30", "estimated_takeoff_at": "2026-06-21T10:00:00", "estimated_completion_at": "2026-06-21T10:30:00", "maximum_elevation_ft_amsl": 200, "location_description": "E2E north apron survey", "location_latitude": 51.623389, "location_longitude": -4.069231, "location_inside_frz": "yes", "notes": "Created by Playwright e2e", } def test_drone_requests_requires_login_and_loads_queue(page): skip_without_admin_credentials(pytest) page.goto(app_url("/drone-requests")) expect(page).to_have_title(re.compile("Drone Flight Requests")) expect(page.get_by_role("heading", name="Drone Flight Requests")).to_be_visible() expect(page.get_by_role("heading", name="Login")).to_be_visible() login_as_admin(page) expect(page.locator("#request-list-body")).not_to_contain_text("Loading requests...") expect(page.locator("#request-count")).to_have_text(re.compile(r"\d+")) def test_public_drone_request_appears_in_tower_queue(page): skip_without_admin_credentials(pytest) operator_name = f"E2E Rotor Ops {datetime.utcnow().strftime('%H%M%S%f')}" create_response = page.request.post( app_url("/api/v1/drone-requests/public"), data=json.dumps(drone_payload(operator_name)), headers={"Content-Type": "application/json"}, ) assert create_response.ok, create_response.text() created = create_response.json() page.goto(app_url("/drone-requests")) login_as_admin(page) expect(page.locator("#request-list-body")).to_contain_text(created["reference_number"]) expect(page.locator("#request-list-body")).to_contain_text(operator_name)