Skip to main content

Record your E2E tests as MP4 videos with live panel overlays and interactive HTML reports.

Project description

thea-recorder

Record your E2E browser tests as MP4 videos with live panel overlays and interactive HTML reports.

Your tests already prove your app works. But when they fail at 3am in CI, you're left staring at a stack trace trying to imagine what the browser was doing. thea-recorder captures everything — the browser, your test steps, custom status panels — as a video, then generates a report where you can click any step and watch exactly what happened.

Why

E2E tests are the most expensive tests you write. They're slow, flaky, and when they break, they're the hardest to debug. The typical debugging cycle looks like:

  1. Read the failure log
  2. Try to reproduce locally
  3. Add more logging
  4. Push, wait for CI, read logs again
  5. Repeat

This is absurd. Your browser was right there doing the thing. You just weren't watching.

thea-recorder fixes this by recording the virtual display during test execution. Every scenario gets its own MP4. The panel overlay shows you which step is running, the current status, and any custom context you want. The HTML report lets you click a step and the video seeks to that exact moment.

You stop guessing. You start watching.

Features

  • HTTP server + native SDKs — use from Go, Python, Ruby, TypeScript, or Java
  • CLI — server mode and client mode, scriptable from any language
  • Panel overlay system — named columns below the viewport with live-updating text
  • Smart scrolling — panels auto-scroll to keep the active content visible
  • Interactive HTML reports — embedded videos with clickable step timelines
  • Framework agnostic — works with any test runner in any language
  • Docker ready — example Dockerfile and E2E test suite included

Install

pip install thea-recorder

System dependencies (in your Docker image or CI runner):

apt install xvfb ffmpeg x11-xserver-utils fonts-dejavu-core

Quick start — HTTP server

Start the server:

thea serve --port 9123

Then use any SDK:

Go

client := recorder.NewClient("http://localhost:9123")
client.StartDisplay(ctx)
stop, _ := client.Recording(ctx, "login_test")
defer stop()
// ... run your browser test ...

Python

from thea import RecorderClient
client = RecorderClient("http://localhost:9123")
client.start_display()
with client.recording("login_test"):
    # ... run your browser test ...
    pass

TypeScript

const client = new RecorderClient({ url: "http://localhost:9123" });
await client.startDisplay();
await client.recording("login_test", async () => {
  // ... run your Playwright test ...
});

Ruby

client = Recorder::Client.new("http://localhost:9123")
client.start_display
client.recording("login_test") do
  # ... run your browser test ...
end

Java

try (var client = new RecorderClient("http://localhost:9123")) {
    client.startDisplay();
    client.recording("login_test", c -> {
        // ... run your Selenium test ...
    });
}

Quick start — Python library

from recorder import Recorder, generate_report

recorder = Recorder(output_dir="./recordings", display=99)
recorder.add_panel("status", title="Status", width=120)
recorder.add_panel("steps", title="Steps")
recorder.start_display()

recorder.start_recording("login_test")
recorder.update_panel("status", "Running")
recorder.update_panel("steps", "  Given a user\n* When I log in\n  Then I see the dashboard")

# ... run your browser automation here (on DISPLAY :99) ...

video = recorder.stop_recording()

generate_report(
    videos=[{
        "feature": "Authentication",
        "scenario": "Login",
        "status": "passed",
        "video": video,
        "steps": [
            {"keyword": "Given", "name": "a user", "status": "passed", "offset": 0.0},
            {"keyword": "When", "name": "I log in", "status": "passed", "offset": 2.5},
            {"keyword": "Then", "name": "I see the dashboard", "status": "passed", "offset": 5.0},
        ],
    }],
    output_dir="./recordings",
    title="My Test Report",
)

recorder.cleanup()

CLI

# Server mode
thea serve --port 9123 --output-dir ./recordings --cors

