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

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

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

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

View File

@@ -0,0 +1,153 @@
*** Settings ***
Documentation Server settings + log viewer + log observation coverage.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/auth.resource
Suite Setup Wait For Backend Health
*** Test Cases ***
Server Settings GET Returns Expected Keys
[Documentation] GET /api/v1/server/settings returns log level, target, etc.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${resp}= GET On Session bangsess /api/v1/server/settings
... headers=${headers} expected_status=200
${body}= Set Variable ${resp.json()}
Dictionary Should Contain Key ${body} loglevel
Server Settings Update Log Level
[Documentation] PUT /api/v1/server/settings updates log level to INFO.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary loglevel INFO
${resp}= PUT On Session bangsess /api/v1/server/settings
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 204]
Server Settings Reject Invalid Log Level
[Documentation] Invalid log level must return 4xx.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary loglevel NOT_A_LEVEL
${resp}= PUT On Session bangsess /api/v1/server/settings
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} >= 400 msg=Invalid log level accepted
Server Settings Update DB Purge Age
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary dbpurgeage 648000
${resp}= PUT On Session bangsess /api/v1/server/settings
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 204]
Server Settings Update Max Matches
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary maxmatches 10
${resp}= PUT On Session bangsess /api/v1/server/settings
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 204]
Server Settings Reject Path Outside Allowlist
[Documentation] Log target must validate against /var/log or /config/log allowlist.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary logtarget /etc/passwd
${resp}= PUT On Session bangsess /api/v1/server/settings
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} >= 400 msg=Path outside allowlist accepted
Server Settings Accept Stdout Special Target
[Documentation] STDOUT is a valid special log target.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary logtarget STDOUT
${resp}= PUT On Session bangsess /api/v1/server/settings
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 204] msg=STDOUT target rejected
Server Settings Accept Syslog Special Target
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary logtarget SYSLOG
${resp}= PUT On Session bangsess /api/v1/server/settings
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 204] msg=SYSLOG target rejected
Server Settings Accept Safe File Path
[Documentation] A path inside /var/log must be accepted.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary logtarget /var/log/fail2ban.log
${resp}= PUT On Session bangsess /api/v1/server/settings
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 204]
Flush Logs Endpoint Works
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${resp}= POST On Session bangsess /api/v1/server/flush-logs
... json=${EMPTY} headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 204]
Log Preview Endpoint Returns Content
[Documentation] GET /api/v1/config/log/preview returns tail of log file.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${resp}= GET On Session bangsess /api/v1/config/log/preview
... params=lines=100 headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 400, 404] msg=Unexpected log preview status: ${resp.status_code}
Log Endpoint Returns Content Or 404
[Documentation] GET /api/v1/config/log returns full log or 404 if logging to non-file.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${resp}= GET On Session bangsess /api/v1/config/log
... headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 404] msg=Unexpected log status: ${resp.status_code}
Log Observation Add Rejects Path Outside Allowlist
[Documentation] POST /api/v1/config/add-log-observation rejects /etc/passwd.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary path /etc/passwd jail nonexistent
${resp}= POST On Session bangsess /api/v1/config/add-log-observation
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} >= 400 msg=Path outside allowlist accepted
Log Observation Add Endpoint Exists
[Documentation] POST /api/v1/config/add-log-observation is reachable.
Set Random Xff Header
Login Via HTTP
${headers}= Create Dictionary X-BanGUI-Request 1
Set To Dictionary ${headers} X-Forwarded-For ${XFF_HEADER}
${payload}= Create Dictionary path /var/log/nonexistent.log jail none
${resp}= POST On Session bangsess /api/v1/config/add-log-observation
... json=${payload} headers=${headers} expected_status=any
Should Be True ${resp.status_code} in [200, 201, 400, 404] msg=Endpoint missing