git clone https://github.com/BetsolLLC/reenact
cd reenact
uv sync
uv run playwright install chromiumuv run ruff check src tests # lint
uv run mypy --strict src # type check
uv run pytest tests/ -v # testsAll three must pass before opening a PR. CI enforces this.
src/reenact/
schema.py # Pydantic v2 models — change here first
interpolation.py # {{var}} substitution
storage.py # JSON load/save
recorder/ # browser → Recording
replayer/ # Recording → ReplayReport
cli.py # Typer commands
tests/
test_schema.py
test_selectorgen.py
test_recorder.py
test_replayer.py
test_interpolation.py
- Add a new
*Stepmodel inschema.pywith aLiteraltype discriminator andintent: str. - Add it to the
_StepUnioninschema.py. - Handle it in
engine.py::_dispatch. - Handle it in
recorder.py::EventQueue.process(if recordable). - Write tests.
If you change the JSON schema in a breaking way, bump SCHEMA_VERSION in schema.py and add a migration in migrations.py.
Do not change the fallback order. It is: testid → role → text → css → xpath. This is a hard architectural constraint documented in CLAUDE.md.
src/reenact must have zero runtime imports from any AI/LLM provider. The JSON intent field exists so an optional external agent layer can read workflows — that tooling is out of scope for this package.