# Client mode (talks to running server)
thea --server http://localhost:9123 start-display
thea --server http://localhost:9123 add-panel --name editor --title "Code" --width 80
thea --server http://localhost:9123 start-recording --name login_test
thea --server http://localhost:9123 stop-recording
thea --server http://localhost:9123 list-recordings
thea --server http://localhost:9123 health

Set RECORDER_URL to avoid repeating --server:

export RECORDER_URL=http://localhost:9123
thea health
thea start-display
thea start-recording --name my-test

Docker

FROM python:3.12-slim

RUN apt-get update && apt-get install -qyy --no-install-recommends \
    chromium-driver xvfb ffmpeg x11-xserver-utils fonts-dejavu-core \
    && rm -rf /var/lib/apt/lists/*

RUN pip install thea-recorder
EXPOSE 9123
CMD ["thea", "serve", "--host", "0.0.0.0", "--port", "9123"]

Panel system

Panels are named overlay columns rendered below the browser viewport in a dark bar. They update in real-time during recording.

# Fixed-width panel
recorder.add_panel("status", title="Status", width=120)

# Auto-width panel (shares remaining space)
recorder.add_panel("log", title="Activity Log")

# Update content (atomically — no tearing in the video)
recorder.update_panel("log", "Line 1\nLine 2\nLine 3")

# Scroll to keep a specific line visible
recorder.update_panel("log", long_text, focus_line=current_step)

Report

The HTML report is a single self-contained file with:

  • Embedded MP4 video players per scenario
  • Clickable step timelines that seek the video
  • Video playback highlights the current step
  • Feature/scenario grouping with pass/fail badges
  • Dark theme, responsive layout
  • Customisable title, subtitle, and logo

Documentation

API

Recorder(output_dir, display, browser_size, framerate, font, font_bold)

Param Default Description
output_dir /tmp/recordings Where MP4 files are saved
display 99 X11 display number
browser_size 1920x1080 Virtual display resolution
framerate 15 Recording FPS
font auto-detect Path to regular TTF font
font_bold auto-detect Path to bold TTF font

Methods

Method Description
start_display() Launch Xvfb
stop_display() Terminate Xvfb
add_panel(name, title, width) Register a panel
remove_panel(name) Remove a panel
update_panel(name, text, focus_line) Update panel content
start_recording(filename) Start ffmpeg capture
stop_recording() Stop capture, return MP4 path
recording_elapsed Seconds since recording started
cleanup() Stop everything, remove temp files

generate_report(videos, output_dir, title, subtitle, logo_text)

Takes a list of video metadata dicts and writes report.html.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

thea_recorder-0.2.0.tar.gz (34.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

thea_recorder-0.2.0-py3-none-any.whl (22.6 kB view details)

Uploaded Python 3

File details

Details for the file thea_recorder-0.2.0.tar.gz.

File metadata

  • Download URL: thea_recorder-0.2.0.tar.gz
  • Upload date:
  • Size: 34.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for thea_recorder-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f8361a7097e0a210c265a1e1226ff30f00fa4462fb595434ce73d9a6d30a5d74
MD5 666a3e2a8423dc80d15fb4b351608df0
BLAKE2b-256 88c9963dd2ae93133fe44db51b5130ff1afa732dafadb48e56c02edee99839df

See more details on using hashes here.

Provenance

The following attestation bundles were made for thea_recorder-0.2.0.tar.gz:

Publisher: publish-python.yml on barkingiguana/thea-recorder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file thea_recorder-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: thea_recorder-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 22.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for thea_recorder-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1f25910dac1a325d7b3bed98bde0eeb6acba26b12608638b06eafd33cda24b01
MD5 6d3ff3904504726e7ed3f96e1193c524
BLAKE2b-256 ade8b7970a4c9e957494430bd8075dabca50a17d7a4074b87e124704fae4df28

See more details on using hashes here.

Provenance

The following attestation bundles were made for thea_recorder-0.2.0-py3-none-any.whl:

Publisher: publish-python.yml on barkingiguana/thea-recorder

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page