Skip to content

DmitryGontsa/aqa-spring-boot-automation-framework

Repository files navigation

Task Manager — Spring Boot Full‑Stack App + Advanced Test Automation (API + UI) + CI (GitHub Actions)

A production-style demo project that combines a Spring Boot 3 backend, a classic Thymeleaf UI, and a 3‑level testing strategy:

  • Unit tests (fast, isolated)
  • API E2E tests (Rest Assured)
  • UI E2E tests (Selenide + Selenoid)

Everything is runnable locally and in CI via one deterministic Docker Compose environment.

CI for this repository is implemented with GitHub Actions: .github/workflows/ci.yml.


Contents


Project Highlights

✅ Full‑Stack application (API + Web UI)

  • REST API with JWT auth for stateless clients
  • Web UI with Form Login (Thymeleaf + Bootstrap)
  • Separate Spring Security filter chains for JWT vs Form Login (clean and realistic)
  • DB migrations via Flyway
  • Actuator health endpoint used by CI to wait for service readiness

✅ Testing & reliability

  • Unit tests: tagged @Tag("Unit")
  • E2E tests: tagged @Tag("Api") and @Tag("UI")
  • E2E runs in an isolated environment (PostgreSQL + app + Selenoid) using docker-compose.e2e.yml
  • JUnit 5 + Gradle retry configured for flaky E2E scenarios

✅ CI-ready Docker setup

  • The pipeline follows the idea: build once → test everywhere
  • CI reuses the same Docker Compose definition you can run locally:
    • PostgreSQL (db)
    • Application (app)
    • Selenoid (selenoid) for remote browser execution + video
    • Test runner container (e2e-tests) that executes ./gradlew e2eTest

Tech Stack

  • Java 17, Gradle
  • Spring Boot 3.x: Web, Security, Data JPA, Validation, Actuator, Cache
  • Thymeleaf (+ thymeleaf-layout-dialect), Bootstrap 5
  • JWT: jjwt
  • DB: H2 (local fast run), PostgreSQL (docker profile), Flyway
  • API tests: Rest Assured
  • UI tests: Selenide + remote execution in Selenoid
  • Reporting: Allure (JUnit 5, Rest Assured, Selenide)

Project Structure

.
├── src/main
│   ├── java/com/example/taskmanager
│   │   ├── controller/        # web + api controllers
│   │   ├── security/          # JWT + security configuration
│   │   ├── service/           # business logic
│   │   └── ...                # dto/model/repository/etc
│   └── resources
│       ├── application.yml    # default (H2) + docker profile (PostgreSQL)
│       ├── db/migration       # Flyway migrations
│       └── templates          # Thymeleaf views
├── src/test
│   ├── java/com/example/taskmanager
│   │   ├── unit/              # @Tag("Unit")
│   │   ├── api/               # @Tag("Api") (Rest Assured)
│   │   └── ui/                # @Tag("UI")  (Selenide)
│   └── resources
│       └── junit-platform.properties
├── config/browsers.json       # Selenoid browser config (video + version pinning)
├── docker-compose.e2e.yml     # full E2E environment (db + app + selenoid + tests)
├── Dockerfile                 # application image
├── Dockerfile.tests           # test-runner image
└── .github/workflows/ci.yml   # GitHub Actions pipeline

Prerequisites

For local runs you have two options:

Option A — run everything locally (H2)

  • JDK 17
  • (Optional) Docker, if you also want E2E environment

Option B — run the full E2E environment (recommended before pushing)

  • Docker Desktop / Docker Engine
  • Docker Compose v2 (docker compose ...)

Quick Start

1) Run the app locally (fast H2 mode)

./gradlew bootRun

Open:

  • App: http://localhost:8080
  • H2 console: http://localhost:8080/h2-console
    • JDBC URL: jdbc:h2:mem:testdb
    • user: sa

2) Run unit tests

./gradlew unitTest

3) Run full E2E (API + UI) in Docker (one command)

docker compose -f docker-compose.e2e.yml up --build

Reports will appear in build/ after completion.


How to Run

Important: default Gradle test task is disabled

This repository uses dedicated tasks:

  • unitTest → only @Tag("Unit")
  • e2eTest → runs @Tag("Api") + @Tag("UI")

So use these tasks explicitly:

Run unit tests

./gradlew unitTest

Run E2E tests locally (without Docker)

If you already have the app running at http://localhost:8080:

./gradlew e2eTest

Run E2E tests in Docker Compose (recommended)

This reproduces the CI environment:

docker compose -f docker-compose.e2e.yml up --build   --abort-on-container-exit   --exit-code-from e2e-tests

To clean up afterwards:

docker compose -f docker-compose.e2e.yml down --volumes

Configuration

Application profiles

src/main/resources/application.yml contains:

  • default profile: H2 in-memory DB (fast local run)
  • docker profile: PostgreSQL (db service)

To run app with PostgreSQL profile locally:

SPRING_PROFILES_ACTIVE=docker ./gradlew bootRun

E2E runtime properties

The E2E test runner supports overriding endpoints via system properties:

Property Default Used for
api.base.uri http://localhost:8080 Rest Assured base URI
selenide.base.url http://localhost:8080 UI base URL
selenide.remote (empty) Remote WebDriver URL (Selenoid)
selenide.headless true Headless UI mode

In Docker Compose E2E these are passed automatically:

  • -Dapi.base.uri=http://app:8080
  • -Dselenide.base.url=http://app:8080
  • -Dselenide.remote=http://selenoid:4444/wd/hub

Allure Reporting

Raw results:

  • build/allure-results

Generate HTML report:

./gradlew allureReport

Resulting HTML:

  • build/reports/allure-report

Tip: In CI, Allure results and the generated report are uploaded as workflow artifacts.


CI (GitHub Actions)

Workflow:

  • .github/workflows/ci.yml

What it does:

  1. Sets up Java 17 + Gradle cache
  2. Builds the app once (without tests)
  3. Runs ./gradlew unitTest
  4. Spins up Docker Compose E2E environment and executes E2E via e2e-tests container
  5. Generates Allure report and uploads artifacts:
    • build/test-results
    • build/allure-results
    • build/reports/allure-report
    • Selenoid videos (if produced)

Troubleshooting

“No matching tests found …”

In this project the default test task is disabled. Use:

./gradlew unitTest
./gradlew e2eTest

UI tests fail locally

  • Run the full E2E via Docker Compose (most deterministic):
    docker compose -f docker-compose.e2e.yml up --build
  • If running without Docker, you may need a local browser and/or set:
    ./gradlew e2eTest -Dselenide.headless=true

Docker Compose stuck waiting for app readiness

The test runner waits for:

  • GET /actuator/health to return "status":"UP"

If you changed Actuator exposure settings, ensure health is still available.


About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages