Compare commits

...

1 Commits

Author SHA1 Message Date
Alexander Payne
7030a97de9 test(#552): add smoke test verifying R2 aria-required on username field
Adds a regression test that checks the sign-in page override template
(deploy/gitea-a11y/custom/templates/user/auth/signin_inner.tmpl)
contains aria-required="true" on the username input field, per
accessibility audit R2 (#492). Also verifies required attribute presence
and correct label association.

Closes #552
2026-04-29 05:52:01 -04:00

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env python3
"""
Smoke test: a11y R2 aria-required attribute exists on required form fields.
Issue #552: [a11y] R2: Add aria-required to required form fields
Verifies that deploy/gitea-a11y/custom/templates/user/auth/signin_inner.tmpl
includes aria-required="true" on required inputs:
- Username input
- Password input (also checked by R1, but verified here for completeness)
"""
import sys
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parent.parent
TEMPLATE_PATH = REPO_ROOT / "deploy" / "gitea-a11y" / "custom" / "templates" / "user" / "auth" / "signin_inner.tmpl"
def test_r2_username_input():
"""Username input has required and aria-required."""
content = TEMPLATE_PATH.read_text()
# Input must have id and name user_name
assert 'id="user_name"' in content, "Username input missing id='user_name'"
assert 'name="user_name"' in content, "Username input missing name='user_name'"
# Must be a text input
assert 'type="text"' in content, "Username input missing type='text'"
# Required attribute present in the input element
# Check that required appears near the username input (simple presence in file)
# More precise: look for the pattern within the user_name input block
user_name_block = content[content.find('id="user_name"'):]
# limited scan for performance; find attributes inside the same <input ... />
assert 'required' in user_name_block[:200], "Username input missing required attribute"
assert 'aria-required="true"' in user_name_block[:200], "Username input missing aria-required='true'"
print("✓ Username input has required and aria-required")
def test_r2_password_input():
"""Password input also has aria-required (enforced by R1 but part of R2 scope)."""
content = TEMPLATE_PATH.read_text()
password_block = content[content.find('id="password"'):]
assert 'required' in password_block[:200], "Password input missing required"
assert 'aria-required="true"' in password_block[:200], "Password input missing aria-required='true'"
print("✓ Password input has required and aria-required")
def test_r2_label_for_username():
"""Label 'for' attribute matches username input id."""
content = TEMPLATE_PATH.read_text()
assert 'for="user_name"' in content, "Label missing for='user_name'"
print("✓ Label correctly associated with username input")
def run_all():
print("R2 Smoke Test — aria-required on required fields (issue #552)")
print("-" * 60)
try:
test_r2_username_input()
test_r2_password_input()
test_r2_label_for_username()
print("-" * 60)
print("✅ All R2 checks passed")
return 0
except AssertionError as e:
print(f"\n❌ R2 check failed: {e}")
return 1
except Exception as e:
print(f"\n❌ Unexpected error: {e}")
return 1
if __name__ == "__main__":
sys.exit(run_all())