Claude
Skills
Sign in
Back

qa

Included with Lifetime
$97 forever

Run a QA verification pass for a Jira ticket or adhoc investigation against a deployed environment (dev, qa, or staging). Composes a scenario from how-tos and test data, drives automated steps via Chrome MCP, prompts the user for manual steps, captures evidence, and reports the verdict. No local code clones — for local-branch verification use /smoke instead. Argument is `<key-or-hint> <env>`.

AI Agents

What this skill does


In this skill, `<workspace>` refers to the Workspace path defined in the workspace `CLAUDE.md` `## Configuration` block. `<CloudId>` refers to the Jira CloudId from the same Configuration block. `<vpn-host>` refers to the On-prem VPN host from the same block.

# QA

Run a QA verification pass over a Jira ticket or adhoc investigation. Drives the multi-app data setup and verification across dev, qa, or staging environments. For local-branch verification, use `/smoke` instead. Uses a hybrid execution model: Claude drives `[automated]` steps via Chrome MCP, prompts the user for `[manual]` steps, validates `[assertion]` steps against a source of truth.

This skill runs the orchestrator pipeline (phases 1–4) directly in the main conversation. Subagents are NOT dispatched for v1 — manual-step interaction requires real-time user response, which only the main conversation can provide. The `playwright-driver` agent (at `agents/playwright-driver.md`) is a pure-function Playwright walker that any future fully-automated regression flow can dispatch — it has no /qa or /smoke specifics; the caller supplies the plan, app config, and screenshots dir, and gets back a structured verdict + step results.

## Configuration

Read from the workspace `CLAUDE.md` `## Configuration` table:
- `Jira CloudId` (referred to as `<CloudId>` below)

Hardcoded in this skill:
- QA root: `<workspace>\QA\`
- Active issues folder: `<workspace>\Active\`
- Jira key pattern (regex): `^[A-Z]+-\d+$`
- Envs accepted: `dev`, `qa`, `staging`
- Per-app URLs (dev / qa / staging): read from `<workspace>\PlanningWorkspace\<repo>\CLAUDE.md` `## Environments` section. `QA\Environments.md` is the workspace-level fallback when a repo's CLAUDE.md doesn't declare URLs for the target env.

## Invocation

`/qa <key-or-hint> <env>` — both arguments required.

- `<key-or-hint>`: Jira key (e.g., `CRD-123`), adhoc slug (kebab-case, e.g., `flaky-payment-bug`), or a substring hint.
- `<env>`: `dev`, `qa`, or `staging`. For local-branch verification, use `/smoke` instead.

If either argument is missing or `<env>` is not one of the three valid values, print exactly:

```
Usage: /qa <key-or-hint> <env>
  env must be dev, qa, or staging.
```

and stop.

## Argument Resolution

See [references/argument-resolution.md](../../references/argument-resolution.md). Apply the **multi-root** variant — `/qa` searches both `<workspace>\QA\Active\` and `<workspace>\Active\` because the QA run folder can exist independently of the issue folder. Store the resolved name as `<TARGET>`. Resolution runs BEFORE Phase 1.

## Phases

Run these phases in order. Do NOT skip ahead.

### Phase 1: VPN check

Two probes — Atlassian Cloud is public-internet, so it succeeds with or without VPN. The on-prem host (`<vpn-host>`) is the actual VPN signal. Both must succeed.

**Probe 1 — Atlassian reachability:** call `mcp__plugin_atlassian_atlassian__atlassianUserInfo` with no parameters. On failure (network error, auth error, timeout, any non-200 response), print:
```
VPN check failed — Atlassian API unreachable. Connect to VPN and re-run /qa.
```
and stop.

**Probe 2 — On-prem reachability:** run `nslookup <vpn-host> 2>&1 | head -5`. If output contains `can't find`, `NXDOMAIN`, `server can't find`, or the command exits non-zero, print:
```
VPN check failed — <vpn-host> not resolving. Connect to VPN and re-run /qa.
```
(substituting the actual host) and stop.

Only proceed to Phase 2 when both probes pass.

### Phase 2: Resolve target and set up run folder

Branch by whether the QA run folder already exists.

**If `<workspace>\QA\Active\<TARGET>\` exists — resume case.** Read `run.md`, extract `status` from frontmatter, then:

- `status: in-progress` — find the highest step in `## Execution Log`, print `Resuming <TARGET> from step <N>: <description>.`, continue to Phase 3.
- `status: passed | failed | blocked` — print `## Verdict`, then prompt:
  ```
  Run is currently <status>. Options:
    R — re-run from scratch (archives current run.md to run-<timestamp>.md)
    F — fork to a new scenario (archives, then prompts Phase 3 Step 3 for new scope)
    C — close (no action, /qa exits)
  ```
  On `R` or `F`: rename existing `run.md` to `run-<YYYYMMDDHHMMSS>.md`, then proceed as fresh case below (F sets a flag for Phase 3 Step 3 to ask new scope). On `C`: print `Closed.` and stop.

