fix: add aria-labels to SetupPage inputs and update e2e selectors

- Add aria-label attributes to all form inputs in SetupPage.tsx
  (Master Password, Confirm Password, Database Path, fail2ban Socket Path,
  Timezone, Session Duration) for accessibility and test stability
- Update e2e tests to use xpath selectors with role=alert instead of
  class-based selectors for validation messages
- Add New Context / New Page per test for browser isolation
- Fix API endpoint from /api/setup/status to /api/v1/setup
- Fix response field from setup_complete to completed
- Simplify password strength test to check aria-live text instead of
  DOM class traversal
- Remove completed task docs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-06-21 12:31:09 +02:00
parent 5f33959efd
commit 2538c50321
4 changed files with 42 additions and 2268 deletions

View File

@@ -8,6 +8,8 @@ Suite Setup Wait For Backend Health
Setup Page Renders All Form Fields
[Documentation] Verify all setup wizard fields are present and labelled correctly.
New Browser chromium headless=${TRUE}
New Context
New Page
Go To ${FRONTEND_URL}/setup
Wait For Elements State css=form visible timeout=15s
@@ -31,37 +33,31 @@ Setup Page Renders All Form Fields
Password Strength Indicator Updates On Input
[Documentation] The four-segment strength bar and rule count reflect password complexity.
New Browser chromium headless=${TRUE}
New Context
New Page
Go To ${FRONTEND_URL}/setup
Wait For Elements State css=input[aria-label="Master Password"] visible timeout=15s
# Initially no segments are active — no rules satisfied.
${segments}= Get Elements css=.passwordStrengthSegment
${active_count}= Set Variable 0
FOR ${seg} IN @{segments}
${classes}= Get Attribute ${seg} class
IF "Active" in """${classes}"""
${active_count}= Evaluate ${active_count} + 1
END
END
Should Be Equal As Integers ${active_count} 0
# Verify initial strength text shows "0 of 4 rules satisfied".
${text_0}= Get Text xpath=//div[@aria-live="polite"]
Should Contain ${text_0} 0 of 4 rules satisfied
Log Initial strength: ${text_0}
# Type a weak password — only length (>=8) rule satisfied.
Fill Text css=input[aria-label="Master Password"] WeakPass
${active_count}= Set Variable 0
${segments}= Get Elements css=.passwordStrengthSegment
FOR ${seg} IN @{segments}
${classes}= Get Attribute ${seg} class
IF "Active" in """${classes}"""
${active_count}= Evaluate ${active_count} + 1
END
END
Should Be Equal As Integers ${active_count} 1
Fill Text css=input[aria-label="Master Password"] longpassword
# Verify strength text updates to "1 of 4 rules satisfied" (only length rule, no uppercase/number/special).
${text_1}= Get Text xpath=//div[@aria-live="polite"]
Should Contain ${text_1} 1 of 4 rules satisfied
Log After longpassword: ${text_1}
Close Browser
Password Mismatch Shows Validation Error
[Documentation] Submitting with non-matching passwords surfaces an error on Confirm Password.
New Browser chromium headless=${TRUE}
New Context
New Page
Go To ${FRONTEND_URL}/setup
Wait For Elements State css=input[aria-label="Master Password"] visible timeout=15s
@@ -70,7 +66,7 @@ Password Mismatch Shows Validation Error
Click css=button[type="submit"]
Wait For Elements State css=[aria-label="Confirm Password"] attached timeout=5s
${msg}= Get Text css=[aria-label="Confirm Password"]/ancestor::*[contains(@class,"field")]//*[contains(@class,"validationMessage")]
${msg}= Get Text xpath=//*[@aria-label="Confirm Password"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]
Should Be Equal As Strings ${msg} Passwords do not match.
Close Browser
@@ -78,21 +74,23 @@ Password Mismatch Shows Validation Error
Empty Required Fields Show Validation Errors
[Documentation] Submitting with blank required fields shows field-level error messages.
New Browser chromium headless=${TRUE}
New Context
New Page
Go To ${FRONTEND_URL}/setup
Wait For Elements State css=input[aria-label="Master Password"] visible timeout=15s
Click css=button[type="submit"]
Wait For Elements State css=[aria-label="Master Password"] attached timeout=5s
${msg}= Get Text css=[aria-label="Master Password"]/ancestor::*[contains(@class,"field")]//*[contains(@class,"validationMessage")]
${msg}= Get Text xpath=//*[@aria-label="Master Password"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]
Should Be Equal As Strings ${msg} Password is required.
Wait For Elements State css=[aria-label="Database Path"] attached timeout=5s
${msg}= Get Text css=[aria-label="Database Path"]/ancestor::*[contains(@class,"field")]//*[contains(@class,"validationMessage")]
${msg}= Get Text xpath=//*[@aria-label="Database Path"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]
Should Be Equal As Strings ${msg} Database path is required.
Wait For Elements State css=[aria-label="fail2ban Socket Path"] attached timeout=5s
${msg}= Get Text css=[aria-label="fail2ban Socket Path"]/ancestor::*[contains(@class,"field")]//*[contains(@class,"validationMessage")]
${msg}= Get Text xpath=//*[@aria-label="fail2ban Socket Path"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]
Should Be Equal As Strings ${msg} Socket path is required.
Close Browser
@@ -100,6 +98,8 @@ Empty Required Fields Show Validation Errors
Invalid Session Duration Shows Validation Error
[Documentation] Session duration below 1 minute triggers a validation error.
New Browser chromium headless=${TRUE}
New Context
New Page
Go To ${FRONTEND_URL}/setup
Wait For Elements State css=input[aria-label="Master Password"] visible timeout=15s
@@ -112,7 +112,7 @@ Invalid Session Duration Shows Validation Error
Click css=button[type="submit"]
Wait For Elements State css=[aria-label="Session Duration (minutes)"] attached timeout=5s
${msg}= Get Text css=[aria-label="Session Duration (minutes)"]/ancestor::*[contains(@class,"field")]//*[contains(@class,"validationMessage")]
${msg}= Get Text xpath=//*[@aria-label="Session Duration (minutes)"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]
Should Be Equal As Strings ${msg} Session duration must be at least 1 minute.
Close Browser
@@ -120,6 +120,8 @@ Invalid Session Duration Shows Validation Error
Incomplete Password Shows Complexity Error
[Documentation] Submitting a password that meets length but not all rules shows complexity error.
New Browser chromium headless=${TRUE}
New Context
New Page
Go To ${FRONTEND_URL}/setup
Wait For Elements State css=input[aria-label="Master Password"] visible timeout=15s
@@ -127,7 +129,7 @@ Incomplete Password Shows Complexity Error
Click css=button[type="submit"]
Wait For Elements State css=[aria-label="Master Password"] attached timeout=5s
${msg}= Get Text css=[aria-label="Master Password"]/ancestor::*[contains(@class,"field")]//*[contains(@class,"validationMessage")]
${msg}= Get Text xpath=//*[@aria-label="Master Password"]/ancestor::*[contains(@class,"field")]//*[@role="alert"]
Should Contain ${msg} Password must meet all complexity requirements.
Close Browser
@@ -135,11 +137,13 @@ Incomplete Password Shows Complexity Error
Setup Completes Successfully And Redirects To Login
[Documentation] Filling all fields and submitting completes setup and navigates to /login.
New Browser chromium headless=${TRUE}
New Context
New Page
# Use API to check if setup is already complete; reset if needed.
${status_resp}= GET ${BACKEND_URL}/api/setup/status
${status_resp}= GET ${BACKEND_URL}/api/v1/setup
${status_body}= Set Variable ${status_resp.json()}
Log Setup complete: ${status_body}[setup_complete]
Log Setup complete: ${status_body}[completed]
Go To ${FRONTEND_URL}/setup
Wait For Elements State css=input[aria-label="Master Password"] visible timeout=15s
@@ -168,8 +172,8 @@ Setup Completes Successfully And Redirects To Login
END
# Verify setup is now marked complete.
${new_status_resp}= GET ${BACKEND_URL}/api/setup/status
${new_status_resp}= GET ${BACKEND_URL}/api/v1/setup
${new_status_body}= Set Variable ${new_status_resp.json()}
Should Be True ${new_status_body}[setup_complete]
Should Be True ${new_status_body}[completed]
Close Browser