test(e2e): split suite by feature area with shared resources

Restructure 5 existing .robot files into 10 numbered files, one per
feature area in Docs/Features.md. Each file is independently runnable.
Add api.resource + data.resource for CSRF/XFF-aware wrappers and
RFC5737 IP generators.

Coverage: 110 new tests across login, dashboard, map, jails, config,
history, blocklists, layout. Uses existing data-testid/aria-label/role
selectors only — no frontend changes.

Tests bypass per-IP rate limits via X-Forwarded-For header rotation.
Hard rule preserved: failures are findings, never app-code fixes.
This commit is contained in:
2026-06-21 07:55:19 +02:00
parent 3af8f0571b
commit 0d21e3253e
17 changed files with 1620 additions and 230 deletions

View File

@@ -1,8 +1,38 @@
# E2E Tests — Running Robot Framework Tests
## Test File Structure
The E2E suite is organized **one `.robot` file per feature area** defined in `Docs/Features.md`. Each file is independently runnable.
| File | Feature |
|---|---|
| `01_setup_and_auth.robot` | Setup wizard (formerly `05_setup.robot`) — form fields, password strength, validation, full submit |
| `02_login.robot` | Login page — wrong password, rate limit (429), session validation 401, logout |
| `03_dashboard.robot` | Ban Overview (Dashboard) — status bar, time-range presets, data-source badges, API endpoints |
| `04_map.robot` | World Map View — country fills, click-to-filter, zoom controls, sticky table header/footer |
| `05_jails.robot` | Jail Management — list, ban/unban API, IP lookup, ignore list, jail controls |
| `06_config_jails_filters_actions.robot` | Configuration View — Jails/Filters/Actions tabs, inline edit, raw config, regex tester |
| `07_config_log_and_serversettings.robot` | Server settings + log viewer + log observation allowlist |
| `08_history.robot` | Ban History — table, filters, per-IP timeline, archive vs fail2ban source |
| `09_blocklists.robot` | External Blocklist Importer — CRUD, SSRF validation, schedule, import log, delete restriction |
| `10_general_layout.robot` | General UI/layout — sidebar nav, theme toggle, session persistence, health endpoints |
| `02_ban_records.robot` | (pre-existing) end-to-end ban pipeline: fail2ban log → history |
| `03_blocklist_import.robot` | (pre-existing) blocklist manual import via UI |
| `04_config_edit.robot` | (pre-existing) config field auto-save round trip |
## Resource Files
Shared keywords live in `resources/`:
| File | Purpose |
|---|---|
| `common.resource` | `Wait For Backend Health`, `Wait For Frontend`, `Page Should Contain` wrapper, `XFF` helpers, IP/jail name generators |
| `auth.resource` | `Login As Admin`, `Login Via HTTP`, `Logout`, `Verify Session Invalid`, `Login With Wrong Password`, `Login Exceeds Rate Limit` |
| `api.resource` | `Api Get/Post/Put/Delete` wrappers that auto-inject CSRF + X-Forwarded-For headers |
| `data.resource` | Unique IP / jail name / blocklist name generators (RFC5737 ranges) |
## Setup
Install dependencies:
```bash
pip install -r requirements.txt
rfbrowser init
@@ -14,10 +44,17 @@ rfbrowser init
robot --outputdir results --log log.html --report report.html tests/
```
Or via the Makefile from the repo root:
```bash
make e2e
```
## Run Specific Test File
```bash
robot --outputdir results tests/01_page_loading.robot
robot --outputdir results tests/02_login.robot
robot --outputdir results tests/08_history.robot
```
## Run with Browser Visible
@@ -26,10 +63,42 @@ robot --outputdir results tests/01_page_loading.robot
robot --outputdir results --variable BROWSER:chromium tests/
```
## Rate-Limit Workaround
BanGUI rate-limits several endpoints per source IP:
| Bucket | Default Limit | Window |
|---|---|---|
| `POST /api/v1/auth/login` | 5 / IP | 60 s |
| `POST /api/v1/blocklists/import` | 10 / IP | 3600 s |
| `POST /api/v1/bans` | 10 000 / IP | 60 s |
| `PUT /api/v1/config/jails/{name}` | 10 000 / IP | 60 s |
Tests bypass these by sending a fresh `X-Forwarded-For: 192.0.2.<n>` header per test. The `Set Random Xff Header` keyword in `common.resource` rotates the IP. The `auth.resource` `Login Via HTTP` and the `api.resource` `Api Get/Post/Put/Delete` wrappers all accept and propagate `${XFF_HEADER}` automatically.
## Test-IP Convention
All test data uses RFC5737 documentation-only ranges to avoid colliding with real internet addresses:
| Range | Purpose |
|---|---|
| `192.0.2.0/24` (TEST-NET-1) | X-Forwarded-For headers |
| `198.51.100.0/24` (TEST-NET-2) | Geo-lookup test IPs |
| `203.0.113.0/24` (TEST-NET-3) | Ban / unban test IPs |
## View Results
Open `results/log.html` or `results/report.html` in a browser.
## Failure Protocol
Per project policy, **test failures are NOT fixed by editing app code**. If a test fails:
1. Stop.
2. Report the failure with: test name, expected vs actual, log excerpt, API request/response.
3. Do not edit the test to weaken assertions.
4. Do not edit frontend / backend / fail2ban config to make the test pass.
5. The failure is a finding — separate from any bug-fix task.
---
# AI Agent — General Instructions