Test Automation Plan for Tournaments

The Padel Society · TPS
29 test cases v1.0
Test Automation Plan · The Padel Society

Tournament E2E
Test Automation

Automated regression suite for all tournament formats — Americano, Mexicano, Mini Tournament, and King of the Court — running on every deployment that touches tournament code.

14
Backend API tests
9
Mobile UI tests
6
Hybrid tests
2
Test repos
🧩
Architecture

Two-Layer Strategy

Backend logic tests run fast on every PR; mobile UI flows run after deployment
⚙️

Layer 1 — Backend API

Test tournament algorithms (matchup generation, partner rotation, leaderboard math) by calling service methods and Supabase edge functions directly. No UI needed. Runs in ~30 seconds.

Tool Vitest + @supabase/supabase-js
📱

Layer 2 — Mobile UI

Test critical user flows (event creation, score entry, permissions, share links) by driving the Flutter app with Maestro YAML flows on a real device or simulator.

Tool Maestro + Maestro Cloud
🔁

Layer 3 — CI/CD Trigger

GitHub Actions with paths: filters — API tests fire on any PR touching tournament services; UI flows fire after a successful deployment via Maestro Cloud webhook.

Tool GitHub Actions + path filters
🔁
CI/CD

Automation Pipeline

End-to-end flow from code push to test results
📝
PR / Push
touches tournament files
→
⚙️
API Tests
Vitest ~30s
→
🚀
Deploy
Preview / Production
→
📱
UI Flows
Maestro Cloud ~5min
→
✅
PR Status
pass / fail reported
💡
Path filter logic
API tests only run when tournament-related files change — not on every push. If you push a profile screen fix, zero tournament tests fire. This keeps CI fast and noise-free.
🛠
Stack

Technology & File Paths

