docling-studio/e2e/ui
Pier-Jean Malandrino 39091358ae fix(e2e): use word-match selector for remaining toggle-btn references
analysis.feature and full-ui-path.feature still used exact-match
[data-e2e=toggle-btn] which broke after #178 changed the attribute to
compound values. Switch to [data-e2e~=configure-btn].
2026-04-12 20:35:28 +02:00
..
src/test fix(e2e): use word-match selector for remaining toggle-btn references 2026-04-12 20:35:28 +02:00
pom.xml feat: add Karate UI e2e tests with data-e2e selectors (#124) 2026-04-08 17:53:52 +02:00
README.md feat: add Karate UI e2e tests with data-e2e selectors (#124) 2026-04-08 17:53:52 +02:00

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 APIcleanup.feature deletes test data after each scenario
  • Polling with optional() — graceful handling of fast completions (no waitFor on spinners that may flash)
  • data-e2e selectors[data-e2e=doc-item] instead of .doc-item — decoupled from CSS, never breaks on style refactors
  • karate.sizeOf() for countskarate.sizeOf(locateAll('[data-e2e=xxx]')) instead of raw .length or script()

Reports

After a run, Karate HTML reports are in e2e/ui/target/karate-reports/.