Runs GovTool and its integration suites against a local Cardano devnet. Once
images are pulled or built, nothing reaches a public network, hosted Kuber,
Blockfrost, a faucet, Pinata or an IPFS gateway, and no secrets are needed.
CI: .github/workflows/test_integration_devnet.yml (push to develop,
manual).
- Chain: adaup (
cardano devnet up --docker) runs cardano-node 11.0.1 (magic 42, protocol 10), Kuber, db-sync 13.7 with its Postgres and an anchor file server on the Docker networkadaup-devnet. - App (
docker-compose.yml, all ports on loopback): govtool-backend on the db-sync provider (GOVTOOL_DBSYNC_NETWORK=devnet, genesis from adaup's config volume; serves/governance-actionstoo), the metadata service and its Postgres, the metadata bucket (tests/test-metadata-api: anchor uploads, IPFS pinning viaGOVTOOL_PINNING_PROVIDER=test, and the/ipfs/<cid>gateway for the backend, metadata service, db-sync and browser), the pdf backend and its Postgres, the frontend image, andblockfrost-shim. Chatwoot, Sentry and analytics are off. blockfrost-shim/answers the three Blockfrost calls the suites make:POST /v0/tx/submit(to Kuber),GET /v0/accounts/{stake}andGET /v0/governance/dreps/{id}(from db-sync).npm testthere.
pip install "adaup>=0.3.0" # the `cardano` CLI
tests/devnet/up.sh # chain, faucet, app, seed, env files
tests/devnet/run-tests.sh pytest # PYTHON=<venv python> if needed
tests/devnet/run-tests.sh playwright # extra args go to playwright
tests/devnet/run-tests.sh playwright --last-failed # re-run failures only
DEVNET_PLAYWRIGHT_FILES=cip179/ tests/devnet/run-tests.sh playwright # cip179 only
DEVNET_PLAYWRIGHT_CIP179=0 tests/devnet/run-tests.sh playwright # without cip179
tests/devnet/down.sh # everything, volumes includedup.sh steps: a fresh devnet (the previous one is removed); the faucet
(scripts/faucet-env.js derives FAUCET_* from adaup's faucet key, adds a
stake key and moves FAUCET_FUND_ADA, default 100M ADA, to the base
address); the app stack, built and healthy; seed.sh; then
.state/playwright.env (mode 600: it holds the wallet mnemonic and faucet
keys) and .state/pytest.env; the run scripts export them, overriding each
suite's own .env. Skip steps with
SKIP_CHAIN=1, SKIP_FAUCET=1, SKIP_SEED=1; DEVNET_COMPOSE_BUILD=0
starts existing images without rebuilding. Step timings go to
.state/timings.txt.
seed.sh: fixture anchors into the bucket; cardano devnet smoke twice
(round 1 ratifies DEVNET_SEED_RATIFY plus extra treasury withdrawals and
waits for enactment, for action history data; round 2 ratifies nothing, so one proposal of every type stays live);
scripts/seed-pytest-wallets.sh registers the backend suite's fixed DReps
and ADA holders from tests/govtool-backend/test_data.json; then waits for
the backend to list every type and for DRep voting power (next epoch).
All in .env.devnet; local overrides in .env.devnet.local (gitignored,
read first, so derived URLs follow it). Useful knobs:
ADAUP_CARDANO: path to adaup'scardanoCLI.- Timings (adaup):
ADAUP_DEVNET_SLOT_LENGTH0.2 s,ADAUP_DEVNET_EPOCH_LENGTH300 slots (60 s epochs),ADAUP_DEVNET_LIVE_SECONDS172800: proposal lifetime and DRep activity (2880 epochs, 48 h). It must outlast the whole run, and the frontend shows expiry as a date, so seeded proposals must expire on a later day (4H). - Ports:
FRONTEND_PORT8080,BACKEND_PORT9999,PDF_PORT1337,BLOCKFROST_SHIM_PORT3100,METADATA_BUCKET_PORT3001; adaup's Kuber 8081, Postgres 5433, anchors 8090. FRONTEND_DOCKERFILE:Dockerfilebuilds from source (needs about 8 GB of Docker memory);../../tests/devnet/frontend/prebuilt.Dockerfileserves a host build (cd govtool/frontend && npm ci && npm run build).DEVNET_SEED_ACTIONS/DEVNET_SEED_RATIFY,DEVNET_SEED_EXTRA_TREASURY(10 more enacted withdrawals: action history needs a second page),FAUCET_FUND_ADA,DEVNET_TEST_WORKERS(4),DEVNET_TX_TIMEOUT(120000 ms).- Playwright selection:
DEVNET_PLAYWRIGHT_PROJECTS,DEVNET_PLAYWRIGHT_FILES,DEVNET_PLAYWRIGHT_GREP_INVERT,DEVNET_PLAYWRIGHT_CIP179=0(leaves the cip179 specs out, and with them the need forgovtool/frontend/node_modules). Failures keep a trace intest-results/(DEVNET_PLAYWRIGHT_TRACE, defaultretain-on-failure;offdrops it).
The bucket URL (http://metadata-bucket.localhost:<port>) must work from
the host and the containers: it is a network alias in Docker and loopback on
the host (macOS and systemd-resolved map *.localhost; otherwise add it to
/etc/hosts). On macOS up.sh also publishes it on [::1].
Playwright runs every project, the proposal discussion forum, mobile and
cip179 included; the pdf backend in the stack serves the forum. The cip179
projects mock the backend and wallet against the devnet's frontend, and load
the frontend's codecs, so govtool/frontend needs npm ci --ignore-scripts
first, unless DEVNET_PLAYWRIGHT_CIP179=0.
10-feedback/chatwoot.spec.ts: Chatwoot is disabled.- pytest survey tests: opt-in upstream (
RUN_SURVEY_TESTS=1).
- Wallet connect first requests
/is-maintenance-mode-on, which a frontend built before the maintenance banner asked for without the page's port, so it failed off port 80 and blocked every connect;lib/wallet/pageWallet.tsanswers it (false) in the page. registeredDRepWallet()registers with CIP-119 metadata unless given an anchor (without it the app treats the wallet as a direct voter); 2F and 2W pre-register their ADA holders' stake keys (fresh HD wallets are unregistered, and the app reads registration only on connect).- pytest
test_epoch_boundarydates epochs asepochLength × slotLength(devnet slots are 0.2 s). - The backend's DRep-list cache is 20 s here (600 s in
config.json, sized for day-long epochs).
Only links and optional assets: Google Fonts in the frontend's
index.html (falls back to system fonts), docs.gov.tools and other links
(tests that open them need internet), ada handle lookups (handle.me), and
cexplorer links.