qa-agent 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. qa_agent-0.1.0/PKG-INFO +468 -0
  2. qa_agent-0.1.0/README.md +429 -0
  3. qa_agent-0.1.0/pyproject.toml +78 -0
  4. qa_agent-0.1.0/qa_agent/__init__.py +14 -0
  5. qa_agent-0.1.0/qa_agent/__main__.py +22 -0
  6. qa_agent-0.1.0/qa_agent/agent.py +532 -0
  7. qa_agent-0.1.0/qa_agent/ai_planner.py +302 -0
  8. qa_agent-0.1.0/qa_agent/cli.py +412 -0
  9. qa_agent-0.1.0/qa_agent/config.py +98 -0
  10. qa_agent-0.1.0/qa_agent/models.py +259 -0
  11. qa_agent-0.1.0/qa_agent/plan_cache.py +132 -0
  12. qa_agent-0.1.0/qa_agent/reporters/__init__.py +8 -0
  13. qa_agent-0.1.0/qa_agent/reporters/base.py +43 -0
  14. qa_agent-0.1.0/qa_agent/reporters/console.py +166 -0
  15. qa_agent-0.1.0/qa_agent/reporters/json_reporter.py +78 -0
  16. qa_agent-0.1.0/qa_agent/reporters/markdown.py +226 -0
  17. qa_agent-0.1.0/qa_agent/reporters/pdf.py +430 -0
  18. qa_agent-0.1.0/qa_agent/testers/__init__.py +19 -0
  19. qa_agent-0.1.0/qa_agent/testers/accessibility.py +629 -0
  20. qa_agent-0.1.0/qa_agent/testers/base.py +70 -0
  21. qa_agent-0.1.0/qa_agent/testers/custom.py +220 -0
  22. qa_agent-0.1.0/qa_agent/testers/errors.py +382 -0
  23. qa_agent-0.1.0/qa_agent/testers/forms.py +505 -0
  24. qa_agent-0.1.0/qa_agent/testers/keyboard.py +400 -0
  25. qa_agent-0.1.0/qa_agent/testers/mouse.py +387 -0
  26. qa_agent-0.1.0/qa_agent/testers/wcag_compliance.py +1165 -0
  27. qa_agent-0.1.0/qa_agent/web/__init__.py +0 -0
  28. qa_agent-0.1.0/qa_agent/web/server.py +654 -0
  29. qa_agent-0.1.0/qa_agent.egg-info/PKG-INFO +468 -0
  30. qa_agent-0.1.0/qa_agent.egg-info/SOURCES.txt +33 -0
  31. qa_agent-0.1.0/qa_agent.egg-info/dependency_links.txt +1 -0
  32. qa_agent-0.1.0/qa_agent.egg-info/entry_points.txt +3 -0
  33. qa_agent-0.1.0/qa_agent.egg-info/requires.txt +19 -0
  34. qa_agent-0.1.0/qa_agent.egg-info/top_level.txt +3 -0
  35. qa_agent-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,468 @@
