Tool · Prompt + skill

AI test plan generator.

Asked cold, an AI writes a generic, happy-path plan you cannot trust. This makes it ask for the real context first, cover the whole lifecycle, and apply the patterns that catch production bugs. My actual first move on a new feature. You get a risk-shaped plan in minutes that you then edit and publish as a page your team tests against, not a markdown file in a chat window.

Download the skill
Start by giving it real context. The biggest lever on plan quality is what you feed it. Hand the agent the product spec, the ticket and its parent, the designs, and the real code before you run this. A plan written from a one-line ticket is a guess. Give your AI real context shows how to connect all of it.

The prompt you reuse

test-plan-prompt.txt
You are generating a QA test plan for a feature, then publishing it as a page the
team can see. Work from real context, not guesses. Ask me for anything missing before you write.

Give it as much context as you can up front: the product spec, the ticket and its parent,
the designs, and the part of the codebase that implements this. The more real detail you feed
it, the closer the plan lands to something worth shipping behind.

Confirm first:
- Feature name and a short description
- The spec or ticket (read it in full; if it is thin, read the parent and any linked design before drafting)
- Frontend, backend, or both
- The roles involved, and any feature flag
- Plan size: mini (about 10 to 15, the critical path only), medium (about 40 to 60), or full (80 plus)
- Where it gets published: a Confluence page, or the ticket's description

Then:
1. Assess risk before you count cases. For each area weigh money, security, customer impact,
   data accuracy, and operational load. Every high-risk area gets the most depth and a P0
   priority. Do not spread cases evenly.
2. Identify the functional areas; they become numbered sections covering the whole lifecycle:
   happy path, validation, errors, permissions, duplicates, post-action verification, edge
   cases, and an explicit regression list.
3. Write each case as a table row:
   ID | Verify that <condition> <expected result> | Priority (P0/P1/P2) | Status
   Leave Status blank for the tester. IDs are a short section prefix plus a number.
4. Apply the patterns that catch real bugs:
   - one case per condition for multi-condition logic, plus a two-at-once case and the boundaries
   - a case that pins the exact on-screen wording
   - a stale-state case after a filter, a sort, or a change to the data
   - per-total recalculation cases, plus a case for a backend-versus-frontend mismatch
   - verify the result in the backend, not just the confirmation screen: the record saved with the
     right values, the entitlement granted, the email queued
   - for anything that charges, refunds, or prorates, pin the amount to the cent and assert what was
     actually charged, not the total the summary screen shows
   - a duplicate or double-submit case, so the action runs exactly once (one record, one charge, one
     analytics event), including a replayed webhook or a retried request
   - a concurrency case where two users or two tabs act on the same record at once
   - illegal state transitions: cancel an already-cancelled order, act on an expired invite, edit a
     deleted item
   - failure paths: a dependency times out or errors, the user gets a clear message, and the system
     is not left half-written
   - empty, first-run, boundary and nasty-input cases: zero, negative, maximum length, an emoji, an
     apostrophe
   - one case that the control is hidden in the interface, and one that a direct API call from
     an unauthorized role is rejected
   - split bundled behaviours into separate cases
5. List open questions for anything undefined, each tied to the cases it affects.
6. Add an end-to-end walkthrough detailed enough for a tester who has never seen the app to
   follow without guessing. List the preconditions first (accounts, roles, test data, the URL).
   Then one concrete action per numbered step: open the browser, go to the URL, sign in, and
   split every navigation, click, and field entry into its own step. Name the exact buttons and
   fields in quotes and where they are, give the exact data to enter, and state what to see
   after each step. Cover a happy path, an error path, a validation path, and a permission path.
7. Publish it. Put the finished plan on a Confluence page titled "<Feature>: QA Test Plan",
   or write it into the ticket's description under a "QA Test Plan" heading without overwriting
   what is there. Never leave it as a markdown file or a chat reply. The page is the artifact
   the team tests against.

Do not invent field labels or error messages. Ask.

The full skill it comes from

The prompt above is the short version. The installable skill is the whole thing: the context-gathering, the Jira chain it traverses when a ticket is thin, the risk pass that drives priority, the granularity patterns, the publish step, and a quality bar it checks itself against. Here it is in full.

qa-test-plan/SKILL.md
---
name: qa-test-plan
description: >
  Generate a QA test plan for a software feature or module and publish it to Confluence or into a Jira ticket's description.
  Use this whenever someone asks to create a test plan, write a QA plan, generate or add test cases for a feature
  (mini, medium, or full), or asks "what should be tested" after sharing a product spec, Jira ticket, or feature spec.
  This is for planning QA on a specific feature, not questions about CI failures or existing test suites.
  Always use this skill rather than producing the plan as plain markdown in chat.
argument-hint: "[mini|medium|full] [confluence|jira] [feature name or TICKET-####]"
allowed-tools:
  - mcp__atlassian__getAccessibleAtlassianResources
  - mcp__atlassian__searchConfluenceUsingCql
  - mcp__atlassian__getConfluenceSpaces
  - mcp__atlassian__getConfluencePage
  - mcp__atlassian__createConfluencePage
  - mcp__atlassian__updateConfluencePage
  - mcp__atlassian__getJiraIssue
  - mcp__atlassian__getJiraIssueRemoteIssueLinks
  - mcp__atlassian__editJiraIssue
  - WebFetch
  - Read
  - Glob
  - Grep
