5.2 KiB
80. Patrol Web Integration Test — Setup & Execution
Date: 2026-04-15
Status
Accepted
Related ADRs
- ADR-0053 — Patrol for mobile integration testing (foundation)
- ADR-0081 — Cross-platform test architecture
- ADR-0082 — Migration guide & implementation example
- ADR-0083 — PR-by-PR migration plan
Context
ADR-0053 established Patrol for mobile (Android/iOS) integration testing. As Twake Mail is also deployed as a web app, the same level of E2E coverage is needed on the browser. Patrol 4.x added Chrome support via --device=chrome, making it feasible to extend the existing setup without introducing a second testing framework.
Decision
Use Patrol with Chrome as the target device for web integration testing, sharing the same backend Docker infrastructure used for mobile tests.
Prerequisites
- Flutter 3.38.9
- Patrol CLI 4.3.1:
dart pub global activate patrol_cli 4.3.1 patrolpackage 4.5.0 (andpatrol_finders 3.x,patrol_log 0.8.x) — requires upgrading from the 3.x currently inpubspec.yaml- Docker Desktop (running)
opensslinstalled (used to generate JWT keys for the backend)
Unlike mobile tests, web tests do not require
ngrokorjq. The app runs atlocalhostand Chrome connects to it directly — no traffic forwarding needed.
Environment Variables
All tests receive configuration via --dart-define. Store values in an env file and source it in the run scripts — this keeps credentials out of command-line history and git history (add the file to .gitignore):
# integration_test/test_config.env
BASIC_AUTH_URL=http://localhost/
USERNAME=test_user
PASSWORD=test_password
BASIC_AUTH_EMAIL=test@example.com
ADDITIONAL_MAIL_RECIPIENT=recipient@example.com
The run scripts source this file and forward each value:
source integration_test/test_config.env
patrol test \
--dart-define=BASIC_AUTH_URL=$BASIC_AUTH_URL \
--dart-define=USERNAME=$USERNAME \
--dart-define=PASSWORD=$PASSWORD \
--dart-define=BASIC_AUTH_EMAIL=$BASIC_AUTH_EMAIL \
--dart-define=ADDITIONAL_MAIL_RECIPIENT=$ADDITIONAL_MAIL_RECIPIENT \
...
| Variable | Description |
|---|---|
BASIC_AUTH_URL |
App server URL (e.g. http://localhost/) |
USERNAME |
Test account username |
PASSWORD |
Test account password |
BASIC_AUTH_EMAIL |
Test account email address |
ADDITIONAL_MAIL_RECIPIENT |
Secondary email for multi-recipient tests |
--dart-define-from-fileonly accepts JSON, not.envformat, so sourcing in the script is the correct approach.
Running Locally (with visible browser)
./scripts/patrol-web-local-integration-test-with-docker.sh
This starts the Docker backend, then runs patrol with Chrome visible. Useful during development.
To run a single test file, edit the script and replace patrol test -v with:
patrol test -v -t integration_test/tests/composer/send_email_test.dart
After migrating to the architecture defined in ADR-0081, test files no longer have a
web_prefix — one file covers all platforms.
Running in CI (headless)
./scripts/patrol-web-integration-test-with-docker.sh
Adds --web-headless=true — no display required. The GitHub Actions workflow (.github/workflows/patrol-web-integration-test.yaml) runs this script on pull requests.
CI Orchestration — Running the Full Project
Mobile and web test suites run as separate parallel jobs in CI. Each job targets its own platform:
PR opened / push
│
├── job: patrol-mobile-integration-test (ubuntu-latest + Android emulator)
│ patrol test --device=android
│
└── job: patrol-web-integration-test (ubuntu-latest + Chrome via Patrol)
./scripts/patrol-web-integration-test-with-docker.sh
# patrol test --device=chrome --web-headless=true
The two jobs are independent — they share no state and can run concurrently. A PR is gated on both jobs passing.
Platform filtering is handled automatically by runPatrolTest() (see ADR-0082). Tests that do not apply to the current platform skip themselves — no --exclude-tags flag needed in either job.
Viewing Results
- Terminal: Patrol prints pass/fail per test with full stack traces on failure.
- GitHub Actions: Results appear in the workflow run summary under the "Test" step. Each platform job has its own step, making it easy to identify which platform a failure comes from.
Consequences
- Web and mobile tests share the same test files; platform-only tests skip themselves in
runPatrolTest()— no manual tagging required. - The same Docker JMAP backend serves both platforms — no additional infrastructure needed.
- Data isolation limitations from ADR-0053 still apply: backend state is shared across all tests in a single run.
- Patrol automatically installs and manages Chromium — no manual Chrome installation is needed on local machines or CI runners.