These tests check that each Privatus Analytics language package really works: in a real browser, with the real tracker, end to end.
Each package ships a tiny example app. The tests start it next to a mock collector (a small server that stands in for Privatus), open every page in Chromium and check what the browser sends. A package passes when:
- the tag is in the page head, the tracker loads and nothing is blocked;
- pageviews and events reach the collector with the right site id and props;
- buttons, forms and click map names made with the package's helpers work;
- values with
</script>, quotes and odd line breaks are escaped safely; - auto inject adds the tag once;
- a tag turned off prints only the queue stub (when it is on), so
privatus.trackcalls still work, and otherwise prints nothing.
What each example app must do is in CONTRACT.md.
You need Docker with Compose. Nothing else: Node, the browser and every language run inside containers.
./run.sh ../python # one package (a folder with example/Dockerfile)
./run-all.sh # every package next to this folder, then a table
./run-all.sh ~/src # every package in another folderrun.sh exits with a non-zero code when anything fails. It removes its
containers and volumes when it is done. Reports go to reports/<package>/:
| File | What it holds |
|---|---|
html/index.html |
The Playwright report, with a trace for each failed test |
junit.xml |
Results for CI tools |
build.log |
The Docker build output |
services.log |
The example app's and the mock collector's logs |
run.log |
Everything run.sh printed (from run-all.sh) |
| Path | What it is |
|---|---|
mock/server.mjs |
The mock collector. Plain Node, no dependencies |
tracker/ |
A pinned copy of the real tracker (pa.js and its modules) |
tests/ |
The Playwright tests (TypeScript) |
docker-compose.yml |
The mock, one example app and the test runner |
packages.json |
The package repos the nightly run tests |
It serves the tracker files at /js/pa.js, /js/pa.clicks.js and so on.
Like the real server, it fills in the tracker's __PA_TRACKER_ORIGIN__
placeholder with its own address, so the tracker sends hits back to it.
POST /api/event takes a hit the way the real endpoint does: a JSON object
of up to 32 KB, answered with 202 and no body. It turns the tracker's
short keys (s, t, u, p and so on) into their long names, notes
anything the real server would drop, and keeps every hit in memory.
| Route | What it does |
|---|---|
GET /__hits |
Every hit so far, oldest first, as JSON |
POST /__reset |
Forgets every hit |
GET /__health |
Answers ok |
Run it on its own with node mock/server.mjs (port 4000, or set PORT).
The tests use the copy in tracker/, so a run is the same until you
choose to change it. tracker/PINNED.txt lists a checksum for each file.
To copy the latest tracker from the web app:
scripts/refresh-tracker.sh /path/to/web/tracker/srcThen run ./run-all.sh before you commit the new copy.
- Add
example/to the package, following CONTRACT.md. - Run
./run.sh ../<package>until it passes. - Add the repo to
packages.json, so the nightly run tests it. A package inside a monorepo is listed with its folder, for example{ "repo": "js", "dir": "express" }. Its Dockerfile can reach the rest of the repo through aFROM ... AS workspacestage:run.shpasses the folder above the package (orWORKSPACE_DIR) as that build context.
- The browser reaches the app at
http://example-app:8080. Two names do not work:localhost(the tracker sends nothing from it) andapp(Chromium always uses HTTPS for.appnames). - The tracker sends nothing from an automated browser. The tests hide the flag that says the browser is automated, as a person's browser would.
- The tests run one at a time. Each page gets its own
utm_contentvalue in its address, so a test only looks at its own hits.
.github/workflows/conformance.yml runs every night and when started by
hand (Actions, Conformance, Run workflow; you can name one package). For
each repo in packages.json it checks out this repo and that one, runs
./run.sh and uploads the report.
- Docs: https://privatusanalytics.com/docs
- Script attributes: https://privatusanalytics.com/docs/tracker/attributes
MIT. Copyright (c) 2026 Two Phase LLC. See LICENSE.