Add initial web editor app, CLI scripts, and test scaffolding.

This introduces the FastAPI editor implementation and related project setup so the app can be run and validated locally.

Made-with: Cursor
This commit is contained in:
2026-04-11 02:14:26 +12:00
parent fb5f55cda7
commit f9bf119af6
33 changed files with 4846 additions and 0 deletions

91
tests/test_browser.py Normal file
View File

@@ -0,0 +1,91 @@
import importlib
import socket
import subprocess
import sys
import time
from pathlib import Path
import pytest
def _is_port_open(port: int) -> bool:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.settimeout(0.3)
return sock.connect_ex(("127.0.0.1", port)) == 0
@pytest.mark.integration
def test_browser_create_file_not_forced_into_new(tmp_path):
playwright = pytest.importorskip("playwright.sync_api")
sync_playwright = playwright.sync_playwright
editor_dir = Path(__file__).resolve().parents[1]
port = 8123
env = dict(**__import__("os").environ, WORKSPACE_ROOT=str(tmp_path))
server = subprocess.Popen(
[
sys.executable,
"-m",
"uvicorn",
"app:app",
"--app-dir",
"src",
"--host",
"127.0.0.1",
"--port",
str(port),
],
cwd=str(editor_dir),
env=env,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
try:
for _ in range(50):
if _is_port_open(port):
break
time.sleep(0.1)
else:
pytest.fail("Server did not start in time")
with sync_playwright() as p:
try:
browser = p.chromium.launch()
except Exception as exc: # pragma: no cover
pytest.skip(f"Playwright browser not installed: {exc}")
page = browser.new_page()
page.goto(f"http://127.0.0.1:{port}/editor", wait_until="networkidle")
page.click("#new-file-btn")
page.fill("#new-filename", "browser-test.txt")
page.click("#create-file-btn")
page.wait_for_timeout(500)
browser.close()
assert (tmp_path / "browser-test.txt").exists()
assert not (tmp_path / "new" / "browser-test.txt").exists()
finally:
server.terminate()
try:
server.wait(timeout=3)
except subprocess.TimeoutExpired:
server.kill()
def test_new_file_uses_api_file_route(tmp_path):
import editor_app.config as config
import editor_app.main as main
from fastapi.testclient import TestClient
config.WORKSPACE_ROOT = tmp_path
importlib.reload(main)
client = TestClient(main.app)
response = client.post(
"/api/file/code/routing-check.txt",
json={"content": "ok"},
)
assert response.status_code == 200
assert (tmp_path / "code" / "routing-check.txt").exists()
assert not (tmp_path / "new" / "routing-check.txt").exists()