ettool
A hands-free session recorder for exploratory testing. You test in the browser, narrate your observations out loud, and the tool writes the notes.
The Principle
ettool is a session recorder for exploratory testing. You launch a browser, explore the application, and talk through what you see. Press a hotkey when something is worth noting. When you're done, the tool correlates your voice with your browser actions and generates structured findings in org-mode format, ready for review in Emacs and posting to GitHub PRs.
Most "AI testing tools" try to find bugs for you. ettool does the opposite: it assumes you're the expert and handles the paperwork. The LLM structures what you described. It never invents expected behavior, never upgrades an observation to a bug, and never infers what you meant. If you didn't say it, it doesn't appear in the report.
How It Works
1. Record
Launch a browser with ettool start --pr 123 --charter "Test login flow".
Three systems run concurrently: a browser controller captures clicks, navigation,
and input. An audio recorder captures your microphone. A hotkey handler listens
for your commands.
You test normally. When something catches your attention, press
Ctrl+Shift+F7 and classify it. The tool takes a screenshot and
marks the moment. When you're done, Ctrl+Shift+F8 ends the session.
2. Transcribe
The recorded audio goes through faster-whisper with VAD filtering and word-level timestamps. Full-buffer transcription, not streaming. This matters: full context produces significantly better transcription quality than real-time streaming, which I verified empirically by building both approaches and comparing the output.
3. Correlate
The correlation pipeline merges browser actions, transcript segments, and captures into a unified timeline sorted by timestamp. For each finding, it gathers context from a 60-second window: what you said, what you clicked, what pages you visited.
An LLM then generates titles and structured descriptions from this context. Different finding types get different prompts. Bugs get steps to reproduce (only if evident from the narration). Expected behavior is included only if you explicitly stated it.
4. Review
Findings open in Emacs as an org-mode file with a custom major mode. Navigate between findings, view inline screenshots, edit descriptions, and post directly to GitHub PRs. Screenshots are uploaded to a dedicated branch and embedded in PR comments. Nothing leaves your machine until you explicitly approve it.
The Hotkey System
During a session, you classify findings yourself. The tester decides what's a bug and what's just an observation. The tool never guesses.
| Hotkey | Action |
|---|---|
Ctrl+Shift+F5 |
Take screenshot |
Ctrl+Shift+F6 |
Create checkpoint (screenshot + DOM snapshot + console + network state) |
Ctrl+Shift+F7 |
Mark finding (opens type selector) |
Ctrl+Shift+F8 |
End session |
When you press Ctrl+Shift+F7, an in-browser dialog appears with
five finding types:
Bug Issue Comment Observation Question
Each type carries different certainty and tone. A bug is confirmed and definitive. An issue is uncertain and invites discussion. An observation is neutral, noted for the record. The classification drives how the LLM structures the output.
What You Get
The output is an org-mode file with structured findings, context quotes from your narration, embedded screenshots, and a raw timeline of the session.
Findings are written in first person because you'll post them as your own observations. Steps to reproduce only appear for bugs where clear steps are evident. Expected behavior only appears if you said what you expected. The context section preserves your exact words so you can verify the LLM didn't embellish.
What I Built and Then Rejected
Real-Time Voice Detection
I built a complete real-time voice pipeline: streaming transcription with GPU-accelerated Whisper, LLM intent detection every 1.5 seconds, automatic screenshot capture when findings were detected. It worked. I rejected it after testing because the AI was deciding what counted as a finding instead of the tester. Classification quality was poor, and the loss of control felt wrong. Hotkeys give the tester explicit control. Voice detection guesses. The branch is preserved as an empirical record of why the simpler approach wins.
I also evaluated seven local LLM models for the correlation pipeline. All of them conflated distinct issues into single findings. Only Claude Sonnet correctly separated them. At roughly two cents per session, the API cost isn't worth optimizing away at the expense of finding quality and trust in the tool.
Technology
Python 3.11+ with Playwright for browser automation, faster-whisper for
transcription (CTranslate2, GPU-accelerated), pynput for global hotkeys,
Claude Sonnet API for correlation, and a custom Emacs major mode for review
with GitHub PR integration via the gh CLI.
Configuration is layered TOML (project-local overrides global overrides defaults). Browser profiles persist cookies across sessions so you log in once. Output is plain-text org-mode with no vendor lock-in.
Status
ettool is in active development and daily use for real testing work. The full pipeline works end-to-end. Open source release is planned but not yet scheduled.
The tool and its development story (including the real-time voice rejection) are part of my conference talks on AI accountability and the difference between fast implementation and active architecture.
Interested?
If you're working on similar problems, whether building tools for exploratory testing, thinking about where AI belongs in the testing workflow, or designing human-governed AI systems, I'd enjoy the conversation.