An AI-powered Quality Engineering SDK. Turns a failing test from ANY automation framework (Playwright, Selenium, Cypress, Robot Framework, pytest, ...) into an evidence-grounded root-cause analysis, confidence score, owner, and tracker-ready bug report. Framework-agnostic core, adapter-based, works fully offline with zero API keys.
Project description
AIQA — an AI-powered Quality Engineering SDK
Turn a failing test from any automation framework into an evidence-grounded root-cause analysis, a confidence score, an owning team, and a tracker-ready bug report.
AIQA is not a Playwright tool. Its core understands only failures, evidence, context, analysis, and reports — never a specific application, framework, or DOM. Framework knowledge lives entirely in swappable adapters, so the same engine works with Playwright, Selenium, Cypress, Robot Framework, Appium, Requests, REST Assured, JUnit, NUnit, TestNG, pytest — or anything that can emit JSON.
It runs fully offline with zero API keys (deterministic heuristic engine + pure-Python similarity search) and upgrades transparently to an LLM when you configure one.
Install name:
playwright-tc-failure-ai-analyzer· Import name:aiqa
Architecture
Dependencies point in one direction only. The core domain depends on nothing; everything depends on the core.
Adapters (framework-specific: Playwright, Selenium, pytest…)
│ produce
▼
FailureContext ← Core Domain (pure, framework-agnostic models)
│ consumed by
▼
AI Analysis Engine analyze(context) -> AnalysisResult (never imports a framework)
│ produces
▼
Reporting (Markdown · JSON · HTML · Console · your own)
│
▼
Output
| Layer | Package | Knows a framework? | Depends on |
|---|---|---|---|
| Adapters | aiqa.adapters |
Yes (only here) | core |
| Core domain | aiqa.core |
No | standard library only |
| AI engine | aiqa.analysis |
No | core (+ optional LLM SDK, lazy) |
| Reporting | aiqa.reporting |
No | core |
The engine's entire contract is one method:
analyze(context: FailureContext) -> AnalysisResult.
Install
pip install playwright-tc-failure-ai-analyzer # core SDK (offline)
pip install "playwright-tc-failure-ai-analyzer[openai]" # + LLM analysis
Quick start
from aiqa import FailureAnalyzer, FailureContext, render
context = FailureContext.from_dict({
"metadata": {"test_name": "checkout::test_pay", "framework": "cypress"},
"exception": {"type": "AssertionError", "message": "server returned HTTP 500"},
"evidence": {"network": [{"method": "POST", "url": "/api/pay", "status": 500}]},
})
result = FailureAnalyzer().analyze(context) # offline by default
print(render(result, "markdown", context))
print(result.category.value, result.confidence.value, result.owner)
Using adapters
Every adapter exposes collect_failure_context(...) and returns a
FailureContext.
Playwright
from aiqa import FailureAnalyzer, render
from aiqa.adapters import PlaywrightAdapter, PlaywrightEventRecorder
recorder = PlaywrightEventRecorder(page) # at test start (captures console/network)
# ... on failure:
context = PlaywrightAdapter(page=page, recorder=recorder).collect_failure_context(
exc, test_name="login::test_submit", screenshot="fail.png", browser="chromium",
)
print(render(FailureAnalyzer().analyze(context), "console", context))
Selenium
from aiqa.adapters import SeleniumAdapter
context = SeleniumAdapter(driver=driver).collect_failure_context(exc, test_name="orders::checkout")
pytest (any test type — UI, API, unit)
from aiqa.adapters import PytestAdapter
# in conftest.py pytest_runtest_makereport:
context = PytestAdapter().collect_failure_context(item=item, call=call, report=report)
Robot Framework
from aiqa.adapters import RobotFrameworkAdapter
context = RobotFrameworkAdapter().collect_failure_context(
test_name="Login Works", message="Element not visible", suite="Login")
Anything (JSON) — Cypress, REST Assured, JUnit, NUnit, TestNG, CI scripts:
from aiqa.adapters import GenericAdapter
context = GenericAdapter().collect_failure_context("failure.json") # dict | JSON str | path
Runnable scripts live in examples/.
Core domain
Pure, JSON-serialisable dataclasses in aiqa.core, independent of every
framework:
FailureContext— the single input to the engine, composed of:FailureMetadata(test id/name, suite, framework, tags, timing, git commit)ExceptionInfo(type, message, stacktrace)Evidence(screenshot, DOM snapshot, console, network, API responses, logs, artifacts, and open-endedcustomevidence)ExecutionContext(environment, browser, OS, URL, timestamp, configuration)
AnalysisResult—RootCause,ConfidenceScore,Severity,owner,evidence,Recommendation[],SimilarFailure[]BugReport— a tracker-ready report
AI analysis
FailureAnalyzer.analyze(context):
- Retrieves similar past failures (RAG) — optional, pure-Python by default.
- If an LLM provider is available, asks for an evidence-grounded JSON verdict; any failure transparently falls back to…
- …a deterministic heuristic classifier (HTTP 5xx → Backend, 401 → Auth, locator / timeout / assertion signals, console errors, …).
- Assigns a category, confidence, severity, and owning team.
Every claim is grounded in the collected evidence — the model cannot invent signals that were not captured.
Reports
Reporters consume an AnalysisResult only. Built in: markdown, json,
html, console.
from aiqa import get_reporter, available_formats
print(available_formats()) # ['console', 'html', 'json', 'markdown']
html = get_reporter("html").render(result, context)
Bug reports:
from aiqa.reporting import BugReportBuilder
bug = BugReportBuilder().build(result, context)
print(BugReportBuilder.to_markdown(bug))
Extensibility
Every seam is an interface (aiqa.core.interfaces) — extend without touching
existing code.
Custom LLM provider — implement three members:
class MyProvider:
name = "my-llm"
def available(self): return True
def complete_json(self, prompt, system=""): return {...}
FailureAnalyzer(llm=MyProvider())
Custom reporter — subclass and register:
from aiqa.core.interfaces import Reporter
from aiqa.reporting import register_reporter
@register_reporter
class SlackReporter(Reporter):
format = "slack"
def render(self, result, context=None): return f":rotating_light: {result.root_cause.summary}"
Custom adapter — subclass FrameworkAdapter and return a FailureContext.
Custom similarity/RAG backend — implement the SimilarityIndex protocol.
Configuration (all optional, env-driven)
| Variable | Default | Purpose |
|---|---|---|
AIQA_PROVIDER |
offline |
offline (heuristic) or openai. |
AIQA_MODEL |
gpt-4o-mini |
Model name for the chosen provider. |
AIQA_API_KEY |
– | Key (falls back to OPENAI_API_KEY). |
AIQA_BASE_URL |
– | Custom/compatible endpoint (Azure, local, …). |
AIQA_ENABLE_HISTORY |
false |
Persist a local similarity index. |
AIQA_BASE_DIR |
.aiqa |
Where history is written. |
Offline mode requires no keys and no extra dependencies.
Design guarantees
- The core has zero framework and zero application knowledge.
- The engine accepts only a
FailureContextand never imports Playwright. - Reports consume only an
AnalysisResult. - All framework logic is isolated in adapters (framework libs lazy-imported).
- Full type hints, SOLID boundaries, no circular dependencies, unit-testable.
Also included: qa_ai_engine pytest plugin (backward-compatible)
The same distribution still ships the original auto-discovered pytest plugin for
pytest + Playwright projects, unchanged. Enable it with AI_ENABLED=true and
use from qa_ai_engine import AIEngine. New projects should prefer the
framework-agnostic aiqa SDK above.
License
MIT © Aman Deep
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file playwright_tc_failure_ai_analyzer-2.0.1.tar.gz.
File metadata
- Download URL: playwright_tc_failure_ai_analyzer-2.0.1.tar.gz
- Upload date:
- Size: 87.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d311262d659ed48ba91ef56a33d0992a67b2bda4ebceeb02bb58cf6c0d5595c0
|
|
| MD5 |
a5d3a88ae5efd5c09ba677b6636221b0
|
|
| BLAKE2b-256 |
cff282a69b829c0744e9ed984e2c0f869d90a069f29bfaf5eb17a39427731425
|
File details
Details for the file playwright_tc_failure_ai_analyzer-2.0.1-py3-none-any.whl.
File metadata
- Download URL: playwright_tc_failure_ai_analyzer-2.0.1-py3-none-any.whl
- Upload date:
- Size: 94.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f1b1011052fe25dbba8567827bb62b274f4d142fc065d496da4b1da0863c684
|
|
| MD5 |
8e73cf4edc51fbd0140d6678a4203b12
|
|
| BLAKE2b-256 |
616a36b1451611636004c8bafdf6c5d3786d90ec46b6866333bad44bf991327f
|