**If `<workspace>\QA\Active\<TARGET>\` does not exist — fresh case.**

1. Create folders: `<workspace>\QA\Active\<TARGET>\Screenshots` and `Notes`.
2. **Ticketed target** (matches `^[A-Z]+-\d+$`): call `getJiraIssue` (`cloudId: <CloudId>`, `issueIdOrKey: <TARGET>`, `fields: ["summary", "description", "status"]`). On failure, print `Failed to fetch Jira ticket <TARGET>: <error>. Continuing without Jira-pre-fill.` and treat as adhoc below.
3. Write `run.md` using the canonical template (next subsection); only the `## Scope` section differs:
   - Ticketed: Jira summary as a bold line, then Jira description verbatim.
   - Adhoc (or ticketed-with-failed-fetch): the placeholder `_(Adhoc — to be authored at start of execution.)_`. Phase 3 Step 2 will prompt the user to author Scope.

#### Canonical `run.md` template

Used for both fresh ticketed and fresh adhoc runs. Substitute `<TARGET>`, `<ENV>`, the ISO 8601 timestamp, and the Scope content.

```markdown
---
target: <TARGET>
env: <ENV>
scenario: (to be determined)
started: <ISO 8601 timestamp>
status: in-progress
---

# QA Run: <TARGET>

## Scope

<Scope content — see Phase 2 rules above for ticketed vs adhoc>

## Plan

_(To be composed in Phase 3.)_

## Execution Log

_(Newest entries appended below.)_

## Verdict

_(Pending.)_
```

### Phase 3: Execute QA (in-conversation execution loop)

This phase runs in the main conversation. Claude IS the QA runner.

#### Step 1: Read run state

Read `QA\Active\<TARGET>\run.md`. Note:
- The `env` from frontmatter.
- The contents of `## Scope`.
- Whether `## Plan` already has content (resume case) or is `_(To be composed in Phase 3.)_` (fresh case).
- The highest step number in `## Execution Log` (for resume).

#### Step 2: Author Scope (adhoc, fresh runs only)

If `## Scope` contains the placeholder text `_(Adhoc — to be authored at start of execution.)_`, prompt user:

```
What are we testing in this adhoc QA run? Describe the scope (one or more sentences):
```

Wait for response. Replace the placeholder with the user's response in `run.md`.

#### Step 3: Compose the plan

If `## Plan` already has content (resume case), skip to Step 5.

Otherwise:

1. List the contents of `QA\Scenarios\` via `Glob` for `*.md`.
2. For each scenario file, read its frontmatter `description` field. Identify any scenario whose description matches the Scope semantically.
3. **If a matching scenario exists:**
   - Read the scenario file.
   - Write the scenario's `## Steps` (with parameter bindings filled in from Scope context) into `run.md`'s `## Plan` section.
   - Set the frontmatter field: `scenario: <scenario-name>`.
4. **If no scenario matches:**
   - List `QA\HowTos\` for available how-tos. Read each one's frontmatter `description` to understand what they do.
   - List `QA\TestData\` for available data templates.
   - Compose a bespoke plan as a numbered list of how-to invocations, manual steps, and assertions, using this format:
     ```markdown
     ## Plan

     1. how-to `create-borrower` with `borrower_template=happy-path-borrower` → `borrower_id`
     2. **[manual]** Verify in Gateway.Web that the borrower appears in the customer list.
     3. **[assertion]** NextGenOrig DB: `SELECT Status FROM Borrowers WHERE Id={{borrower_id}}` → expected `Active`.
     ```
   - For parts where no how-to exists yet, inline `[manual]` steps with explicit instructions.
   - Set frontmatter: `scenario: bespoke`.
5. Write the plan into `run.md`, replacing the placeholder.

#### Step 4: Confirm plan with user (hard gate)

Print the plan you just wrote, followed by:

```
Plan composed (above). Choose:
  R — run as-is
 

Related in AI Agents