## 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.*