-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_accessibility.py
More file actions
194 lines (152 loc) · 6.9 KB
/
test_accessibility.py
File metadata and controls
194 lines (152 loc) · 6.9 KB
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
"""
Tests for the accessibility plugin.
Tests the real accessibility hook with an actual URL to verify
accessibility tree and page outline extraction.
"""
import json
import shutil
import subprocess
import tempfile
from pathlib import Path
import pytest
pytestmark = pytest.mark.usefixtures("ensure_chrome_test_prereqs")
from abx_plugins.plugins.chrome.tests.chrome_test_helpers import (
chrome_session,
get_test_env,
get_plugin_dir,
get_hook_script,
)
def chrome_available() -> bool:
"""Check if Chrome/Chromium is available."""
for name in ['chromium', 'chromium-browser', 'google-chrome', 'chrome']:
if shutil.which(name):
return True
return False
# Get the path to the accessibility hook
PLUGIN_DIR = get_plugin_dir(__file__)
ACCESSIBILITY_HOOK = get_hook_script(PLUGIN_DIR, 'on_Snapshot__*_accessibility.*')
class TestAccessibilityPlugin:
"""Test the accessibility plugin."""
def test_accessibility_hook_exists(self):
"""Accessibility hook script should exist."""
assert ACCESSIBILITY_HOOK is not None, "Accessibility hook not found in plugin directory"
assert ACCESSIBILITY_HOOK.exists(), f"Hook not found: {ACCESSIBILITY_HOOK}"
class TestAccessibilityWithChrome:
"""Integration tests for accessibility plugin with Chrome."""
def setup_method(self, _method=None):
"""Set up test environment."""
self.temp_dir = Path(tempfile.mkdtemp())
self.snap_dir = self.temp_dir / 'snap'
self.snap_dir.mkdir(parents=True, exist_ok=True)
def teardown_method(self, _method=None):
"""Clean up."""
shutil.rmtree(self.temp_dir, ignore_errors=True)
def test_accessibility_extracts_page_outline(self, chrome_test_url):
"""Accessibility hook should extract headings and accessibility tree."""
test_url = chrome_test_url
snapshot_id = 'test-accessibility-snapshot'
try:
with chrome_session(
self.temp_dir,
crawl_id='test-accessibility-crawl',
snapshot_id=snapshot_id,
test_url=test_url,
navigate=True,
timeout=30,
) as (chrome_process, chrome_pid, snapshot_chrome_dir, env):
# Use the environment from chrome_session (already has CHROME_HEADLESS=true)
# Run accessibility hook with the active Chrome session
result = subprocess.run(
['node', str(ACCESSIBILITY_HOOK), f'--url={test_url}', f'--snapshot-id={snapshot_id}'],
cwd=str(snapshot_chrome_dir),
capture_output=True,
text=True,
timeout=60,
env=env
)
# Check for output file
accessibility_output = Path(env['SNAP_DIR']) / 'accessibility' / 'accessibility.json'
accessibility_data = None
# Try parsing from file first
if accessibility_output.exists():
with open(accessibility_output) as f:
try:
accessibility_data = json.load(f)
except json.JSONDecodeError:
pass
# Verify hook ran successfully
assert result.returncode == 0, f"Hook failed: {result.stderr}"
assert 'Traceback' not in result.stderr
# example.com has headings, so we should get accessibility data
assert accessibility_data is not None, "No accessibility data was generated"
# Verify we got page outline data
assert 'headings' in accessibility_data, f"Missing headings: {accessibility_data}"
assert 'url' in accessibility_data, f"Missing url: {accessibility_data}"
except RuntimeError:
raise
def test_accessibility_disabled_skips(self, chrome_test_url):
"""Test that ACCESSIBILITY_ENABLED=False skips without error."""
test_url = chrome_test_url
snapshot_id = 'test-disabled'
env = get_test_env() | {'SNAP_DIR': str(self.snap_dir)}
env['ACCESSIBILITY_ENABLED'] = 'False'
result = subprocess.run(
['node', str(ACCESSIBILITY_HOOK), f'--url={test_url}', f'--snapshot-id={snapshot_id}'],
cwd=str(self.temp_dir),
capture_output=True,
text=True,
timeout=30,
env=env
)
# Should exit 0 even when disabled
assert result.returncode == 0, f"Should succeed when disabled: {result.stderr}"
# Should NOT create output file when disabled
accessibility_output = self.snap_dir / 'accessibility' / 'accessibility.json'
assert not accessibility_output.exists(), "Should not create file when disabled"
def test_accessibility_missing_url_argument(self):
"""Test that missing --url argument causes error."""
snapshot_id = 'test-missing-url'
result = subprocess.run(
['node', str(ACCESSIBILITY_HOOK), f'--snapshot-id={snapshot_id}'],
cwd=str(self.temp_dir),
capture_output=True,
text=True,
timeout=30,
env=get_test_env() | {'SNAP_DIR': str(self.snap_dir)}
)
# Should fail with non-zero exit code
assert result.returncode != 0, "Should fail when URL missing"
def test_accessibility_missing_snapshot_id_argument(self, chrome_test_url):
"""Test that missing --snapshot-id argument causes error."""
test_url = chrome_test_url
result = subprocess.run(
['node', str(ACCESSIBILITY_HOOK), f'--url={test_url}'],
cwd=str(self.temp_dir),
capture_output=True,
text=True,
timeout=30,
env=get_test_env() | {'SNAP_DIR': str(self.snap_dir)}
)
# Should fail with non-zero exit code
assert result.returncode != 0, "Should fail when snapshot-id missing"
def test_accessibility_with_no_chrome_session(self, chrome_test_url):
"""Test that hook fails gracefully when no Chrome session exists."""
test_url = chrome_test_url
snapshot_id = 'test-no-chrome'
result = subprocess.run(
['node', str(ACCESSIBILITY_HOOK), f'--url={test_url}', f'--snapshot-id={snapshot_id}'],
cwd=str(self.temp_dir),
capture_output=True,
text=True,
timeout=30,
env=get_test_env()
)
# Should fail when no Chrome session
assert result.returncode != 0, "Should fail when no Chrome session exists"
# Error should mention CDP or Chrome
err_lower = result.stderr.lower()
assert any(
x in err_lower for x in ['chrome', 'cdp', 'cannot find', 'puppeteer']
), f"Should mention Chrome/CDP in error: {result.stderr}"
if __name__ == '__main__':
pytest.main([__file__, '-v'])