Turn on only what you use. Every integration is opt-in by env var, non-blocking
(a broken TMS is a warning, never a failed test), and noisy only for findings
your team cares about — high + critical by default.
analyze_* call, or define your own.Three rules across every integration.
high and critical findings create records. Change per-target with TESTERSAI_<TMS>_SEVERITIES.Creates one Jira issue per qualifying finding in the configured project.
| Env var | Purpose |
|---|---|
TESTERSAI_JIRA_URL | Base URL, e.g. https://acme.atlassian.net |
TESTERSAI_JIRA_EMAIL | Account email for API-token auth |
TESTERSAI_JIRA_API_TOKEN | Jira API token (create one) |
TESTERSAI_JIRA_PROJECT | Project key (e.g. QA) |
TESTERSAI_JIRA_ISSUE_TYPE | Defaults to Bug |
TESTERSAI_JIRA_SEVERITIES | Comma-separated (default high,critical) |
[testersai:<kind>:<severity>] <message>,
description with category / location / evidence / context, labels
testersai, testersai-<severity>, testersai-<category>.
Imports results into an existing Xray Test Execution, matching on a test_key context field.
| Env var | Purpose |
|---|---|
TESTERSAI_XRAY_CLIENT_ID | Xray API client id |
TESTERSAI_XRAY_CLIENT_SECRET | Xray API client secret |
TESTERSAI_XRAY_EXECUTION_KEY | Existing Test Execution key, e.g. EX-42 |
TESTERSAI_XRAY_URL | Defaults to Xray Cloud. Override for self-hosted. |
Pass the test key via context:
r = client.analyze_screenshot(
img,
context={"test_key": "QA-101"}
)
Posts a result to an existing TestRail run, matching on a case_id context field.
| Env var | Purpose |
|---|---|
TESTERSAI_TESTRAIL_URL | Base URL, e.g. https://acme.testrail.io |
TESTERSAI_TESTRAIL_USER | Account email |
TESTERSAI_TESTRAIL_API_KEY | API key |
TESTERSAI_TESTRAIL_RUN_ID | Numeric TestRail run id |
The result is status_id=5 (Failed) when findings contain high/critical severity, else status_id=1 (Passed). Comment contains the finding list.
r = client.analyze_page_text(
html,
context={"case_id": 501}
)
Attaches Testers.AI findings to the current Cypress Cloud run.
| Env var | Purpose |
|---|---|
CYPRESS_RECORD_KEY (or TESTERSAI_CYPRESS_RECORD_KEY) | Standard Cypress Cloud record key |
CYPRESS_PROJECT_ID (or TESTERSAI_CYPRESS_PROJECT_ID) | Project id |
CYPRESS_RUN_ID | Run id (usually injected by CI after cypress run --record) |
TESTERSAI_CYPRESS_URL | Defaults to https://api.cypress.io |
No run id = silent no-op. The SDK won't post to a random run.
r = client.analyze_screenshot(
img,
context={
"cypress_run_id": "run-555",
"cypress_instance_id": "inst-abc",
"spec": "login.cy.js",
}
)
You can turn on every integration simultaneously. A single analysis fires in parallel to all configured targets; any that fails is skipped silently.
context = {
"test_key": "QA-9", # → Xray
"case_id": 77, # → TestRail
"cypress_run_id": "run-9", # → Cypress Cloud
}
# Jira needs no context — creates an issue per high-severity finding.
r = client.analyze_console(logs, context=context)
sdk_test/integrations/test_integrations.py starts a
mock TMS server, configures all four integrations pointed at it, and asserts the exact
payloads posted to each endpoint — including the "broken TMS doesn't fail tests"
resilience case.