---

# QA Test Plan Skill

Generates a thorough, structured QA test plan for a software feature and publishes it to Confluence or directly into a Jira ticket's description.

## When This Skill Triggers

- "Create a test plan for [feature]"
- "Write QA test cases for [feature]"
- "Make a test plan" (with a product spec, Jira ticket, or feature description provided)
- "Make a mini / quick test plan for [feature]"
- "Add test cases to this ticket" / "Put the test plan in the Jira ticket description"
- "What should we test for [feature]?"
- User shares a product spec and asks about testing

---

## Reference Examples

The `examples/` folder next to this file holds real, published test plans. Skim the one that matches the requested size and destination before writing, and model your sectioning, structure, and "Verify that..." voice on it, but write fresh content for the feature at hand, do not copy a plan's cases.

- `examples/full-subscription-billing.md`: a full plan for a billing feature (plan upgrade, downgrade, and proration); numbered sections through eligibility, proration math, payment, invoices, failed-payment and dunning, refunds, entitlement changes, analytics, monitoring, cross-browser, and regression, with several end-to-end walkthroughs.
- `examples/medium-product-reviews.md`: a medium plan for an e-commerce ratings-and-reviews feature, all areas covered with balanced depth.
- `examples/mini-reorder.md`: a mini, P0-only plan for a food-delivery reorder feature: the critical path and a single happy-path walkthrough.

These three are the worked examples shown on the resource page for this skill, each a different product, so it sees the range and the published plan matches the house style.

---

## Step 0: Parse Arguments

This skill supports both inline invocation and a fully guided flow. If the user passed arguments (e.g. `/qa-test-plan medium confluence TICKET-1234`), parse them first and use whatever is present; fall back to the interactive questions in Step 1 only for what's missing. With no arguments, run the fully guided flow.

Arguments passed: `$ARGUMENTS`

