Skip to content
prod e051e98
Browse

5 · Functional QA & debugger review

Objective — drive every critical journey and role (automate the repetitive smoke tests with Playwright MCP), run live security tests, triage failures by severity, then mine Telescope/Sentry/logs and check for unmerged fixes — the live counterpart to the static audit.

This is the live counterpart to the earlier static audits: you drive the running app instead of reading the code. Automate the repetitive smoke tests; keep human eyes on the journeys that need judgment.

flowchart LR
Static[Static + security audits] --> Auto[Automated smoke Playwright MCP]
Auto --> Human[Human judgment journeys]
Human --> UAT[User acceptance sign-off]

Drive the running app across every critical journey and role. Automate the repetitive smoke tests with the Playwright MCP (navigate, fill forms, capture console errors, screenshot at each step); keep human eyes on judgment-heavy flows.

SuitePriorityCovers
Functional testingMUSTAuth, subscriptions, CRUD, emails, error pages
Security testing (runtime)MUSTRate limiting, IDOR, session handling, prod config
Performance testingMUSTPage speed, TTFB, caching, load
User acceptance testingMUSTEnd-to-end user journeys, onboarding
Cross-browserSHOULDChrome, Firefox, Safari, Edge
Mobile & responsiveSHOULD375 / 768 / 1024 / 1440px, touch targets
Load testingSHOULDApache Bench / k6 on staging
Reference test matrices (functional + runtime security)

Authentication — register (valid / duplicate-email / weak-password / missing-fields), login (valid / wrong-password / non-existent-email → generic “Invalid credentials”), remember-me across browser restart, password-reset request → email → reset form → new password works / old fails, logout protects /dashboard.

Subscription/pricing shows correct plans/prices/currency, checkout with test card 4242 4242 4242 4242 → success, dashboard shows active plan, invoice email received, upgrade / downgrade-at-period-end / cancel, billing history visible.

Core CRUD (per entity) — create / edit / delete (with confirm) / list / search / paginate / export / report generate / report export / custom date range.

Error handling — custom pages:

TriggerExpected
/nonexistent-page-xyzCustom 404 page
Forced 500Custom 500 page
Forbidden resourceCustom 403 page
Expired session / stale CSRFCustom 419 page
Empty / invalid-email / excessive-length / special-char inputsInline validation, handled gracefully

Runtime security:

TestExpected
10+ rapid failed loginsRate-limit lockout after threshold
Password-reset token after 1 hourExpired
Password-reset token reusedSingle-use — rejected on second use
Session after password changeOld sessions invalidated
User A opens User B’s resource by ID (IDOR)403 or redirect
Non-admin hits admin route403 or redirect
Unauthenticated API call401
Session cookiesSecure=true, HttpOnly=true
  1. Drive each suite, then triage every failure by severity. Use the Stripe test card 4242 4242 4242 4242 for the full payment lifecycle (subscribe → upgrade → downgrade → cancel → billing history). Confirm every transactional email lands in the inbox (mail-tester.com target 9–10/10) and that custom 404/500/403/419 pages render.

    • ✅ Every MUST suite passes; the payment lifecycle, emails (9–10/10), and custom error pages all work.
    • ✅ Each failure is triaged — CRITICAL blocks launch, MEDIUM has a workaround (fix within a week), LOW is cosmetic.

Mine the tools you wired in earlier for bugs that QA didn’t surface.

ReviewWhat to find
Telescope exceptionsHidden exceptions (local); categorize by severity
Slow queries> 500ms = CRITICAL, > 100ms = HIGH; fix with eager loading / indexes
Sentry (production)Unresolved issues, prioritized by events & users affected
Log file scanErrors, warnings, deprecations across local + production logs
Git unmerged fixesFixes stranded on feature branches, never merged to develop
  1. Work each review row, categorizing findings by severity and confirming no fix is stranded off develop.

    Terminal window
    git branch -a --contains <hash> | grep -E 'origin/develop|origin/main|develop|main'
    # Expected: develop or main is listed — the fix is in the release line

    Also check for dependency bumps stranded off the release line — a composer.lock update merged only to a feature branch is a silent regression (e.g. a package fix that never reached develop):

    Terminal window
    git log --oneline --all -- composer.lock | head -10
    # For any bump not obviously on develop/main:
    # git branch -a --contains <hash> | grep -E 'origin/develop|origin/main' || echo "STRANDED: bump not in release line"
    • ✅ Telescope/Sentry/log findings are categorized; slow queries fixed; every fix commit is on develop.

3. Run the SHOULD suites — cross-browser, mobile, load

Section titled “3. Run the SHOULD suites — cross-browser, mobile, load”

The MUST suites gate launch; these catch what real users hit on other browsers, on phones, and under traffic. Run them on staging, never production.

  1. Cross-browser — drive the key journeys (homepage, login/register, all form types, modals/dropdowns, AJAX) in Chrome, Firefox, Safari, and Edge, watching the console on each.

    • ✅ Every journey renders and works in all four browsers with a clean console; browserslist in package.json covers > 1%, last 2 versions, not dead.
  2. Mobile & responsive — test each page at 375 / 768 / 1024 / 1440px in DevTools, then on at least one real iPhone + one real Android.

    • ✅ No horizontal scroll at any breakpoint; touch targets ≥ 44×44px; passes on a real iPhone (Safari) and a real Android (Chrome).
  3. Load test (staging only) — a quick Apache Bench pass, then a scripted k6 ramp if you need a realistic profile.

    Terminal window
    ab -n 500 -c 50 https://<staging-domain>/ # quick baseline
    # realistic ramp: brew install k6 && k6 run load-test.js

    Monitor the server during the run (separate shell on staging):

    Terminal window
    top # CPU — target < 80%
    free -m # Memory — should stay stable, no runaway growth
    # In a MySQL client:
    # SHOW STATUS LIKE 'Threads_connected'; # not near max_connections
    # SHOW GLOBAL STATUS LIKE 'Slow_queries'; # should not climb sharply under load

    Read the bottleneck:

    SymptomDiagnosisQuick fix
    High CPUUn-cached PHP / hot code pathEnable OPcache
    Memory growsLeak / unbounded workersFix leak, limit workers
    Slow DBMissing indexesAdd indexes, add Redis cache
    Connection errorsConnection limit reachedRaise max_connections
    • ✅ On staging: avg response < 500ms, 95th percentile < 1s, error rate < 0.1% (requests/sec > 100, 0 failed).

Do not mark this step done until every box below is checked.

  • 🔀 MUST suites pass — functional, runtime security, performance, and UAT all green.
  • 👤 Payments + emails verified — test-card lifecycle works; transactional emails land (9–10/10).
  • 🤖 Failures triaged — every failure tagged CRITICAL / MEDIUM / LOW.
  • 🤖 Debugger review done — Telescope/Sentry/logs mined; slow queries fixed.
  • 🤖 No unmerged fixes — every fix commit confirmed on develop.
  • 🔀 SHOULD suites run (staging) — cross-browser (4 browsers), mobile (4 breakpoints + real devices), and load test all pass on staging.
  • 🤖 ZajModules verified or skippedzajmodsys:list clean, or no packages/ZajModSys/ so skipped.