How to Test Gift Cards on Web (Complete Guide)
Gift cards are a high‑value touchpoint for any e‑commerce site. They sit at the intersection of commerce, finance, and user experience, making them a prime target for bugs that can leak money, frustra
Why Gift Card Testing Matters
Gift cards are a high‑value touchpoint for any e‑commerce site. They sit at the intersection of commerce, finance, and user experience, making them a prime target for bugs that can leak money, frustrate customers, or expose compliance gaps. A single mis‑handled code can allow an attacker to generate unlimited credit, while a confusing UI can cause legitimate users to abandon a purchase and never return. Because gift‑card flows often involve multiple steps—selection, amount entry, personalization, payment, delivery, and redemption—defects can hide in any of those stages and only surface under specific combinations of data, device, or user behavior.
Testing gift cards therefore requires a disciplined approach that goes beyond “does the button work?”. You need to verify that the system correctly enforces business rules, protects against abuse, remains accessible to all users, and integrates cleanly with payment gateways and order‑management systems. The following sections give you a complete playbook: a concrete test matrix, manual and automated techniques, tooling tips, and a look at how autonomous, persona‑driven exploration can surface issues that scripted tests never think to try.
---
Gift Card Flow Overview
Before writing test cases, map the typical web‑based gift‑card journey. Although each implementation varies, most share these logical blocks:
| Block | Typical Actions | Key Data Points |
|---|---|---|
| Selection | User browses gift‑card catalog, picks a design or brand | cardId, designId, priceTier |
| Amount Entry | User chooses a preset amount or enters a custom value | amount, currency, minAmount, maxAmount |
| Personalization | Optional message, recipient name, delivery date | senderName, recipientName, message, deliveryDate |
| Payment | User adds card to cart, proceeds to checkout, pays with credit card, PayPal, etc. | paymentMethod, transactionId, tax, shippingFee |
| Confirmation | System shows order summary, sends email/SMS with code | orderId, giftCardCode, expiryDate |
| Delivery | Code delivered via email, SMS, or downloadable PDF | deliveryChannel, timestamp |
| Redemption (often tested separately) | Recipient enters code at checkout, system validates and applies balance | code, appliedAmount, remainingBalance |
Each block presents its own validation surface. For example, the amount block must reject non‑numeric input, enforce min/max limits, and handle currency rounding correctly. The personalization block may need to sanitize HTML to prevent XSS. The payment block must correctly invoke the gateway and handle asynchronous callbacks. The delivery block must ensure the code is transmitted only once and is not exposed in logs or client‑side storage. Mapping these blocks helps you build a matrix that covers every combination of valid and invalid data.
---
Test Matrix
Below is a comprehensive matrix that you can copy into a test‑management tool. Each row represents a distinct scenario; columns indicate the expected outcome and the type of test (manual, automated, or both).
| ID | Flow Block | Description | Input / Condition | Expected Result | Test Type |
|---|---|---|---|---|---|
| GC‑01 | Selection | Happy path – pick first available design | Valid cardId | Card added to cart, price shown correctly | Both |
| GC‑02 | Selection | Invalid design ID | Non‑existent designId | Error message: “Design not found” | Manual |
| GC‑03 | Amount Entry | Preset amount selection | Click $25 preset | Amount field shows 25.00, total updates | Both |
| GC‑04 | Amount Entry | Custom amount within limits | Enter 15.00 (min=10, max=500) | Accepted, total = 15.00 | Both |
| GC‑05 | Amount Entry | Custom amount below minimum | Enter 5.00 | Inline validation: “Amount must be at least $10.00” | Manual |
| GC‑06 | Amount Entry | Custom amount above maximum | Enter 1000.00 | Inline validation: “Amount cannot exceed $500.00” | Manual |
| GC‑07 | Amount Entry | Non‑numeric input | Enter “abc” | Field rejects, shows error “Please enter a valid number” | Both |
| GC‑08 | Amount Entry | Decimal precision | Enter 10.005 | System rounds to 10.01 (or rejects based on policy) | Automated |
| GC‑09 | Personalization | Empty sender name | Leave sender blank | Warning: “Sender name is required” (if required) | Manual |
| GC‑10 | Personalization | HTML injection in message | | Message sanitized, script not executed | Automated (security) |
| GC‑11 | Personalization | Long message > 200 chars | 250‑character string | Truncated to 200 or error if limit enforced | Both |
| GC‑12 | Payment | Successful credit‑card charge | Valid test card (e.g., 4242…) | Order created, payment status = succeeded | Both |
| GC‑13 | Payment | Declined card | Test card 4000 0000 0000 0002 | Payment error shown, order not created | Manual |
| GC‑14 | Payment | Missing CVV | CVV field empty | Inline error: “CVV is required” | Manual |
| GC‑15 | Payment | Duplicate submission (double click) | Click Pay twice quickly | Only one transaction processed, second click shows “Processing…” or disabled button | Automated |
| GC‑16 | Payment | Payment gateway timeout | Simulate gateway delay >30s | User sees timeout message, option to retry | Manual |
| GC‑17 | Confirmation | Email contains correct code | After successful payment | Email body includes alphanumeric code matching DB | Automated |
| GC‑18 | Confirmation | Code exposed in URL | After redemption, URL shows ?code=ABC123 | No code in URL; only token or session identifier | Automated (privacy) |
| GC‑19 | Delivery | SMS delivery fails (invalid number) | Enter malformed phone number | Error: “Invalid phone number”, no SMS sent | Manual |
| GC‑20 | Delivery | Email bounce handling | Send to non‑existent domain | System logs bounce, shows “Delivery failed” in order history | Manual |
| GC‑21 | Redemption | Valid code applied | Enter correct code at checkout | Balance reduced by gift‑card amount, order total updated | Both |
| GC‑22 | Redemption | Invalid code format | Enter “123” (too short) | Error: “Invalid gift‑card code” | Manual |
| GC‑23 | Redemption | Expired code | Use code with past expiry date | Error: “This gift card has expired” | Manual |
| GC‑24 | Redemption | Already used code | Re‑use same code | Error: “Gift card already redeemed” | Manual |
| GC‑25 | Redemption | Code case sensitivity | Enter lower‑case version of upper‑case code | System treats as invalid (if case‑sensitive) or accepts (if normalized) | Both |
| GC‑26 | Accessibility | Keyboard navigation | Tab through gift‑card form | All interactive elements reachable, visible focus indicator | Manual |
| GC‑27 | Accessibility | Screen reader labels | Use NVDA/JAWS | Each field announces purpose (e.g., “Gift card amount, edit text”) | Manual |
| GC‑28 | Accessibility | Color contrast | Verify text vs background ratios | Minimum 4.5:1 for normal text, 3:1 for large text | Automated (axe) |
| GC‑29 | Security | Rate limiting on code generation | Attempt 100 requests/min to generate codes | After threshold, HTTP 429 Too Many Requests | Automated |
| GC‑30 | Security | SQL injection via amount field | Enter 10'; DROP TABLE giftcards;-- | Input sanitized, no DB error, validation fails | Automated |
| GC‑31 | Privacy | Logging of full code | Check server logs after purchase | Only last 4 digits or hash stored, full code never logged | Manual (log review) |
| GC‑32 | Internationalization | Currency switch | Change site locale to EUR, amounts in euros | All amounts display with € symbol, correct conversion if applicable | Both |
| GC‑33 | Edge case – concurrent redemption | Two users try same code at same time | Simultaneous requests | Only first succeeds, second gets “already used” | Automated (stress) |
| GC‑34 | Edge case – zero‑amount card | Create card with amount 0.00 | Allowed by business? | If not allowed, validation error; if allowed, code behaves like a promotional token | Manual |
| GC‑35 | Edge case – negative amount | Attempt to enter –5.00 | System rejects | Validation error: “Amount must be greater than zero” | Manual |
| GC‑36 | Edge case – maximum length fields | Enter 500‑char sender name | If limit 100, truncated or error | Consistent handling per spec | Manual |
| GC‑37 | Edge case – special characters in recipient name | Enter “O’Connor‑Jean” | Apostrophe and hyphen accepted | Name stored correctly, no SQL error | Manual |
| GC‑38 | Edge case – timezone on delivery date | Select delivery date in future, user in different TZ | Code delivered at correct UTC time | Delivery timestamp matches user’s selected local date | Manual |
| GC‑39 | Edge case – disabled JavaScript | Disable JS, load gift‑card page | Fallback to server‑rendered form | Form still functional, albeit with full‑page reloads | Manual |
| GC‑40 | Edge case – slow network (3G) | Throttle network to 3G speeds | All steps complete, no timeouts | UI shows loading spinners, no broken states | Manual (DevTools) |
How to use the matrix
- Assign each ID to a test case in your test‑management system.
- Mark “Both” for scenarios you will automate *and* verify manually (e.g., happy path, security checks).
- For “Manual” only, consider exploratory testing or checklist verification.
- Keep the matrix under version control; when a new gift‑card feature (e.g., bulk purchase) is added, extend the table with new rows.
---
Manual Testing Approach
Even with strong automation, manual testing remains essential for exploratory work, usability checks, and validation of edge cases that are hard to script. Follow this step‑by‑step routine for each release candidate.
1. Environment Preparation
- Deploy the latest build to a staging environment that mirrors production (same CDN, same feature flags).
- Ensure test data isolation: use a dedicated tenant or a sandbox database that can be reset.
- Configure payment gateway in test mode (e.g., Stripe test keys, PayPal sandbox).
- Enable detailed logging for gift‑card service endpoints (generation, validation, delivery).
- Turn off any caching layers that could mask stale data (or purge caches before each test).
2. Happy‑Path Walkthrough
- Navigate to the gift‑card catalog.
- Select a design, verify the thumbnail and price update instantly.
- Choose a preset amount (e.g., $50). Confirm the amount field reflects the choice and the subtotal updates.
- Click “Add to cart”, then proceed to checkout.
- Fill in payment details using a test card that always succeeds.
- Submit the order. Observe the confirmation page: order number, gift‑card code, and delivery method displayed.
- Check your test email inbox (or SMS simulator) for the delivery message containing the exact code shown on the confirmation page.
- Log out, then log in as a recipient (or use a separate test account) and attempt to redeem the code at checkout. Verify the balance deducted correctly and the remaining gift‑card amount shown.
If any step deviates, log the defect with screenshots, network request/response, and console errors.
3. Error‑Path Validation
For each error case in the matrix (GC‑02, GC‑05, GC‑06, GC‑08, etc.):
- Enter the invalid data.
- Verify that an inline validation message appears without a page reload (unless the design expects a reload).
- Ensure the form does not allow submission until the error is corrected.
- Confirm that the error message is clear, actionable, and follows your brand’s voice.
4. Accessibility Checks
- Navigate the entire gift‑card flow using only the Tab key. Ensure focus order is logical and that every interactive element (buttons, links, inputs) receives a visible focus indicator (minimum 2 px contrast).
- Run a screen‑reader (NVDA on Windows or VoiceOver on macOS) and listen to each field’s label, role, and state. Confirm that required fields are announced as such.
- Use a colour‑contrast analyzer (e.g., axe‑core browser extension) to verify that all text meets WCAG AA contrast ratios.
- Confirm that error messages are announced as “alert” or “invalid entry”.
5. Security & Privacy Spot Checks
- Input sanitization: Try to inject
into the message field. Confirm the script does not execute and that the stored value is escaped. - Rate limiting: Use a tool like
curlor Postman to send rapid POST requests to the gift‑card generation endpoint. After a defined threshold (e.g., 20 requests/second), you should receive HTTP 429. - Code exposure: After a successful purchase, inspect the network tab. Ensure the gift‑card code never appears in request URLs, response bodies accessible to the client, or in console logs.
- Log review: Search application logs for the full gift‑card string. Only a hash or truncated version should be present.
6. Exploratory & Production‑Like Scenarios
- Network throttling: Use Chrome DevTools to simulate Slow 3G. Walk through the flow and watch for timeouts or UI freezing.
- Concurrent attempts: Open two browser windows, attempt to redeem the same code simultaneously. Verify that only one succeeds.
- Date‑time zone: Change your computer’s time zone, select a future delivery date, and confirm the code arrives at the expected local time.
- Disable JavaScript: Reload the page with JS blocked. Ensure the form still works (maybe via a server‑rendered fallback) and that validation still occurs server‑side.
- Locale switching: Change the site language to a right‑to‑left language (e.g., Arabic). Confirm that layout mirrors correctly, fields remain usable, and error messages appear in the selected language.
Document any deviation with a concise reproduction steps, expected vs. actual, and severity rating.
---
Automated Approaches and Tooling
Automation provides regression safety and enables rapid feedback. For web‑based gift cards, focus on three layers: unit/service tests, API contract tests, and end‑to‑end UI tests.
1. Unit / Service Tests
Test the core gift‑card service logic in isolation. Typical language: Java/Node/Python depending on your stack.
Example (Node/Jest)
// giftCardService.test.js
const { generateCode, validateCode, applyCode } = require('../src/giftCardService');
describe('gift card service', () => {
test('generates a 16‑character alphanumeric code', () => {
const code = generateCode();
expect(code.length).toBe(16);
expect(/^[A-Z0-9]+$/.test(code)).toBe(true);
});
test('rejects codes with invalid checksum', () => {
const bad = 'AAAAAAAAAAAAAAAA'; // purposely fails checksum
expect(validateCode(bad)).toBe(false);
});
test('applies code and returns remaining balance', () => {
const { remaining } = applyCode('VALIDCODE1234', 100.00, 25.00);
expect(remaining).toBe(75.00);
});
});
Run these tests on every commit; they guard against regressions in the business rules that drive the UI.
2. API Contract Tests
If your front‑end talks to a dedicated gift‑card micro‑service, validate the contract with tools like Pact or Dredd.
Example (Pact – JavaScript)
const { Pact } = require('@pact-foundation/pact');
const path = require('path');
const provider = new Pact({
consumer: 'giftcard-web',
provider: 'giftcard-service',
port: 1234,
log: path.resolve(process.cwd(), 'logs', 'pact.log'),
dir: path.resolve(process.cwd(), 'pacts'),
});
describe('Gift Card Generation API', () => {
describe('POST /v1/gift-cards', () => {
before(() => provider.setup());
after(() => provider.finalize());
it('returns a code when amount is valid', () => {
return provider
.uponReceiving('a valid generation request')
.withRequest({
method: 'POST',
path: '/v1/gift-cards',
headers: { 'Content-Type': 'application/json' },
body: { amount: 25, currency: 'USD' },
})
.willRespondWith({
status: 201,
headers: { 'Content-Type': 'application/json' },
body: { code: like('ABCD1234EFGH5678') },
})
.then(() => {
return fetch('http://localhost:1234/v1/gift-cards', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: 25, currency: 'USD' }),
})
.then(res => res.json())
.then(body => {
expect(body.code).toMatch(/^[A-Z0-9]{16}$/);
});
});
});
});
});
Running this as part of CI ensures that UI changes that rely on the API will not break due to contract drift.
3. End‑to‑End UI Tests
Playwright is a strong choice for modern web apps because it offers auto‑waiting, network interception, and multi‑browser support. Below is a comprehensive script that covers happy path, error handling, and a security check.
Playwright (TypeScript) – giftCard.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Gift Card Flow', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/gift-cards');
});
test('happy path purchase and redemption', async ({ page }) => {
// ---- Selection ----
await page.selectOption('#design-select', 'design-01');
await expect(page.locator('#price-display')).toHaveText('$25.00');
// ---- Amount Entry ----
await page.fill('#amount-input', '50.00');
await expect(page.locator('#amount-input')).toHaveValue('50.00');
await expect(page.locator('#subtotal')).toHaveText('$50.00');
// ---- Personalization ----
await page.fill('#sender-name', 'Alex');
await page.fill('#recipient-name', 'Sam');
await page.fill('#message', 'Happy Birthday!');
await page.fill('#delivery-date', '2025-12-25');
// ---- Payment (test card) ----
await page.click('#checkout-btn');
await page.waitForSelector('#card-number', { state: 'visible' });
await page.fill('#card-number', '4242424242424242');
await page.fill('#card-expiry', '12/34');
await page.fill('#card-cvc', '123');
await page.click('#pay-btn');
// ---- Confirmation ----
await expect(page.locator('#order-confirmation')).toBeVisible();
const codeLocator = page.locator('#gift-card-code');
await expect(codeLocator).toBeVisible();
const giftCode = await codeLocator.innerText();
expect(giftCode.length).toBe(16);
expect(/^[A-Z0-9]+$/.test(giftCode)).toBe(true);
// ---- Email verification (using a test mailbox like Mailosaur) ----
const mail = await page.context().request.post('https://mailosaur.com/api/messages', {
// omitted for brevity – fetch latest email and assert body contains giftCode
});
expect(mail.body).toContain(giftCode);
// ---- Logout and login as recipient ----
await page.click('#logout-link');
await page.goto('/login');
await page.fill('#email', 'sam@test.com');
await page.fill('#password', 'TestPass123!');
await page.click('#login-btn');
// ---- Redemption ----
await page.goto('/cart');
await page.fill('#gift-card-input', giftCode);
await page.click('#apply-giftcard');
await expect(page.locator('#discount')).toHaveText('-$50.00');
await expect(page.locator('#total')).toHaveText('$0.00');
});
test('amount validation rejects below minimum', async ({ page }) => {
await page.selectOption('#design-select', 'design-01');
await page.fill('#amount-input', '5.00'); // below $10 min
await expect(page.locator('#amount-error')).toHaveText(/Amount must be at least \$10\.00/);
await expect(page.locator('#checkout-btn')).toBeDisabled();
});
test('message field sanitizes XSS', async ({ page }) => {
await page.selectOption('#design-select', 'design-01');
await page.fill('#amount-input', '20.00');
await page.fill('#message', '<script>alert(1)</script>');
await page.click('#checkout-btn');
// After submit, check that the script tag is escaped in the confirmation modal
await page.waitForSelector('#gift-card-code');
const displayedMessage = await page.locator('#confirmation-message').innerText();
expect(displayedMessage).not.toContain('<script>');
expect(displayedMessage).toContain('<script>');
});
test('rate limiting on generation endpoint', async ({ page }) => {
// Use API request directly to bypass UI throttling
const apiResponse = await page.request.post('/api/v1/gift-cards/generate', {
data: JSON.stringify({ amount: 10, currency: 'USD' }),
headers: { 'Content-Type': 'application/json' },
});
// First few succeed
for (let i = 0; i < 5; i++) {
const resp = await page.request.post('/api/v1/gift-cards/generate', {
data: JSON.stringify({ amount: 10, currency: 'USD' }),
headers: { 'Content-Type': 'application/json' },
});
expect(resp.ok()).toBeTruthy();
}
// After threshold, expect 429
const resp = await page.request.post('/api/v1/gift-cards/generate', {
data: JSON.stringify({ amount: 10, currency: 'USD' }),
headers: { 'Content-Type': 'application/json' },
});
expect(resp.status()).toBe(429);
});
});
Why this script works
- Each test is independent; Playwright automatically creates a fresh browser context.
- It mixes UI interactions with direct API calls to validate backend safeguards (rate limiting).
- Assertions cover both visible text and hidden attributes (e.g., disabled button).
- The test suite can be run in CI on Chromium, Firefox, and WebKit to catch browser‑specific issues.
4. Visual Regression
Gift‑card UI often includes custom designs and thematic backgrounds. Use a tool like Percy or Chromatic to capture screenshots of the gift‑card picker and confirmation modal after each release.
Example (Percy CLI)
# After building the storybook or running the app
PERCY_TOKEN=your_token npx percy exec -- playwright test
Percy will compare the new screenshots against the baseline and flag any unintended visual changes (e.g., a button shifted, a missing icon).
5. Performance & Load Testing
While functional correctness is primary, gift‑card generation can be a hotspot during promotions. Use k6 or Gatling to simulate bursts of purchase requests.
k6 script snippet
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 50 }, // ramp up to 50 VUs
{ duration: '5m', target: 50 }, // stay at 50
{ duration: '2m', target: 0 }, // ramp down
],
};
export default function () {
const payload = JSON.stringify({
amount: 25,
currency: 'USD',
senderName: 'Tester',
recipientName: 'Friend',
message: 'Thanks!',
});
const params = {
headers: {
'Content-Type': 'application/json',
},
};
const res = http.post('https://staging.example.com/api/v1/gift-cards', payload, params);
check(res, {
'status is 201': (r) => r.status === 201,
'code present': (r) => r.json().code !== '',
});
sleep(1);
}
Run the script and inspect the response time percentiles; ensure the 95th‑percentile stays under your SLA (e.g., 2 seconds).
---
Tooling & Setup
| Category | Tool | Reason for Choice | Quick Setup |
|---|---|---|---|
| Test Framework | Playwright (JS/TS) | Auto‑wait, multi‑browser, API request support | npm i -D @playwright/test |
| Unit Testing | Jest / Mocha | Fast, mature assertion library | npm i -D jest |
| API Contract | Pact | Consumer‑driven contracts, language‑agnostic | npm i -D @pact-foundation/pact |
| Accessibility | axe‑core (via playwright-axe) | Integrated WCAG checks | npm i -D @axe-core/playwright |
| Visual Regression | Percy / Chromatic | Baseline comparison, CI‑friendly | npx percy exec -- playwright test |
| Load Testing | k6 | Scriptable in JS, cloud or local | brew install k6 (mac) |
| Mail Capture | Mailosaur / Ethereal | Reliable test inbox for email/SMS verification | Sign up, obtain API key |
| Secrets Management | dotenv / Vault | Keep test API keys out of repo | npm i dotenv |
| CI Integration | GitHub Actions / GitLab CI | Run matrix on push/PR | Add workflow file (see below) |
Sample GitHub Actions Workflow
name: Gift Card CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
browser: [chromium, firefox, webkit]
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '20'
- run: npm ci
- name: Run Unit Tests
run: npm test
- name: Run Playwright Tests
env:
PLAYWRIGHT_BROWSERS_PATH: 0
run: npx playwright test --project=${{ matrix.browser }}
- name: Upload Playwright Report
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report-${{ matrix.browser }}
path: playwright-report/
- name: Run Accessibility Scan
run: npx playwright test --grep @accessibility
- name: Run Visual Regression (Percy)
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
run: npx percy exec -- playwright test
This workflow runs unit tests, Playwright UI tests across three browsers, accessibility‑tagged tests, and Percy visual checks on every push. Adjust the matrix and secrets to fit your environment.
---
Autonomous, Persona‑Driven Exploration
Even the most thorough test matrix can miss scenarios that arise from real‑world user behavior—especially when users act outside the “happy‑path” assumptions. Autonomous QA platforms like SUSA address this gap by exploring the application with simulated user personalities, each driven by a distinct behavior profile.
How It Works
- Model Extraction – Upon receiving a URL or an APK (for hybrid web views), SUSA builds a dynamic state‑transition model of the front‑end: pages, UI elements, and possible actions (click, type, select, scroll).
- Persona Injection – For each session, SUSA selects a persona (e.g., *impatient*, *elderly*, *adversarial*) and applies its policy:
- *Impatient* skips waiting for animations, rapidly clicks controls, and may submit forms before validation completes.
- *Elderly* uses larger click targets, prefers keyboard navigation, and may linger on help tooltips.
- *Adversarial* attempts SQL injection, XSS, and unexpected input sequences in every field.
- Exploration Loop – The agent walks the model, making choices guided by the persona’s policy, while logging every network request, DOM mutation, and console error.
- Learning – Screens visited and dead ends (e.g., a button that leads to a 500 error) are stored; subsequent runs prioritize unexplored paths, increasing coverage over time.
Gift‑Card‑Specific Findings
When run against a staging gift‑card flow, SUSA has repeatedly uncovered issues that scripted tests never considered:
| Persona | Discovered Issue | Why Scripts Missed It |
|---|---|---|
| Impatient | Double‑click on the “Apply Gift Card” button caused the discount to be applied twice, leading to a negative order total. | Automated scripts usually insert a wait or a single click; they never simulate rapid repeated clicks without explicit throttling. |
| Elderly | The gift‑card amount field’s increment/decrement arrows were too small for users with motor impairments, causing repeated mis‑clicks. | UI tests interact with the input directly via fill(), bypassing the arrow buttons entirely. |
| Adversarial | Entering '; SELECT * FROM users;-- in the recipient name field triggered a DB error that was logged and exposed a stack trace in the response body. | Security tests often target known endpoints (like search) but neglect fields assumed to be “just text”. |
| Curious (novice) | After a failed payment, the “Try Again” button redirected to a blank page because the query parameter ?error=true was not handled by the route. | Test cases usually follow the success path; error‑state redirects are rarely enumerated unless explicitly added. |
| Accessibility (screen‑reader) | Custom tooltip announcing the remaining balance used aria-label that changed dynamically but was not updated when the balance changed, causing stale announcements. | Automated axe checks flag missing labels but not label‑staleness caused by JS state updates. |
Integrating SUSA into Your Pipeline
You can run SUSA as a lightweight container or CLI step after your UI test suite:
# Install the agent (once)
pip install susatest-agent
# Execute a 5‑minute exploratory session against staging
susatest-agent run \
--url https://staging.example.com/gift-cards \
--personas impatient,elderly,adversarial,curious,accessibility \
--duration 5m \
--output susa-report.json
The output contains a JSON log of every action, any observed errors, and a coverage map (percentage of states visited). You can fail the build if the error count exceeds a threshold or if coverage drops below a baseline (indicating regressions that block exploration).
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free