Parse for any of these (order-independent; ignore tokens you can't classify):
- Size: `mini`/`small`, `medium`, or `full`; also accept synonyms ("quick"/"smoke" maps to mini, "standard" to medium, "thorough"/"comprehensive" to full; see the Step 1 mapping).
- Destination: `confluence` or `jira` (also "ticket"/"description" maps to Jira). `both` is allowed.
- Feature / ticket: a Jira key like `TICKET-1234` (fetch and read it), a product spec/Confluence link (fetch and read it), or a free-text feature name.

Briefly confirm what you parsed, do not re-ask for anything already supplied, then go to Step 1 for whatever is still missing.

---

## Step 1: Gather Context

Before writing anything, extract what you can from the conversation, from `$ARGUMENTS` (Step 0), and from any linked tickets/pages. Then ask the user for anything still missing. Do not ask for things you can already determine.

Required, extract or ask:
- Feature name and brief description
- Link to product spec or Jira ticket (if available, fetch and read it before writing)
- Jira context chain: when a Jira issue is available, fetch enough fields to inspect its hierarchy and links before drafting: `parent`, `issuelinks`, `subtasks`, remote links, description, acceptance criteria, status, assignee/PM, labels/components, and any product, design, or spec fields returned by the project. Read the parent epic/parent issue and any linked Confluence, product spec, or design pages from both the story and the parent. If the ticket is thin or stub-like (a one-line description, "QA plan", "add tests", or no acceptance criteria), treat it as incomplete context and traverse upward or ask the user instead of guessing.
- Additional references and code: explicitly ask the user whether there's anything else you should look at for more detail before writing, such as other documents (design docs, Figma, RFCs, Slack threads), or specific folders / files / repos of frontend or backend code that implement the feature. If they point you to code or docs, read the relevant parts first; grounding cases in the actual implementation (real field names, routes, error states, permission checks) produces far better test cases than working from the product spec alone.
- Frontend UI, backend API, or both? A test plan for a UI wizard is fundamentally different from one for API endpoints. If it's unclear who the end user is (browser, API client, CLI), ask before writing.
- Plan size: the size labels are internal, do not assume the user knows them. Always ask the user which size they want, presenting this plain-language menu so they can just pick one:
  - Mini / Small (~10-15 cases): quick smoke / critical-path check; P0 only, core areas only
  - Medium (~40-60 cases): standard, balanced coverage; all areas
  - Full (80+ cases): comprehensive / exhaustive; all areas

  If the user's request already implies a size, infer it from their wording and confirm rather than asking from scratch: "quick" / "smoke" / "small" / "mini" / "short" / "just the basics" / "for the ticket" maps to mini; "standard" / "normal" / "balanced" maps to medium; "thorough" / "comprehensive" / "exhaustive" / "everything" maps to full. Only if the user declines to choose, default to full. If someone wants something between mini and medium (all areas but lightweight), land at the low end of medium. Medium and full plans should cover all functional areas, they cut depth within each area, not whole areas. A mini plan is the exception: it intentionally covers only the core functional areas and skips optional/edge sections (see Step 3 for how mini differs).
- Destination: ask where the plan should go, a Confluence page (default for medium/full) or directly into a Jira ticket's description (a natural fit for mini plans attached to the implementation ticket). If the user says "add it to the ticket" / "put it in the description," that's the Jira destination. If unclear and a Jira ticket is already in context, ask which they want. You can also do both. See Step 4.
- Scope vs. release sequence: if the product spec has a phased rollout (for example, "single user, then bulk, then follow-up filters"), confirm which phase this ticket covers before writing. A ticket titled "[Feature] (Phase 1)" may or may not include later phases, ask if ambiguous. Cases that belong to a later phase belong in a different plan.
- Key user roles involved (for example, admin, manager, standard user, read-only)
- Feature flag name (if applicable)
- Target ship date (if known)

Existing app context, always ask if not obvious:
- Is this feature being added to an existing app? If so, ask: "What does the existing app currently do, how do users log in, and what's its URL?" Do not assume you know the app from the product spec alone.
- If the feature lives in a separate app or repo from what's been shared, ask the user to describe the existing app (pages, auth flow, tech stack) or provide a link to its docs before writing implementation-specific test cases.
- If the app uses monitoring (Datadog, Sentry, etc.), ask which tool, include a Monitoring section if confirmed, skip it if unknown.

Nice to have:
- Known edge cases or risk areas
- Analytics events to verify
- Specific desktop browsers / screen resolutions to test

---

## Step 2: Research and Plan

Before writing test cases:

1. Complete the source chain:
   - Fetch and read any linked product spec, Jira ticket, or Confluence page in full, plus any extra docs, Figma, or frontend/backend code paths the user pointed you to in Step 1
   - For Jira-sourced plans, read the requested issue, its parent epic/parent issue, issue links, subtasks that clarify scope, and remote links; follow any product spec, Confluence, design, or spec references found at each level
   - If the implementation ticket and its direct links do not contain enough product context, do not draft yet. Keep traversing to the parent/source material or ask the user for the missing spec
   - Before drafting, know the source chain you used (for example: `TICKET-8412 -> TICKET-8407 -> Feature product spec`) so scope and assumptions can be checked
2. Assess risk before deciding case counts. For each functional area, judge its impact across these dimensions:
   - Revenue: does a failure here lose money or block a paid/contractual flow?
   - Security: auth, access control, data exposure, injection surface
   - Customer-facing: does a failure directly hit end users or the support team?
   - Data integrity: could the feature save or display the wrong values, duplicates, or miscalculations (as visible through the app)? Verify this through the app's own surfaces (see Post-Action Verification), we don't do direct database-level testing.
   - Operational: does it affect on-call load, background jobs, or escalation paths?

   Mark each area high / medium / low risk. Every high-risk area must get P0 coverage and the most depth. Do not spread cases evenly, concentrate them where the risk is. A 40-case plan split evenly across 10 areas when only 4 carry real risk is a bad plan.
3. Identify the distinct functional areas of the feature (these become numbered sections)
4. Define the test data you'll need (the user/account states and dataset shapes cases will reference, see Test Data Requirements in Step 3)
5. Think through the full lifecycle: happy path, duplicates, error states, permissions, post-action verification, performance, regression

Sections to consider (adapt to the feature). A flat, numbered list of only the relevant sections, like most published plans, is the default. Grouping into Functional / Non-Functional is optional; use it only if it genuinely helps a large plan.

Functional:
- Access and Authentication (login method, unauthorized access, unauthenticated redirects, required for any tool with a login flow)
- Feature Flag and Navigation
- Onboarding / First-run experience
- Core UI sections (filters, tables, cards, drawers, modals, forms)
- Form Field Entry and Validation (required fields, format validation, inline errors, submit button state)
- Submission and Provisioning (loading states, disabled submit during processing, success confirmation, downstream effects)
- Duplicate Handling (what happens when a user tries to create something that already exists, name conflicts, domain conflicts, etc.)
- Error Handling and Escalation (backend failures, network errors, retry flows, escalation paths to Engineering)
- Post-Creation / Post-Action Verification (verify the thing worked downstream; confirm no Engineering handoff is needed; check form reset and next-step links after success; verify the user can immediately create another without reloading)
- CRUD operations
- Permissions / Access Control (who can see/do what, including scoped vs. wildcard access patterns)
- Guided Flow and Usability (intuitive flow, helper text/tooltips, cancel/back navigation, unsaved data warnings)
- Audit Trail (if the app has audit logs, verify the action is captured with correct user, timestamp, and details)
- Concurrent Users (two users creating at the same time, race conditions on unique fields, include for any creation/provisioning feature)
- Session / Auth Edge Cases (token expiry during form fill or long-running operations, unsaved data on session timeout, include for multi-step forms or long-running provisioning)
- URL State and Deep Linking
- Export / Share
- Notifications / Emails
- Analytics Events
- Edge Cases
- Data Accuracy
- API Validation (required for backend-heavy / API features, see the checklist in Step 3): status codes, request validation, response schema, idempotency, authentication, authorization, rate limiting, backwards/contract compatibility
- Existing Functionality, Regression (explicitly list the existing pages/features that must still work)

Non-Functional:
- Performance (time-to-complete for key flows, back-to-back operations, provisioning time, include for any creation, provisioning, or background-processing feature)
- Accessibility (any UI feature, including internal tools, see the checklist in Step 3): keyboard navigation, focus management, screen-reader labels, color contrast, form-error announcements
- Security (authorization boundaries, input sanitization, sensitive-data exposure, beyond the functional auth cases)
- Reliability (retries, timeouts, partial-failure handling, graceful degradation)
- Observability / Monitoring (only if confirmed with user, Datadog, Sentry, etc.)
- Cross-Browser and Viewport (desktop only, latest Chrome/Firefox/Safari/Edge and common desktop resolutions like 1920x1080, 1366x768, 1280x720; it's a web app, so no mobile/responsive/native testing)

Not every feature needs every section, use judgment, and don't pad a plan with sections the feature doesn't warrant. For internal tools, Access and Authentication, Guided Flow and Usability, Audit Trail, and Regression are almost always required. For backend-heavy features, include API Validation. Accessibility, Test Data Requirements, and Automation Candidates are optional, add them only when they add real value (for example, Accessibility for a significant new UI surface), not by default.

---

## Step 3: Write the Test Plan

### Mini Plan, What Changes

When the user asked for a mini plan, write a focused smoke/critical-path plan, not a trimmed full plan:
- ~10-15 cases, P0 only, the core happy path plus the highest-risk error, validation, and permission cases. Drop P1/P2 entirely.
- Cover only the core functional areas (the main action's happy path, its primary failure mode, access control). Skip optional sections (Concurrent Users, Audit Trail, Performance, Accessibility, Cross-Browser, Analytics, Monitoring, Automation Candidates, Test Data Requirements, etc.) unless the user calls one out.
- Still include the highest-risk P0 cases from Step 2, for example, if it's an API feature, keep the core authz and request/response-validation cases. Mini cuts breadth, never the top-risk coverage.
- Still apply the granularity patterns below where a P0 case warrants it (split a bundled P0 behavior; pin exact P0 copy).
- end-to-end walkthrough: include a single Happy Path walkthrough only (skip the error/validation/permission/back-to-back walkthroughs).
- Skip the metadata header block when the destination is a Jira ticket description (the ticket already carries that context); keep a compact header for a Confluence page.
- Status column is optional for a mini plan, drop it and use just `ID | Test Case | Priority` so it reads as a quick checklist, especially in a Jira ticket description. Keep it only if the user wants to track pass/fail per case.
- Still include the Open Questions section if the product spec has gaps.

For medium/full plans, follow the full guidance below.

### Test Case Granularity, Patterns That Catch Real Bugs

Apply these when relevant to the feature. Each addresses a class of production bug that single-line coverage tends to miss.

- Multi-criterion detection logic: if a feature flags/classifies records based on multiple OR conditions (for example, "flag if duration under 30s OR fewer than 5 messages OR one-sided OR anomalous"), write one case per criterion, not one case for "the detector works." Also write a case for a record that hits two or more criteria at once, and a case for each boundary condition.
- Exact UI copy: when the product spec specifies exact wording for a toast, tooltip, button, or empty state (including punctuation like middle dots, possessives, or interpolated names), write a dedicated case pinning the exact string. Copy bugs ship constantly.
- Stale view state on filter/tab/sort change: for any feature that filters, sorts, or paginates a table, include a case verifying rows from the previous filter state don't linger after a swap. This is a common table bug class.
- Dashboard/aggregate recalculation: for features that affect aggregate metrics, write cases per major metric. Also write a case verifying the backend request and frontend refresh both use the new state, these can desync, leaving dashboard and table disagreeing. Also write a case for the empty-filtered-result case (dashboard shows zeros, not stale prior values).
- Bundled UI behaviors: if a case starts with "Verify that checkboxes, select-all, indeterminate state, bulk bar, and clear selection work," split it. When a bundled case fails, the QA engineer can't tell which behavior broke. Two or three focused cases beat one omnibus case.
- UI permissions vs API permissions: UI hiding is not backend enforcement. For any role-gated action, write one case verifying the UI element is hidden AND one case verifying a direct API call from an unauthorized role is rejected.
- Undo and analytics: for any reversible action with analytics, include a case verifying the analytics event isn't duplicated or left in an inconsistent state after undo or rapid repeated actions.

### Test Case Format

For medium/full plans, every test case must follow this structure:

| ID | Test Case | Priority | Status |
|----|-----------|----------|--------|

For mini plans in Jira ticket descriptions, prefer the compact structure unless the user asks to track status:

| ID | Test Case | Priority |
|----|-----------|----------|

ID format: `{SECTION_PREFIX}-{NUMBER}` (for example, `FF-01`, `KPI-03`, `TS-14`)
- Section prefix should be 2-5 uppercase letters derived from the section name
- Numbers are zero-padded (01, 02, ... 10, 11)

Test Case wording:
- Always start with "Verify that..."
- Be specific, include the exact condition being tested, not vague descriptions
- Include the expected result in the same sentence
- If there's a nuance or open question, add a NOTE in parentheses

Priority:
- `P0`: Must pass before ship; blocking
- `P1`: Should pass before ship; high value
- `P2`: Nice to have; low risk if deferred

Drive priority by the Step 2 risk assessment, not by even distribution. Every case covering a high-risk area (revenue, security, customer-facing, data integrity, or operational impact) is P0. P1/P2 cover medium/low-risk areas and added depth. If an area carries no real risk, cover it lightly or drop it, never pad the plan to hit a case count.

Status: Leave blank (empty cell) when included, the QA engineer fills this in.

### Test Data Requirements (optional)

Only when it adds value (complex data setup, many roles/states), include a "Test Data Requirements" section before the test-case tables listing the data the QA engineer needs staged. Skip it for straightforward features. Typical entries (adapt to the feature):
- Valid user / happy-path account
- Invalid user (bad credentials, unverified)
- Expired / suspended account
- Admin (or full-access) role
- Read-only / scoped role
- Large dataset (pagination, performance)
- Empty dataset (empty states, zero-result handling)

### Section Templates (use when applicable)

Add these as numbered sections (same `ID | Test Case | Priority | Status` format) when they fit the feature.

API Validation, include for backend-heavy / API features:
- Status codes (200/201/400/401/403/404/409/422/429/500 as applicable)
- Request validation (required fields, types, bounds, malformed payloads)
- Response schema validation (shape, types, required fields, nullability)
- Idempotency (safe retries of the same request don't double-create)
- Authentication (missing / expired / invalid token is rejected)
- Authorization (each role can only call what it's allowed to, verify at the API, not just the UI)
- Rate limiting (limits enforced; correct 429 and retry-after behavior)
- Backwards / contract compatibility (existing consumers don't break)

Accessibility (optional), include a basic pass for a significant new UI surface when worthwhile; skip for minor UI changes:
- Keyboard navigation (all actions reachable without a mouse; logical tab order)
- Focus management (focus moves correctly into/out of modals and drawers; no traps)
- Screen-reader labels (controls, icons, and form fields have accessible names)
- Color contrast (text and status indicators meet contrast minimums)
- Form error announcements (validation errors are announced, not conveyed by color alone)

### Automation Candidates (optional)

When useful (the team plans to automate, or leadership asks what to automate), include an "Automation Candidates" section after the test-case tables flagging which cases are worth automating first. Skip it otherwise. Prioritize:
- Happy path (high value, stable, run every build)
- Permission / authorization checks (security-critical, tedious by hand)
- Critical validations (the P0 cases for high-risk areas)
- Regression-prone flows (areas that have broken before or are frequently touched)

### Open Questions

If the product spec references fields, settings, or flows that are not yet defined (vague "configuration settings," unspecified error messages, TBD field names), do not guess. Instead, add an "Open Questions" section at the end of the test plan listing each ambiguity explicitly. Example:

> Open Questions
> - What are the exact field labels on the creation form? (Update test cases TF-02, TF-03 once designs are finalized)
> - What error message is shown when provisioning fails? (Update EH-01 once confirmed)

### End-to-End Walkthrough Section

After all test case tables, include an "End-to-End Testing Walkthrough". Write it so a tester who has never seen this application can execute it without guessing or asking anyone. That is the whole purpose: a follow-along script, not a summary. This means:
- Start from zero. Open the browser, go to the exact app URL, and sign in, naming the role or account to use and the fields to fill. Never assume the tester is already on the right page or knows how to get there.
- One concrete action per numbered step. Do not compress. "Add two items and go to checkout" is not one step, it is five: search, open the product, add to cart, open the cart, click checkout. Split every navigation, click, selection, and field entry into its own step.
- Name the exact control and where it is. Put button, link, tab, and field labels in quotation marks and say where they sit, for example: click the "Apply" button to the right of the promo code field; open the cart icon in the top-right; in the row's three-dot menu on the far right, choose "Deactivate".
- Give the exact data to enter: which code, which quantity, which test account, which file. Never "enter some data".
- After each action, state what the tester should see, so a pass or fail is unambiguous. Use "Note that..." for the things to verify. A step with nothing to verify still gets its own line as an action.
- List the preconditions and test data the tester must have staged before step one: accounts, roles, seeded records, feature-flag state, the app URL.
- Cover at minimum: a Happy Path, an error or failure scenario, a validation flow, and a permission or scoping scenario, plus a back-to-back run if the feature is used repeatedly. For mini plans, a single but fully detailed Happy Path is enough.
- It does not repeat every table case, but every step on the path it covers is spelled out, so a stranger could follow it end to end and reproduce the exact result.

### Page Header

At the top of the Confluence page, include this metadata block:

```
product spec: [link or "TBD"]
Jira: [ticket link or "TBD"]
Status: [Discovery / In Progress / etc.]
App URL: [URL of the app being tested, if applicable]
Feature Flag: `flagName` (or omit if no flag)
PM: [name]
```

If designs are not yet finalized, include a prominent note after the header:
> Note: This test plan is based on the product spec user journeys and existing app patterns. Specific field labels, step names, and error messages should be updated once designs are finalized.

---

## Step 4: Publish

This publishing step is intentionally kept separate from plan generation (Steps 1-3). The plan content is destination-agnostic, if the tooling changes (different wiki, new MCP, export to a doc), only this step changes and the generation guidance above stays intact. Generate the full plan first; only then publish.

Publish to the destination chosen in Step 1, using the Atlassian MCP. Default to a Confluence page for medium/full plans; use the Jira ticket description when the user asked for that (common for mini plans). If the user asked for both, do both and share both links.

### Option A: Confluence page

1. Get the accessible Atlassian resources to find the cloud ID
2. Find the appropriate parent page (ask the user which space/parent to use if not obvious, default to the same space as existing QA/test plan pages)
3. Create the page with the full content in markdown format
4. Share the link with the user

Page title format: `[Feature Name]: QA Test Plan`

To find the right space/parent:
- Ask the user, or
- Search Confluence for existing test plan pages to find where they live
- Default to your team's QA/test plan space

### Option B: Jira ticket description

Write the test plan into the description of the relevant Jira ticket using `editJiraIssue`.

1. Get the accessible Atlassian resources to find the cloud ID
2. Confirm the target issue key (for example, `TICKET-1234`), use the ticket already in context if there is one; otherwise ask
3. Do not clobber existing content. First read the current description (`getJiraIssue`). If it already has content, append the plan under a clear `h2.` / `## QA Test Plan` heading rather than overwriting it. Confirm with the user before replacing any existing description text.
4. Update the description via `editJiraIssue`. Keep the markdown table format, the MCP renders it into the ticket. Lead with a one-line note (for example, "QA test plan, mini" plus generated date) so readers know what it is.
5. Share the ticket link with the user

Keep it ticket-sized: a Jira description is not a Confluence page, prefer the mini size here unless the user insists on a larger plan. Omit the metadata header block (the ticket already carries product spec/flag/PM context); keep the test-case tables, a short Happy Path walkthrough, and Open Questions.

---

## Quality Bar

A good test plan from this skill should:
- Match the requested plan size: mini (~10-15, P0 only), medium (~40-60), or full (80+). Medium and full plans should still cover all relevant functional areas, they cut depth within each area, not whole areas. A mini plan covers only core areas (P0) and skips optional sections by design
- For Jira-sourced plans, be grounded in the full context chain: requested issue, parent epic/parent issue, relevant linked issues/subtasks, remote links, and linked product spec/Confluence/design/spec pages. A thin implementation ticket by itself is not enough context
- Go to the destination the user asked for, a Confluence page, a Jira ticket description (without clobbering existing description content), or both
- Cover both happy paths AND error/edge states
- Assign priority by the Step 2 risk assessment, not even distribution, every high-risk area (revenue, security, customer-facing, data integrity, operational) gets P0 coverage and the most depth; low-risk areas get light coverage or are dropped
- Include only the sections the feature actually warrants, as a clean numbered list, don't pad. Accessibility, Test Data Requirements, Automation Candidates, and Functional/Non-Functional grouping are optional extras, used only when they add value
- Apply the granularity patterns above (multi-criterion splits, exact copy, stale state, dashboard recalc, split bundled cases, UI vs API permissions, undo and analytics) where the feature warrants them
- Clarify frontend vs. backend scope before writing, do not write a UI test plan for an API feature or vice versa
- Include an API Validation section for backend-heavy / API features (status codes, request and response-schema validation, idempotency, authn, authz, rate limiting, contract compatibility)
- Include Access and Authentication section for any tool with a login flow
- Include Duplicate Handling cases for any feature that creates a named/unique resource
- Include Post-Creation Verification cases, verify the thing worked downstream and the user can immediately use it without an Engineering handoff
- Include Concurrent Users cases for any creation or provisioning feature
- Include Session / Auth Edge Cases for any feature with multi-step forms or long-running provisioning
- Include a Performance section for any feature involving creation, provisioning, or background processing
- Include Guided Flow and Usability cases for internal tools
- Include Audit Trail cases if the app has an existing audit log
- Include Permissions section covering scoped vs. wildcard access for any authenticated feature
- Include analytics event verification if the feature has tracking
- Include Monitoring section only if confirmed with the user, do not guess the tool
- Have an end-to-end walkthrough with at minimum: Happy Path, Error/Failure scenario, Validation Flow, Permission scenario, and back-to-back scenario for repeatable flows (mini plans: a single Happy Path walkthrough is enough)
- end-to-end walkthroughs must start from the app URL and login step, not mid-flow
- Flag open questions at the end rather than guessing at undefined fields, labels, or error messages
- Use consistent, specific "Verify that..." language throughout
- Confirm scope against the product spec's release sequence before writing, don't include cases for phases that belong to a later ticket
- Not have duplicate section numbers (deduplicate before publishing)

---

## Example Section (for reference)

```markdown
# 1. Access and Authentication

| ID | Test Case | Priority | Status |
| --- | --- | --- | --- |
| AA-01 | Verify that an authorized user can log in via the identity provider and access the tool | P0 | |
| AA-02 | Verify that a user not in the allowed group is redirected to the Unauthorized page | P0 | |
| AA-03 | Verify that an unauthenticated user navigating directly to the feature page is redirected to login | P0 | |
```

---

## Notes

- Always deduplicate section numbers before publishing
- If the user wants to iterate after publishing, update in place: use `updateConfluencePage` for a Confluence page, or `editJiraIssue` for a Jira ticket description
- When writing into a Jira ticket description, never overwrite existing content without confirming, append under a `## QA Test Plan` heading
- If the feature has sub-tickets, reference them in the relevant sections
- If the requested Jira issue is thin and no parent/product spec/design can be found, stop and ask for the missing context before writing the plan
- When a Status column is included, leave it intentionally empty, QA engineers fill it in as they test
- Do not skip the "Open Questions" section if the product spec has gaps, flagging ambiguity is better than inventing test cases based on assumptions

What it produces, at three sizes

Not a blob of text in a chat window. A page your whole team opens and tests against, published to Confluence or written into the ticket. Here are three real plans across three different products: a food-delivery reorder at mini size, an online store's ratings and reviews at medium, and a subscription billing change at full. You see both the range of what it produces and how the detail scales with size. These three are the skill's examples/ folder, the plans it reads before writing yours, which is how its output lands in this house style.

About 12 cases, the P0 critical path for a small feature, freshly created so nothing is run yet. One end-to-end walkthrough, happy path only.

Confluence › Irie Eats › QA scroll the page Mini plan

QA Test Plan

Reorder Your Last Order

Product spec linked Ticket FD-318 QA task FD-340 Status Not started PM Julia Pottinger Flag one_tap_reorder

This plan is based on the product spec and the existing order history. One tap on a past order rebuilds the cart and drops the shopper into a normal, checkable cart. Exact labels and error copy to be confirmed once the designs are final.

1. Rebuild the Cart from a Past Order

IDTest casePriStatus
RO-01 Verify that tapping Reorder on a past order rebuilds the cart with the same items and the same quantities as that order P0
RO-02 Verify that the rebuilt cart is from the chosen restaurant only, so reordering does not mix items from other past orders P0
RO-03 Verify that item options and add-ons from the past order (for example "no onions", an extra side) are carried into the rebuilt cart exactly as they were ordered P0
RO-04 Verify that after a successful reorder the shopper lands on a normal cart screen they can review and edit, not straight onto a placed order P0

2. Unavailable and Changed Items

IDTest casePriStatus
AV-01 Verify that an item that is no longer on the menu is left out of the rebuilt cart and the shopper is told it could not be added P0
AV-02 Verify that an item that is temporarily sold out is shown as unavailable in the rebuilt cart rather than silently added or silently dropped P0
AV-03 Verify that when one or more items could not be added, the cart still rebuilds with the items that are available rather than failing the whole reorder P0

3. Current Prices, Not Old Prices

IDTest casePriStatus
PR-01 Verify that every item in the rebuilt cart is priced at the current menu price, not the price from the past order P0
PR-02 Verify that an item whose price has changed since the past order is rebuilt at the new price and the cart subtotal reflects it P0
PR-03 Verify that the cart subtotal equals the sum of the current item prices times their quantities, with no leftover total carried from the old order P0

4. Restaurant State

IDTest casePriStatus
ST-01 Verify that reordering from a restaurant that is currently closed tells the shopper it is closed rather than building a cart that cannot be checked out P0
ST-02 Verify that reordering from a restaurant that no longer delivers to the saved address handles it cleanly, with a clear message and no broken cart P0

End-to-End Walkthrough

Happy path: reorder a past order and reach a correct cart

  1. Open a browser and go to https://app.irieeats.test.
    • The Irie Eats landing or sign-in page loads with no error.
  2. Click the "Log in" button in the top-right of the page.
    • The sign-in form appears with an email field and a password field.
  3. In the "Email" field, type the test shopper address reorder.shopper@irieeats.test.
  4. In the "Password" field, type the test password Test1234! and click the "Log in" button below the fields.
    • Sign-in succeeds and the shopper lands on the Irie Eats home screen.
    • The account menu in the top-right shows the shopper is signed in, with the one_tap_reorder flag enabled for this account.
  5. Click the account menu in the top-right, then choose "Order history" from the dropdown.
    • The order history page loads and lists past orders, each card showing the restaurant name, the items, and the order date.
  6. Find the most recent order card, which is from a restaurant that is currently open and where every item is still available, and note its restaurant name, items, and quantities.
    • The most recent order is at the top of the list, with a "Reorder" button on the right of the card.
  7. Click the "Reorder" button on the right of that most recent order card.
    • The app rebuilds the cart and opens the cart screen.
    • The cart contains the same items as that past order, with the same quantities.
  8. Check each line item against the items and quantities you noted from the past order.
    • Every item from the past order is present, and no item from any other past order has been mixed in.
    • Each quantity matches the quantity from the past order.
  9. Expand the first line item that had options on the past order, for example an item ordered with "no onions" and an extra side.
    • The item options and add-ons from the past order are carried into this line exactly as they were ordered, for example "no onions" and the extra side are both shown.
  10. Read the price shown on each line in the cart.
    • Each line shows the current menu price for that item, not the price from the old order.
  11. Read the cart subtotal shown near the bottom of the cart screen.
    • The subtotal equals the sum of the current line prices times their quantities, with no leftover total carried from the old order.
  12. Change the quantity of the first line item using its quantity stepper, then change it back.
    • The cart is a normal editable cart, so the quantity can be increased and decreased.
    • The subtotal updates as the quantity changes and returns to its earlier value when set back.
  13. Click the "Go to checkout" button at the bottom of the cart screen.
    • The checkout screen opens, exactly as it does for a cart built by hand.
  14. Confirm the delivery address and the payment method shown on the checkout screen.
    • The saved delivery address and a payment method are shown, and the order total matches the cart subtotal plus any fees, with nothing carried over from the old order.
  15. Place the order using the "Place order" button.
    • The order is placed successfully and an order confirmation screen is shown.
    • Note that this confirms the reordered cart checks out the same as any normal cart.

Test Environment

  • An account with at least one completed past order
  • The one_tap_reorder flag enabled for the test account
  • A past order from a restaurant that is currently open and delivering to the saved address
  • A test menu where at least one item is sold out, one item has been removed, and one item has a changed price since the past order
  • A restaurant that can be set to closed, to test reordering when ordering is not possible
Open Questions
  • What is the exact message when an item from the past order is no longer on the menu? (Affects AV-01)
  • When some items can be added and some cannot, do we still drop the shopper into the cart with what is available, or stop and ask first? (Affects AV-03)
  • When the restaurant is closed, do we block the reorder entirely or build the cart and disable checkout until it opens? (Affects ST-01)

The plans live where the team works, not as an .md file on your laptop. The installable qa-test-plan.skill carries these three as its worked examples and reads the closest match before writing, so a "make a test plan" request lands on a page in this style automatically. Everything above is fictional, written for a made-up store so nothing real is exposed.

The patterns that catch real bugs

Multi-condition logic. When a rule fires on A or B or C, the bug lives in the combinations. Write one case per condition, one where two are true at once, and one at each boundary. The failure is almost always the overlap the code only half-checked.
Exact on-screen wording. When the spec pins a string, assert that exact string, not just that some text appeared. A wrong error message, a leftover placeholder, a typo in a confirmation: copy bugs reach production constantly because no case pinned the words.
Stale view state. After a filter, a sort, a tab switch, or a delete, assert the old rows are gone and the count updated. The classic bug is the row you just removed still sitting there, or a filter that clears on screen while the data underneath does not.
The total recalculates. For every count, sum, average, or badge, check the number after an item is added, removed, and edited, plus the empty-filtered case. Then add one case that the backend total and the on-screen total agree, because a figure read from a cache quietly drifts from the truth.
Hidden is not denied. Hiding a button is not a permission. For each restricted action, write one case that the control is hidden in the interface and a separate case that a direct API call from an unauthorized role is rejected. The real breach is the endpoint that trusts the UI to have hidden it.
Test the promise, not the screen. A green confirmation is not proof the thing happened. After the action, verify the actual record: the row saved with the right values, the entitlement really granted, the email really queued. The worst bugs look perfect on screen and are wrong underneath.
Money, proration, and rounding. Anything that charges, refunds, prorates, or discounts is P0 and has to be pinned to the cent. Test the boundary dates, stacked discounts, partial refunds, and currency rounding, and assert the amount actually charged, not the total the summary screen displays.
Duplicate and double-submit. Double-click the button, retry the request, replay the webhook. A reliable action runs exactly once: one record, one charge, one email, one analytics event. The bug is the impatient tap that bills twice, or the retry that sends a second invite.
Concurrency and last-write-wins. Two users, or two tabs, acting on the same record at the same time. Test that simultaneous edits do not silently clobber each other and that a stale update is rejected rather than quietly accepted. No single-user test will ever see this.
Illegal state transitions. Map the lifecycle and test the moves that should not be allowed: cancel an already-cancelled order, act on an expired invite, edit a deleted item, downgrade a plan that is already downgrading. Bugs hide in the transitions nobody drew on the happy-path diagram.
Empty, first-run, and the edges. The brand-new account with no data, the empty list, a single item, exactly at the limit and one over, zero, negative, a very long name, an emoji, an apostrophe. Happy-path data is the data least likely to break; the edges are where it does.
Failure paths and partial writes. When a dependency times out or errors, the user should get a clear message, not a spinner forever, and the system should not be left half-written. Test the retry, the dunning path, and that a failed step rolls back instead of leaving an order with no payment.