altqa-cli 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.
- altqa_cli-0.1.0/.gitignore +34 -0
- altqa_cli-0.1.0/LICENSE +21 -0
- altqa_cli-0.1.0/PKG-INFO +206 -0
- altqa_cli-0.1.0/README.md +170 -0
- altqa_cli-0.1.0/pyproject.toml +63 -0
- altqa_cli-0.1.0/src/altqa/__init__.py +3 -0
- altqa_cli-0.1.0/src/altqa/agents/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/agents/accessibility_auditor.py +125 -0
- altqa_cli-0.1.0/src/altqa/agents/assertion_interpreter.py +145 -0
- altqa_cli-0.1.0/src/altqa/agents/data_generator.py +184 -0
- altqa_cli-0.1.0/src/altqa/agents/failure_analyzer.py +180 -0
- altqa_cli-0.1.0/src/altqa/agents/flow_generator.py +147 -0
- altqa_cli-0.1.0/src/altqa/agents/natural_test.py +124 -0
- altqa_cli-0.1.0/src/altqa/agents/prompts/accessibility_audit.md +42 -0
- altqa_cli-0.1.0/src/altqa/agents/prompts/analyze_failure.md +44 -0
- altqa_cli-0.1.0/src/altqa/agents/prompts/analyze_ticket.md +28 -0
- altqa_cli-0.1.0/src/altqa/agents/prompts/generate_flows.md +52 -0
- altqa_cli-0.1.0/src/altqa/agents/prompts/interpret_test_case.md +53 -0
- altqa_cli-0.1.0/src/altqa/agents/prompts/natural_test.md +61 -0
- altqa_cli-0.1.0/src/altqa/agents/prompts/visual_review.md +38 -0
- altqa_cli-0.1.0/src/altqa/agents/root_cause_analyzer.py +198 -0
- altqa_cli-0.1.0/src/altqa/agents/selector_healer.py +104 -0
- altqa_cli-0.1.0/src/altqa/agents/test_case_interpreter.py +232 -0
- altqa_cli-0.1.0/src/altqa/agents/ticket_analyzer.py +120 -0
- altqa_cli-0.1.0/src/altqa/agents/visual_reviewer.py +135 -0
- altqa_cli-0.1.0/src/altqa/browser/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/browser/actions.py +277 -0
- altqa_cli-0.1.0/src/altqa/browser/health.py +362 -0
- altqa_cli-0.1.0/src/altqa/browser/manager.py +141 -0
- altqa_cli-0.1.0/src/altqa/browser/network.py +172 -0
- altqa_cli-0.1.0/src/altqa/browser/session.py +60 -0
- altqa_cli-0.1.0/src/altqa/cli/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/cli/audit_cmd.py +128 -0
- altqa_cli-0.1.0/src/altqa/cli/chat_cmd.py +182 -0
- altqa_cli-0.1.0/src/altqa/cli/config_cmd.py +56 -0
- altqa_cli-0.1.0/src/altqa/cli/crawl_cmd.py +122 -0
- altqa_cli-0.1.0/src/altqa/cli/flow_cmd.py +263 -0
- altqa_cli-0.1.0/src/altqa/cli/init_cmd.py +238 -0
- altqa_cli-0.1.0/src/altqa/cli/jira_cmd.py +213 -0
- altqa_cli-0.1.0/src/altqa/cli/main.py +224 -0
- altqa_cli-0.1.0/src/altqa/cli/run_cmd.py +418 -0
- altqa_cli-0.1.0/src/altqa/cli/test_cmd.py +185 -0
- altqa_cli-0.1.0/src/altqa/config/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/config/manager.py +40 -0
- altqa_cli-0.1.0/src/altqa/config/models.py +45 -0
- altqa_cli-0.1.0/src/altqa/config/schema.py +51 -0
- altqa_cli-0.1.0/src/altqa/crawler/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/crawler/crawler.py +173 -0
- altqa_cli-0.1.0/src/altqa/crawler/graph.py +168 -0
- altqa_cli-0.1.0/src/altqa/crawler/page_analyzer.py +142 -0
- altqa_cli-0.1.0/src/altqa/flows/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/flows/assertions.py +133 -0
- altqa_cli-0.1.0/src/altqa/flows/generator.py +170 -0
- altqa_cli-0.1.0/src/altqa/flows/parser.py +180 -0
- altqa_cli-0.1.0/src/altqa/flows/runner.py +228 -0
- altqa_cli-0.1.0/src/altqa/flows/variables.py +72 -0
- altqa_cli-0.1.0/src/altqa/jira/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/jira/agent.py +212 -0
- altqa_cli-0.1.0/src/altqa/jira/attachments.py +76 -0
- altqa_cli-0.1.0/src/altqa/jira/bug_reporter.py +254 -0
- altqa_cli-0.1.0/src/altqa/jira/test_case_parser.py +195 -0
- altqa_cli-0.1.0/src/altqa/jira/ticket_parser.py +100 -0
- altqa_cli-0.1.0/src/altqa/pipeline/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/pipeline/orchestrator.py +353 -0
- altqa_cli-0.1.0/src/altqa/pipeline/result.py +107 -0
- altqa_cli-0.1.0/src/altqa/utils/__init__.py +0 -0
- altqa_cli-0.1.0/src/altqa/utils/cleanup.py +25 -0
- altqa_cli-0.1.0/src/altqa/utils/logger.py +53 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
*.egg
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
*.whl
|
|
9
|
+
|
|
10
|
+
# Virtual env
|
|
11
|
+
.venv/
|
|
12
|
+
venv/
|
|
13
|
+
env/
|
|
14
|
+
|
|
15
|
+
# AltQA runtime artifacts
|
|
16
|
+
logs/
|
|
17
|
+
*.png
|
|
18
|
+
altqa.json
|
|
19
|
+
|
|
20
|
+
# IDE
|
|
21
|
+
.vscode/
|
|
22
|
+
.idea/
|
|
23
|
+
*.swp
|
|
24
|
+
*.swo
|
|
25
|
+
.cursor/
|
|
26
|
+
|
|
27
|
+
# OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
|
|
31
|
+
# Testing
|
|
32
|
+
.pytest_cache/
|
|
33
|
+
htmlcov/
|
|
34
|
+
.coverage
|
altqa_cli-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rohit Jangral
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
altqa_cli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: altqa-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-powered QA automation CLI — tests your app from Jira tickets, reports bugs back automatically
|
|
5
|
+
Project-URL: Homepage, https://gitlab.com/rohithyphen05/altqa
|
|
6
|
+
Project-URL: Repository, https://gitlab.com/rohithyphen05/altqa
|
|
7
|
+
Project-URL: Issues, https://gitlab.com/rohithyphen05/altqa/-/issues
|
|
8
|
+
Author-email: Rohit Jangral <rohitnishantjangral@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,automation,cli,jira,playwright,qa,testing
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
21
|
+
Classifier: Topic :: Software Development :: Testing
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: agno>=2.0
|
|
25
|
+
Requires-Dist: anthropic>=0.20
|
|
26
|
+
Requires-Dist: httpx>=0.25
|
|
27
|
+
Requires-Dist: jira>=3.5
|
|
28
|
+
Requires-Dist: openai>=1.10
|
|
29
|
+
Requires-Dist: openpyxl>=3.1
|
|
30
|
+
Requires-Dist: playwright>=1.40
|
|
31
|
+
Requires-Dist: pydantic>=2.0
|
|
32
|
+
Requires-Dist: pyyaml>=6.0
|
|
33
|
+
Requires-Dist: rich>=13.0
|
|
34
|
+
Requires-Dist: typer>=0.9
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# AltQA
|
|
38
|
+
|
|
39
|
+
**AI-powered QA automation from your terminal.** AltQA reads Jira tickets, runs browser tests, detects bugs, and reports them back to Jira — like having an autonomous QA engineer on your team.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
pip install altqa # or: uv pip install altqa
|
|
43
|
+
altqa init # one-time setup (asks for keys, crawls your app)
|
|
44
|
+
altqa run JIRA-123 # test a ticket end-to-end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## How It Works
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
altqa run PROJ-42
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
1. Fetches the Jira ticket
|
|
56
|
+
2. Checks for attached test case files (Excel/CSV) — **these always take priority**
|
|
57
|
+
3. If no test cases attached, falls back to AI analysis of the ticket description
|
|
58
|
+
4. AI converts test cases into executable browser flows
|
|
59
|
+
5. Launches a real browser and runs every step
|
|
60
|
+
6. Monitors for console errors, API failures, JS exceptions, and memory leaks
|
|
61
|
+
7. Analyses failures with AI and generates detailed bug reports
|
|
62
|
+
8. Creates sub-task bug tickets on Jira with screenshots as proof
|
|
63
|
+
9. Cleans up screenshots from your project after upload
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
**Requirements:** Python 3.11+
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# With pip
|
|
73
|
+
pip install altqa
|
|
74
|
+
|
|
75
|
+
# With uv (recommended)
|
|
76
|
+
uv pip install altqa
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Then initialize in your project directory:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cd your-project/
|
|
83
|
+
altqa init
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The wizard will:
|
|
87
|
+
1. Ask for your app URL (e.g. `http://localhost:3000`)
|
|
88
|
+
2. Ask for LLM provider & API key (OpenAI, Anthropic, or Ollama for local)
|
|
89
|
+
3. Ask for Jira credentials (base URL, project key, email, API token)
|
|
90
|
+
4. Ask for browser preference (Chromium, Firefox, or WebKit)
|
|
91
|
+
5. Install the Playwright browser binary automatically
|
|
92
|
+
6. Crawl your application and build a navigation graph
|
|
93
|
+
7. Auto-generate starter test flows from discovered pages
|
|
94
|
+
|
|
95
|
+
After init, you just run `altqa run JIRA-123` — that's it.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Commands
|
|
100
|
+
|
|
101
|
+
| Command | Description |
|
|
102
|
+
|---|---|
|
|
103
|
+
| `altqa init` | Interactive setup wizard |
|
|
104
|
+
| `altqa run JIRA-123` | Full pipeline: fetch ticket, test, report bugs |
|
|
105
|
+
| `altqa run JIRA-123 --dry-run` | Show the test plan without executing |
|
|
106
|
+
| `altqa run-local file.xlsx` | Run tests from local Excel/CSV files (no Jira) |
|
|
107
|
+
| `altqa crawl` | Discover app routes and build navigation graph |
|
|
108
|
+
| `altqa run-flow login` | Execute a specific YAML test flow |
|
|
109
|
+
| `altqa flows list` | List all available flows |
|
|
110
|
+
| `altqa generate-flows` | Auto-generate YAML flows from the navigation graph |
|
|
111
|
+
| `altqa generate-flows --ai` | AI-powered flow generation (happy paths + edge cases) |
|
|
112
|
+
| `altqa test "login and add a product"` | Generate and run a test from plain English |
|
|
113
|
+
| `altqa chat` | Interactive AI QA session (REPL) |
|
|
114
|
+
| `altqa audit` | AI accessibility audit (WCAG compliance) |
|
|
115
|
+
| `altqa config show` | Display current configuration |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## AI-Powered Features
|
|
120
|
+
|
|
121
|
+
### Core Pipeline
|
|
122
|
+
- **Jira-aware testing** — reads ticket descriptions and attached test case files (Excel/CSV)
|
|
123
|
+
- **AI test interpretation** — converts human-written test steps into browser actions
|
|
124
|
+
- **AI failure analysis** — generates bug reports with root cause, fix suggestions, and regression tests
|
|
125
|
+
- **Automatic bug filing** — creates Jira sub-tasks with screenshots and detailed descriptions
|
|
126
|
+
|
|
127
|
+
### Runtime Health Monitoring
|
|
128
|
+
- Console errors and JS exceptions
|
|
129
|
+
- API failures and network errors
|
|
130
|
+
- Memory leaks and performance issues
|
|
131
|
+
- Page crashes and security warnings
|
|
132
|
+
|
|
133
|
+
### Advanced AI Features
|
|
134
|
+
- **Plain-text testing** — `altqa test "login with wrong password and verify error"`
|
|
135
|
+
- **Visual AI review** — screenshot analysis for UI/layout bugs using vision models
|
|
136
|
+
- **AI flow generation** — generates comprehensive test flows from your app's navigation graph
|
|
137
|
+
- **Smart selector healing** — auto-fixes broken CSS selectors when elements change
|
|
138
|
+
- **Conversational QA** — `altqa chat` for interactive testing sessions
|
|
139
|
+
- **AI test data generation** — realistic form data (valid, invalid, edge cases, security payloads)
|
|
140
|
+
- **Root cause clustering** — groups test failures by probable root cause
|
|
141
|
+
- **Accessibility audit** — WCAG compliance checking across your app
|
|
142
|
+
- **Enhanced bug descriptions** — AI-generated fix suggestions, user impact analysis, and regression tests
|
|
143
|
+
- **Natural language assertions** — write assertions in plain English in your YAML flows
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## YAML Test Flows
|
|
148
|
+
|
|
149
|
+
Define reusable test flows:
|
|
150
|
+
|
|
151
|
+
```yaml
|
|
152
|
+
name: login
|
|
153
|
+
description: Log in with valid credentials
|
|
154
|
+
steps:
|
|
155
|
+
- action: navigate
|
|
156
|
+
url: "{{app_url}}/login"
|
|
157
|
+
- action: fill
|
|
158
|
+
selector: "#username"
|
|
159
|
+
value: "{{username}}"
|
|
160
|
+
- action: fill
|
|
161
|
+
selector: "#password"
|
|
162
|
+
value: "{{password}}"
|
|
163
|
+
- action: click
|
|
164
|
+
selector: "button[type=submit]"
|
|
165
|
+
- action: wait_for
|
|
166
|
+
selector: ".dashboard"
|
|
167
|
+
assertions:
|
|
168
|
+
- type: url_contains
|
|
169
|
+
value: "/dashboard"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Supports variable interpolation (`{{var}}`), flow includes, and natural language assertions.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Architecture
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
CLI (Typer + Rich)
|
|
180
|
+
|
|
|
181
|
+
+-- Config (Pydantic schemas, altqa.json)
|
|
182
|
+
+-- AI Agents (Agno framework, multi-provider LLM)
|
|
183
|
+
+-- Flow Engine (YAML parser, variable resolver, assertions)
|
|
184
|
+
+-- Browser (Playwright — deterministic actions, not AI-controlled)
|
|
185
|
+
+-- Crawler (BFS discovery, navigation graph)
|
|
186
|
+
+-- Jira Integration (issue CRUD, attachments, comments)
|
|
187
|
+
+-- Pipeline Orchestrator (ties everything together)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Design principle:** Browser actions are deterministic (click, fill, navigate). AI handles *intelligence* — planning, analysis, and reporting. This avoids flaky, non-reproducible tests.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Supported LLM Providers
|
|
195
|
+
|
|
196
|
+
| Provider | Models | Notes |
|
|
197
|
+
|---|---|---|
|
|
198
|
+
| OpenAI | gpt-4o, gpt-4o-mini, o1, etc. | Best overall experience |
|
|
199
|
+
| Anthropic | claude-sonnet-4-20250514, claude-3.5-haiku, etc. | Great for analysis |
|
|
200
|
+
| Ollama | llama3, mistral, codellama, etc. | Fully local, no API key |
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
MIT
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# AltQA
|
|
2
|
+
|
|
3
|
+
**AI-powered QA automation from your terminal.** AltQA reads Jira tickets, runs browser tests, detects bugs, and reports them back to Jira — like having an autonomous QA engineer on your team.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
pip install altqa # or: uv pip install altqa
|
|
7
|
+
altqa init # one-time setup (asks for keys, crawls your app)
|
|
8
|
+
altqa run JIRA-123 # test a ticket end-to-end
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## How It Works
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
altqa run PROJ-42
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
1. Fetches the Jira ticket
|
|
20
|
+
2. Checks for attached test case files (Excel/CSV) — **these always take priority**
|
|
21
|
+
3. If no test cases attached, falls back to AI analysis of the ticket description
|
|
22
|
+
4. AI converts test cases into executable browser flows
|
|
23
|
+
5. Launches a real browser and runs every step
|
|
24
|
+
6. Monitors for console errors, API failures, JS exceptions, and memory leaks
|
|
25
|
+
7. Analyses failures with AI and generates detailed bug reports
|
|
26
|
+
8. Creates sub-task bug tickets on Jira with screenshots as proof
|
|
27
|
+
9. Cleans up screenshots from your project after upload
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
**Requirements:** Python 3.11+
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# With pip
|
|
37
|
+
pip install altqa
|
|
38
|
+
|
|
39
|
+
# With uv (recommended)
|
|
40
|
+
uv pip install altqa
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then initialize in your project directory:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cd your-project/
|
|
47
|
+
altqa init
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The wizard will:
|
|
51
|
+
1. Ask for your app URL (e.g. `http://localhost:3000`)
|
|
52
|
+
2. Ask for LLM provider & API key (OpenAI, Anthropic, or Ollama for local)
|
|
53
|
+
3. Ask for Jira credentials (base URL, project key, email, API token)
|
|
54
|
+
4. Ask for browser preference (Chromium, Firefox, or WebKit)
|
|
55
|
+
5. Install the Playwright browser binary automatically
|
|
56
|
+
6. Crawl your application and build a navigation graph
|
|
57
|
+
7. Auto-generate starter test flows from discovered pages
|
|
58
|
+
|
|
59
|
+
After init, you just run `altqa run JIRA-123` — that's it.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Commands
|
|
64
|
+
|
|
65
|
+
| Command | Description |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `altqa init` | Interactive setup wizard |
|
|
68
|
+
| `altqa run JIRA-123` | Full pipeline: fetch ticket, test, report bugs |
|
|
69
|
+
| `altqa run JIRA-123 --dry-run` | Show the test plan without executing |
|
|
70
|
+
| `altqa run-local file.xlsx` | Run tests from local Excel/CSV files (no Jira) |
|
|
71
|
+
| `altqa crawl` | Discover app routes and build navigation graph |
|
|
72
|
+
| `altqa run-flow login` | Execute a specific YAML test flow |
|
|
73
|
+
| `altqa flows list` | List all available flows |
|
|
74
|
+
| `altqa generate-flows` | Auto-generate YAML flows from the navigation graph |
|
|
75
|
+
| `altqa generate-flows --ai` | AI-powered flow generation (happy paths + edge cases) |
|
|
76
|
+
| `altqa test "login and add a product"` | Generate and run a test from plain English |
|
|
77
|
+
| `altqa chat` | Interactive AI QA session (REPL) |
|
|
78
|
+
| `altqa audit` | AI accessibility audit (WCAG compliance) |
|
|
79
|
+
| `altqa config show` | Display current configuration |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## AI-Powered Features
|
|
84
|
+
|
|
85
|
+
### Core Pipeline
|
|
86
|
+
- **Jira-aware testing** — reads ticket descriptions and attached test case files (Excel/CSV)
|
|
87
|
+
- **AI test interpretation** — converts human-written test steps into browser actions
|
|
88
|
+
- **AI failure analysis** — generates bug reports with root cause, fix suggestions, and regression tests
|
|
89
|
+
- **Automatic bug filing** — creates Jira sub-tasks with screenshots and detailed descriptions
|
|
90
|
+
|
|
91
|
+
### Runtime Health Monitoring
|
|
92
|
+
- Console errors and JS exceptions
|
|
93
|
+
- API failures and network errors
|
|
94
|
+
- Memory leaks and performance issues
|
|
95
|
+
- Page crashes and security warnings
|
|
96
|
+
|
|
97
|
+
### Advanced AI Features
|
|
98
|
+
- **Plain-text testing** — `altqa test "login with wrong password and verify error"`
|
|
99
|
+
- **Visual AI review** — screenshot analysis for UI/layout bugs using vision models
|
|
100
|
+
- **AI flow generation** — generates comprehensive test flows from your app's navigation graph
|
|
101
|
+
- **Smart selector healing** — auto-fixes broken CSS selectors when elements change
|
|
102
|
+
- **Conversational QA** — `altqa chat` for interactive testing sessions
|
|
103
|
+
- **AI test data generation** — realistic form data (valid, invalid, edge cases, security payloads)
|
|
104
|
+
- **Root cause clustering** — groups test failures by probable root cause
|
|
105
|
+
- **Accessibility audit** — WCAG compliance checking across your app
|
|
106
|
+
- **Enhanced bug descriptions** — AI-generated fix suggestions, user impact analysis, and regression tests
|
|
107
|
+
- **Natural language assertions** — write assertions in plain English in your YAML flows
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## YAML Test Flows
|
|
112
|
+
|
|
113
|
+
Define reusable test flows:
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
name: login
|
|
117
|
+
description: Log in with valid credentials
|
|
118
|
+
steps:
|
|
119
|
+
- action: navigate
|
|
120
|
+
url: "{{app_url}}/login"
|
|
121
|
+
- action: fill
|
|
122
|
+
selector: "#username"
|
|
123
|
+
value: "{{username}}"
|
|
124
|
+
- action: fill
|
|
125
|
+
selector: "#password"
|
|
126
|
+
value: "{{password}}"
|
|
127
|
+
- action: click
|
|
128
|
+
selector: "button[type=submit]"
|
|
129
|
+
- action: wait_for
|
|
130
|
+
selector: ".dashboard"
|
|
131
|
+
assertions:
|
|
132
|
+
- type: url_contains
|
|
133
|
+
value: "/dashboard"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Supports variable interpolation (`{{var}}`), flow includes, and natural language assertions.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Architecture
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
CLI (Typer + Rich)
|
|
144
|
+
|
|
|
145
|
+
+-- Config (Pydantic schemas, altqa.json)
|
|
146
|
+
+-- AI Agents (Agno framework, multi-provider LLM)
|
|
147
|
+
+-- Flow Engine (YAML parser, variable resolver, assertions)
|
|
148
|
+
+-- Browser (Playwright — deterministic actions, not AI-controlled)
|
|
149
|
+
+-- Crawler (BFS discovery, navigation graph)
|
|
150
|
+
+-- Jira Integration (issue CRUD, attachments, comments)
|
|
151
|
+
+-- Pipeline Orchestrator (ties everything together)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Design principle:** Browser actions are deterministic (click, fill, navigate). AI handles *intelligence* — planning, analysis, and reporting. This avoids flaky, non-reproducible tests.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Supported LLM Providers
|
|
159
|
+
|
|
160
|
+
| Provider | Models | Notes |
|
|
161
|
+
|---|---|---|
|
|
162
|
+
| OpenAI | gpt-4o, gpt-4o-mini, o1, etc. | Best overall experience |
|
|
163
|
+
| Anthropic | claude-sonnet-4-20250514, claude-3.5-haiku, etc. | Great for analysis |
|
|
164
|
+
| Ollama | llama3, mistral, codellama, etc. | Fully local, no API key |
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "altqa-cli"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "AI-powered QA automation CLI — tests your app from Jira tickets, reports bugs back automatically"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Rohit Jangral", email = "rohitnishantjangral@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
keywords = ["qa", "testing", "automation", "jira", "ai", "playwright", "cli"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"Environment :: Console",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
22
|
+
"Topic :: Software Development :: Testing",
|
|
23
|
+
"Typing :: Typed",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"typer>=0.9",
|
|
27
|
+
"rich>=13.0",
|
|
28
|
+
"playwright>=1.40",
|
|
29
|
+
"pydantic>=2.0",
|
|
30
|
+
"agno>=2.0",
|
|
31
|
+
"pyyaml>=6.0",
|
|
32
|
+
"httpx>=0.25",
|
|
33
|
+
"openpyxl>=3.1",
|
|
34
|
+
"openai>=1.10",
|
|
35
|
+
"anthropic>=0.20",
|
|
36
|
+
"jira>=3.5",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://gitlab.com/rohithyphen05/altqa"
|
|
41
|
+
Repository = "https://gitlab.com/rohithyphen05/altqa"
|
|
42
|
+
Issues = "https://gitlab.com/rohithyphen05/altqa/-/issues"
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
altqa = "altqa.cli.main:app"
|
|
46
|
+
|
|
47
|
+
[build-system]
|
|
48
|
+
requires = ["hatchling"]
|
|
49
|
+
build-backend = "hatchling.build"
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.targets.wheel]
|
|
52
|
+
packages = ["src/altqa"]
|
|
53
|
+
|
|
54
|
+
[tool.hatch.build.targets.sdist]
|
|
55
|
+
include = ["src/altqa", "README.md", "LICENSE"]
|
|
56
|
+
|
|
57
|
+
[dependency-groups]
|
|
58
|
+
dev = [
|
|
59
|
+
"fastapi>=0.135.1",
|
|
60
|
+
"jinja2>=3.1.6",
|
|
61
|
+
"uvicorn>=0.42.0",
|
|
62
|
+
"pytest>=8.0",
|
|
63
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""AccessibilityAuditorAgent — AI-powered WCAG accessibility auditing.
|
|
2
|
+
|
|
3
|
+
Crawls pages and uses AI to identify accessibility violations, mapping
|
|
4
|
+
them to WCAG 2.1 criteria with concrete fix suggestions.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import logging
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from agno.agent import Agent
|
|
15
|
+
from pydantic import BaseModel, Field
|
|
16
|
+
|
|
17
|
+
from altqa.config.models import resolve_model
|
|
18
|
+
from altqa.config.schema import AltQAConfig
|
|
19
|
+
|
|
20
|
+
log = logging.getLogger("altqa.agents")
|
|
21
|
+
|
|
22
|
+
_PROMPT_PATH = Path(__file__).parent / "prompts" / "accessibility_audit.md"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class A11yIssue(BaseModel):
|
|
26
|
+
severity: str = "warning"
|
|
27
|
+
wcag_criterion: str = ""
|
|
28
|
+
description: str = ""
|
|
29
|
+
element: str = ""
|
|
30
|
+
fix: str = ""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class A11yAuditResult(BaseModel):
|
|
34
|
+
page_url: str = ""
|
|
35
|
+
score: str = "unknown"
|
|
36
|
+
issues: list[A11yIssue] = Field(default_factory=list)
|
|
37
|
+
summary: str = ""
|
|
38
|
+
passed_checks: list[str] = Field(default_factory=list)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AccessibilityAuditorAgent:
|
|
42
|
+
"""Audit web pages for WCAG 2.1 accessibility compliance."""
|
|
43
|
+
|
|
44
|
+
def __init__(self, config: AltQAConfig) -> None:
|
|
45
|
+
self.config = config
|
|
46
|
+
self.model = resolve_model(config.llm)
|
|
47
|
+
self._system_prompt = _PROMPT_PATH.read_text()
|
|
48
|
+
|
|
49
|
+
def audit_html(self, html: str, page_url: str = "") -> A11yAuditResult:
|
|
50
|
+
"""Audit raw HTML content for accessibility issues."""
|
|
51
|
+
html_snippet = html[:6000] if len(html) > 6000 else html
|
|
52
|
+
|
|
53
|
+
user_prompt = (
|
|
54
|
+
f"## Page to audit\n"
|
|
55
|
+
f"**URL:** {page_url}\n\n"
|
|
56
|
+
f"```html\n{html_snippet}\n```"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
from agno.utils.log import logger as agno_logger
|
|
60
|
+
prev_handlers = agno_logger.handlers[:]
|
|
61
|
+
prev_propagate = agno_logger.propagate
|
|
62
|
+
agno_logger.handlers = [logging.NullHandler()]
|
|
63
|
+
agno_logger.propagate = False
|
|
64
|
+
try:
|
|
65
|
+
agent = Agent(
|
|
66
|
+
model=self.model,
|
|
67
|
+
instructions=[self._system_prompt],
|
|
68
|
+
markdown=False,
|
|
69
|
+
)
|
|
70
|
+
response = agent.run(user_prompt)
|
|
71
|
+
content = _clean(response.content or "{}")
|
|
72
|
+
data = json.loads(content)
|
|
73
|
+
except Exception as exc:
|
|
74
|
+
log.warning("Accessibility audit failed for %s: %s", page_url, exc)
|
|
75
|
+
return A11yAuditResult(page_url=page_url, summary=f"Audit failed: {exc}")
|
|
76
|
+
finally:
|
|
77
|
+
agno_logger.handlers = prev_handlers
|
|
78
|
+
agno_logger.propagate = prev_propagate
|
|
79
|
+
|
|
80
|
+
issues = [
|
|
81
|
+
A11yIssue(
|
|
82
|
+
severity=i.get("severity", "warning"),
|
|
83
|
+
wcag_criterion=i.get("wcag_criterion", ""),
|
|
84
|
+
description=i.get("description", ""),
|
|
85
|
+
element=i.get("element", ""),
|
|
86
|
+
fix=i.get("fix", ""),
|
|
87
|
+
)
|
|
88
|
+
for i in data.get("issues", [])
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
return A11yAuditResult(
|
|
92
|
+
page_url=page_url,
|
|
93
|
+
score=data.get("score", "unknown"),
|
|
94
|
+
issues=issues,
|
|
95
|
+
summary=data.get("summary", ""),
|
|
96
|
+
passed_checks=data.get("passed_checks", []),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def audit_page(self, page, page_url: str = "") -> A11yAuditResult:
|
|
100
|
+
"""Audit a live Playwright page."""
|
|
101
|
+
html = page.content()
|
|
102
|
+
url = page_url or page.url
|
|
103
|
+
return self.audit_html(html, url)
|
|
104
|
+
|
|
105
|
+
def audit_many(
|
|
106
|
+
self,
|
|
107
|
+
pages_html: list[tuple[str, str]],
|
|
108
|
+
) -> list[A11yAuditResult]:
|
|
109
|
+
"""Audit multiple pages. Each tuple is (html, page_url)."""
|
|
110
|
+
results: list[A11yAuditResult] = []
|
|
111
|
+
for html, url in pages_html:
|
|
112
|
+
result = self.audit_html(html, url)
|
|
113
|
+
results.append(result)
|
|
114
|
+
log.info("A11y audit %s: score=%s, %d issues", url, result.score, len(result.issues))
|
|
115
|
+
return results
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _clean(content: str) -> str:
|
|
119
|
+
content = content.strip()
|
|
120
|
+
if content.startswith("```"):
|
|
121
|
+
first_newline = content.index("\n") if "\n" in content else 3
|
|
122
|
+
content = content[first_newline + 1:]
|
|
123
|
+
if content.endswith("```"):
|
|
124
|
+
content = content[:-3]
|
|
125
|
+
return content.strip()
|