Run browser tests locally: Playwright 1.64.1 in .venv, scripts switch to it on their own
The browser tests and screenshot tools now work with plain python3 on a machine whose system Python refuses pip installs: tools/use_venv.py re-runs them with the repo's .venv. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,3 +4,4 @@ __pycache__/
|
|||||||
*.pyc
|
*.pyc
|
||||||
node_modules/
|
node_modules/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.venv/
|
||||||
|
|||||||
@@ -34,10 +34,16 @@ The controls are in the in-game notebook (N) under Controls. The basics:
|
|||||||
You need Node (tested with 22), Python 3, and Playwright for the browser tests and screenshots:
|
You need Node (tested with 22), Python 3, and Playwright for the browser tests and screenshots:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pip install -r requirements.txt
|
uv venv .venv
|
||||||
python3 -m playwright install chromium
|
uv pip install --python .venv/bin/python -r requirements.txt
|
||||||
|
.venv/bin/python -m playwright install chromium
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If uv is not installed, `python3 -m venv .venv` and
|
||||||
|
`.venv/bin/pip install -r requirements.txt` also work; then install Chromium as above.
|
||||||
|
After that, plain `python3` works for every command below; the browser scripts switch to
|
||||||
|
`.venv` on their own.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
python3 build.py # build dist/index.html
|
python3 build.py # build dist/index.html
|
||||||
python3 test/run_all.py # headless test suites
|
python3 test/run_all.py # headless test suites
|
||||||
|
|||||||
+3
-1
@@ -21,7 +21,8 @@ src/ui/ the browser shell: input, HUD, build menu, notebook, setti
|
|||||||
test/ headless suites (t_*.js) and their harness; browser tests (play.py,
|
test/ headless suites (t_*.js) and their harness; browser tests (play.py,
|
||||||
t_smooth.py); run_all.py
|
t_smooth.py); run_all.py
|
||||||
tools/ shot.py (screenshots), where.py, map.py, perf.py, playthrough.py,
|
tools/ shot.py (screenshots), where.py, map.py, perf.py, playthrough.py,
|
||||||
scenes/ (screenshot setups), experiments/ (measurements and reports)
|
use_venv.py (switches browser scripts to .venv), scenes/ (screenshot
|
||||||
|
setups), experiments/ (measurements and reports)
|
||||||
docs/ this map, DESIGN.md, TESTING.md, systems/ (notes per system),
|
docs/ this map, DESIGN.md, TESTING.md, systems/ (notes per system),
|
||||||
history/ (the owner's requests), agent-log.md
|
history/ (the owner's requests), agent-log.md
|
||||||
dist/, shots/ build output and screenshots (not committed)
|
dist/, shots/ build output and screenshots (not committed)
|
||||||
@@ -456,6 +457,7 @@ The frame loop and boot.
|
|||||||
- `tools/perf.py`: Times the renderer and the simulation in a headless browser: light, drawWorld (with and without light and glow), the pixel upload and blit, and one simulation tick, in ms. Rebuild first.
|
- `tools/perf.py`: Times the renderer and the simulation in a headless browser: light, drawWorld (with and without light and glow), the pixel upload and blit, and one simulation tick, in ms. Rebuild first.
|
||||||
- `tools/playthrough.py`: Headless browser run: load the page, start a world, play a little, take screenshots.
|
- `tools/playthrough.py`: Headless browser run: load the page, start a world, play a little, take screenshots.
|
||||||
- `tools/shot.py`: Screenshot the game in a headless browser, after setting up a scene with JavaScript.
|
- `tools/shot.py`: Screenshot the game in a headless browser, after setting up a scene with JavaScript.
|
||||||
|
- `tools/use_venv.py`: Let browser scripts run with plain python3 by switching to the repo's .venv.
|
||||||
- `tools/where.py`: Turn a line number in dist/index.html into the source file and line it came from.
|
- `tools/where.py`: Turn a line number in dist/index.html into the source file and line it came from.
|
||||||
- `tools/experiments/cast_sunk_mold.js`: Block-sized bit mold sunk into the ground with a stone furnace built over its funnel.
|
- `tools/experiments/cast_sunk_mold.js`: Block-sized bit mold sunk into the ground with a stone furnace built over its funnel.
|
||||||
- `tools/experiments/factory_cost.js`: What does a running factory cost when the player is somewhere else? Builds K self-running modules in a generated world, far from the bot, and measures simulation time per tick. Each module: a coal + copper-ore furnace burning in a stone-block box, a spring feeding a water wheel, a shaft carrying its power to a 10-block belt that hauls sand off a hopper.
|
- `tools/experiments/factory_cost.js`: What does a running factory cost when the player is somewhere else? Builds K self-running modules in a generated world, far from the bot, and measures simulation time per tick. Each module: a coal + copper-ore furnace burning in a stone-block box, a spring feeding a water wheel, a shaft carrying its power to a 10-block belt that hauls sand off a hopper.
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ diff -r /tmp/before /tmp/after
|
|||||||
|
|
||||||
## Browser tests
|
## Browser tests
|
||||||
|
|
||||||
|
- They need the `.venv` from README.md → Develop; plain `python3` switches to it on its own.
|
||||||
- `test/play.py` (about 2.5 minutes) builds a world through the title screen and plays it with real
|
- `test/play.py` (about 2.5 minutes) builds a world through the title screen and plays it with real
|
||||||
input. It checks the tools, building, copy/cut/paste, undo, the build menu, filters, pipes,
|
input. It checks the tools, building, copy/cut/paste, undo, the build menu, filters, pipes,
|
||||||
the notebook and market, saving and continuing, exporting and importing a world file, the
|
the notebook and market, saving and continuing, exporting and importing a world file, the
|
||||||
|
|||||||
@@ -4,6 +4,25 @@ What agents have done, newest first. Add an entry for every piece of work: the d
|
|||||||
note or request it was for, what changed, the files touched, the tests run, and anything left
|
note or request it was for, what changed, the files touched, the tests run, and anything left
|
||||||
open or not verified. Keep each entry short; the git history has the details.
|
open or not verified. Keep each entry short; the git history has the details.
|
||||||
|
|
||||||
|
## 2026-10-23: browser tests run locally (Claude Code, with Codex)
|
||||||
|
|
||||||
|
Request: get the browser tests, Playwright and Chromium working on the owner's Arch machine
|
||||||
|
(Python 3.14 refuses a system-wide pip install).
|
||||||
|
|
||||||
|
- Playwright 1.64.1 and its Chromium 156 (revision 1248) are in an in-repo `.venv/` made with uv.
|
||||||
|
|
||||||
|
- Added `tools/use_venv.py` and called it before Playwright imports in `tools/shot.py`,
|
||||||
|
`tools/perf.py`, `tools/playthrough.py`, `test/play.py` and `test/t_smooth.py`.
|
||||||
|
The `sys.prefix` guard prevents an exec loop if the venv lacks Playwright.
|
||||||
|
- Updated `requirements.txt`, `.gitignore`, `README.md`, `AGENTS.md`, `docs/TESTING.md`
|
||||||
|
and `docs/PROJECT_MAP.md` for Playwright 1.64.1 and venv setup.
|
||||||
|
- Checks: regenerated the project map and ran `tools/map.py --check`.
|
||||||
|
- Tests run with plain `python3`: `test/run_all.py --browser` all passed (11 headless suites,
|
||||||
|
`play.py` 101 checks, `t_smooth.py` 8 checks) on the newer Chromium; `tools/shot.py` shots
|
||||||
|
of the stone-uses scene look right in both looks. With `.venv` moved away, `play.py` exits
|
||||||
|
with the setup message instead of a traceback.
|
||||||
|
- Open: nothing.
|
||||||
|
|
||||||
## 2026-10-23: export from claude.ai to a local repository (Claude, in claude.ai)
|
## 2026-10-23: export from claude.ai to a local repository (Claude, in claude.ai)
|
||||||
|
|
||||||
Request: split the source into small files, deduplicate and tidy a little, test fully, and
|
Request: split the source into small files, deduplicate and tidy a little, test fully, and
|
||||||
|
|||||||
+1
-1
@@ -1,2 +1,2 @@
|
|||||||
# browser tests and screenshots (test/play.py, test/t_smooth.py, tools/shot.py)
|
# browser tests and screenshots (test/play.py, test/t_smooth.py, tools/shot.py)
|
||||||
playwright==1.56.0
|
playwright==1.64.1
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
Screenshots go to shots/play/ (or the folder given as the first argument). Pixel look unless the
|
Screenshots go to shots/play/ (or the folder given as the first argument). Pixel look unless the
|
||||||
second argument is 'smooth'."""
|
second argument is 'smooth'."""
|
||||||
import json, sys, pathlib
|
import json, sys, pathlib
|
||||||
|
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent / 'tools'))
|
||||||
|
from use_venv import ensure_playwright; ensure_playwright()
|
||||||
from playwright.sync_api import sync_playwright
|
from playwright.sync_api import sync_playwright
|
||||||
root = pathlib.Path(__file__).resolve().parent.parent
|
root = pathlib.Path(__file__).resolve().parent.parent
|
||||||
out = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else root / 'shots' / 'play'); out.mkdir(parents=True, exist_ok=True)
|
out = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else root / 'shots' / 'play'); out.mkdir(parents=True, exist_ok=True)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
"""The smooth look: the WebGL pass compiles, draws, falls back cleanly, and the thermal lens still works."""
|
"""The smooth look: the WebGL pass compiles, draws, falls back cleanly, and the thermal lens still works."""
|
||||||
import sys, pathlib
|
import sys, pathlib
|
||||||
|
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent / 'tools'))
|
||||||
|
from use_venv import ensure_playwright; ensure_playwright()
|
||||||
from playwright.sync_api import sync_playwright
|
from playwright.sync_api import sync_playwright
|
||||||
root = pathlib.Path(__file__).resolve().parent.parent
|
root = pathlib.Path(__file__).resolve().parent.parent
|
||||||
out = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else root / 'shots' / 'smooth'); out.mkdir(parents=True, exist_ok=True)
|
out = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else root / 'shots' / 'smooth'); out.mkdir(parents=True, exist_ok=True)
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ light and glow), the pixel upload and blit, and one simulation tick, in ms. Rebu
|
|||||||
python3 tools/perf.py
|
python3 tools/perf.py
|
||||||
"""
|
"""
|
||||||
import sys, pathlib
|
import sys, pathlib
|
||||||
|
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))
|
||||||
|
from use_venv import ensure_playwright; ensure_playwright()
|
||||||
from playwright.sync_api import sync_playwright
|
from playwright.sync_api import sync_playwright
|
||||||
root = pathlib.Path(__file__).resolve().parent.parent
|
root = pathlib.Path(__file__).resolve().parent.parent
|
||||||
url = (root / 'dist' / 'index.html').as_uri()
|
url = (root / 'dist' / 'index.html').as_uri()
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
"""Headless browser run: load the page, start a world, play a little, take screenshots."""
|
"""Headless browser run: load the page, start a world, play a little, take screenshots."""
|
||||||
import sys, time, pathlib
|
import sys, time, pathlib
|
||||||
|
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))
|
||||||
|
from use_venv import ensure_playwright; ensure_playwright()
|
||||||
from playwright.sync_api import sync_playwright
|
from playwright.sync_api import sync_playwright
|
||||||
|
|
||||||
root = pathlib.Path(__file__).resolve().parent.parent
|
root = pathlib.Path(__file__).resolve().parent.parent
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ Example: a belt carrying a heap of sand, in the smooth look:
|
|||||||
import argparse, pathlib, sys
|
import argparse, pathlib, sys
|
||||||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))
|
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))
|
||||||
from where import translate
|
from where import translate
|
||||||
|
from use_venv import ensure_playwright; ensure_playwright()
|
||||||
from playwright.sync_api import sync_playwright
|
from playwright.sync_api import sync_playwright
|
||||||
|
|
||||||
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
"""Let browser scripts run with plain python3 by switching to the repo's .venv."""
|
||||||
|
import os, pathlib, sys
|
||||||
|
|
||||||
|
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
def ensure_playwright():
|
||||||
|
try:
|
||||||
|
import playwright
|
||||||
|
return
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
venv = ROOT / '.venv'
|
||||||
|
py = venv / 'bin' / 'python'
|
||||||
|
if py.exists() and pathlib.Path(sys.prefix).resolve() != venv.resolve():
|
||||||
|
os.execv(str(py), [str(py), *sys.argv])
|
||||||
|
sys.exit('Playwright is not installed; see Develop in README.md (uv venv .venv, '
|
||||||
|
'then uv pip install --python .venv/bin/python -r requirements.txt, '
|
||||||
|
'then .venv/bin/python -m playwright install chromium).')
|
||||||
Reference in New Issue
Block a user