LayerToolWhere tests liveTrigger
Backend API Vitest padel-backend/src/__tests__/tournament/ GitHub Actions on PR — paths: src/services/*Tournament*
Edge Functions Vitest + Deno compat padel-backend/supabase/functions/__tests__/ GitHub Actions on PR — paths: supabase/functions/event-tournament*
Mobile UI Maestro YAML mobile-app-padel/maestro/flows/ Maestro Cloud webhook after deployment
CI Orchestration GitHub Actions .github/workflows/tournament-tests.yml On push to any branch
Test layer:
Backend API — Vitest, calls service/function directly
Mobile UI — Maestro YAML flow on device
Hybrid — API assertion + UI verification
📅
Group A — 5 tests

Event Setup & Joining

Creation, level restrictions, capacity, share links
4 UI 1 hybrid
A1
Create event — No Competition format
UI · Maestro P1
▼
Test file
maestro/flows/events/create-no-competition.yaml
Triggers
Any deploy touching lib/screens/events/ or event-tournament-v3
Assertions
  1. 1
    Event appears in community Events tab after publish
  2. 2
    No leaderboard or round info visible — just join button and event details
  3. 3
    Any-level player joins instantly — no restriction shown
A2
Level restriction — auto-join vs request to join
Hybrid P1
▼
API file
__tests__/tournament/event-requirements.test.ts
Service: set-event-requirements edge function
UI file
maestro/flows/events/level-restriction.yaml
API assertions
POST to /set-event-requirements with range 2.0–4.0 → response confirms requirements set
UI assertions
  1. 1
    Player level 1.5 → sees "Request to Join" button
  2. 2
    Player level 3.0 → joins instantly without approval
  3. 3
    Admin approves → Player 1.5 gets push notification
A3
Event image upload and share card
UI · Maestro P2
▼
Test file
maestro/flows/events/image-upload-share.yaml
Assertions
  1. 1
    Uploaded image appears as event banner in Events tab
  2. 2
    Share card preview shows image + event name + date + location
A4
Max capacity — waitlist flow
Hybrid P1
▼
API file
__tests__/tournament/waitlist.test.ts
Service: join-event-waitlist + manage-event-participants
UI file
maestro/flows/events/waitlist-flow.yaml
Assertions
  1. 1
    5th player (event max=4) sees "Join Waitlist"
  2. 2
    Player 1 cancels → waitlisted player is promoted and notified
A5
Share event link — opens without account
UI · Maestro P2
▼
Test file
maestro/flows/events/share-link.yaml
Assertions
  1. 1
    Link loads event page with name, date, location
  2. 2
    Non-logged-in device → download prompt, no crash/404
🟢
Group B — 6 tests

Americano — Classic

Individual rotation, partners change every round
4 API 2 UI
B1
Basic setup — matchups generated correctly
API · Vitest P1
▼
Test file
__tests__/tournament/americano-classic.test.ts
Source
AmericanoTournamentService.ts → generateRound(players, courts)
Assertions
  1. 1
    Input: 8 players, 2 courts → output has exactly 2 matchups
  2. 2
    All 8 players assigned — no one sits out Round 1
  3. 3
    No duplicate players in a single matchup
  4. 4
    Each court has exactly 4 players (2 per side)
B2
Score entry updates leaderboard instantly
UI · Maestro P1
▼
Test file
maestro/flows/americano/score-entry.yaml
Assertions
  1. 1
    Enter Court 1: Team A 21 – Team B 13 → confirm
  2. 2
    Leaderboard shows Team A players with 21 pts, Team B with 13 pts
  3. 3
    All 8 players ranked after Court 2 score also entered
B3
Round only advances when all courts scored
API · Vitest P1
▼
Test file
__tests__/tournament/americano-classic.test.ts
Source
TournamentManagementService.ts → canProgressRound(tournamentId)
Assertions
  1. 1
    Score Court 1 only → canProgressRound() returns false
  2. 2
    Score Court 2 → canProgressRound() returns true
  3. 3
    Round 2 matchups generated only after both courts confirmed
B4
Partner rotation — no repeat partners
API · Vitest P1
▼
Test file
__tests__/tournament/americano-rotation.test.ts
Source
AmericanoTournamentService.ts → rotation algorithm
Assertions
  1. 1
    Simulate 8 players × 3 rounds → extract partner history per round
  2. 2
    No player has the same partner twice across first 3 rounds
  3. 3
    No player faces the exact same opponents more than once in first few rounds
B5
Leaderboard totals match manual calculation
API · Vitest P1
▼
Test file
__tests__/tournament/leaderboard.test.ts
Source
TournamentManagementService.ts → leaderboard aggregation
Assertions
  1. 1
    Feed 3 rounds of known scores (e.g. player A: 21+13+18=52)
  2. 2
    Leaderboard total for each player matches manually summed value
  3. 3
    Ranking order is correct (highest total first)
B6
Share leaderboard — viewable without account
UI · Maestro P2
▼
Test file
maestro/flows/americano/share-leaderboard.yaml
Assertions
  1. 1
    Share link opens live standings in browser — no login required
  2. 2
    Enter new score in app → refresh browser → standings update
👫
Group C — 2 tests

Americano — Team

Fixed pairs play together throughout — partners never change
2 API
C1
Fixed pairs stay together every round
API · Vitest P1
▼
Test file
__tests__/tournament/americano-team.test.ts
Source
TeamAmericanoTournamentService.ts → round generation
Assertions
  1. 1
    Define 4 pairs: (A+B), (C+D), (E+F), (G+H) → generate 3 rounds
  2. 2
    In every round, A is always paired with B, C with D, etc.
  3. 3
    No partner swaps at any point
C2
Leaderboard tracks teams not individuals
API · Vitest P1
▼
Test file
__tests__/tournament/americano-team.test.ts
Source
TeamAmericanoTournamentService.ts → leaderboard aggregation
Assertions
  1. 1
    Leaderboard entries are keyed by pair — not by individual player ID
  2. 2
    Points accumulated per pair — not split between pair members
🟠
Group D — 3 tests

Mexicano — Classic & Team

Round 1 random, then matchups based on current standings
3 API
D1
Round 1 is random (same as Americano)
API · Vitest P1
▼
Test file
__tests__/tournament/mexicano.test.ts
Source
TournamentManagementService.ts → Mexicano round 1 generation
Assertions
  1. 1
    Run Round 1 generation 10 times — matchups are not identical every time (randomness test)
  2. 2
    Round 1 matchup does not correlate with player seeding or level
D2
Round 2+ matchups are based on standings
API · Vitest P1
▼
Test file
__tests__/tournament/mexicano.test.ts
Source
TournamentManagementService.ts → Mexicano next-round algorithm
Assertions
  1. 1
    Feed Round 1 results with clear gaps (Court 1: 21–5, Court 2: 21–15)
  2. 2
    Top-2 ranked players from Round 1 are on the same court in Round 2
  3. 3
    Bottom-2 ranked players face each other in Round 2
D3
Mexicano Team — standings drive pair matchups
API · Vitest P1
▼
Test file
__tests__/tournament/mexicano-team.test.ts
Source
TeamAmericanoTournamentService.ts → Mexicano Team next-round
Assertions
  1. 1
    4 fixed pairs → Round 1 complete with clear winner pair
  2. 2
    Top-ranked pairs face each other in Round 2
  3. 3
    After 4+ rounds, a winning-streak pair consistently faces stronger opponents
🏆
Group E — 2 tests

Mini Tournament

Fixed teams, Round Robin then Knockout phase
2 API
E1
Round robin schedule generated correctly
API · Vitest P1
▼
Test file
__tests__/tournament/mini-tournament.test.ts
Source
TournamentManagementService.ts → round robin generation
Assertions
  1. 1
    4 teams → schedule has exactly 6 matches (n×(n-1)/2)
  2. 2
    Every team plays every other team exactly once
  3. 3
    W/D/L standings update correctly after each result input
E2
Knockout phase generated after round robin
API · Vitest P1
▼
Test file
__tests__/tournament/mini-tournament.test.ts
Source
TournamentManagementService.ts → knockout bracket generation
Assertions
  1. 1
    After all round robin results → KO bracket is generated with correct top teams
  2. 2
    Semifinal results → final matchup created
  3. 3
    Final result → event status set to Completed, winner declared
⚠️
Group F — 7 tests

Edge Cases & Error Handling

Odd numbers, restarts, permissions, stress tests
3 API 3 UI 1 hybrid
F1
Odd number of players — handled gracefully
API · Vitest P2
▼
Test file
__tests__/tournament/edge-cases.test.ts
Source
AmericanoTournamentService.ts → validation / bye logic
Assertions
  1. 1
    7 players → service either returns an error or assigns a bye — no silent failure
  2. 2
    If bye assigned: bye player is different each round (fair rotation)
F2
Remove player mid-tournament
Hybrid P2
▼
API file
__tests__/tournament/edge-cases.test.ts
Service: manage-event-participants
UI file
maestro/flows/edge-cases/remove-player.yaml
Assertions
  1. 1
    Remove 1 player after Round 1 → 7 players remain
  2. 2
    Round 2 matchups adjust — no crash, no ghost player entry
F3
Restart tournament — warning shown, data cleared
UI · Maestro P2
▼
Test file
maestro/flows/edge-cases/restart-tournament.yaml
Assertions
  1. 1
    Tap ··· → Restart → warning dialog appears with "cannot be undone" language
  2. 2
    Confirm → all scores deleted, returns to player selection screen
  3. 3
    Leaderboard is completely empty — no trace of previous rounds
F4
Non-admin cannot start or enter scores
UI · Maestro P1
▼
Test file
maestro/flows/edge-cases/non-admin-readonly.yaml
Assertions
  1. 1
    Log in as regular member → open in-progress event
  2. 2
    "Start Tournament" button is not visible
  3. 3
    Court matchups are read-only — no score entry option
F5
Start tournament with no courts — blocked
API · Vitest P1
▼
Test file
__tests__/tournament/edge-cases.test.ts
Source
TournamentManagementService.ts → validation before start
Assertions
  1. 1
    Call startTournament with courts=0 → service throws validation error
  2. 2
    Error message identifies missing courts as the cause
F6
Large event — 20 players, 5 courts
API · Vitest P2
▼
Test file
__tests__/tournament/edge-cases.test.ts
Assertions
  1. 1
    20 players, 5 courts → exactly 5 matchups, all 20 players assigned
  2. 2
    No player appears in more than one court per round
  3. 3
    Leaderboard correctly ranks all 20 players after scoring
F7
Edit confirmed score — correct behavior
UI · Maestro P3
▼
Test file
maestro/flows/edge-cases/edit-score.yaml
Assertions
  1. 1
    Confirm a score → re-open court → attempt to change it
  2. 2
    If editing allowed: leaderboard recalculates with new score
  3. 3
    If editing blocked: clear error message shown, original score preserved
👑
Group G — 4 tests

King of the Court

Defending kings vs rotating challengers
2 API 1 UI 1 hybrid
G1
Create KoC — setup and configuration
UI · Maestro P2
▼
Test file
maestro/flows/koc/create-koc.yaml
Assertions
  1. 1
    Create KoC event → setup screen shows kings side + challenger queue clearly
  2. 2
    Tap Start → court is live with kings vs first challengers from queue
G2
Challengers win — they become the new kings
Hybrid P1
▼
API file
__tests__/tournament/koc.test.ts
Source: TournamentManagementService.ts → KoC rotation
UI file
maestro/flows/koc/challenger-wins.yaml
Assertions
  1. 1
    Challengers win → they move to the kings side in state
  2. 2
    Previous kings join back of challenger queue
  3. 3
    Next matchup: new kings vs next challengers in queue
G3
Kings win — challengers go to back of queue
API · Vitest P1
▼
Test file
__tests__/tournament/koc.test.ts
Assertions
  1. 1
    Kings win → kings remain on court
  2. 2
    Losing challengers added to back of queue — not front
  3. 3
    After 3 alternating rounds, queue order is consistent with insertion order
G4
Leaderboard — reigns and wins tracked per player
API · Vitest P2
▼
Test file
__tests__/tournament/koc.test.ts
Assertions
  1. 1
    Simulate 5 rounds with known outcomes → check each player's win/reign count
  2. 2
    Player who defended 3 times has reign count of 3 in leaderboard
  3. 3
    Final standings identify a clear winner based on most reigns/wins
⚙️
Configuration

GitHub Actions — Path Filters

Only fires tournament tests when tournament code changes
# .github/workflows/tournament-tests.yml
name: Tournament Tests

on:
  push:
    paths:
      # Backend services
      - 'src/services/AmericanoTournamentService.ts'
      - 'src/services/AmericanoTournamentServiceV2.ts'
      - 'src/services/TeamAmericanoTournamentService.ts'
      - 'src/services/TournamentManagementService.ts'
      # Edge functions
      - 'supabase/functions/event-tournament/**'
      - 'supabase/functions/event-tournament-v2/**'
      - 'supabase/functions/event-tournament-v3/**'
      - 'supabase/functions/manage-event-participants/**'
      - 'supabase/functions/event-join-request/**'
      - 'supabase/functions/join-event-waitlist/**'
      # Test files themselves
      - 'src/__tests__/tournament/**'

jobs:
  api-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm install && npx vitest run src/__tests__/tournament/
📱
Maestro Cloud trigger (Mobile UI tests)
Mobile flows run via Maestro Cloud after each deployment. Set up a webhook in your deployment pipeline that calls the Maestro Cloud API to kick off the maestro/flows/ suite. Results post back to the PR as a GitHub check.
🗓
Roadmap

Implementation Phases

Recommended rollout order — highest ROI first
1
Phase 1 — Backend API Tests (Week 1)
Add Vitest to padel-backend and write the 14 API test cases. Wire GitHub Actions with path filters. ~30s feedback loop on every PR.
  • Add Vitest + config to padel-backend/package.json
  • Write B1, B3, B4, B5 — Americano Classic algorithm tests
  • Write C1, C2 — Team Americano pair/leaderboard tests
  • Write D1, D2, D3 — Mexicano standings algorithm tests
  • Write E1, E2 — Mini Tournament schedule + knockout tests
  • Write F1, F5, F6 — Edge case validation tests
  • Write G3, G4 — KoC queue + leaderboard tests
  • Add .github/workflows/tournament-tests.yml with path filters
2
Phase 2 — Mobile UI Flows (Week 2–3)
Set up Maestro in the mobile repo. Write the 9 pure UI flows. Connect to Maestro Cloud for post-deploy execution.
  • Install Maestro CLI locally (curl -Ls "https://get.maestro.mobile.dev" | bash)
  • Create mobile-app-padel/maestro/flows/ directory structure
  • Write A1 — create event flow (smoke test for the whole event system)
  • Write B2 — score entry updates leaderboard
  • Write F3, F4 — restart warning + non-admin read-only
  • Write G1 — King of the Court setup
  • Sign up for Maestro Cloud → add API key to GitHub Secrets
  • Add deployment webhook to trigger Maestro Cloud runs
3
Phase 3 — Hybrid & Remaining Flows (Week 4+)
Complete coverage: the 6 hybrid tests (API + UI) and remaining flows for A2, A4, F2, G2.
  • Write A2 — level restriction (API sets requirements + UI verifies join behavior)
  • Write A4 — waitlist flow (API + UI notification check)
  • Write F2 — remove player mid-tournament (API + UI)
  • Write G2 — challenger wins rotation (API + UI)
  • Add Slack/Teams notification on test failure
  • Set up test result dashboard