Files
trakqr/docs/test-plan.md
2026-01-30 21:01:32 -05:00

24 KiB

TrakQR Test Plan

Manual test plan for validating all features before release.

  • Test Plan Overview

    Item Details
    Application TrakQR - QR-First URL Shortener SaaS
    Version MVP
    Test Type Functional / End-to-End
    Environment Development (localhost:5173 + localhost:42001)
  • How to Use This Document

    1. Work through each section sequentially
    2. Check the box [x] when a test passes
    3. Mark [F] for failures and add notes
    4. Mark [S] for skipped tests with reason

  • 1. Authentication

  • 1.1 Registration

    # Test Case Steps Expected Result Status
    1.1.1 Register with valid email 1. Go to /register
    2. Enter valid email and password (8+ chars)
    3. Click Register
    Account created, redirected to dashboard, default workspace created [ ]
    1.1.2 Register with invalid email 1. Go to /register
    2. Enter invalid email format
    3. Click Register
    Error message shown, no account created [ ]
    1.1.3 Register with short password 1. Go to /register
    2. Enter valid email, password < 8 chars
    3. Click Register
    Error message about password length [ ]
    1.1.4 Register with existing email 1. Register a new account
    2. Try to register again with same email
    Error message about email already in use [ ]
    1.1.5 Registration rate limiting 1. Attempt to register 15+ times in 1 minute Rate limit error after ~10 attempts [ ]
  • 1.2 Login

    # Test Case Steps Expected Result Status
    1.2.1 Login with valid credentials 1. Go to /login
    2. Enter registered email/password
    3. Click Login
    Logged in, redirected to dashboard [ ]
    1.2.2 Login with wrong password 1. Go to /login
    2. Enter valid email, wrong password
    3. Click Login
    Error message, not logged in [ ]
    1.2.3 Login with non-existent email 1. Go to /login
    2. Enter unregistered email
    3. Click Login
    Error message (generic, no email enumeration) [ ]
    1.2.4 Login rate limiting 1. Attempt failed logins 15+ times Rate limit error after ~10 attempts [ ]
    1.2.5 Redirect after login 1. Try to access /links while logged out
    2. Get redirected to login
    3. Login successfully
    Redirected back to /links [ ]
  • 1.3 Password Reset

    # Test Case Steps Expected Result Status
    1.3.1 Request password reset 1. Go to /forgot-password
    2. Enter registered email
    3. Click Submit
    Success message shown (check console for email in dev) [ ]
    1.3.2 Reset with valid token 1. Get reset token from email/console
    2. Go to /reset-password?token=xxx
    3. Enter new password
    Password changed, can login with new password [ ]
    1.3.3 Reset with invalid token 1. Go to /reset-password?token=invalid
    2. Enter new password
    Error message about invalid/expired token [ ]
    1.3.4 Reset with expired token 1. Wait for token to expire (or modify DB)
    2. Try to use token
    Error message about expired token [ ]
  • 1.4 Email Verification

    | # | Test Case | Steps | Expected Result | Status | |----------------|-------|-----------------|--------| | 1.4.1 | Verify with valid token | 1. Register new account
    2. Get verification token from console
    3. Go to /verify-email?token=xxx | Email verified, success message | [ ] | | 1.4.2 | Verify with invalid token | 1. Go to /verify-email?token=invalid | Error message about invalid token | [ ] | | 1.4.3 | Resend verification | 1. Login with unverified account
    2. Go to Settings
    3. Click "Resend verification" | New email sent (check console) | [ ] |

  • 1.5 Logout

    # Test Case Steps Expected Result Status
    1.5.1 Logout 1. Login
    2. Click Logout in sidebar
    Logged out, redirected to login, protected routes inaccessible [ ]
    1.5.2 Session persistence 1. Login
    2. Close browser
    3. Reopen and go to app
    Still logged in (token in localStorage) [ ]

  • 2. Workspaces

  • 2.1 Workspace Management

    # Test Case Steps Expected Result Status
    2.1.1 Default workspace exists 1. Register new account
    2. Check workspace selector
    Default workspace present [ ]
    2.1.2 Create workspace 1. Click + button in workspace selector
    2. Enter name
    3. Click Create
    New workspace created, switched to it [ ]
    2.1.3 Switch workspace 1. Have 2+ workspaces
    2. Select different workspace from dropdown
    Workspace switched, data refreshed [ ]
    2.1.4 Update workspace name 1. Click settings icon in workspace selector
    2. Change name
    3. Save
    Name updated [ ]
    2.1.5 Delete workspace 1. Have 2+ workspaces
    2. Open workspace settings
    3. Click Delete
    Workspace deleted, switched to another [ ]
    2.1.6 Cannot delete only workspace 1. Have only 1 workspace
    2. Try to delete it
    Delete button disabled or error shown [ ]
    2.1.7 Workspace persistence 1. Switch to workspace B
    2. Refresh page
    Still on workspace B (localStorage) [ ]

  • 3. Projects

  • 3.1 Project CRUD

    # Test Case Steps Expected Result Status
    3.1.1 View projects page 1. Go to /projects Projects list shown (or empty state) [ ]
    3.1.2 Create project 1. Click "New Project"
    2. Enter name and description
    3. Save
    Project created, appears in list [ ]
    3.1.3 Edit project 1. Click edit on a project
    2. Change name/description
    3. Save
    Project updated [ ]
    3.1.4 Delete project 1. Click delete on a project
    2. Confirm deletion
    Project removed from list [ ]
    3.1.5 Project shows link count 1. Create project
    2. Create links assigned to project
    3. View projects
    Link count displayed correctly [ ]

  • # Test Case Steps Expected Result Status
    4.1.1 Create link with auto slug 1. Click "Create Link"
    2. Enter destination URL only
    3. Save
    Link created with auto-generated slug [ ]
    4.1.2 Create link with custom slug 1. Click "Create Link"
    2. Enter URL and custom slug
    3. Save
    Link created with custom slug [ ]
    4.1.3 Create link with title 1. Create link with title filled in Title shown in list [ ]
    4.1.4 Create link with expiration 1. Create link with expiration date set Link shows expiration, stops working after date [ ]
    4.1.5 Create link with password 1. Create link with password set Link requires password to access [ ]
    4.1.6 Invalid destination URL 1. Try to create link with invalid URL Error message shown [ ]
    4.1.7 Duplicate slug 1. Create link with slug "test"
    2. Try to create another with same slug
    Error message about duplicate [ ]
  • # Test Case Steps Expected Result Status
    4.2.1 View links list 1. Go to /links Links listed with short URL, destination, clicks [ ]
    4.2.2 Copy short URL 1. Click copy icon on a link URL copied to clipboard [ ]
    4.2.3 Edit link 1. Click edit on a link
    2. Change destination URL
    3. Save
    Link updated, redirect goes to new URL [ ]
    4.2.4 Delete link (soft) 1. Click delete on a link
    2. Confirm
    Link moved to trash [ ]
    4.2.5 View trash 1. Click "Trash" toggle Deleted links shown [ ]
    4.2.6 Restore link 1. View trash
    2. Click restore on a link
    Link restored, works again [ ]
    4.2.7 Disable link 1. Edit link
    2. Set status to Disabled
    3. Save
    Link returns 404/disabled message [ ]
  • 4.3 Bulk Import

    # Test Case Steps Expected Result Status
    4.3.1 Bulk import URLs 1. Click "Bulk Import"
    2. Paste multiple URLs (one per line)
    3. Import
    All links created [ ]
    4.3.2 Bulk import with titles 1. Paste URLs with titles: https://example.com, My Title
    2. Import
    Links created with titles [ ]
    4.3.3 Bulk import with invalid URLs 1. Include some invalid URLs in list
    2. Import
    Valid URLs imported, errors shown for invalid [ ]
  • 4.4 UTM Builder

    # Test Case Steps Expected Result Status
    4.4.1 Add UTM parameters 1. Create link
    2. Expand UTM builder
    3. Fill in source, medium, campaign
    UTM params appended to destination [ ]
    4.4.2 UTM presets 1. Click "Google Ads" preset Fields populated with Google preset values [ ]
    4.4.3 UTM preview 1. Fill in UTM fields Preview shows full URL with params [ ]

  • 5. Redirect

  • 5.1 Public Redirect

    # Test Case Steps Expected Result Status
    5.1.1 Basic redirect 1. Create link to https://example.com
    2. Visit short URL
    Redirected to example.com [ ]
    5.1.2 Non-existent slug 1. Visit /{random-slug} 404 error page [ ]
    5.1.3 Disabled link 1. Disable a link
    2. Visit its short URL
    Error message (link disabled) [ ]
    5.1.4 Expired link 1. Create link with past expiration
    2. Visit short URL
    Error message (link expired) [ ]
    5.1.5 Password-protected link 1. Create password-protected link
    2. Visit short URL
    Password prompt shown [ ]
    5.1.6 Password entry 1. Visit password-protected link
    2. Enter correct password
    Redirected to destination [ ]
    5.1.7 Wrong password 1. Visit password-protected link
    2. Enter wrong password
    Error, stays on password page [ ]
    5.1.8 Redirect rate limiting 1. Hit redirect endpoint 100+ times rapidly Rate limited after threshold [ ]

  • 6. QR Codes

  • 6.1 QR Creation

    # Test Case Steps Expected Result Status
    6.1.1 Create basic QR 1. Go to /qrcodes/new
    2. Select a link
    3. Save
    QR code created with default style [ ]
    6.1.2 QR requires link 1. Go to /qrcodes/new
    2. Try to save without link
    Error message [ ]
    6.1.3 QR name 1. Create QR with custom name Name shown in list [ ]
  • 6.2 QR Designer

    # Test Case Steps Expected Result Status
    6.2.1 Change foreground color 1. Edit QR
    2. Change foreground color
    3. View preview
    QR updates with new color [ ]
    6.2.2 Change background color 1. Change background color QR updates with new background [ ]
    6.2.3 Module shapes 1. Try Square, Rounded, Dots shapes Each shape renders correctly [ ]
    6.2.4 Eye shapes 1. Try Square, Rounded, Circle eye shapes Each eye shape renders correctly [ ]
    6.2.5 Error correction levels 1. Try L, M, Q, H levels QR generates with different densities [ ]
    6.2.6 Quiet zone 1. Adjust quiet zone size Padding around QR changes [ ]
    6.2.7 Style presets 1. Click each of 6 presets Styles applied correctly [ ]
    6.2.8 Upload logo 1. Click logo upload
    2. Select image file
    Logo appears in center of QR [ ]
    6.2.9 Select existing logo 1. Have uploaded assets
    2. Select from asset gallery
    Logo applied from gallery [ ]
    6.2.10 Remove logo 1. Have QR with logo
    2. Remove logo
    QR renders without logo [ ]
  • 6.3 QR Export

    # Test Case Steps Expected Result Status
    6.3.1 Export PNG 1. View QR
    2. Click "Download PNG"
    PNG file downloaded [ ]
    6.3.2 Export SVG 1. Click "Download SVG" SVG file downloaded [ ]
    6.3.3 PNG has correct size 1. Export PNG
    2. Check dimensions
    Matches selected size (256/512/1024) [ ]
    6.3.4 QR is scannable 1. Export QR
    2. Scan with phone
    Opens correct short URL [ ]
    6.3.5 QR with logo is scannable 1. Add logo to QR
    2. Export and scan
    Still scans correctly [ ]
  • 6.4 QR List

    # Test Case Steps Expected Result Status
    6.4.1 View QR list 1. Go to /qrcodes List shows QR previews [ ]
    6.4.2 QR preview thumbnails 1. View list Each QR shows thumbnail preview [ ]
    6.4.3 Delete QR 1. Click delete on QR
    2. Confirm
    QR removed from list [ ]
    6.4.4 Edit QR 1. Click edit on QR Opens designer with saved settings [ ]

  • 7. Analytics

  • 7.1 Event Tracking

    # Test Case Steps Expected Result Status
    7.1.1 Click event recorded 1. Create link
    2. Visit short URL
    3. Check analytics
    Click count increased [ ]
    7.1.2 Scan event recorded 1. Create QR
    2. Export and scan QR
    3. Check QR analytics
    Scan count increased [ ]
    7.1.3 Unique visitor tracking 1. Visit same link multiple times quickly
    2. Check analytics
    Only 1 unique visitor (dedupe) [ ]
    7.1.4 Device detection 1. Visit from mobile device
    2. Check device breakdown
    Mobile device recorded [ ]
    7.1.5 Referrer tracking 1. Visit link from a webpage
    2. Check referrer breakdown
    Referrer domain recorded [ ]
    7.1.6 Country detection 1. Visit link
    2. Check geo breakdown
    Country detected (if GeoIP configured) [ ]
  • 7.2 Dashboard Analytics

    # Test Case Steps Expected Result Status
    7.2.1 View dashboard 1. Go to /dashboard Stats cards, chart, breakdowns shown [ ]
    7.2.2 Total clicks 1. Check total clicks card Matches sum of all link clicks [ ]
    7.2.3 Time series chart 1. View activity chart Shows clicks/scans over time [ ]
    7.2.4 Top links 1. View top links section Most clicked links shown [ ]
    7.2.5 Device breakdown 1. View device breakdown Desktop/Mobile/Tablet shown [ ]
    7.2.6 Referrer breakdown 1. View referrer breakdown Top referrers listed [ ]
    7.2.7 Country breakdown 1. View geo breakdown Countries with flags shown [ ]
  • 7.3 Period Filters

    # Test Case Steps Expected Result Status
    7.3.1 24h filter 1. Click "24h" period Data filtered to last 24 hours [ ]
    7.3.2 7d filter 1. Click "7d" period Data filtered to last 7 days [ ]
    7.3.3 30d filter 1. Click "30d" period Data filtered to last 30 days [ ]
  • # Test Case Steps Expected Result Status
    7.4.1 View link detail 1. Go to /links/{id} Link analytics shown [ ]
    7.4.2 Link-specific stats 1. View link detail Stats match only that link's data [ ]
  • 7.5 Per-QR Analytics

    # Test Case Steps Expected Result Status
    7.5.1 View QR analytics 1. Go to /qrcodes/{id}/analytics QR scan stats shown [ ]
    7.5.2 QR-specific stats 1. View QR detail Stats match only that QR's scans [ ]

  • 8. Domains

  • 8.1 Domain Management

    # Test Case Steps Expected Result Status
    8.1.1 View domains page 1. Go to /domains Domains list or upgrade prompt (Free plan) [ ]
    8.1.2 Add domain (Pro+) 1. Click "Add Domain"
    2. Enter hostname
    3. Submit
    Domain added with Pending status [ ]
    8.1.3 Verification instructions 1. Add new domain TXT record and CNAME instructions shown [ ]
    8.1.4 Copy verification token 1. Click copy on verification token Token copied to clipboard [ ]
    8.1.5 Verify domain 1. Add DNS records
    2. Click "Verify"
    Domain status changes to Verified [ ]
    8.1.6 Delete domain 1. Click delete on domain
    2. Confirm
    Domain removed [ ]
    8.1.7 Free plan restriction 1. Be on Free plan
    2. Try to add domain
    Upgrade prompt shown [ ]

  • 9. Settings

  • 9.1 Profile

    # Test Case Steps Expected Result Status
    9.1.1 View profile 1. Go to /settings Current email shown [ ]
    9.1.2 Update email 1. Change email
    2. Save
    Email updated [ ]
    9.1.3 Verification warning 1. Have unverified email Warning shown with resend link [ ]
  • 9.2 Password Change

    # Test Case Steps Expected Result Status
    9.2.1 Change password 1. Enter current password
    2. Enter new password twice
    3. Submit
    Password changed [ ]
    9.2.2 Wrong current password 1. Enter wrong current password
    2. Submit
    Error message [ ]
    9.2.3 Passwords don't match 1. Enter different passwords
    2. Submit
    Error message [ ]
  • 9.3 API Keys

    # Test Case Steps Expected Result Status
    9.3.1 View API keys 1. Scroll to API Keys section List of keys (or empty state) [ ]
    9.3.2 Create API key 1. Click "Create Key"
    2. Enter name
    3. Create
    Key created, full key shown once [ ]
    9.3.3 Copy API key 1. Create key
    2. Click copy
    Key copied to clipboard [ ]
    9.3.4 Key with expiry 1. Create key with 30-day expiry Expiry date shown [ ]
    9.3.5 Delete API key 1. Click delete on a key
    2. Confirm
    Key removed [ ]
    9.3.6 Key prefix shown 1. View existing keys Only prefix visible (e.g., tq_abc...) [ ]
  • 9.4 Danger Zone

    # Test Case Steps Expected Result Status
    9.4.1 Delete account prompt 1. Click "Delete Account" Confirmation modal with password [ ]
    9.4.2 Delete account 1. Enter password
    2. Confirm delete
    Account deleted, logged out [ ]
    9.4.3 Wrong password on delete 1. Enter wrong password Error, account not deleted [ ]

  • 10. Billing

  • 10.1 Plan Display

    # Test Case Steps Expected Result Status
    10.1.1 View billing page 1. Go to /billing Current plan and features shown [ ]
    10.1.2 Plan comparison 1. View billing page Free/Pro/Business plans compared [ ]
    10.1.3 Current plan highlighted 1. View billing page Current plan marked as "Current" [ ]
  • 10.2 Stripe Integration

    # Test Case Steps Expected Result Status
    10.2.1 Upgrade to Pro 1. Click "Upgrade" on Pro
    2. Complete Stripe checkout
    Plan upgraded [ ]
    10.2.2 Manage subscription 1. Click "Manage Subscription"
    2. Stripe portal opens
    Can update payment, cancel [ ]
    10.2.3 Cancel subscription 1. Cancel in Stripe portal Plan downgrades at period end [ ]

  • 11. Plan Limits

  • 11.1 Free Plan Limits

    # Test Case Steps Expected Result Status
    11.1.1 Workspace limit 1. Be on Free plan
    2. Try to create 2nd workspace
    Error: limit reached [ ]
    11.1.2 Link limit 1. Create 50 links
    2. Try to create 51st
    Error: limit reached [ ]
    11.1.3 QR code limit 1. Create 25 QR codes
    2. Try to create 26th
    Error: limit reached [ ]
    11.1.4 No custom domains 1. Try to add domain on Free Upgrade prompt [ ]
  • 11.2 Usage Display

    # Test Case Steps Expected Result Status
    11.2.1 View usage 1. Check billing or dashboard Usage stats shown (links, QRs, events) [ ]

  • 12. UI/UX

  • 12.1 Navigation

    # Test Case Steps Expected Result Status
    12.1.1 Sidebar navigation 1. Click each nav item Correct page loads [ ]
    12.1.2 Active nav highlight 1. Navigate to different pages Current page highlighted in sidebar [ ]
    12.1.3 Mobile responsive 1. Resize to mobile width Layout adapts correctly [ ]
  • 12.2 Loading States

    # Test Case Steps Expected Result Status
    12.2.1 Loading indicators 1. Navigate to data-heavy page Loading indicator shown while fetching [ ]
    12.2.2 Button loading states 1. Submit a form Button shows loading state [ ]
  • 12.3 Error Handling

    # Test Case Steps Expected Result Status
    12.3.1 API errors shown 1. Trigger an API error User-friendly error message [ ]
    12.3.2 Network error 1. Disable network
    2. Try an action
    Appropriate error message [ ]
    12.3.3 401 redirect 1. Clear token from localStorage
    2. Try protected action
    Redirected to login [ ]
  • 12.4 Empty States

    # Test Case Steps Expected Result Status
    12.4.1 No links 1. View links with none created Empty state with CTA [ ]
    12.4.2 No QR codes 1. View QR codes with none created Empty state with CTA [ ]
    12.4.3 No projects 1. View projects with none created Empty state with CTA [ ]
    12.4.4 No analytics data 1. View analytics with no events Empty state message [ ]

  • 13. Security

  • 13.1 Authentication

    # Test Case Steps Expected Result Status
    13.1.1 Protected routes 1. Log out
    2. Try to access /dashboard
    Redirected to login [ ]
    13.1.2 JWT expiry 1. Wait for token to expire
    2. Try an action
    Redirected to login [ ]
    13.1.3 Cross-workspace access 1. Try to access another user's workspace ID 404 or 403 error [ ]
  • 13.2 Input Validation

    # Test Case Steps Expected Result Status
    13.2.1 XSS in link title 1. Create link with <script> in title Script not executed, text escaped [ ]
    13.2.2 SQL injection attempt 1. Enter SQL in form fields No SQL executed, handled safely [ ]

  • Test Summary

    Section Total Tests Passed Failed Skipped
    1. Authentication 16
    2. Workspaces 7
    3. Projects 5
    4. Short Links 17
    5. Redirect 8
    6. QR Codes 17
    7. Analytics 17
    8. Domains 7
    9. Settings 12
    10. Billing 5
    11. Plan Limits 5
    12. UI/UX 11
    13. Security 4
    TOTAL 131

  • Test Environment Setup

  • Prerequisites

    1. Backend running: cd src/api && dotnet run
    2. Frontend running: cd src/frontend && npm run dev
    3. Database: PostgreSQL with migrations applied
    4. Email: Console output in development (check terminal)
    5. Stripe: Test mode with test API keys (optional for billing tests)
    6. GeoIP: MaxMind database configured (optional for geo tests)
  • Test Accounts

    Create these accounts before testing:

    Email Password Purpose
    test@example.com password123 General testing
    pro@example.com password123 Pro plan testing
    free@example.com password123 Free limits testing

  • Notes

  • Mark tests as [F] if they fail and add details below

  • Mark tests as [S] if skipped with reason

  • Re-run failed tests after fixes

  • Update this document as features change

  • Failed Tests Log

    Test # Issue Date Fixed
  • Skipped Tests Log

    Test # Reason Date