File size: 7,988 Bytes
cc036ff | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | """
Accessibility violation detection tests for browser bug discovery.
This module tests for WCAG 2.1 AA compliance violations using axe-core.
Tests detect missing ARIA labels, color contrast issues, and other a11y bugs.
Tests use accessibility_checker and assert_accessibility fixtures from conftest.py.
"""
import pytest
from tests.browser_discovery.conftest import (
authenticated_page,
accessibility_checker,
assert_accessibility,
)
pytestmark = pytest.mark.accessibility
class TestAccessibility:
"""Test suite for detecting WCAG 2.1 AA accessibility violations."""
@pytest.mark.accessibility
def test_dashboard_wcag_aa_compliance(
self, authenticated_page, assert_accessibility
):
"""Verify dashboard page meets WCAG 2.1 AA accessibility standards.
Navigates to /dashboard and checks for accessibility violations
that would prevent users with disabilities from using the dashboard.
Args:
authenticated_page: Authenticated page fixture (API-first auth)
assert_accessibility: Assertion helper fixture for WCAG compliance
"""
base_url = "http://localhost:3001"
dashboard_url = base_url + "/dashboard"
authenticated_page.goto(dashboard_url)
authenticated_page.wait_for_load_state("domcontentloaded")
assert_accessibility()
@pytest.mark.accessibility
def test_agents_list_wcag_aa_compliance(
self, authenticated_page, assert_accessibility
):
"""Verify agents list page meets WCAG 2.1 AA accessibility standards.
Navigates to /agents and checks for accessibility violations
in agent listings, filters, and action buttons.
Args:
authenticated_page: Authenticated page fixture
assert_accessibility: Assertion helper fixture for WCAG compliance
"""
base_url = "http://localhost:3001"
agents_url = base_url + "/agents"
authenticated_page.goto(agents_url)
authenticated_page.wait_for_load_state("domcontentloaded")
assert_accessibility()
@pytest.mark.accessibility
def test_agent_creation_form_wcag_aa(
self, authenticated_page, assert_accessibility
):
"""Verify agent creation form meets WCAG 2.1 AA accessibility standards.
Navigates to /agents/new and checks for form accessibility violations
including missing labels, unclear error messages, and keyboard navigation issues.
Args:
authenticated_page: Authenticated page fixture
assert_accessibility: Assertion helper fixture for WCAG compliance
"""
base_url = "http://localhost:3001"
agent_creation_url = base_url + "/agents/new"
authenticated_page.goto(agent_creation_url)
authenticated_page.wait_for_load_state("domcontentloaded")
assert_accessibility()
@pytest.mark.accessibility
def test_canvas_list_wcag_aa_compliance(
self, authenticated_page, assert_accessibility
):
"""Verify canvas list page meets WCAG 2.1 AA accessibility standards.
Navigates to /canvas and checks for accessibility violations
in canvas listings, visual presentations, and interactive elements.
Args:
authenticated_page: Authenticated page fixture
assert_accessibility: Assertion helper fixture for WCAG compliance
"""
base_url = "http://localhost:3001"
canvas_url = base_url + "/canvas"
authenticated_page.goto(canvas_url)
authenticated_page.wait_for_load_state("domcontentloaded")
assert_accessibility()
@pytest.mark.accessibility
def test_workflows_list_wcag_aa_compliance(
self, authenticated_page, assert_accessibility
):
"""Verify workflows list page meets WCAG 2.1 AA accessibility standards.
Navigates to /workflows and checks for accessibility violations
in workflow DAG visualizations, node selectors, and action buttons.
Args:
authenticated_page: Authenticated page fixture
assert_accessibility: Assertion helper fixture for WCAG compliance
"""
base_url = "http://localhost:3001"
workflows_url = base_url + "/workflows"
authenticated_page.goto(workflows_url)
authenticated_page.wait_for_load_state("domcontentloaded")
assert_accessibility()
@pytest.mark.accessibility
def test_accessibility_violation_metadata(
self, authenticated_page, accessibility_checker
):
"""Verify accessibility violations include id, impact, description, and help_url.
Checks that accessibility_checker returns structured violation data
with all necessary fields for bug triaging and remediation.
Args:
authenticated_page: Authenticated page fixture
accessibility_checker: Accessibility checker fixture with axe-core
"""
base_url = "http://localhost:3001"
dashboard_url = base_url + "/dashboard"
authenticated_page.goto(dashboard_url)
authenticated_page.wait_for_load_state("domcontentloaded")
# Run accessibility audit
violations = accessibility_checker()
# Verify violations is a list (even if empty)
assert isinstance(violations, list), "Violations should be a list"
# If violations exist, verify metadata structure
if violations:
for violation in violations:
assert "id" in violation, "Violation should have id"
assert "impact" in violation, "Violation should have impact"
assert "description" in violation, "Violation should have description"
assert "help" in violation, "Violation should have help"
assert "help_url" in violation, "Violation should have help_url"
assert "tags" in violation, "Violation should have tags"
# Verify WCAG 2.1 AA tags are present
tags = violation.get("tags", [])
assert any(tag in tags for tag in ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"]), \
"Violation should have WCAG 2.1 AA tags"
# Verify impact is one of the expected values
impact = violation.get("impact")
assert impact in ["critical", "serious", "moderate", "minor"], \
"Impact should be critical/serious/moderate/minor, got " + str(impact)
@pytest.mark.accessibility
def test_accessibility_graceful_degradation(
self, authenticated_page, accessibility_checker
):
"""Verify accessibility tests handle axe-core load failures gracefully.
If axe-core fails to load due to network issues or CDN problems,
the test should skip rather than fail with a cryptic error.
Args:
authenticated_page: Authenticated page fixture
accessibility_checker: Accessibility checker fixture with axe-core
"""
base_url = "http://localhost:3001"
dashboard_url = base_url + "/dashboard"
try:
authenticated_page.goto(dashboard_url)
authenticated_page.wait_for_load_state("domcontentloaded")
# Run accessibility audit
violations = accessibility_checker()
# If we got here, axe-core loaded successfully
# Verify violations is a list
assert isinstance(violations, list), "Violations should be a list"
except Exception as e:
# Check if error is related to axe-core loading
error_msg = str(e).lower()
if "axe-core" in error_msg or "axe" in error_msg:
# Skip test if axe-core failed to load (network issue, CDN down, etc.)
pytest.skip("axe-core failed to load: " + str(e))
else:
# Re-raise if it's a different error
raise
|