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.
The prompt you reuse
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.
---
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.
QA Test Plan
Reorder Your Last Order
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
| ID | Test case | Pri | Status |
|---|---|---|---|
| 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
| ID | Test case | Pri | Status |
|---|---|---|---|
| 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
| ID | Test case | Pri | Status |
|---|---|---|---|
| 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
| ID | Test case | Pri | Status |
|---|---|---|---|
| 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
- Open a browser and go to https://app.irieeats.test.
- The Irie Eats landing or sign-in page loads with no error.
- 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.
- In the "Email" field, type the test shopper address reorder.shopper@irieeats.test.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
- 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)
About 45 cases across all relevant areas at balanced depth. Partly executed, with a realistic mix of pass and not-run and a couple of fails with linked tickets. Four end-to-end scenarios.
QA Test Plan
Product Ratings and Reviews
This plan is based on the product spec and the existing product page. A shopper who has bought the product can leave a star rating and a written review, optionally attach one photo, and edit or delete their own. Reviews go through moderation before they are public. The product page shows an average rating, a count, sorting, filtering and a helpful vote. Exact labels and copy to be confirmed once the designs are final.
1. Write a Rating and Review
| ID | Test case | Pri | Status |
|---|---|---|---|
| WR-01 | Verify that a shopper who has purchased the product can submit a star rating from one to five and the rating is recorded | P0 | Pass |
| WR-02 | Verify that a shopper can submit a written review together with the star rating and both are stored against their account and the product | P0 | Pass |
| WR-03 | Verify that the star rating is required, so a review cannot be submitted with text but no stars | P0 | Pass |
| WR-04 | Verify that the review text is optional, so a shopper can leave stars only with no written review | P1 | Pass |
| WR-05 | Verify that the review text enforces the stated maximum length and shows a remaining-character count as the shopper types | P2 | Pass |
| WR-06 | Verify that a shopper who has not purchased the product cannot submit a review through the page, and the control to write one is not offered | P0 | Pass |
| WR-07 | Verify that a direct request to the submit-review endpoint from a shopper who has not purchased the product is rejected by the server, not only hidden in the page | P0 | Fail The Write a review control is correctly hidden for a non-purchaser, but posting straight to the submit endpoint with a valid session still creates the review; the purchase check runs only in the page SHOP-2270 |
| WR-08 | Verify that a shopper can leave at most one review per product, so a second submission edits the existing review rather than creating a duplicate | P0 | Pass |
| WR-09 | Verify that leading and trailing whitespace in the review text is trimmed and a review of only spaces is treated as empty | P2 |
2. Optional Photo
| ID | Test case | Pri | Status |
|---|---|---|---|
| PH-01 | Verify that a shopper can attach one photo to a review and it is shown with the review once approved | P1 | Pass |
| PH-02 | Verify that a file of an unsupported type is rejected with a clear message and does not attach | P1 | Pass |
| PH-03 | Verify that a file over the stated size limit is rejected with a clear message naming the limit | P1 | Fail A file above the stated limit is accepted and uploaded; the size check is missing, so oversized images reach moderation SHOP-2274 |
| PH-04 | Verify that a shopper can remove an attached photo before submitting and the review then has no photo | P2 | Pass |
| PH-05 | Verify that the attached photo is held for moderation and is not shown publicly before the review is approved | P0 |
3. Edit and Delete Your Own
| ID | Test case | Pri | Status |
|---|---|---|---|
| ED-01 | Verify that a shopper can edit their own review and the change in stars and text is saved | P0 | Pass |
| ED-02 | Verify that an edited review re-enters moderation before the change is public, so an approved review cannot be edited into something unmoderated | P0 | Fail Editing an already-approved review publishes the new text immediately without going back through moderation SHOP-2278 |
| ED-03 | Verify that a shopper can delete their own review and it is removed from the product page | P0 | Pass |
| ED-04 | Verify that deleting a review updates the average rating and the review count so the deleted rating no longer counts | P0 | Pass |
| ED-05 | Verify that a shopper cannot edit or delete another shopper’s review from the page, and no edit or delete control is shown on reviews that are not theirs | P0 | Pass |
| ED-06 | Verify that a direct request to edit or delete another shopper’s review is rejected by the server, so ownership is enforced on the endpoint and not only in the page | P0 |
4. Moderation
| ID | Test case | Pri | Status |
|---|---|---|---|
| MO-01 | Verify that a newly submitted review is held as pending and is not shown publicly until it is approved | P0 | Pass |
| MO-02 | Verify that an approved review becomes visible on the product page and is included in the average and the count | P0 | Pass |
| MO-03 | Verify that a rejected review is not shown publicly and is not included in the average or the count | P0 | Pass |
| MO-04 | Verify that the author can see the status of their own pending review (for example a "pending review" label) while it is not yet public to others | P1 | Pass |
| MO-05 | Verify that a review whose text trips the banned-words filter is held for moderation rather than auto-published | P1 | |
| MO-06 | Verify that a rejected review can be edited by the author and resubmitted, and the resubmission is moderated again | P1 |
5. Displayed Average and Count
| ID | Test case | Pri | Status |
|---|---|---|---|
| AG-01 | Verify that the displayed average rating equals the mean of all approved ratings, rounded by the stated rule (for example to one decimal place) | P0 | Pass |
| AG-02 | Verify that the displayed review count equals the number of approved reviews, and pending and rejected reviews are not counted | P0 | Pass |
| AG-03 | Verify that approving a new review recalculates the average and increments the count, and the page reflects the new values | P0 | Pass |
| AG-04 | Verify that editing a review’s star rating recalculates the average to use the new rating, not the original | P0 | Fail Editing a review from five stars to two updates the visible stars but the average still reflects the original five, so the average and the shown reviews disagree SHOP-2283 |
| AG-05 | Verify that a product with no approved reviews shows an empty state (no average, a "no reviews yet" message) rather than a zero average or a divide error | P1 | Pass |
| AG-06 | Verify that the star breakdown (how many reviews gave each star value) sums to the displayed review count | P1 | |
| AG-07 | Verify that the average shown on the product card in a listing matches the average shown on the product page for the same product | P1 |
6. Sort and Filter
| ID | Test case | Pri | Status |
|---|---|---|---|
| SF-01 | Verify that sorting reviews by most recent orders them by submission date with the newest first | P1 | Pass |
| SF-02 | Verify that sorting by highest rating and by lowest rating orders the reviews correctly by star value | P1 | Pass |
| SF-03 | Verify that sorting by most helpful orders the reviews by their helpful vote count, highest first | P1 | |
| SF-04 | Verify that filtering by a star value shows only approved reviews with that rating, and the result count matches the star breakdown for that value | P1 | Pass |
| SF-05 | Verify that filtering to "with photos only" shows only approved reviews that have a photo | P1 | Pass |
| SF-06 | Verify that a sort and a filter applied together combine correctly, for example three-star reviews sorted by most helpful | P1 | Fail Applying a star filter resets the active sort back to most recent instead of keeping the chosen sort, so the two controls do not combine SHOP-2287 |
| SF-07 | Verify that a filter that matches no reviews shows a clear empty result for that filter and leaves the average and total count unchanged | P2 | |
| SF-08 | Verify that the chosen sort and filter persist while paging through the reviews and are reflected in the page state | P2 |
7. Helpful Votes
| ID | Test case | Pri | Status |
|---|---|---|---|
| HV-01 | Verify that voting a review helpful increases its helpful count by one and the new count is shown | P1 | Pass |
| HV-02 | Verify that a shopper can vote a given review helpful only once, so a second tap does not keep increasing the count | P0 | Fail Tapping Helpful repeatedly keeps incrementing the count; there is no single-vote guard, so one shopper can inflate a review without limit SHOP-2291 |
| HV-03 | Verify that a shopper can undo their helpful vote and the count goes back down by one | P1 | Pass |
| HV-04 | Verify that undoing a helpful vote emits a "review_vote_removed" analytics event so an undone vote can be told apart from a vote that was never cast | P2 | |
| HV-05 | Verify that a shopper cannot vote on their own review, and the helpful control is not offered on their own review | P2 | Spec does not yet say whether self-voting is blocked or just discouraged; confirming with the product owner |
8. Analytics Events
| ID | Test case | Pri | Status |
|---|---|---|---|
| AN-01 | Verify that submitting a review emits a "review_submitted" event carrying the product id, the star value and whether a photo was attached | P1 | |
| AN-02 | Verify that a helpful vote emits a "review_voted_helpful" event with the review id, so helpful votes can be measured | P2 | |
| AN-03 | Verify that no analytics event includes the full review text or any personal contact detail, only the fields the data spec lists | P0 |
End-to-End Walkthrough
Scenario 1: Write a review with a photo, through moderation, into the average
- Open a browser and go to https://staging.cedarandcalabash.test.
- The Cedar & Calabash staging storefront loads with no error.
- Click the "Sign in" link in the top-right of the storefront.
- The sign-in form appears with an email field and a password field.
- In the "Email" field, type the buyer account address buyer.one@cedarandcalabash.test, in the "Password" field type Test1234!, then click the "Sign in" button.
- Sign-in succeeds and the account name appears in the top-right.
- This account has a completed purchase of the product under test.
- In the search box at the top of the page, type the product name Blue Mahoe Cutting Board and press Enter, then click the matching product in the results.
- The product page for the Blue Mahoe Cutting Board opens and shows the reviews area lower down the page.
- Scroll to the reviews area and read the current average rating and the current review count, and write both numbers down.
- The average rating and the review count are shown at the top of the reviews area.
- Click the "Write a review" button in the reviews area.
- The review form opens.
- The control to write a review is offered because this shopper has purchased the product.
- In the star selector at the top of the form, click the fourth star to set a four-star rating.
- Four of the five stars are filled to show a four-star rating.
- In the "Your review" text box, type the review text Solid board, good weight, cleans up easily.
- The typed text appears in the box and the remaining-character count decreases as you type.
- Click the "Add photo" button, then in the file picker choose the supported image file review-board.jpg.
- The file is accepted.
- A thumbnail of review-board.jpg is shown attached to the review form.
- Click the "Submit review" button at the bottom of the form.
- The form closes and a confirmation that the review was submitted is shown.
- The review is held as pending and is not yet public to other shoppers.
- The author sees their own review with a "pending review" label.
- Reload the product page and re-read the average rating and the review count.
- The average and the count are unchanged from the numbers you wrote down, because the review is not approved yet.
- In a separate tab, go to the moderation queue at https://staging.cedarandcalabash.test/admin/reviews and sign in as the moderator account moderator@cedarandcalabash.test with password Test1234!.
- The moderation queue loads and the pending four-star review for the Blue Mahoe Cutting Board is listed.
- Click the "Approve" button on that pending review row.
- The review moves out of the pending list and is marked approved.
- Return to the product page tab and reload the product page.
- The four-star review and its photo are now public in the reviews area.
- The average rating recalculates to include the four-star value and the review count goes up by one from the number you wrote down.
Scenario 2: Edit your own rating and watch the average follow
- Open a browser and go to https://staging.cedarandcalabash.test, then sign in as buyer.two@cedarandcalabash.test with password Test1234!.
- Sign-in succeeds.
- This account is the author of an already-approved five-star review on the product under test.
- Search for the product name Blue Mahoe Cutting Board and open its product page.
- The product page opens and the reviews area is shown lower down.
- Read the current average rating and the current review count in the reviews area and write both numbers down.
- The average and count are shown at the top of the reviews area and reflect this account’s five-star review among others.
- Find your own review in the list, the one labelled as yours showing five stars.
- Your own review shows a five-star rating and a three-dot menu on the far right of the review row.
- In your review row’s three-dot menu on the far right, choose "Edit".
- The review form reopens pre-filled with your five-star rating and your existing text.
- In the star selector, click the second star to change the rating from five stars to two stars.
- Two of the five stars are now filled.
- Click the "Save changes" button at the bottom of the form.
- The form closes and a confirmation is shown.
- The edited review re-enters moderation before the change is public.
- In a separate tab, open the moderation queue at https://staging.cedarandcalabash.test/admin/reviews, sign in as moderator@cedarandcalabash.test with password Test1234!, and click "Approve" on the edited two-star review.
- The edited review is approved and leaves the pending list.
- Return to the product page tab, reload the page, and find your review again.
- Your review now shows two stars, not five.
- By hand, recompute the expected average using two stars in place of the original five for your review, then compare it with the average shown on the page.
- The displayed average uses the new two-star value, not the original five, and matches your hand calculation by the stated rounding rule.
Scenario 3: Photo validation rejects an oversized file
- Open a browser and go to https://staging.cedarandcalabash.test, then sign in as buyer.three@cedarandcalabash.test with password Test1234!.
- Sign-in succeeds.
- This account has purchased the product under test and has not yet reviewed it.
- Search for the product name Blue Mahoe Cutting Board and open its product page.
- The product page opens and the reviews area is shown.
- Click the "Write a review" button.
- The review form opens.
- Click the third star in the star selector to set a three-star rating.
- Three of the five stars are filled.
- Click the "Add photo" button on the review form.
- A file picker opens.
- In the file picker, choose the image file oversized-photo.jpg, which is above the stated size limit, and confirm the selection.
- The oversized file is rejected with a clear message that names the size limit.
- No thumbnail is attached and the review still has no photo.
- Note that the known defect SHOP-2274 is the opposite of this, where the oversized file is wrongly accepted.
- Click the "Add photo" button again to reopen the file picker.
- The file picker opens again.
- In the file picker, choose the file wrong-type.txt, which is an unsupported type, and confirm the selection.
- The unsupported file is rejected with a clear message.
- No thumbnail is attached.
- In the "Your review" text box, type the review text No stars here.
- The typed text appears in the box.
- In the star selector, click the already-filled third star again to clear the rating back to none.
- The star rating shows as not set.
- Click the "Submit review" button.
- Submission is blocked because the star rating is required.
- A message indicates that a star rating must be chosen, and no review is created.
- Click the third star again to set a three-star rating, then clear all text from the "Your review" box so it is empty.
- Three stars are filled and the review text box is empty.
- Click the "Submit review" button again.
- The review is accepted with stars only, because the written review is optional.
- The review is held as pending for moderation.
Scenario 4: Permission, by page and by endpoint
- Open a browser and go to https://staging.cedarandcalabash.test, then sign in as nonbuyer@cedarandcalabash.test with password Test1234!.
- Sign-in succeeds.
- This account has NOT purchased the product under test.
- Search for the product name Blue Mahoe Cutting Board, open its product page, and scroll to the reviews area.
- No "Write a review" control is shown, because this shopper has not purchased the product.
- Open an API client, for example a REST client, in a separate window.
- The API client is ready to send requests with a chosen session cookie.
- In the API client, send a POST request to https://staging.cedarandcalabash.test/api/reviews with this shopper’s valid session cookie, the product id for the Blue Mahoe Cutting Board, a five-star rating, and the body text Bypassing the page.
- The server rejects the request because the shopper has not purchased the product.
- No review is created and the review count on the product page does not change.
- Note that the known defect SHOP-2270 is exactly this gap, where the post wrongly succeeds.
- In the browser, click the account menu and choose "Sign out".
- The shopper is signed out and returned to a signed-out view.
- Sign in as buyer.one@cedarandcalabash.test with password Test1234!, then open the same Blue Mahoe Cutting Board product page.
- This account has its own approved review and can see other shoppers’ reviews in the list.
- Find a review written by a different shopper in the list and look at its review row.
- No edit or delete control and no three-dot menu is shown on another shopper’s review.
- Note the review id of that other shopper’s review, for example from its link or from the page source.
- You have the other shopper’s review id to use in the next requests.
- In the API client, send a POST request to https://staging.cedarandcalabash.test/api/reviews/<other-review-id>/edit with buyer.one’s session and a changed body text, using that other shopper’s review id.
- The server rejects the edit request because the review does not belong to this shopper.
- In the API client, send a DELETE request to https://staging.cedarandcalabash.test/api/reviews/<other-review-id> with buyer.one’s session, again using the other shopper’s review id.
- The server rejects the delete request because the review does not belong to this shopper.
- Reload the product page.
- The other shopper’s review is still present, confirming the edit and delete attempts had no effect.
Test Environment
- A staging storefront with the product_reviews flag enabled
- A shopper account with a completed purchase of the product under test, and a second shopper account that has not purchased it
- A moderation tool or queue access, to approve and reject submitted reviews
- A product seeded with a spread of approved reviews across all star values, some with photos, for sort and filter
- A product with no reviews, for the empty state
- Supported and unsupported image files, and one image above the stated size limit
- An API client with a valid shopper session, to post directly to the submit, edit and delete endpoints and bypass the page
- Access to the analytics event stream for the staging environment
- Are the purchase check and the ownership check enforced on the submit, edit and delete endpoints, not only in the page? (Affects WR-07 and ED-06)
- When an approved review is edited, must it always re-enter moderation before the change is public? (Affects ED-02)
- What is the rounding rule for the displayed average, and is the product-card average computed the same way as the product-page average? (Affects AG-01 and AG-07)
- Can a shopper vote helpful on their own review, or is that blocked? (Affects HV-05)
- What are the final analytics event names and payloads, and which review fields are allowed in them? (Affects the AN section)
Eighty-five-plus cases, exhaustive: every area plus analytics, monitoring, cross-browser and an explicit regression section. Mid-execution, with many pass, several fails with linked tickets, some not-run and a couple of notes. Six end-to-end scenarios.
QA Test Plan
Plan Upgrade, Downgrade and Proration
This plan is based on the product spec and the existing billing system. A customer can change plan mid-cycle. An upgrade is prorated and charged immediately: a credit for the unused part of the old plan, against a charge for the rest of the cycle on the new plan. A downgrade is scheduled for the end of the current period. Entitlements change with the plan, an invoice is issued for every charge or credit, failed payments enter a retry and dunning flow, and cancellation and refunds follow the stated rules. The flagship monthly plans used throughout are Starter at 20 dollars, Growth at 60 dollars and Scale at 150 dollars. Exact labels and dunning email copy to be confirmed once the designs are final.
1. Upgrade (Immediate, Prorated)
| ID | Test case | Pri | Status |
|---|---|---|---|
| UP-01 | Verify that upgrading from Growth to Scale mid-cycle takes effect immediately and the customer is moved to the Scale plan | P0 | Pass |
| UP-02 | Verify that the upgrade credits the unused portion of the old plan for the days remaining in the current cycle | P0 | Pass |
| UP-03 | Verify that the upgrade charges the new plan for the days remaining in the current cycle, so the prorated charge is the new-plan portion net of the old-plan credit | P0 | Pass |
| UP-04 | Verify that the prorated amount is computed from the daily rate times the days remaining, by the stated proration rule, and matches a hand calculation to the cent | P0 | Pass |
| UP-05 | Verify that the amount shown on the upgrade confirmation screen is exactly the amount charged to the payment method, with no difference between what is shown and what is taken | P0 | Fail On a cycle that includes a partial first day, the confirmation screen shows the prorated charge computed on whole days while the backend charges on a per-second basis, so the customer is charged a few cents more than the screen showed BILL-1471 |
| UP-06 | Verify that an upgrade on the first day of a cycle charges effectively the full new-plan difference, with proration covering the whole remaining period | P0 | Pass |
| UP-07 | Verify that an upgrade on the last day of a cycle prorates to a single remaining day and does not charge a full additional cycle | P0 | Pass |
| UP-08 | Verify that the next renewal after an upgrade bills the full Scale plan price on the normal renewal date, not a further prorated amount | P0 | Pass |
| UP-09 | Verify that upgrading an annual plan mid-term prorates against the remaining months of the year by the stated rule | P1 | |
| UP-10 | Verify that an upgrade with a still-unused credit on the account applies the credit first and charges only the remainder to the payment method | P0 | |
| UP-11 | Verify that two upgrades within the same cycle (Starter to Growth, then Growth to Scale) each prorate from the moment of change and do not double-charge the overlapping days | P0 | Fail A second upgrade in the same cycle prorates the new credit against the original plan price rather than the mid-cycle Growth price, so the customer is over-credited and underpays BILL-1476 |
2. Downgrade (Scheduled at Period End)
| ID | Test case | Pri | Status |
|---|---|---|---|
| DG-01 | Verify that downgrading from Scale to Growth schedules the change for the end of the current period rather than applying it immediately | P0 | Pass |
| DG-02 | Verify that the customer keeps Scale entitlements until the end of the current period, since they have already paid for that period | P0 | Pass |
| DG-03 | Verify that no immediate charge or credit is raised for a scheduled downgrade, because the change happens at the period boundary | P0 | Pass |
| DG-04 | Verify that the scheduled downgrade is shown clearly on the billing page, including the plan it will change to and the date it takes effect | P1 | Pass |
| DG-05 | Verify that at the period boundary the plan changes to Growth, the renewal charges the Growth price, and entitlements drop to the Growth level | P0 | Fail At the boundary the renewal correctly charges the Growth price, but the entitlements stay at Scale, so the customer keeps the higher limits while paying the lower price BILL-1481 |
| DG-06 | Verify that a scheduled downgrade can be cancelled before the period boundary, leaving the customer on the current plan with no change | P0 | Pass |
| DG-07 | Verify that scheduling a downgrade and then upgrading before the boundary clears the scheduled downgrade and applies the upgrade immediately and prorated | P0 | |
| DG-08 | Verify that changing the scheduled target (Scale to Growth, then changed to Scale to Starter) replaces the scheduled downgrade rather than queuing two | P1 | |
| DG-09 | Verify that a downgrade to a plan the customer’s current usage exceeds (for example more seats in use than the lower plan allows) is handled by the stated rule and does not silently break access at the boundary | P0 | |
| DG-10 | Verify that the billing page never offers an immediate-credit option for a downgrade, since downgrades are scheduled and not prorated mid-cycle by the spec | P1 | Pass |
3. Proration Eligibility and Math
| ID | Test case | Pri | Status |
|---|---|---|---|
| PE-01 | Verify that a plan change qualifies for an immediate prorated charge only when it is an upgrade (a higher-priced plan), by the stated eligibility rule | P0 | Pass |
| PE-02 | Verify that a change to a lower-priced plan never raises an immediate prorated charge and is always scheduled for period end | P0 | Pass |
| PE-03 | Verify that a change between two plans of the same price (a side-grade) follows the stated rule for whether it is immediate or scheduled, and raises no unexpected charge | P1 | |
| PE-04 | Verify that the proration credit and charge use the same day-count basis (both on the actual cycle length), so credit and charge cannot be computed on mismatched bases | P0 | Pass |
| PE-05 | Verify that proration over a billing cycle that contains a 29th, 30th or 31st handles the month length correctly and does not drift by a day | P1 | Fail A cycle spanning a 31-day month is prorated as if it were 30 days, so the daily rate is slightly high and the prorated charge is a few cents over a hand calculation BILL-1486 |
| PE-06 | Verify that the prorated total is rounded to the cent by the stated rule and the credit and charge components add up to the rounded total with no half-cent drift | P0 | Pass |
| PE-07 | Verify that proration in a non-dollar currency uses the local minor-unit and rounding rule and still matches a hand calculation | P1 | |
| PE-08 | Verify that a zero-day proration (an upgrade made at the exact period boundary) does not raise a charge of a full extra cycle or a negative amount | P0 | |
| PE-09 | Verify that the proration calculation the customer is shown is computed on the server and not taken from a value the client can change | P0 | Pass |
4. Payment for the Prorated Charge
| ID | Test case | Pri | Status |
|---|---|---|---|
| PY-01 | Verify that an upgrade charges the prorated amount to the card on file and the plan changes only once the charge succeeds | P0 | Pass |
| PY-02 | Verify that a declined card on an upgrade leaves the customer on the old plan, raises no entitlement change, and shows a clear "payment failed" message | P0 | Pass |
| PY-03 | Verify that a successful prorated charge is idempotent, so a retried or double-submitted upgrade does not charge the customer twice | P0 | Fail Submitting the upgrade twice in quick succession (double click) raises two prorated charges and two invoices for the same plan change BILL-1491 |
| PY-04 | Verify that a prorated charge that requires extra cardholder authentication completes the plan change only after the authentication succeeds | P0 | |
| PY-05 | Verify that if the charge succeeds but the plan change then fails to apply, the system either completes the change or reverses the charge, and does not leave a paid-but-not-upgraded state | P0 | |
| PY-06 | Verify that the amount captured at the payment provider matches the invoice total exactly for the prorated charge | P0 | Pass |
5. Invoices and Credit Notes
| ID | Test case | Pri | Status |
|---|---|---|---|
| IN-01 | Verify that an upgrade produces an invoice that itemises the old-plan credit and the new-plan prorated charge and shows the net amount charged | P0 | Pass |
| IN-02 | Verify that the invoice total equals the net prorated amount and matches the amount charged to the card to the cent | P0 | Pass |
| IN-03 | Verify that a credit (for example an unused balance from a downgrade-related adjustment) is recorded as a credit note and is applied to a later invoice rather than lost | P0 | Pass |
| IN-04 | Verify that the invoice shows the correct plan names, the cycle dates, the proration period and any tax line by the stated rule | P1 | Pass |
| IN-05 | Verify that tax on a prorated charge is calculated on the net prorated amount and not on the full plan price | P0 | Fail Tax on an upgrade invoice is calculated on the full Scale plan price rather than the net prorated charge, so the tax line and the invoice total are too high BILL-1496 |
| IN-06 | Verify that the invoice is downloadable and the downloaded document matches the on-screen invoice | P1 | |
| IN-07 | Verify that invoice numbering is sequential and unique across plan-change invoices, with no gaps or duplicates | P1 | |
| IN-08 | Verify that a refund produces a credit note that references the original invoice and shows the refunded amount | P0 |
6. Entitlement Changes
| ID | Test case | Pri | Status |
|---|---|---|---|
| EN-01 | Verify that an upgrade raises the plan limits (for example seats, projects or usage allowance) immediately once the charge succeeds | P0 | Pass |
| EN-02 | Verify that a feature gated to a higher plan becomes available immediately on a successful upgrade to that plan | P0 | Pass |
| EN-03 | Verify that a scheduled downgrade keeps the higher entitlements until the period boundary and drops them exactly at the boundary | P0 | Fail Entitlements do not drop at the downgrade boundary; the customer remains on Scale limits after renewing at the Growth price (same root cause tracked in DG-05) BILL-1481 |
| EN-04 | Verify that a higher-plan feature is not usable through a direct API call once the plan has dropped to a tier that does not include it, not only hidden in the interface | P0 | Fail After a downgrade takes effect the gated feature is hidden in the interface but the API endpoint for it still returns success, so the entitlement is enforced only in the front end BILL-1501 |
| EN-05 | Verify that when a failed payment suspends the subscription, entitlements drop to the suspended state by the stated rule and are restored on recovery | P0 | |
| EN-06 | Verify that entitlement changes from a plan change are reflected consistently across the product, the billing page and the access checks, with no area left on the old tier | P0 | |
| EN-07 | Verify that a downgrade to a plan below current usage applies the stated rule (for example block new creation but keep existing items) and does not delete customer data | P0 |
7. Failed Payment and Dunning
| ID | Test case | Pri | Status |
|---|---|---|---|
| FP-01 | Verify that a failed renewal charge starts the dunning flow and does not immediately cancel the subscription | P0 | Pass |
| FP-02 | Verify that the retry schedule follows the stated rule (for example retries on day 3, day 7 and day 14) and stops as soon as a retry succeeds | P0 | Pass |
| FP-03 | Verify that the customer keeps access during the grace period defined by the spec and only loses access after the final failed attempt | P0 | Pass |
| FP-04 | Verify that a dunning email is sent on the stated schedule and tells the customer how to update their payment method | P1 | Pass |
| FP-05 | Verify that updating the card during dunning triggers an immediate retry, and a successful charge clears the dunning state and restores full access | P0 | Fail After a successful card update and retry the charge succeeds and the invoice is marked paid, but the account stays in the past-due banner state and full access is not restored until the next scheduled job runs BILL-1466 |
| FP-06 | Verify that after the final failed retry the subscription moves to the stated end state (for example cancelled or suspended) and entitlements drop accordingly | P0 | Pass |
| FP-07 | Verify that a failed prorated upgrade charge does not start full dunning on an otherwise current subscription; the upgrade simply does not apply | P0 | |
| FP-08 | Verify that dunning does not double-charge: once a retry succeeds, no further scheduled retry for the same invoice is attempted | P0 | |
| FP-09 | Verify that the past-due state is shown clearly on the billing page with the amount owed and a way to pay it, throughout the dunning window | P1 | |
| FP-10 | Verify that the dunning email copy matches the agreed wording and does not include any full card detail | P1 | Email copy still in review with the lifecycle team; placeholder text in staging is expected for now |
8. Cancellation and Refunds
| ID | Test case | Pri | Status |
|---|---|---|---|
| CR-01 | Verify that cancelling a subscription stops future renewals and leaves access in place until the end of the paid period, by the stated rule | P0 | Pass |
| CR-02 | Verify that a cancellation can be undone (the subscription resumed) before the period boundary with no new charge and no lost data | P1 | Pass |
| CR-03 | Verify that at the period boundary a cancelled subscription ends, entitlements drop to the free or no-access state, and no renewal is charged | P0 | Pass |
| CR-04 | Verify that a refund returns the amount actually charged (including any prorated charge) and not a full plan price the customer never paid | P0 | Fail Refunding a customer who upgraded mid-cycle refunds the full Scale monthly price rather than the prorated amount that was actually charged, over-refunding the difference BILL-1461 |
| CR-05 | Verify that a partial refund reduces the entitlement or period by the stated rule and is reflected on the billing page and in a credit note | P1 | |
| CR-06 | Verify that a refund of a prorated upgrade charge also reverses the entitlement change if the plan is reverted, so the customer is not left on the higher plan after a full refund | P0 | |
| CR-07 | Verify that the refunded amount at the payment provider matches the credit note to the cent | P0 |
9. Abuse and Permissions
| ID | Test case | Pri | Status |
|---|---|---|---|
| AB-01 | Verify that the plan-change endpoint requires the request to belong to the account it is changing, so a user cannot change another account’s plan | P0 | |
| AB-02 | Verify that only a user with the billing role can change the plan, and the change controls are hidden for members without that role | P0 | Pass |
| AB-03 | Verify that a direct plan-change request from a member without the billing role is rejected by the server, so the permission is enforced on the endpoint and not only hidden in the interface | P0 | Fail The change-plan controls are correctly hidden for a non-billing member, but posting directly to the plan-change endpoint with that member’s session succeeds and changes the plan BILL-1456 |
| AB-04 | Verify that the prorated amount and the target plan are taken from the server, so a tampered request that lowers the charge or jumps to a higher plan for less money is rejected | P0 | |
| AB-05 | Verify that a one-time upgrade offer or trial credit can be redeemed only once per account and cannot be reused by repeatedly upgrading and downgrading | P0 | |
| AB-06 | Verify that rapid repeated plan changes are handled safely (rate limited or serialised) and do not produce inconsistent proration or duplicate charges | P0 |
10. Analytics Events
| ID | Test case | Pri | Status |
|---|---|---|---|
| AN-01 | Verify that an upgrade emits a "plan_upgraded" event carrying the account id, the old and new plan, and the net prorated amount charged | P1 | Pass |
| AN-02 | Verify that a downgrade emits a "plan_downgrade_scheduled" event with the target plan and the effective date | P1 | |
| AN-03 | Verify that cancelling a scheduled downgrade emits a "plan_downgrade_cancelled" event so a scheduled-then-cancelled change can be told apart from one that took effect | P2 | |
| AN-04 | Verify that a failed payment and each dunning step emit events that let recovery be measured from the data | P1 | |
| AN-05 | Verify that the revenue figure on the upgrade event matches the net prorated amount on the invoice, so reporting agrees with billing | P0 | Fail The plan_upgraded event reports the full new-plan price as revenue rather than the net prorated charge, so analytics overstates upgrade revenue against the invoices BILL-1499 |
| AN-06 | Verify that no analytics event includes full card details or any payment credential, only the billing fields the data spec lists | P0 | Pass |
11. Monitoring and Backend Health
| ID | Test case | Pri | Status |
|---|---|---|---|
| MO-01 | Verify that a mismatch between the amount shown to the customer and the amount charged is logged as a distinct error class and alerts, because it means the wrong amount was taken | P0 | |
| MO-02 | Verify that the plan-change and payment endpoints record request count, error rate and latency so a spike in failed plan changes is visible on the dashboard | P1 | |
| MO-03 | Verify that dunning recovery rate (retries that succeed) is queryable, so a drop in recovery can be caught from the data | P2 | |
| MO-04 | Verify that the scheduled job that applies downgrades and runs dunning retries at the period boundary is monitored, and a missed or failed run alerts rather than silently leaving plans unchanged | P0 | |
| MO-05 | Verify that when the payment provider is slow or unavailable, plan changes fail cleanly with a retry message and the rest of the billing page still works | P0 | |
| MO-06 | Verify that proration and charge amounts are reconciled against the payment provider on a schedule, so any drift between the invoice total and the captured amount is surfaced | P0 | Reconciliation job is planned but not yet in staging; tracked separately, not a blocker for this release |
12. Cross-Browser and Responsive
| ID | Test case | Pri | Status |
|---|---|---|---|
| BX-01 | Verify that upgrade, downgrade and cancellation flows work and the prorated amounts show correctly on the latest Chrome | P1 | Pass |
| BX-02 | Verify that upgrade, downgrade and cancellation flows work and the prorated amounts show correctly on the latest Safari | P1 | Pass |
| BX-03 | Verify that upgrade, downgrade and cancellation flows work and the prorated amounts show correctly on the latest Firefox | P1 | Pass |
| BX-04 | Verify that upgrade, downgrade and cancellation flows work and the prorated amounts show correctly on the latest Edge | P2 | |
| BX-05 | Verify that the plan-change screens and the proration summary are usable on mobile Safari (iOS), with the confirmation amount and button visible without obstruction | P1 | Fail On mobile Safari the confirm-upgrade button is pushed below the fold by the proration breakdown and the sticky footer, so the customer cannot reach Confirm without an awkward scroll BILL-1494 |
| BX-06 | Verify that the plan-change screens and the proration summary are usable on mobile Chrome (Android) | P1 | Pass |
| BX-07 | Verify that the plan-change flow is reachable and operable by keyboard alone with a visible focus state across the supported browsers | P1 | |
| BX-08 | Verify that the proration breakdown and the invoice remain legible at 200 percent browser zoom and at a narrow viewport without clipping | P2 |
13. Regression: Existing Billing and Flag Off
| ID | Test case | Pri | Status |
|---|---|---|---|
| RG-01 | Verify that with the plan_change_v2 flag off, the billing page and renewals behave exactly as before this feature and no proration is offered | P0 | Pass |
| RG-02 | Verify that a normal on-cycle renewal with no plan change charges the full plan price correctly with the flag on | P0 | Pass |
| RG-03 | Verify that an account already mid-dunning when the flag is turned on continues its existing retry schedule without being reset or double-charged | P0 | |
| RG-04 | Verify that existing tax calculation on full-price renewals is unchanged by the proration feature | P0 | Pass |
| RG-05 | Verify that a plan that was changed under the old flow keeps its correct plan, entitlements and renewal date after the new flag is enabled | P1 | |
| RG-06 | Verify that a previously scheduled downgrade created under the old behaviour still takes effect correctly at its boundary after the flag change | P1 | |
| RG-07 | Verify that the renewal confirmation email and the receipt for a full-price renewal are unchanged, with the charged amount matching the invoice | P1 | Fail After enabling the flag, the renewal receipt email for an upgraded account shows the old plan name and the pre-upgrade price while the charge is the new plan, so the receipt and the charge disagree BILL-1489 |
| RG-08 | Verify that the account billing-history view shows past invoices and credit notes correctly alongside the new plan-change invoices | P1 | |
| RG-09 | Verify that downstream revenue reporting totals reconcile against the invoices before and after the feature, so the change does not silently shift reported revenue | P0 | |
| RG-10 | Verify that the billing page load time and the time to apply a plan change are not noticeably worse with the feature enabled | P1 |
End-to-End Walkthrough
Scenario 1: Upgrade mid-cycle, charge what was shown
- Open a browser and go to https://staging.tallawah.test.
- The Tallawah Billing staging app loads with no error.
- Click the "Sign in" button, then in the "Email" field type billing.admin@tallawah.test, in the "Password" field type Test1234!, and click "Sign in".
- Sign-in succeeds and the account dashboard loads.
- This account is on the Growth plan at 60 dollars and is partway through its cycle, and this user has the billing role.
- In the left navigation, click "Billing".
- The billing page loads and shows the current plan as Growth, the cycle dates, and the next renewal date.
- Note the cycle start date, the cycle end date, and today’s date shown on the billing page, so the remaining days can be counted.
- The cycle start, cycle end, and current date are all visible, which fixes the number of days remaining in the cycle.
- Click the "Change plan" button on the billing page.
- A plan picker opens listing Starter at 20 dollars, Growth at 60 dollars, and Scale at 150 dollars.
- Click "Scale" at 150 dollars, then click the "Continue" button.
- A proration breakdown screen opens for the Growth to Scale upgrade.
- Read the proration breakdown line by line, noting the credit line for the unused Growth days and the charge line for the remaining days on Scale.
- The breakdown shows a credit for the unused part of Growth and a charge for the remaining days on Scale.
- A net amount due today is shown at the bottom of the breakdown.
- By hand, compute the expected net using the Growth daily rate times the days remaining as the credit and the Scale daily rate times the days remaining as the charge, then compare with the net amount shown.
- The net amount is computed on the server and matches your hand calculation to the cent.
- Write down the exact net amount shown on the confirmation screen.
- The net amount due today is recorded so it can be checked against the actual charge.
- Click the "Confirm upgrade" button.
- The payment step runs against the card on file using the test success card 4242 4242 4242 4242.
- Wait for the confirmation that the upgrade is complete.
- The amount charged matches the net amount you wrote down from the confirmation screen exactly.
- The plan on the billing page now shows Scale.
- Open a Scale-only feature in the product, for example one gated to the Scale plan.
- The Scale entitlements are available immediately, so the gated feature can now be used.
- On the billing page, open the most recent invoice for this account.
- The invoice itemises the old-plan credit and the new-plan prorated charge and shows the net amount.
- The invoice total equals the net amount charged to the card to the cent.
- On the billing page, read the next renewal date and the amount it will bill.
- The next renewal is dated normally and will bill the full Scale price of 150 dollars, not a further prorated amount.
Scenario 2: Schedule a downgrade and let it take effect
- Open a browser and go to https://staging.tallawah.test, then sign in as billing.admin@tallawah.test with password Test1234!.
- Sign-in succeeds.
- Use an account that is currently on the Scale plan at 150 dollars.
- In the left navigation, click "Billing".
- The billing page loads and shows the current plan as Scale and the current period end date.
- Click the "Change plan" button.
- The plan picker opens listing Starter, Growth, and Scale.
- Click "Growth" at 60 dollars, then click "Continue".
- Because Growth is a lower-priced plan, the screen states the change is scheduled for the end of the current period and offers no immediate-credit option.
- No proration charge or credit is shown for this downgrade.
- Click the "Schedule downgrade" button.
- A confirmation is shown that the downgrade is scheduled.
- No immediate charge or credit is raised.
- Read the scheduled-change banner on the billing page.
- The billing page shows the scheduled change, the target plan Growth, and the date it takes effect, which is the current period end.
- Open a Scale-only feature in the product right now, before the boundary.
- Scale entitlements remain available, because the period that was paid for has not ended.
- Using the staging clock control, advance the clock to just past the current period boundary so the scheduled job runs.
- The clock moves past the period end and the scheduled downgrade job runs.
- Reload the billing page.
- The current plan now shows Growth.
- The renewal charged the Growth price of 60 dollars.
- Try to open the same Scale-only feature in the product interface.
- The feature is no longer offered in the interface.
- Note that the known defect BILL-1481 is that entitlements wrongly stay at Scale at this boundary, so this is the step that exposes it.
- In an API client, send a request to the Scale-only feature endpoint with this account’s session, for example POST https://staging.tallawah.test/api/scale-feature.
- The server rejects the call because the entitlement is gone after the downgrade.
- Note that the known defect BILL-1501 is that this endpoint wrongly still returns success, so this step exposes it.
Scenario 3: Failed payment, dunning and recovery
- Open a browser and go to https://staging.tallawah.test, then sign in as billing.admin@tallawah.test with password Test1234!.
- Sign-in succeeds.
- Use an account on a current paid subscription whose card on file is the test decline card 4000 0000 0000 0002.
- In the left navigation, click "Billing", and note the current renewal date.
- The billing page shows the subscription as current with a renewal date coming up.
- Using the staging clock control, advance the clock to the renewal date so the renewal charge runs against the decline card.
- The renewal charge fails because the card declines.
- The subscription enters the dunning flow rather than cancelling at once.
- Reload the billing page.
- A past-due state is shown with the amount owed and a way to pay it.
- Access to the product continues during the grace period.
- Advance the clock to the first scheduled retry date by the stated schedule, for example day 3, and let the retry run.
- The retry runs on the stated schedule and fails again because the card still declines.
- The subscription stays in dunning and access still continues during the grace period.
- Open the staging email inbox for the account and find the dunning email.
- A dunning email has been sent on the stated schedule.
- The email explains how to update the payment method and contains no full card detail.
- Return to the billing page and click the "Update payment method" button.
- A card-entry form opens.
- In the card-entry form, type the test success card number 4242 4242 4242 4242, a future expiry date, and any valid test security code.
- The card fields accept the test values with no validation error.
- Click the "Save card" button.
- The new card is saved against the account.
- Observe the retry that follows the card update.
- An immediate retry runs and the charge succeeds on the new card.
- Open the renewal invoice for this account.
- The invoice for the renewal is now marked paid.
- Reload the billing page and check the account state and the past-due banner.
- The dunning state and the past-due banner clear and full access is restored without waiting for the next scheduled job.
- Note that the known defect BILL-1466 is that the banner wrongly persists until the next scheduled job, so this step exposes it.
Scenario 4: Proration math and money verification, to the cent
- Open a browser and go to https://staging.tallawah.test, then sign in as billing.admin@tallawah.test with password Test1234!.
- Sign-in succeeds.
- Use a Growth account whose current cycle spans a 31-day month, so month length is exercised.
- In the left navigation, click "Billing", and write down the cycle start date, the cycle end date, and today’s date.
- The cycle is 31 days long, and the days remaining in the cycle can be counted from these dates.
- By hand, compute the Growth daily rate as 60 dollars divided by the actual cycle length in days, and the Scale daily rate as 150 dollars divided by the same cycle length.
- Both daily rates use the same actual cycle length, so credit and charge are on the same day-count basis.
- By hand, compute the expected credit as the Growth daily rate times the days remaining, the expected charge as the Scale daily rate times the days remaining, and the expected net as charge minus credit, rounded to the cent by the stated rule.
- You now have an expected credit, charge, and net to compare against the screen.
- On the billing page, click the "Change plan" button.
- The plan picker opens listing Starter, Growth, and Scale.
- Click "Scale" at 150 dollars, then click the "Continue" button.
- The proration breakdown screen opens for the Growth to Scale upgrade.
- Compare the credit line on the breakdown with your hand-computed credit.
- The credit line matches your hand-computed Growth credit for the days remaining.
- Note that the known defect BILL-1486 is that a 31-day cycle is wrongly prorated as 30 days, so the daily rate runs slightly high here, which this comparison exposes.
- Compare the charge line and the net total on the breakdown with your hand-computed charge and net.
- The charge line and the net total match your hand calculation, and the credit and charge components add up to the rounded net total with no half-cent drift.
- Write down the exact net total shown on the breakdown.
- The net total is recorded so it can be checked against the invoice and the captured charge.
- Click the "Confirm upgrade" button and complete payment with the test success card 4242 4242 4242 4242.
- The upgrade completes and a charge is taken.
- Open the resulting invoice from the billing history.
- The invoice opens and itemises the Growth credit and the Scale prorated charge.
- Read the tax line and the total on the invoice.
- The tax line is calculated on the net prorated amount, not on the full Scale plan price.
- Note that the known defect BILL-1496 is that tax is wrongly calculated on the full plan price, so the tax line and total are too high, which this step exposes.
- Open the payment provider dashboard in test mode and find the captured charge for this account.
- The amount captured at the provider matches the invoice total exactly, and matches the net total you wrote down from the breakdown.
Scenario 5: Permission, by interface and by endpoint
- Open a browser and go to https://staging.tallawah.test, then sign in as the account member member.nobilling@tallawah.test with password Test1234!.
- Sign-in succeeds.
- This member belongs to the account but does NOT have the billing role.
- In the left navigation, click "Billing".
- The billing page loads but the change-plan controls are not shown, because this member lacks the billing role.
- Open an API client in a separate window and load this member’s valid session cookie into it.
- The API client is ready to send requests as the non-billing member.
- In the API client, send a POST request to https://staging.tallawah.test/api/subscription/change-plan with this member’s session and a body asking to change the plan to Scale.
- The server rejects the request because the member lacks the billing role.
- The plan does not change and no charge is raised.
- Note that the known defect BILL-1456 is that this post wrongly succeeds, so this step exposes it.
- In the browser, click the account menu and choose "Sign out".
- The member is signed out.
- Sign in as the billing user billing.admin@tallawah.test with password Test1234!.
- Sign-in succeeds and this user has the billing role.
- Load this billing user’s valid session cookie into the API client.
- The API client is now ready to send requests as the billing user.
- On the billing page, start a Growth to Scale upgrade and capture the change-plan request the browser sends, then cancel out of the upgrade before confirming.
- You have a captured change-plan request to modify and replay.
- No upgrade is applied, because you cancelled before confirming.
- In the API client, resend the captured request with the net amount field lowered well below the server-computed proration.
- The amount is taken from the server, not the request, so the tampered low amount is rejected and no undercharge is taken.
- In the API client, resend the captured request with the target plan field changed to Scale while the amount field is left at the Growth proration.
- The target plan and the amount are taken from the server, not the request, so the tampered request is rejected.
- No plan jump to Scale for less money is allowed and no incorrect charge is taken.
- In the API client, resend the captured request with the account id field set to a different account than the one the session belongs to.
- The server rejects the request because it does not belong to the account it is trying to change.
- Reload the billing page for the billing user’s own account.
- The plan is unchanged by any of the tampered requests and no unexpected charge appears in the billing history.
Scenario 6: Cancel and refund the right amount
- Open a browser and go to https://staging.tallawah.test, then sign in as billing.admin@tallawah.test with password Test1234!.
- Sign-in succeeds.
- Use an account that upgraded to Scale mid-cycle earlier today, so a prorated charge was taken today.
- In the left navigation, click "Billing".
- The billing page shows the account on the Scale plan with a recent prorated upgrade charge.
- Find today’s prorated upgrade charge in the billing history and write down its exact amount.
- The prorated amount actually charged today is recorded so the refund can be checked against it.
- Click the "Cancel subscription" button.
- A cancellation confirmation dialog opens.
- Confirm the cancellation in the dialog.
- Future renewals stop.
- Access remains in place until the end of the paid period.
- Open the upgrade invoice from today from the billing history.
- The upgrade invoice opens, itemising the Growth credit and the Scale prorated charge.
- Click the "Refund" action on that invoice.
- A refund form opens showing the amount available to refund for this invoice.
- Confirm the refund of the plan change.
- The refund is for the prorated amount you wrote down, not a full Scale plan price of 150 dollars.
- Note that the known defect BILL-1461 is that the full Scale price is wrongly refunded, so this step exposes it.
- Open the credit note produced by the refund.
- The credit note references the original invoice and shows the refunded amount, which matches the prorated charge.
- Open the payment provider dashboard in test mode and find the refund for this account.
- The refunded amount at the provider matches the credit note to the cent.
- If the refund reverts the plan as part of the flow, try to open a Scale-only feature in the product interface.
- The customer is not left on Scale after a full refund of the upgrade, so the Scale-only feature is no longer offered.
- In the API client, send a request to the Scale-only feature endpoint with this account’s session.
- The server rejects the call, confirming the entitlement was reverted along with the refund and not only hidden in the interface.
Scenario 7: Regression, flag off and existing renewals
- In the staging admin, turn the plan_change_v2 flag off.
- The flag is off for the staging environment.
- Open a browser and go to https://staging.tallawah.test, then sign in as billing.admin@tallawah.test with password Test1234!.
- Sign-in succeeds.
- Use an account on an unchanged plan with a renewal coming up.
- In the left navigation, click "Billing".
- The billing page behaves as before this feature and offers no proration option.
- Using the staging clock control, advance the clock to the renewal date and let the normal renewal run.
- The full plan price is charged correctly.
- No proration is offered or applied.
- Open the renewal receipt email for this account from the staging inbox.
- The renewal confirmation email and the receipt are unchanged from before this feature.
- Open the renewal invoice for this account and compare the charged amount with the receipt.
- The charged amount on the receipt matches the renewal invoice.
- In the staging admin, turn the plan_change_v2 flag back on.
- The flag is on for the staging environment.
- Sign in to a Growth account and click "Billing", then click the "Change plan" button.
- The plan picker opens listing Starter, Growth, and Scale.
- Click "Scale" at 150 dollars, click "Continue", then click "Confirm upgrade" and complete payment with the test success card 4242 4242 4242 4242.
- The upgrade completes and a prorated charge is taken.
- Open the receipt email for this upgrade from the staging inbox.
- The receipt shows the new Scale plan and the charged prorated amount, consistent with the invoice.
- Note that the known defect BILL-1489 is that the receipt wrongly shows the old plan name and pre-upgrade price, so this step exposes it.
- Open the account billing-history view.
- Billing history shows the past invoices and credit notes together with the new plan-change invoice, all correctly.
- Open the revenue report for the period and reconcile its totals against the invoices for the same period.
- The reported totals reconcile against the invoices, with no silent shift from the feature.
- Note that the known defect BILL-1499 is that the upgrade event reports the full new-plan price as revenue rather than the net prorated charge, so the report can overstate revenue here.
Test Environment
- A staging billing environment with the plan_change_v2 flag toggleable, and the payment provider in test mode
- Accounts seeded on each plan (Starter 20 dollars, Growth 60 dollars, Scale 150 dollars) at known points in their cycles
- A way to advance the clock or set the cycle boundary, to run scheduled downgrades and dunning retries
- Test cards for success, decline, and a card that requires extra cardholder authentication
- An account already mid-dunning, and an account with a scheduled downgrade, for regression after the flag change
- Cycles spanning a 30-day month and a 31-day month, plus a non-dollar currency configuration, for proration math
- An account whose usage exceeds a lower plan, for the over-limit downgrade rule
- A billing user and an account member without the billing role, plus an API client with each session, for permission and endpoint checks
- The ability to make the payment provider slow or unavailable, for graceful-degradation testing
- Access to the analytics event stream and the monitoring dashboards for the staging environment
- The supported browser matrix (Chrome, Safari, Firefox, Edge) and mobile Safari and mobile Chrome devices
- Access to the invoice and credit-note records and the payment provider dashboard, to reconcile shown amounts against captured amounts
- Is proration computed on whole days or on a finer basis, and which one should the confirmation screen show so it matches the charge? (Affects UP-05 and the PE section)
- On a second upgrade within one cycle, what price is the new credit computed against: the original plan or the mid-cycle plan? (Affects UP-11)
- At a downgrade boundary, what exactly drives the entitlement drop, and why is it not firing with the price change? (Affects DG-05, EN-03 and EN-04)
- Is tax on a prorated upgrade meant to be on the net prorated charge or the full plan price? (Affects IN-05)
- On a refund of a mid-cycle upgrade, do we refund the prorated amount actually charged, and is the plan reverted with it? (Affects CR-04 and CR-06)
- After a successful card update during dunning, should access be restored immediately rather than on the next scheduled job? (Affects FP-05)
- Are all permission, ownership and amount checks enforced on the plan-change and payment endpoints, not only in the interface? (Affects AB-01, AB-03 and AB-04)
- Should the revenue figure on the upgrade analytics event be the net prorated charge so it reconciles with the invoice? (Affects AN-05 and RG-09)
- What is the expected behaviour when the payment provider is unavailable: block the plan change only, or block the billing page? (Affects MO-05)
- What are the final dunning email copy and the analytics event names and payloads for the plan-change and dunning lifecycle? (Affects FP-10 and the AN section)
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.