1
+ Metadata-Version: 2.4
2
+ Name: qa-agent
3
+ Version: 0.1.0
4
+ Summary: Agentic exploratory QA testing for web applications
5
+ Author: Bill Richards
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/billrichards/qa-agent
8
+ Project-URL: Repository, https://github.com/billrichards/qa-agent
9
+ Project-URL: Issues, https://github.com/billrichards/qa-agent/issues
10
+ Project-URL: Changelog, https://github.com/billrichards/qa-agent/blob/main/CHANGELOG.md
11
+ Keywords: qa,testing,playwright,accessibility,agentic,automation,exploratory-testing
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Testing
20
+ Classifier: Environment :: Console
21
+ Classifier: Environment :: Web Environment
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ Requires-Dist: playwright>=1.40.0
25
+ Requires-Dist: anthropic>=0.50.0
26
+ Provides-Extra: pdf
27
+ Requires-Dist: weasyprint>=60.0; extra == "pdf"
28
+ Provides-Extra: web
29
+ Requires-Dist: flask>=3.0; extra == "web"
30
+ Requires-Dist: markdown>=3.5; extra == "web"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
33
+ Requires-Dist: pytest-playwright>=0.4.0; extra == "dev"
34
+ Requires-Dist: black>=23.0.0; extra == "dev"
35
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
36
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
37
+ Provides-Extra: all
38
+ Requires-Dist: qa-agent[pdf,web]; extra == "all"
39
+
40
+ # QA Agent
41
+
42
+ Automated exploratory QA testing for web applications. Simulates real user interactions (mouse, keyboard, form input, accessibility checks) and optionally uses Claude to generate custom test steps from plain-English instructions.
43
+
44
+ ![console output showing a test run in progress](./docs/console-output-showing-a-test-run-in-progress.png)
45
+
46
+ ---
47
+
48
+ ## Table of Contents
49
+
50
+ - [Features](#features)
51
+ - [Installation](#installation)
52
+ - [Quick Start](#quick-start)
53
+ - [Agentic Testing](#agentic-testing)
54
+ - [Web Interface](#web-interface)
55
+ - [CLI Reference](#cli-reference)
56
+ - [Programmatic Usage](#programmatic-usage)
57
+ - [Test Categories](#test-categories)
58
+ - [Output Formats](#output-formats)
59
+ - [CI/CD Integration](#cicd-integration)
60
+ - [Architecture](#architecture)
61
+ - [Exit Codes](#exit-codes)
62
+
63
+ ---
64
+
65
+ ## Features
66
+
67
+ | Category | What it does |
68
+ |---|---|
69
+ | **Agentic testing** | Give Claude a bug report or feature spec; it generates custom Playwright test steps automatically |
70
+ | **Two modes** | `focused` tests only given URLs; `explore` crawls and discovers additional pages |
71
+ | **Six test suites** | Keyboard nav, mouse interaction, form handling, accessibility (WCAG), WCAG 2.1 AA compliance (opt-in), error detection |
72
+ | **Auth support** | Username/password, cookies, Bearer tokens, custom headers |
73
+ | **Four output formats** | Console, Markdown, JSON, PDF |
74
+ | **Screenshots & video** | On-error or every-interaction screenshots; full session video recording |
75
+ | **Web UI** | Browser-based dashboard for launching runs, watching live output, and browsing past sessions |
76
+
77
+ ---
78
+
79
+ ## Installation
80
+
81
+ ```bash
82
+ # Core install
83
+ pip install qa-agent
84
+ playwright install chromium
85
+
86
+ # PDF report support
87
+ pip install "qa-agent[pdf]"
88
+
89
+ # Web UI support
90
+ pip install "qa-agent[web]"
91
+
92
+ # Everything
93
+ pip install "qa-agent[all]"
94
+ playwright install chromium
95
+ ```
96
+
97
+ **Requirements:** Python 3.10+, Playwright ≥ 1.40
98
+
99
+ > **Note:** Playwright requires browser binaries installed separately after the Python package.
100
+ > Run `playwright install chromium` (or `playwright install` for all browsers) once after install.
101
+
102
+ **Agentic testing** requires an Anthropic API key:
103
+
104
+ ```bash
105
+ export ANTHROPIC_API_KEY=sk-ant-...
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Quick Start
111
+
112
+ ```bash
113
+ # Test a single URL
114
+ qa-agent https://example.com
115
+
116
+ # Test multiple URLs
117
+ qa-agent https://example.com https://example.com/about
118
+
119
+ # Crawl and test discovered pages (depth 2, up to 20 pages)
120
+ qa-agent --mode explore --max-depth 2 https://example.com
121
+
122
+ # Generate JSON + Markdown reports
123
+ qa-agent --output json,markdown https://example.com
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Agentic Testing
129
+
130
+ Pass natural-language instructions and Claude generates custom test steps that run alongside the standard suite.
131
+
132
+ ```bash
133
+ # From a bug report
134
+ qa-agent --instructions "The login button does nothing when email is blank — no validation error is shown" \
135
+ https://example.com/login
136
+
137
+ # From a feature description
138
+ qa-agent --instructions "We added a 'Remember me' checkbox to the login form. \
139
+ It should persist the session across browser restarts and be unchecked by default." \
140
+ https://example.com/login
141
+
142
+ # From a file (for longer specs)
143
+ qa-agent --instructions-file feature-spec.txt https://example.com
144
+ ```
145
+
146
+ ### What happens
147
+
148
+ 1. Before any browser testing, Claude receives your instructions and the target URL.
149
+ 2. Claude returns a structured plan: summary, focus areas, custom Playwright test steps, and suggested URLs.
150
+ 3. The agent prints the plan, then runs those custom steps on every tested page alongside the five standard suites.
151
+ 4. Assertion failures become findings in the report with the severity and category Claude assigned.
152
+
153
+ If the API call fails, a warning is printed and the run continues with standard tests only.
154
+
155
+ ### Model & caching
156
+
157
+ ```bash
158
+ # Use a different model (default: claude-sonnet-4-6)
159
+ qa-agent --ai-model claude-opus-4-6 --instructions "Test checkout" https://shop.example.com
160
+
161
+ # Bypass the plan cache and always call the API
162
+ qa-agent --no-cache --instructions "..." https://example.com
163
+ ```
164
+
165
+ Generated test plans are cached by default; rerunning with the same instructions and URL reuses the cached plan.
166
+
167
+ ---
168
+
169
+ ## Web Interface
170
+
171
+ ![Web interface configuration form](./docs/web-UI-configuration-form.png)
172
+
173
+ A browser-based dashboard for configuring and monitoring runs.
174
+
175
+ ```bash
176
+ # Start the server (opens at http://127.0.0.1:5000)
177
+ python -m qa_agent web
178
+ # or
179
+ qa-agent-web
180
+
181
+ # Custom host/port
182
+ qa-agent-web --host 0.0.0.0 --port 8080
183
+ ```
184
+
185
+ **Features:**
186
+ - Configuration form with all options (collapsible sections, preset save/load)
187
+ - Real-time streaming output via Server-Sent Events
188
+ - Stop a running test mid-run
189
+ - Browse past sessions grouped by domain
190
+ - Session detail: findings table, severity breakdown, screenshot gallery, report downloads
191
+
192
+ ![Session detail view showing findings table](./docs/session-detail-view-showing-findings-table.png)
193
+
194
+ > The web interface has no authentication — intended for local or internal use only.
195
+
196
+ All output is written to `output/` in the project directory. CLI sessions are also visible in the web UI as long as JSON output format was used.
197
+
198
+ ---
199
+
200
+ ## CLI Reference
201
+
202
+ ### Modes
203
+
204
+ ```bash
205
+ qa-agent --mode focused https://example.com # default: test only given URLs
206
+ qa-agent --mode explore https://example.com # crawl and test discovered pages
207
+ ```
208
+
209
+ ### Exploration options (explore mode)
210
+
211
+ | Flag | Default | Description |
212
+ |---|---|---|
213
+ | `--max-depth N` | `3` | Max link depth to follow |
214
+ | `--max-pages N` | `20` | Max pages to test |
215
+ | `--allow-external` | off | Follow links to other domains |
216
+ | `--ignore PATTERN` | — | Regex pattern(s) for URLs to skip (repeatable) |
217
+
218
+ ### Authentication
219
+
220
+ ```bash
221
+ # Username/password with login URL
222
+ qa-agent --auth "username:password@https://example.com/login" https://example.com/dashboard
223
+
224
+ # JSON auth file
225
+ qa-agent --auth-file auth.json https://example.com
226
+
227
+ # Pre-set cookies
228
+ qa-agent --cookies cookies.json https://example.com
229
+
230
+ # Custom header (repeatable)
231
+ qa-agent --header "Authorization: Bearer token123" https://example.com
232
+ ```
233
+
234
+ **auth.json schema:**
235
+ ```json
236
+ {
237
+ "username": "testuser",
238
+ "password": "testpass",
239
+ "auth_url": "https://example.com/login",
240
+ "username_selector": "input#email",
241
+ "password_selector": "input#password",
242
+ "submit_selector": "button[type=submit]"
243
+ }
244
+ ```
245
+
246
+ ### Output
247
+
248
+ ```bash
249
+ # Formats: console, markdown, json, pdf (comma-separated, default: console,markdown)
250
+ qa-agent --output console,markdown,json,pdf https://example.com
251
+
252
+ # Custom output directory (default: <project-root>/output)
253
+ qa-agent --output-dir ./reports https://example.com
254
+ ```
255
+
256
+ Output is organized as `output/{domain}/{session_id}/qa_reports|screenshots|recordings`.
257
+
258
+ > PDF requires `weasyprint`. Install with `pip install "qa-agent[pdf]"`. Falls back to Markdown if not installed.
259
+
260
+ ### Screenshots & recording
261
+
262
+ ```bash
263
+ qa-agent --screenshots https://example.com # capture on errors
264
+ qa-agent --screenshots-all https://example.com # capture after every interaction
265
+ qa-agent --full-page https://example.com # full-page screenshots
266
+ qa-agent --record https://example.com # record session video
267
+ ```
268
+
269
+ ### Browser options
270
+
271
+ ```bash
272
+ qa-agent --no-headless # visible browser window
273
+ qa-agent --viewport 1920x1080 # custom viewport (default: 1280x720)
274
+ qa-agent --timeout 60000 # timeout in ms (default: 30000)
275
+ ```
276
+
277
+ ### Test category flags
278
+
279
+ ```bash
280
+ # Skip standard suites
281
+ qa-agent --skip-keyboard https://example.com
282
+ qa-agent --skip-mouse https://example.com
283
+ qa-agent --skip-forms https://example.com
284
+ qa-agent --skip-accessibility https://example.com
285
+ qa-agent --skip-errors https://example.com
286
+
287
+ # Enable opt-in suites
288
+ qa-agent --wcag-compliance https://example.com # detailed WCAG 2.1 AA audit
289
+ ```
290
+
291
+ ---
292
+
293
+ ## Programmatic Usage
294
+
295
+ ```python
296
+ from qa_agent import QAAgent, TestConfig, TestMode, OutputFormat
297
+
298
+ config = TestConfig(
299
+ urls=["https://example.com"],
300
+ mode=TestMode.EXPLORE,
301
+ output_formats=[OutputFormat.CONSOLE, OutputFormat.JSON, OutputFormat.PDF],
302
+ max_depth=2,
303
+ max_pages=10,
304
+ # Optional: agentic testing
305
+ instructions="Verify the password reset flow sends an email and the link expires after 24 hours.",
306
+ ai_model="claude-opus-4-6",
307
+ )
308
+
309
+ agent = QAAgent(config)
310
+ session = agent.run()
311
+
312
+ print(f"Pages tested: {len(session.pages)}")
313
+ print(f"Total findings: {session.total_findings}")
314
+
315
+ for finding in session.get_all_findings():
316
+ print(f" [{finding.severity.value.upper()}] {finding.title}")
317
+ ```
318
+
319
+ ---
320
+
321
+ ## Test Categories
322
+
323
+ ### Keyboard Navigation
324
+ TAB order and focusability · Arrow key navigation in widgets · Enter key activation · Escape key for closing modals · Keyboard trap detection · Focus visibility indicators
325
+
326
+ ### Mouse Interaction
327
+ Click target functionality · Hover states · Double-click behavior · Right-click/context menus · Click target sizes (WCAG 2.5.5 minimum 44×44 px) · Overlapping element detection
328
+
329
+ ### Form Handling
330
+ Required field indicators · Input validation feedback · Error message accessibility · Label associations · HTML5 input types · Autocomplete attributes
331
+
332
+ ### Accessibility (WCAG)
333
+ Image alt text · Heading structure (h1–h6) · Link text quality · Color contrast · ARIA usage · Landmark regions · Language attributes · Skip navigation links
334
+
335
+ ### Error Detection
336
+ Console errors and warnings · Network errors (4xx, 5xx) · JavaScript exceptions · Broken images · Broken anchor links · Mixed content (HTTP on HTTPS)
337
+
338
+ ### WCAG 2.1 AA Compliance (opt-in: `--wcag-compliance`)
339
+ Covers WCAG criteria not already in the standard accessibility suite: non-text contrast (1.4.11) · use of color (1.4.1) · content on hover/focus (1.4.13) · meaningful sequence (1.3.2) · input purpose (1.3.5) · focus visible (2.4.7) · label in name (2.5.3) · target size (2.5.5) · language of parts (3.1.2) · error identification (3.3.1) · detailed ARIA role/property validation
340
+
341
+ ---
342
+
343
+ ## Output Formats
344
+
345
+ ### Console
346
+
347
+ ![./docs/colorized-console-output-with-summary-table.png](./docs/colorized-console-output-with-summary-table.png)
348
+
349
+ ```
350
+ ======================================================================
351
+ QA AGENT TEST REPORT
352
+ ======================================================================
353
+ Session ID: a1b2c3d4
354
+ Started: 2024-01-15 10:30:00
355
+ Duration: 45.2 seconds
356
+ Mode: explore
357
+ ======================================================================
358
+
359
+ SUMMARY
360
+ Pages tested: 5
361
+ Total findings: 12
362
+
363
+ By Severity:
364
+ HIGH: 2
365
+ MEDIUM: 5
366
+ LOW: 5
367
+ ```
368
+
369
+ ### JSON
370
+
371
+ ```json
372
+ {
373
+ "meta": {
374
+ "session_id": "a1b2c3d4",
375
+ "start_time": "2024-01-15T10:30:00",
376
+ "duration_seconds": 45.2
377
+ },
378
+ "summary": {
379
+ "pages_tested": 5,
380
+ "total_findings": 12,
381
+ "findings_by_severity": { "high": 2, "medium": 5, "low": 5 }
382
+ },
383
+ "findings": [...]
384
+ }
385
+ ```
386
+
387
+ ### Severity levels
388
+
389
+ | Level | Meaning |
390
+ |---|---|
391
+ | `CRITICAL` | Security issues, data loss |
392
+ | `HIGH` | Major usability blockers |
393
+ | `MEDIUM` | UX problems, accessibility issues |
394
+ | `LOW` | Minor improvements, best practices |
395
+ | `INFO` | Informational findings |
396
+
397
+ ---
398
+
399
+ ## CI/CD Integration
400
+
401
+ ```yaml
402
+ # GitHub Actions example
403
+ - name: Run QA Tests
404
+ env:
405
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
406
+ run: |
407
+ pip install qa-agent
408
+ playwright install chromium
409
+ qa-agent --output json --output-dir ./qa-results https://staging.example.com
410
+
411
+ - name: Upload Results
412
+ uses: actions/upload-artifact@v3
413
+ with:
414
+ name: qa-results
415
+ path: ./qa-results/
416
+ ```
417
+
418
+ The process exits with code `1` when critical or high severity issues are found, failing the CI step automatically.
419
+
420
+ ---
421
+
422
+ ## Architecture
423
+
424
+ ```
425
+ qa_agent/
426
+ ├── cli.py # Argument parsing, entry point
427
+ ├── agent.py # Core orchestrator
428
+ ├── config.py # TestConfig, AuthConfig, ScreenshotConfig, RecordingConfig
429
+ ├── models.py # Finding, PageAnalysis, TestSession
430
+ ├── ai_planner.py # Claude integration (plan generation & caching)
431
+ ├── plan_cache.py # Plan cache persistence
432
+ ├── testers/
433
+ │ ├── keyboard.py # Keyboard navigation tests
434
+ │ ├── mouse.py # Mouse interaction tests
435
+ │ ├── forms.py # Form handling tests
436
+ │ ├── accessibility.py # WCAG / accessibility tests
437
+ │ ├── wcag_compliance.py # Detailed WCAG 2.1 AA compliance (opt-in)
438
+ │ └── errors.py # Console & network error detection
439
+ └── reporters/
440
+ ├── console.py # Real-time colored output
441
+ ├── markdown.py # Markdown report
442
+ ├── json_reporter.py # JSON report
443
+ └── pdf.py # PDF report (requires weasyprint)
444
+ ```
445
+
446
+ ### Adding a custom tester
447
+
448
+ 1. Create `testers/my_tester.py` extending `BaseTester`, implement `run() -> list[Finding]`
449
+ 2. Export it from `testers/__init__.py`
450
+ 3. Add a `test_my_feature: bool = True` flag to `TestConfig` in `config.py`
451
+ 4. Call it from `agent.py` in `_test_page()`
452
+
453
+ ---
454
+
455
+ ## Exit Codes
456
+
457
+ | Code | Meaning |
458
+ |---|---|
459
+ | `0` | All tests passed (no critical/high findings) |
460
+ | `1` | Critical or high severity issues found |
461
+ | `2` | Error running tests |
462
+ | `130` | Interrupted by user (Ctrl+C) |
463
+
464
+ ---
465
+
466
+ ## License
467
+
468
+ MIT