- Add e2e/ui/ as peer project to e2e/api/ (own pom.xml, runner, config) - 5 critical UI journeys: upload, delete, analysis, batch-progress, rechunk - 4 local-only tests: sidebar, i18n, error-states, pipeline-options - 1 full happy path workflow covering all modes - Add data-e2e attributes on all tested Vue components (decoupled from CSS) - Add CONVENTIONS.md with 7 golden rules for writing Karate UI tests - Update CI with dedicated e2e-ui job (Chrome headless, --no-sandbox) - Update docs/contributing.md with UI test instructions Closes #124
3.3 KiB
3.3 KiB
E2E UI Tests — Karate UI
Browser-based end-to-end tests for Docling Studio using Karate UI (Chrome headless).
Prerequisites
- JDK 17+ (e.g.
brew install openjdk@17) - Maven 3.9+ (e.g.
brew install maven) - Google Chrome (headless, auto-detected)
- Python 3.12+ (for test data generation)
- Docker (for running the full stack)
Quick start
# 1. Generate test PDFs (from repo root)
python e2e/generate-test-data.py
# 2. Start the stack
docker compose up -d --wait
# 3. Run all UI tests
mvn test -f e2e/ui/pom.xml
# 4. Tear down
docker compose down
Run by tag
# Critical only — CI scope (~1min30)
mvn test -f e2e/ui/pom.xml -Dkarate.options="--tags @critical"
# All UI tests — local scope (~3min)
mvn test -f e2e/ui/pom.xml -Dkarate.options="--tags @ui"
Custom URLs
mvn test -f e2e/ui/pom.xml -DbaseUrl=http://your-host:8000 -DuiBaseUrl=http://your-host:3000
Structure
e2e/ui/
├── pom.xml # Maven + Karate dependency
├── src/test/java/
│ └── UIRunner.java # JUnit5 Karate runner
└── src/test/resources/
├── karate-config.js # URLs, timeouts, Chrome driver config
├── common/helpers/
│ ├── upload.feature # API helper — upload (setup)
│ ├── analyze.feature # API helper — analyze (setup)
│ ├── cleanup.feature # API helper — delete (teardown)
│ ├── ui-upload.feature # UI helper — upload via file input
│ └── ui-wait-analysis.feature # UI helper — poll for completion
├── documents/ # @critical @ui
│ ├── upload.feature # Upload + preview
│ ├── delete.feature # Delete via hover + click
│ └── error-states.feature # Non-PDF rejection, hints
├── analyses/ # @critical @ui
│ ├── analysis.feature # Run analysis, verify tabs
│ ├── batch-progress.feature # Progress bar on multi-page
│ ├── rechunk.feature # Prepare mode, rechunk
│ └── pipeline-options.feature # OCR, table mode toggles
├── navigation/ # @ui
│ ├── sidebar.feature # Sidebar navigation
│ └── i18n.feature # FR/EN language switch
└── workflows/ # @ui
└── full-ui-path.feature # Complete happy path via browser
Tags
| Tag | Scope | When |
|---|---|---|
@critical |
5 features, 6 scenarios | CI on main branch |
@ui |
All UI features | Local development |
Design patterns
- Setup via API, verify via UI — fast setup with API helpers, then browser assertions
- Cleanup via API —
cleanup.featuredeletes test data after each scenario - Polling with
optional()— graceful handling of fast completions (nowaitForon spinners that may flash) data-e2eselectors —[data-e2e=doc-item]instead of.doc-item— decoupled from CSS, never breaks on style refactorskarate.sizeOf()for counts —karate.sizeOf(locateAll('[data-e2e=xxx]'))instead of raw.lengthorscript()
Reports
After a run, Karate HTML reports are in e2e/ui/target/karate-reports/.