Compare commits
1 Commits
step35/595
...
step35/552
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2588d6f39c |
84
tests/test_a11y_r2_aria_required.py
Normal file
84
tests/test_a11y_r2_aria_required.py
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Smoke test for a11y R2: aria-required on required form fields (#552).
|
||||||
|
|
||||||
|
Verifies that required form inputs in the Gitea sign-in template
|
||||||
|
include aria-required="true" for WCAG 3.3.1 compliance.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
REPO_ROOT = Path(__file__).parent.parent
|
||||||
|
TEMPLATE_PATH = (
|
||||||
|
REPO_ROOT / "deploy" / "gitea-a11y" / "custom" / "templates" / "user" / "auth" / "signin_inner.tmpl"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_signin_username_has_aria_required():
|
||||||
|
"""R2 requirement: username input must have aria-required='true'."""
|
||||||
|
assert TEMPLATE_PATH.exists(), f"Template not found: {TEMPLATE_PATH}"
|
||||||
|
|
||||||
|
content = TEMPLATE_PATH.read_text()
|
||||||
|
|
||||||
|
# Check that the template contains the username input section
|
||||||
|
assert 'id="user_name"' in content, "username input (id=user_name) not found"
|
||||||
|
assert 'name="user_name"' in content, "username input (name=user_name) not found"
|
||||||
|
|
||||||
|
# Check for aria-required on username field
|
||||||
|
# The attribute should be in the input tag for user_name
|
||||||
|
assert 'aria-required="true"' in content, "aria-required='true' not found in template"
|
||||||
|
|
||||||
|
print(" PASS: username field has aria-required='true'")
|
||||||
|
|
||||||
|
|
||||||
|
def test_signin_password_has_aria_required():
|
||||||
|
"""R2 requirement: password input must have aria-required='true'."""
|
||||||
|
assert TEMPLATE_PATH.exists(), f"Template not found: {TEMPLATE_PATH}"
|
||||||
|
|
||||||
|
content = TEMPLATE_PATH.read_text()
|
||||||
|
|
||||||
|
# Check that the template contains the password input section
|
||||||
|
assert 'id="password"' in content, "password input (id=password) not found"
|
||||||
|
assert 'type="password"' in content, "password input (type=password) not found"
|
||||||
|
|
||||||
|
# Check for aria-required on password field
|
||||||
|
assert 'aria-required="true"' in content, "aria-required='true' not found in template"
|
||||||
|
|
||||||
|
print(" PASS: password field has aria-required='true'")
|
||||||
|
|
||||||
|
|
||||||
|
def test_both_required_fields_marked():
|
||||||
|
"""R2: all required form fields must be marked with aria-required."""
|
||||||
|
assert TEMPLATE_PATH.exists(), f"Template not found: {TEMPLATE_PATH}"
|
||||||
|
|
||||||
|
content = TEMPLATE_PATH.read_text()
|
||||||
|
|
||||||
|
# Count required inputs — R2 applies to ALL required fields
|
||||||
|
required_inputs = []
|
||||||
|
in_input = False
|
||||||
|
current_input = []
|
||||||
|
for line in content.split('\n'):
|
||||||
|
if '<input' in line:
|
||||||
|
in_input = True
|
||||||
|
current_input = [line]
|
||||||
|
elif in_input:
|
||||||
|
current_input.append(line)
|
||||||
|
if '/>' in line or '>' in line:
|
||||||
|
in_input = False
|
||||||
|
input_str = '\n'.join(current_input)
|
||||||
|
if 'required' in input_str:
|
||||||
|
required_inputs.append(input_str)
|
||||||
|
current_input = []
|
||||||
|
|
||||||
|
assert len(required_inputs) >= 2, f"Expected at least 2 required inputs, found {len(required_inputs)}"
|
||||||
|
|
||||||
|
for inp in required_inputs:
|
||||||
|
assert 'aria-required="true"' in inp, f"required input missing aria-required: {inp.strip()}"
|
||||||
|
|
||||||
|
print(f" PASS: all {len(required_inputs)} required input(s) have aria-required='true'")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_signin_username_has_aria_required()
|
||||||
|
test_signin_password_has_aria_required()
|
||||||
|
test_both_required_fields_marked()
|
||||||
|
print("\nAll R2 smoke tests passed.")
|
||||||
Reference in New Issue
Block a user