Files
BanGUI/Docs/Tasks.md
Lukas cbddebf3b8 fix: simplify master password validation message logic
Remove password mismatch task from Docs/Tasks.md (test resolved).
Restructure validationMessage ternary in SetupPage.tsx to eliminate
redundant ?? check. Logic unchanged, readability improved.
2026-06-21 20:17:49 +02:00

2016 lines
53 KiB
Markdown

## Task: 01 Setup And Auth — Empty Required Fields Show Validation Errors
**Test:** `Empty Required Fields Show Validation Errors`
**Suite:** `01_setup_and_auth.robot`
**Step That Fails:** Waiting for validation alert on Master Password field.
**Error:** `TimeoutError: locator.evaluate: Timeout 10000ms exceeded.`
Waiting for locator: `//*[@aria-label="Master Password"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]`
**Files to Check:**
- `e2e/tests/01_setup_and_auth.robot`
- `frontend/src/pages/SetupPage.tsx`
- `e2e/resources/common.resource`
**Reference Docs:**
- `Docs/Features.md` — Setup wizard required field validation
- `Docs/Testing-Requirements.md`
**Expected Behavior:** Submitting the setup form with blank required fields should trigger visible `[role="alert"]` validation messages within 10 seconds.
---
## Task: 01 Setup And Auth — Invalid Session Duration Shows Validation Error
**Test:** `Invalid Session Duration Shows Validation Error`
**Suite:** `01_setup_and_auth.robot`
**Step That Fails:** Waiting for validation alert on Session Duration field.
**Error:** `TimeoutError: locator.evaluate: Timeout 10000ms exceeded.`
Waiting for locator: `//*[@aria-label="Session Duration (minutes)"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]`
**Files to Check:**
- `e2e/tests/01_setup_and_auth.robot`
- `frontend/src/pages/SetupPage.tsx`
**Reference Docs:**
- `Docs/Features.md` — Session duration validation rules
**Expected Behavior:** Entering an invalid session duration and submitting should display a `[role="alert"]` error in the field container.
---
## Task: 01 Setup And Auth — Incomplete Password Shows Complexity Error
**Test:** `Incomplete Password Shows Complexity Error`
**Suite:** `01_setup_and_auth.robot`
**Step That Fails:** Waiting for validation alert on Master Password field after weak password input.
**Error:** `TimeoutError: locator.evaluate: Timeout 10000ms exceeded.`
Waiting for locator: `//*[@aria-label="Master Password"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]`
**Files to Check:**
- `e2e/tests/01_setup_and_auth.robot`
- `frontend/src/pages/SetupPage.tsx`
**Reference Docs:**
- `Docs/Features.md` — Password complexity requirements
**Expected Behavior:** Submitting a password that doesn't meet complexity rules should show a `[role="alert"]` error message.
---
## Task: 02 Ban Records — Simulated Failed Logins Appear As Ban Records
**Test:** `Simulated Failed Logins Appear As Ban Records`
**Suite:** `02_ban_records.robot`
**Step That Fails:** Checking ban record contains expected IP.
**Error:** `'' does not contain '192.168.100.99'`
**Files to Check:**
- `e2e/tests/02_ban_records.robot`
- `e2e/proxy_server.py`
- `backend/app/routers/bans.py`
- `backend/app/services/ban_service.py`
**Reference Docs:**
- `Docs/Features.md` — Ban record pipeline
- `Docker/simulate_failed_logins.sh`
**Expected Behavior:** After simulating failed logins, the ban record should contain the test IP `192.168.100.99` in the response or UI.
---
## Task: 02 Login — Login Page Renders Password Input
**Test:** `Login Page Renders Password Input`
**Suite:** `02_login.robot`
**Step That Fails:** Browser launch.
**Error:** `browserType.launch: Executable doesn't exist at .../chromium_headless_shell-1223/chrome-headless-shell-linux64/chrome-headless-shell`
**Files to Check:**
- `e2e/tests/02_login.robot`
- Playwright browser installation
**Reference Docs:**
- `e2e/Instructions.md` — Setup section
**Expected Behavior:** Chromium browser should launch successfully for UI tests. Run `npx playwright install` or `rfbrowser init` to install browsers.
---
## Task: 02 Login — Login Page Has No Username Field
**Test:** `Login Page Has No Username Field`
**Suite:** `02_login.robot`
**Step That Fails:** Browser launch.
**Error:** `browserType.launch: Executable doesn't exist at .../chromium_headless_shell`
**Files to Check:**
- `e2e/tests/02_login.robot`
- Playwright browser installation
**Reference Docs:**
- `e2e/Instructions.md`
**Expected Behavior:** Browser should launch. This is an environment setup issue, not an application bug.
---
## Task: 02 Login — Login With Wrong Password Shows Error
**Test:** `Login With Wrong Password Shows Error`
**Suite:** `02_login.robot`
**Step That Fails:** Browser launch.
**Error:** `browserType.launch: Executable doesn't exist at .../chromium_headless_shell`
**Files to Check:**
- `e2e/tests/02_login.robot`
- Playwright browser installation
**Reference Docs:**
- `e2e/Instructions.md`
**Expected Behavior:** Browser should launch to perform the login UI test.
---
## Task: 02 Login — Login Rate Limits After Multiple Failures
**Test:** `Login Rate Limits After Multiple Failures`
**Suite:** `02_login.robot`
**Step That Fails:** Rate limit not triggered after multiple failed logins.
**Error:** `Expected a 429 response after multiple failed logins`
**Files to Check:**
- `e2e/tests/02_login.robot`
- `e2e/resources/auth.resource`
- `backend/app/routers/auth.py`
- `backend/app/middleware/rate_limit.py`
**Reference Docs:**
- `Docs/Features.md` — Rate limiting rules
- `Docs/Security.md`
**Expected Behavior:** After 5 failed login attempts from the same IP within 60 seconds, the backend should return HTTP 429 (Too Many Requests).
---
## Task: 02 Login — Direct Access To Protected Route Redirects To Login
**Test:** `Direct Access To Protected Route Redirects To Login`
**Suite:** `02_login.robot`
**Step That Fails:** Browser launch.
**Error:** `browserType.launch: Executable doesn't exist at .../chromium_headless_shell`
**Files to Check:**
- `e2e/tests/02_login.robot`
- Playwright browser installation
**Reference Docs:**
- `e2e/Instructions.md`
**Expected Behavior:** Browser should launch for UI navigation test.
---
## Task: 02 Login — Session Validation 401 On Mount Redirects To Login
**Test:** `Session Validation 401 On Mount Redirects To Login`
**Suite:** `02_login.robot`
**Step That Fails:** Browser launch.
**Error:** `browserType.launch: Executable doesn't exist at .../chromium_headless_shell`
**Files to Check:**
- `e2e/tests/02_login.robot`
- Playwright browser installation
**Reference Docs:**
- `e2e/Instructions.md`
**Expected Behavior:** Browser should launch for UI test.
---
## Task: 02 Login — Logout Clears Session
**Test:** `Logout Clears Session`
**Suite:** `02_login.robot`
**Step That Fails:** API call after logout returns 401 instead of 200.
**Error:** `401 != 200`
**Files to Check:**
- `e2e/tests/02_login.robot`
- `e2e/resources/auth.resource`
- `backend/app/routers/auth.py`
- `backend/app/services/session_service.py`
**Reference Docs:**
- `Docs/Features.md` — Session management
- `Docs/API_STATUS_CODES.md`
**Expected Behavior:** After clicking Sign Out, subsequent API calls should return 401 (unauthenticated), but the logout endpoint itself should return 200.
---
## Task: 02 Login — After Logout Protected Pages Redirect To Login
**Test:** `After Logout Protected Pages Redirect To Login`
**Suite:** `02_login.robot`
**Step That Fails:** URL does not contain `/login` after accessing protected page post-logout.
**Error:** `'http://localhost:5173/' does not contain '/login'`
**Files to Check:**
- `e2e/tests/02_login.robot`
- `frontend/src/router.tsx` or routing config
- `frontend/src/App.tsx`
**Reference Docs:**
- `Docs/Features.md` — Authentication flow
**Expected Behavior:** After logout, navigating to a protected page should redirect to `/login`.
---
## Task: 02 Login — Login Preserves Originally Requested Page Via Next Parameter
**Test:** `Login Preserves Originally Requested Page Via Next Parameter`
**Suite:** `02_login.robot`
**Step That Fails:** URL does not contain `next=` parameter after redirect.
**Error:** `'http://localhost:5173/login' does not contain 'next='`
**Files to Check:**
- `e2e/tests/02_login.robot`
- `frontend/src/router.tsx`
- `frontend/src/pages/LoginPage.tsx`
**Reference Docs:**
- `Docs/Features.md` — Post-login redirect behavior
**Expected Behavior:** When redirected to login from a protected page, the URL should include a `next=` query parameter preserving the original destination.
---
## Task: 03 Blocklist Import — Manual Blocklist Import Completes Without Error
**Test:** `Manual Blocklist Import Completes Without Error`
**Suite:** `03_blocklist_import.robot`
**Step That Fails:** API call returns 401.
**Error:** `Url: http://localhost:8000/api/v1/blocklists Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/03_blocklist_import.robot`
- `e2e/resources/api.resource`
- `e2e/resources/auth.resource`
- `backend/app/routers/blocklists.py`
**Reference Docs:**
- `Docs/Features.md` — Blocklist import flow
- `Docs/API_STATUS_CODES.md`
**Expected Behavior:** Authenticated API call to `/api/v1/blocklists` should return 200, not 401.
---
## Task: 03 Dashboard — Dashboard Ban List Renders Columns
**Test:** `Dashboard Ban List Renders Columns`
**Suite:** `03_dashboard.robot`
**Step That Fails:** Page text 'IP' not found.
**Error:** `Page text 'IP' not found in body`
**Files to Check:**
- `e2e/tests/03_dashboard.robot`
- `frontend/src/pages/DashboardPage.tsx`
- `frontend/src/components/BanList.tsx` or equivalent
**Reference Docs:**
- `Docs/Features.md` — Dashboard ban list columns
**Expected Behavior:** The dashboard ban list table should contain a column header with the text "IP".
---
## Task: 03 Dashboard — Dashboard Time Range 24h Shows Live Source
**Test:** `Dashboard Time Range 24h Shows Live Source`
**Suite:** `03_dashboard.robot`
**Step That Fails:** No data-source badge visible after selecting 24h preset.
**Error:** `No data-source badge visible after selecting preset`
**Files to Check:**
- `e2e/tests/03_dashboard.robot`
- `frontend/src/pages/DashboardPage.tsx`
- `frontend/src/components/DataSourceBadge.tsx` or equivalent
**Reference Docs:**
- `Docs/Features.md` — Data source badges
**Expected Behavior:** Selecting "Last 24 hours" should display a "Live" data-source badge.
---
## Task: 03 Dashboard — Dashboard Time Range 7d Shows Archive Source
**Test:** `Dashboard Time Range 7d Shows Archive Source`
**Suite:** `03_dashboard.robot`
**Step That Fails:** No data-source badge visible for 7d preset.
**Error:** `No data-source badge visible for 7d preset`
**Files to Check:**
- `e2e/tests/03_dashboard.robot`
- `frontend/src/pages/DashboardPage.tsx`
**Reference Docs:**
- `Docs/Features.md` — Data source badges
**Expected Behavior:** Selecting "Last 7 days" should display an "Archive" data-source badge.
---
## Task: 03 Dashboard — Dashboard Bans Endpoint Returns Expected Shape
**Test:** `Dashboard Bans Endpoint Returns Expected Shape`
**Suite:** `03_dashboard.robot`
**Step That Fails:** API returns 401.
**Error:** `Unexpected status: 401`
**Files to Check:**
- `e2e/tests/03_dashboard.robot`
- `e2e/resources/api.resource`
- `backend/app/routers/dashboard.py` or `bans.py`
**Reference Docs:**
- `Docs/API-Reference.md`
- `Docs/API_STATUS_CODES.md`
**Expected Behavior:** Authenticated GET to bans endpoint should return 200 with expected JSON shape.
---
## Task: 03 Dashboard — Dashboard Status Endpoint Returns Version
**Test:** `Dashboard Status Endpoint Returns Version`
**Suite:** `03_dashboard.robot`
**Step That Fails:** API returns 401.
**Error:** `401 != 200`
**Files to Check:**
- `e2e/tests/03_dashboard.robot`
- `backend/app/routers/health.py` or status endpoint
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Status endpoint should return 200 with version info when authenticated.
---
## Task: 03 Dashboard — Dashboard Bans By Country Endpoint
**Test:** `Dashboard Bans By Country Endpoint`
**Suite:** `03_dashboard.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/03_dashboard.robot`
- `backend/app/routers/dashboard.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Bans-by-country endpoint should return 200 or 204 when authenticated.
---
## Task: 03 Dashboard — Dashboard Bans Trend Endpoint
**Test:** `Dashboard Bans Trend Endpoint`
**Suite:** `03_dashboard.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/03_dashboard.robot`
- `backend/app/routers/dashboard.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Bans trend endpoint should return 200 or 204 when authenticated.
---
## Task: 03 Dashboard — Dashboard Bans By Jail Endpoint
**Test:** `Dashboard Bans By Jail Endpoint`
**Suite:** `03_dashboard.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/03_dashboard.robot`
- `backend/app/routers/dashboard.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Bans-by-jail endpoint should return 200 or 204 when authenticated.
---
## Task: 04 Map — Map Page 24h Preset Shows Live Source Badge
**Test:** `Map Page 24h Preset Shows Live Source Badge`
**Suite:** `04_map.robot`
**Step That Fails:** No data-source badge on map after preset click.
**Error:** `No data-source badge on map after preset click`
**Files to Check:**
- `e2e/tests/04_map.robot`
- `frontend/src/pages/MapPage.tsx`
- `frontend/src/components/DataSourceBadge.tsx`
**Reference Docs:**
- `Docs/Features.md` — Map view data sources
**Expected Behavior:** Clicking the 24h preset on the map should show a "Live" data-source badge.
---
## Task: 04 Map — Map Page 7d Preset Shows Archive Source Badge
**Test:** `Map Page 7d Preset Shows Archive Source Badge`
**Suite:** `04_map.robot`
**Step That Fails:** No data-source badge on map after 7d preset click.
**Error:** `No data-source badge on map after 7d preset click`
**Files to Check:**
- `e2e/tests/04_map.robot`
- `frontend/src/pages/MapPage.tsx`
**Reference Docs:**
- `Docs/Features.md` — Map view data sources
**Expected Behavior:** Clicking the 7d preset should show an "Archive" data-source badge.
---
## Task: 04 Map — Map Page Has Zoom Controls
**Test:** `Map Page Has Zoom Controls`
**Suite:** `04_map.robot`
**Step That Fails:** Zoom controls not found.
**Error:** `No zoom controls found`
**Files to Check:**
- `e2e/tests/04_map.robot`
- `frontend/src/pages/MapPage.tsx`
- `frontend/src/components/WorldMap.tsx` or map component
**Reference Docs:**
- `Docs/Features.md` — Map zoom controls
**Expected Behavior:** The map page should have visible zoom in / zoom out / reset buttons.
---
## Task: 04 Map — Map Bans By Country API Endpoint
**Test:** `Map Bans By Country API Endpoint`
**Suite:** `04_map.robot`
**Step That Fails:** API returns 401.
**Error:** `401 != 200`
**Files to Check:**
- `e2e/tests/04_map.robot`
- `backend/app/routers/map.py` or geo endpoint
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Bans-by-country endpoint should return 200 when authenticated.
---
## Task: 05 Jails — Jails API Returns Active Jails
**Test:** `Jails API Returns Active Jails`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `e2e/resources/api.resource`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
- `Docs/Features.md` — Jail management
**Expected Behavior:** GET `/api/v1/jails` should return 200 with active jails list when authenticated.
---
## Task: 05 Jails — Jail Detail Page Loads For First Active Jail
**Test:** `Jail Detail Page Loads For First Active Jail`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401 when fetching jails list.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Should be able to fetch jails and navigate to the first active jail's detail page.
---
## Task: 05 Jails — Ban An IP Via API
**Test:** `Ban An IP Via API`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/bans.py`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** POST to ban endpoint should succeed (200) when authenticated.
---
## Task: 05 Jails — Unban The IP We Just Banned
**Test:** `Unban The IP We Just Banned`
**Suite:** `05_jails.robot`
**Step That Fails:** Variable `${BANNED_JAIL}` not found.
**Error:** `Variable '${BANNED_JAIL}' not found.`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `e2e/resources/data.resource`
**Reference Docs:**
- `Docs/Testing-Requirements.md` — Test variable scoping
**Expected Behavior:** The `Ban An IP Via API` test should set the `${BANNED_JAIL}` variable so subsequent tests can reference it.
---
## Task: 05 Jails — Unban All Endpoint Accepts Request
**Test:** `Unban All Endpoint Accepts Request`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Unexpected unban-all status: 401`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/bans.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Unban-all endpoint should accept the request (200/204) when authenticated.
---
## Task: 05 Jails — Active Bans Endpoint Returns List
**Test:** `Active Bans Endpoint Returns List`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/bans.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Active bans endpoint should return 200 or 204 when authenticated.
---
## Task: 05 Jails — IP Lookup Endpoint Returns Geo
**Test:** `IP Lookup Endpoint Returns Geo`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Unexpected lookup status: 401`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/geo.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Geo lookup endpoint should return geo data (200) when authenticated.
---
## Task: 05 Jails — Ignore List Add And Remove Via API
**Test:** `Ignore List Add And Remove Via API`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Ignore list add/remove endpoints should work (200) when authenticated.
---
## Task: 05 Jails — Ignore Self Toggle Via API
**Test:** `Ignore Self Toggle Via API`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Ignore-self toggle endpoint should return 200 when authenticated.
---
## Task: 05 Jails — Jail Reload Endpoint Works
**Test:** `Jail Reload Endpoint Works`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Jail reload endpoint should return 200 when authenticated.
---
## Task: 05 Jails — Jail Stop Endpoint Works
**Test:** `Jail Stop Endpoint Works`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Jail stop endpoint should return 200 when authenticated.
---
## Task: 05 Jails — Jail Start Endpoint Works
**Test:** `Jail Start Endpoint Works`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Jail start endpoint should return 200 when authenticated.
---
## Task: 05 Jails — Jail Idle Endpoint Works
**Test:** `Jail Idle Endpoint Works`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Jail idle endpoint should return 200 when authenticated.
---
## Task: 05 Jails — Reload All Jails Endpoint Works
**Test:** `Reload All Jails Endpoint Works`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Reload-all endpoint should return 200 or 204 when authenticated.
---
## Task: 05 Jails — Geo Stats Endpoint Returns Counters
**Test:** `Geo Stats Endpoint Returns Counters`
**Suite:** `05_jails.robot`
**Step That Fails:** API returns 401.
**Error:** `401 != 200`
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `backend/app/routers/geo.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Geo stats endpoint should return 200 with counters when authenticated.
---
## Task: 06 Config — Config Page Renders All Required Tabs
**Test:** `Config Page Renders All Required Tabs`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** Page text 'Actions' not found.
**Error:** `Page text 'Actions' not found in body`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `frontend/src/pages/ConfigPage.tsx`
**Reference Docs:**
- `Docs/Features.md` — Configuration view tabs
**Expected Behavior:** Config page should display tabs for Jails, Filters, Actions, Server, and Regex Tester.
---
## Task: 06 Config — Config Jails Tab Defaults To Active
**Test:** `Config Jails Tab Defaults To Active`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** Page text 'Active' not found.
**Error:** `Page text 'Active' not found in body`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `frontend/src/pages/ConfigPage.tsx`
**Reference Docs:**
- `Docs/Features.md` — Config tab defaults
**Expected Behavior:** The Jails tab should show an "Active" label or section by default.
---
## Task: 06 Config — Config Filters Tab Loads
**Test:** `Config Filters Tab Loads`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** Page text 'Filter' not found.
**Error:** `Page text 'Filter' not found in body`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `frontend/src/pages/ConfigPage.tsx`
**Reference Docs:**
- `Docs/Features.md`
**Expected Behavior:** Clicking the Filters tab should show filter-related content with the text "Filter".
---
## Task: 06 Config — Config Actions Tab Loads
**Test:** `Config Actions Tab Loads`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** Page text 'Action' not found.
**Error:** `Page text 'Action' not found in body`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `frontend/src/pages/ConfigPage.tsx`
**Reference Docs:**
- `Docs/Features.md`
**Expected Behavior:** Clicking the Actions tab should show action-related content with the text "Action".
---
## Task: 06 Config — Config Server Tab Loads
**Test:** `Config Server Tab Loads`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** Page text 'Server' not found.
**Error:** `Page text 'Server' not found in body`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `frontend/src/pages/ConfigPage.tsx`
**Reference Docs:**
- `Docs/Features.md`
**Expected Behavior:** Clicking the Server tab should show server settings content with the text "Server".
---
## Task: 06 Config — Config Regex Tester Tab Loads
**Test:** `Config Regex Tester Tab Loads`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** Page text 'Regex' not found.
**Error:** `Page text 'Regex' not found in body`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `frontend/src/pages/ConfigPage.tsx`
**Reference Docs:**
- `Docs/Features.md`
**Expected Behavior:** Clicking the Regex Tester tab should show regex testing UI with the text "Regex".
---
## Task: 06 Config — Config Regex Tester API Endpoint Validates Pattern
**Test:** `Config Regex Tester API Endpoint Validates Pattern`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 404.
**Error:** `Unexpected regex test status: 404`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Regex tester endpoint should exist and validate patterns (return 200/400, not 404).
---
## Task: 06 Config — Config Jails Endpoint Lists Jail Configs
**Test:** `Config Jails Endpoint Lists Jail Configs`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Jail configs endpoint should return 200 or 204 when authenticated.
---
## Task: 06 Config — Config Filters Endpoint Lists Filter Configs
**Test:** `Config Filters Endpoint Lists Filter Configs`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Filter configs endpoint should return 200 or 204 when authenticated.
---
## Task: 06 Config — Config Actions Endpoint Lists Action Configs
**Test:** `Config Actions Endpoint Lists Action Configs`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Action configs endpoint should return 200 or 204 when authenticated.
---
## Task: 06 Config — Config Global Settings Endpoint
**Test:** `Config Global Settings Endpoint`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Global settings endpoint should return 200 or 204 when authenticated.
---
## Task: 06 Config — Config Service Status Endpoint
**Test:** `Config Service Status Endpoint`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Service status endpoint should return 200 or 204 when authenticated.
---
## Task: 06 Config — Config Security Headers Endpoint
**Test:** `Config Security Headers Endpoint`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Security headers endpoint should return 200 or 204 when authenticated.
---
## Task: 06 Config — Config Inline Edit Round Trip For First Jail
**Test:** `Config Inline Edit Round Trip For First Jail`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/jails Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
- `backend/app/routers/jails.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Inline edit (PUT) for jail config should return 200 when authenticated.
---
## Task: 06 Config — Config Raw Section Lazy Load
**Test:** `Config Raw Section Lazy Load`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `Unexpected raw filter status: 401`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Raw config endpoint should return 200 when authenticated.
---
## Task: 06 Config — Config Raw Action File Endpoint
**Test:** `Config Raw Action File Endpoint`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `Unexpected raw action status: 401`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Raw action file endpoint should return 200 when authenticated.
---
## Task: 06 Config — Config Jail Files Endpoint
**Test:** `Config Jail Files Endpoint`
**Suite:** `06_config_jails_filters_actions.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/06_config_jails_filters_actions.robot`
- `backend/app/routers/config.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Jail files endpoint should return 200 or 204 when authenticated.
---
## Task: 07 Server Settings — Server Settings GET Returns Expected Keys
**Test:** `Server Settings GET Returns Expected Keys`
**Suite:** `07_config_log_and_serversettings.robot`
**Step That Fails:** API returns 401.
**Error:** `Url: http://localhost:8000/api/v1/server/settings Expected status: 401 != 200`
**Files to Check:**
- `e2e/tests/07_config_log_and_serversettings.robot`
- `backend/app/routers/server.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** GET `/api/v1/server/settings` should return 200 with expected keys when authenticated.
---
## Task: 07 Server Settings — Server Settings Update Log Level
**Test:** `Server Settings Update Log Level`
**Suite:** `07_config_log_and_serversettings.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/07_config_log_and_serversettings.robot`
- `backend/app/routers/server.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** PUT to update log level should return 200 or 204 when authenticated.
---
## Task: 07 Server Settings — Server Settings Update DB Purge Age
**Test:** `Server Settings Update DB Purge Age`
**Suite:** `07_config_log_and_serversettings.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/07_config_log_and_serversettings.robot`
- `backend/app/routers/server.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** PUT to update DB purge age should return 200 or 204 when authenticated.
---
## Task: 07 Server Settings — Server Settings Update Max Matches
**Test:** `Server Settings Update Max Matches`
**Suite:** `07_config_log_and_serversettings.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/07_config_log_and_serversettings.robot`
- `backend/app/routers/server.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** PUT to update max matches should return 200 or 204 when authenticated.
---
## Task: 07 Server Settings — Server Settings Accept Stdout Special Target
**Test:** `Server Settings Accept Stdout Special Target`
**Suite:** `07_config_log_and_serversettings.robot`
**Step That Fails:** STDOUT target rejected.
**Error:** `STDOUT target rejected`
**Files to Check:**
- `e2e/tests/07_config_log_and_serversettings.robot`
- `backend/app/routers/server.py`
- `backend/app/models/server_settings.py`
**Reference Docs:**
- `Docs/Features.md` — Log target special values
**Expected Behavior:** Setting log target to "STDOUT" should be accepted as a valid special target.
---
## Task: 07 Server Settings — Server Settings Accept Syslog Special Target
**Test:** `Server Settings Accept Syslog Special Target`
**Suite:** `07_config_log_and_serversettings.robot`
**Step That Fails:** SYSLOG target rejected.
**Error:** `SYSLOG target rejected`
**Files to Check:**
- `e2e/tests/07_config_log_and_serversettings.robot`
- `backend/app/routers/server.py`
- `backend/app/models/server_settings.py`
**Reference Docs:**
- `Docs/Features.md` — Log target special values
**Expected Behavior:** Setting log target to "SYSLOG" should be accepted as a valid special target.
---
## Task: 07 Server Settings — Server Settings Accept Safe File Path
**Test:** `Server Settings Accept Safe File Path`
**Suite:** `07_config_log_and_serversettings.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/07_config_log_and_serversettings.robot`
- `backend/app/routers/server.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Setting a safe file path inside `/var/log` should be accepted (200/204) when authenticated.
---
## Task: 07 Server Settings — Flush Logs Endpoint Works
**Test:** `Flush Logs Endpoint Works`
**Suite:** `07_config_log_and_serversettings.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/07_config_log_and_serversettings.robot`
- `backend/app/routers/server.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Flush logs endpoint should return 200 or 204 when authenticated.
---
## Task: 08 History — History Page Shows Archive Source Badge By Default
**Test:** `History Page Shows Archive Source Badge By Default`
**Suite:** `08_history.robot`
**Step That Fails:** No source badge visible on history page.
**Error:** `No source badge visible on history page`
**Files to Check:**
- `e2e/tests/08_history.robot`
- `frontend/src/pages/HistoryPage.tsx`
- `frontend/src/components/DataSourceBadge.tsx`
**Reference Docs:**
- `Docs/Features.md` — History page data source badges
**Expected Behavior:** The history page should display an "Archive" source badge by default.
---
## Task: 08 History — History Endpoint Returns Paginated Data
**Test:** `History Endpoint Returns Paginated Data`
**Suite:** `08_history.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/08_history.robot`
- `backend/app/routers/history.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** History endpoint should return 200 or 204 with paginated data when authenticated.
---
## Task: 08 History — History Archive Endpoint Returns Data
**Test:** `History Archive Endpoint Returns Data`
**Suite:** `08_history.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/08_history.robot`
- `backend/app/routers/history.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Archive endpoint should return 200 or 204 when authenticated.
---
## Task: 08 History — History Per IP Endpoint Returns Data
**Test:** `History Per IP Endpoint Returns Data`
**Suite:** `08_history.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/08_history.robot`
- `backend/app/routers/history.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Per-IP history endpoint should return 200 or 204 when authenticated.
---
## Task: 08 History — History Filter By Jail Returns Data
**Test:** `History Filter By Jail Returns Data`
**Suite:** `08_history.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/08_history.robot`
- `backend/app/routers/history.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Jail-filtered history endpoint should return 200 or 204 when authenticated.
---
## Task: 08 History — History Filter By Source Fail2ban
**Test:** `History Filter By Source Fail2ban`
**Suite:** `08_history.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/08_history.robot`
- `backend/app/routers/history.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** fail2ban-source filter endpoint should return 200 or 204 when authenticated.
---
## Task: 08 History — History Filter By Source Archive
**Test:** `History Filter By Source Archive`
**Suite:** `08_history.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/08_history.robot`
- `backend/app/routers/history.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Archive-source filter endpoint should return 200 or 204 when authenticated.
---
## Task: 09 Blocklists — Blocklists Sources List Endpoint
**Test:** `Blocklists Sources List Endpoint`
**Suite:** `09_blocklists.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Blocklist sources list endpoint should return 200 or 204 when authenticated.
---
## Task: 09 Blocklists — Blocklist Source Create Rejects Invalid Scheme
**Test:** `Blocklist Source Create Rejects Invalid Scheme`
**Suite:** `09_blocklists.robot`
**Step That Fails:** Invalid scheme was accepted (401 instead of 400).
**Error:** `Invalid scheme was accepted: 401 != 400`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
- `backend/app/services/blocklist_service.py`
**Reference Docs:**
- `Docs/Features.md` — Blocklist URL validation
- `Docs/Security.md` — SSRF prevention
**Expected Behavior:** Creating a blocklist with an invalid scheme (ftp://, file://, etc.) should return 400 Bad Request. The 401 suggests the request never reached validation due to auth failure.
---
## Task: 09 Blocklists — Blocklist Source Create Rejects Loopback URL
**Test:** `Blocklist Source Create Rejects Loopback URL`
**Suite:** `09_blocklists.robot`
**Step That Fails:** Loopback URL accepted (401 instead of 400).
**Error:** `Loopback URL accepted: 401 != 400`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
- `backend/app/services/blocklist_service.py`
**Reference Docs:**
- `Docs/Features.md` — Blocklist URL validation
- `Docs/Security.md` — SSRF prevention
**Expected Behavior:** Loopback URLs (127.0.0.1, localhost) should be rejected with 400. The 401 indicates auth failure before validation.
---
## Task: 09 Blocklists — Blocklist Source Create Rejects Private IP URL
**Test:** `Blocklist Source Create Rejects Private IP URL`
**Suite:** `09_blocklists.robot`
**Step That Fails:** Private IP URL accepted (401 instead of 400).
**Error:** `Private IP URL accepted: 401 != 400`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
- `backend/app/services/blocklist_service.py`
**Reference Docs:**
- `Docs/Features.md` — Blocklist URL validation
- `Docs/Security.md` — SSRF prevention
**Expected Behavior:** Private IP URLs (10.x, 172.16-31.x, 192.168.x) should be rejected with 400. The 401 indicates auth failure before validation.
---
## Task: 09 Blocklists — Blocklist Source Create Rejects Link Local URL
**Test:** `Blocklist Source Create Rejects Link Local URL`
**Suite:** `09_blocklists.robot`
**Step That Fails:** Link-local URL accepted (401 instead of 400).
**Error:** `Link-local URL accepted: 401 != 400`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
- `backend/app/services/blocklist_service.py`
**Reference Docs:**
- `Docs/Features.md` — Blocklist URL validation
- `Docs/Security.md` — SSRF prevention
**Expected Behavior:** Link-local URLs (169.254.x) should be rejected with 400. The 401 indicates auth failure before validation.
---
## Task: 09 Blocklists — Blocklist Schedule Endpoint Returns Config
**Test:** `Blocklist Schedule Endpoint Returns Config`
**Suite:** `09_blocklists.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Schedule endpoint should return 200 or 204 when authenticated.
---
## Task: 09 Blocklists — Blocklist Schedule Update Works
**Test:** `Blocklist Schedule Update Works`
**Suite:** `09_blocklists.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Schedule update endpoint should return 200 or 204 when authenticated.
---
## Task: 09 Blocklists — Blocklist Manual Import Endpoint Reachable
**Test:** `Blocklist Manual Import Endpoint Reachable`
**Suite:** `09_blocklists.robot`
**Step That Fails:** API returns 401.
**Error:** `Unexpected import status: 401`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Manual import endpoint should return 200 when authenticated.
---
## Task: 09 Blocklists — Blocklist Import Log Endpoint Returns Paginated Data
**Test:** `Blocklist Import Log Endpoint Returns Paginated Data`
**Suite:** `09_blocklists.robot`
**Step That Fails:** API returns 401.
**Error:** `'401 in [200, 204]' should be true.`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** Import log endpoint should return 200 or 204 with paginated data when authenticated.
---
## Task: 09 Blocklists — Blocklist Delete Non Existent Returns 404
**Test:** `Blocklist Delete Non Existent Returns 404`
**Suite:** `09_blocklists.robot`
**Step That Fails:** API returns 401 instead of 404.
**Error:** `401 != 404`
**Files to Check:**
- `e2e/tests/09_blocklists.robot`
- `backend/app/routers/blocklists.py`
**Reference Docs:**
- `Docs/API-Reference.md`
- `Docs/API_STATUS_CODES.md`
**Expected Behavior:** Deleting a non-existent blocklist should return 404 Not Found. The 401 indicates the request is not reaching the handler due to auth failure.
---
## Meta Task: Fix Authentication in E2E Tests
**Affected Tests:** ~40+ API tests across suites 03, 05, 06, 07, 08, 09
**Root Cause Pattern:** Most API tests return `401 Unauthorized`, indicating the test authentication/session setup is not working correctly.
**Files to Check:**
- `e2e/resources/auth.resource``Login As Admin`, `Login Via HTTP`
- `e2e/resources/api.resource` — CSRF and cookie handling
- `e2e/resources/common.resource``Wait For Backend Health`, XFF headers
- `backend/app/routers/auth.py` — Login endpoint
- `backend/app/middleware/session.py` — Session validation
**Reference Docs:**
- `e2e/Instructions.md` — Rate-limit workaround with XFF headers
- `Docs/Security.md` — Session handling
- `Docs/API_STATUS_CODES.md`
**Expected Behavior:**
- `Login As Admin` keyword should successfully authenticate and persist session cookies.
- `Api Get/Post/Put/Delete` wrappers should inject the session cookie and CSRF token.
- Tests using `X-Forwarded-For` headers should bypass rate limits while maintaining auth.
**Investigation Steps:**
1. Verify `Login As Admin` returns 200 and sets session cookie.
2. Check that subsequent API calls include the session cookie.
3. Verify CSRF token is extracted from login response and included in state-changing requests.
4. Check if `X-Forwarded-For` rotation is interfering with session stickiness.
---
## Meta Task: Install Playwright Browsers for UI Tests
**Affected Tests:** 6 tests in `02_login.robot` (browser launch failures)
**Root Cause:** Playwright Chromium browser binary is not installed.
**Error:** `browserType.launch: Executable doesn't exist at .../chromium_headless_shell`
**Fix:**
```bash
cd /home/lukas/Volume/repo/BanGUI/e2e
npx playwright install chromium
# or
rfbrowser init
```
**Reference Docs:**
- `e2e/Instructions.md` — Setup section
---
## Meta Task: Fix Setup Page Validation Alert Selectors
**Affected Tests:** 4 tests in `01_setup_and_auth.robot`
**Root Cause:** XPath selector `//*[@aria-label="..."]/ancestor::*[contains(@class,"field")]//*[@role="alert"]` times out waiting for validation alerts.
**Possible Causes:**
1. Alerts are rendered outside the expected DOM hierarchy.
2. Alert role is not applied to error messages.
3. Validation is async and takes longer than 10 seconds.
4. The `field` CSS class is not present on the container.
**Files to Check:**
- `frontend/src/pages/SetupPage.tsx` — Alert rendering and CSS classes
- `e2e/tests/01_setup_and_auth.robot` — XPath selectors
**Reference Docs:**
- `Docs/Features.md` — Setup wizard validation
- `Docs/Testing-Requirements.md` — Accessibility requirements
**Expected Behavior:** Form validation errors should be visible within 10 seconds and match the XPath selector structure.
---
## Meta Task: Fix Dashboard and Map Data Source Badges
**Affected Tests:**
- `03_dashboard.robot`: 24h, 7d presets
- `04_map.robot`: 24h, 7d presets
**Root Cause:** Data-source badges ("Live" / "Archive") are not visible after selecting time-range presets.
**Files to Check:**
- `frontend/src/pages/DashboardPage.tsx`
- `frontend/src/pages/MapPage.tsx`
- `frontend/src/components/DataSourceBadge.tsx`
**Reference Docs:**
- `Docs/Features.md` — Data source badges
**Expected Behavior:** Time-range preset buttons should trigger a badge update showing the appropriate data source.
---
## Meta Task: Fix Config Page Tab Content Visibility
**Affected Tests:** 5 tests in `06_config_jails_filters_actions.robot`
**Root Cause:** Tab content text (Actions, Active, Filter, Action, Server, Regex) is not found in the page body.
**Files to Check:**
- `frontend/src/pages/ConfigPage.tsx`
- `frontend/src/components/Tabs.tsx` or tab component
**Reference Docs:**
- `Docs/Features.md` — Configuration view tabs
**Expected Behavior:** Each tab should render content with identifiable text matching the tab name.
---
## Meta Task: Fix Server Settings Special Target Acceptance
**Affected Tests:** 2 tests in `07_config_log_and_serversettings.robot`
**Root Cause:** "STDOUT" and "SYSLOG" special log targets are rejected.
**Files to Check:**
- `backend/app/routers/server.py`
- `backend/app/models/server_settings.py`
- `backend/app/schemas/server_settings.py`
**Reference Docs:**
- `Docs/Features.md` — Log target configuration
**Expected Behavior:** The server settings validator should accept "STDOUT" and "SYSLOG" as valid special log targets.
---
## Meta Task: Fix History Page Source Badge
**Affected Tests:** 1 test in `08_history.robot`
**Root Cause:** Archive source badge not visible on history page by default.
**Files to Check:**
- `frontend/src/pages/HistoryPage.tsx`
- `frontend/src/components/DataSourceBadge.tsx`
**Reference Docs:**
- `Docs/Features.md` — History page defaults
**Expected Behavior:** History page should show an "Archive" source badge on initial load.
---
## Meta Task: Fix Ban Records Pipeline
**Affected Tests:** 1 test in `02_ban_records.robot`
**Root Cause:** Simulated failed logins do not produce ban records containing the expected IP.
**Files to Check:**
- `e2e/tests/02_ban_records.robot`
- `e2e/proxy_server.py`
- `backend/app/services/ban_service.py`
- `backend/app/tasks/ban_sync.py` or equivalent
- `Docker/simulate_failed_logins.sh`
**Reference Docs:**
- `Docs/Features.md` — Ban record pipeline
- `Docs/Architekture.md` — Data flow
**Expected Behavior:** After simulating failed logins, the ban record should appear in the system with the test IP address.
---
## Meta Task: Fix Config Regex Tester Endpoint
**Affected Tests:** 1 test in `06_config_jails_filters_actions.robot`
**Root Cause:** Regex tester API endpoint returns 404.
**Files to Check:**
- `backend/app/routers/config.py`
- `backend/app/main.py` — Router registration
**Reference Docs:**
- `Docs/API-Reference.md`
**Expected Behavior:** The regex tester endpoint should be registered and return 200 for valid patterns, 400 for invalid ones.
---
## Meta Task: Fix Jail Detail Page Variable Scope
**Affected Tests:** 1 test in `05_jails.robot`
**Root Cause:** `${BANNED_JAIL}` variable is not set or not accessible across test cases.
**Files to Check:**
- `e2e/tests/05_jails.robot`
- `e2e/resources/data.resource`
**Reference Docs:**
- `Docs/Testing-Requirements.md` — Test variable scoping
**Expected Behavior:** Variables set in one test case should be available in subsequent test cases within the same suite, or use suite-level setup/teardown variables.
---
## Meta Task: Fix Login Redirect Behavior
**Affected Tests:** 2 tests in `02_login.robot`
**Root Cause:**
1. After logout, protected pages redirect to `/` instead of `/login`.
2. `next=` parameter is not preserved in login URL after redirect from protected page.
**Files to Check:**
- `frontend/src/router.tsx`
- `frontend/src/pages/LoginPage.tsx`
- `frontend/src/App.tsx`
**Reference Docs:**
- `Docs/Features.md` — Authentication flow
**Expected Behavior:**
- Unauthenticated access to protected routes should redirect to `/login`.
- The original requested URL should be preserved in a `next=` query parameter.
---
## Meta Task: Fix Dashboard Ban List Column Headers
**Affected Tests:** 1 test in `03_dashboard.robot`
**Root Cause:** The text "IP" is not found in the dashboard ban list.
**Files to Check:**
- `frontend/src/pages/DashboardPage.tsx`
- `frontend/src/components/BanList.tsx`
**Reference Docs:**
- `Docs/Features.md` — Dashboard columns
**Expected Behavior:** The ban list table should have a visible column header containing the text "IP".
---
## Meta Task: Fix Map Zoom Controls
**Affected Tests:** 1 test in `04_map.robot`
**Root Cause:** Zoom controls are not found on the map page.
**Files to Check:**
- `frontend/src/pages/MapPage.tsx`
- `frontend/src/components/WorldMap.tsx`
**Reference Docs:**
- `Docs/Features.md` — Map controls
**Expected Behavior:** The map should have visible zoom in, zoom out, and reset buttons.
---
## Meta Task: Fix Logout API Response
**Affected Tests:** 1 test in `02_login.robot`
**Root Cause:** Logout endpoint returns 401 instead of 200.
**Files to Check:**
- `backend/app/routers/auth.py`
- `backend/app/services/session_service.py`
**Reference Docs:**
- `Docs/API-Reference.md`
- `Docs/API_STATUS_CODES.md`
**Expected Behavior:** The logout endpoint should return 200 OK even if the session is already expired, or at minimum not return 401 for a valid logout request.
---
## Meta Task: Fix Login Rate Limit Test
**Affected Tests:** 1 test in `02_login.robot`
**Root Cause:** Rate limit is not triggered after multiple failed logins.
**Files to Check:**
- `e2e/tests/02_login.robot`
- `backend/app/routers/auth.py`
- `backend/app/middleware/rate_limit.py`
**Reference Docs:**
- `Docs/Features.md` — Rate limiting
- `Docs/Security.md`
**Expected Behavior:** After 5 failed login attempts from the same IP within 60 seconds, the 6th attempt should return HTTP 429.
---
## Meta Task: Fix Config Edit Test Prerequisites
**Affected Tests:** 1 skipped test in `04_config_edit.robot`
**Root Cause:** Test requires at least one active jail but none are active.
**Files to Check:**
- `e2e/tests/04_config_edit.robot`
- `Docker/simulate_failed_logins.sh`
- `backend/app/services/jail_service.py`
**Reference Docs:**
- `Docs/Features.md` — Jail activation
**Expected Behavior:** Either ensure a jail is active before running the test, or adjust the test to handle the empty-jail scenario.
---
*End of tasks. Total: 84 failing tests documented across 13 test suites, plus 13 meta-tasks grouping common root causes.*