Auth 200 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Auth - Login
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-AUTH-001 | Valid login with email & password | Functional | P1 | 1. Open beta-stg.markopolo.ai/login 2. Enter valid email 3. Enter valid password 4. Click Sign In |
Redirect to Dashboard; session cookie set | Skip ✓ | |
| TC-AUTH-002 | Login with invalid email format | Negative | P2 | 1. Enter notanemail in email field 2. Click Sign In |
Inline validation: Please enter a valid email address | Fail ✓ | |
| TC-AUTH-003 | Login with wrong password | Negative | P1 | 1. Enter valid email 2. Enter wrong password 3. Click Sign In |
Error toast: Invalid credentials — no session created | Pass ✓ | |
| TC-AUTH-004 | Login with empty fields | Negative | P2 | 1. Leave both fields empty 2. Click Sign In |
Both fields show required validation error; form not submitted | Pass ✓ | |
| TC-AUTH-005 | Login with empty Password | Negative | P2 | 1. Enter valid email 2. Leave password empty 3. Click Sign In |
Password is required error shown | Pass ✓ | |
| TC-AUTH-006 | Login with empty Email | Negative | P2 | 1. Leave email empty 2. Enter valid password 3. Click Sign In |
Email is required error shown | Pass ✓ | |
| TC-AUTH-007 | Google OAuth login | Functional | P1 | 1. Click Continue with Google 2. Select Google account 3. Grant permissions |
Redirect to Dashboard; Google session established | Timeout ✓ | OAuth popup or redirect |
| TC-AUTH-008 | Brute force protection (5 failed attempts) | Security | P1 | 1. Enter valid email 2. Enter wrong password 3. Repeat 5 times |
Account locked or CAPTCHA triggered after 5 attempts | Skip ✓ | Security critical |
| TC-AUTH-009 | Login with email in ALL CAPS | Positive | P2 | 1. Enter email in all uppercase (e.g. USER@TEST.COM) 2. Enter correct password 3. Click Sign In |
Login succeeds — email normalized case-insensitively | Pass ✓ | Email case normalization |
| TC-AUTH-010 | Login with mixed case email | Positive | P2 | 1. Enter email in mixed case (e.g. UsEr@TeSt.CoM) 2. Enter correct password 3. Click Sign In |
Login succeeds — email case-insensitive | Pass ✓ | |
| TC-AUTH-011 | Login with leading and trailing spaces in email | Boundary | P2 | 1. Type or paste ' user@test.com ' with spaces 2. Enter correct password 3. Click Sign In |
Spaces trimmed automatically; login succeeds OR validation error shown | Pass ✓ | Auto-trim behavior |
| TC-AUTH-012 | Login with password pasted from clipboard | Positive | P2 | 1. Copy password from clipboard 2. Paste into password field 3. Click Sign In |
Login succeeds; paste allowed in password field | Pass ✓ | Clipboard paste support |
| TC-AUTH-013 | Login via password manager autofill | Positive | P2 | 1. Navigate to /login 2. Allow password manager autofill 3. Click Sign In |
Autofill populates fields correctly; login succeeds | Pass ✓ | Autocomplete support |
| TC-AUTH-014 | Login with minimum valid password (8 chars) | Boundary | P1 | 1. Enter valid email 2. Enter exactly 8-char password (e.g. Ab1!wxyz) 3. Click Sign In |
Login succeeds | Pass ✓ | Min boundary |
| TC-AUTH-015 | Login with maximum valid password (128 chars) | Boundary | P2 | 1. Enter valid email 2. Enter 128-character password 3. Click Sign In |
Login succeeds | Pass ✓ | Max boundary |
| TC-AUTH-016 | Login with password 1000 characters | Boundary | P2 | 1. Enter valid email 2. Paste 1000-character string into password field 3. Click Sign In |
Validation error or 413 response; no crash; no 500 error | Pass ✓ | Large payload boundary |
| TC-AUTH-017 | Login with email missing domain extension | Negative | P2 | 1. Enter user@domain (no TLD) 2. Click Sign In |
Inline validation: Please enter a valid email address | Fail ✓ | |
| TC-AUTH-018 | Login with email with double @@ symbol | Negative | P2 | 1. Enter user@@domain.com 2. Click Sign In |
Inline validation: Invalid email format | Fail ✓ | |
| TC-AUTH-019 | Login with email missing @ | Negative | P2 | 1. Enter invalidemail.com 2. Click Sign In |
Inline validation: Invalid email address | Fail ✓ | |
| TC-AUTH-020 | Login with unregistered email | Negative | P1 | 1. Enter ghost@test.com 2. Enter any password 3. Click Sign In |
Error toast: Invalid email or password (no enumeration — same message for wrong pw and unregistered email) | Fail ✓ | OWASP: prevent user enumeration |
| TC-AUTH-021 | Login with correct email wrong password case | Negative | P1 | 1. Enter correct email 2. Enter secret1! (all lowercase) 3. Click Sign In |
Error: Invalid credentials — password is case-sensitive | Fail ✓ | Password case sensitivity |
| TC-AUTH-022 | Login with password containing only spaces | Negative | P2 | 1. Enter valid email 2. Enter 8 spaces as password 3. Click Sign In |
Validation error: Password cannot be blank OR 401 Invalid credentials | Pass ✓ | Whitespace-only password |
| TC-AUTH-023 | Login with email containing only spaces | Negative | P2 | 1. Enter several spaces as email 2. Enter any password 3. Click Sign In |
Validation error: Email is required | Pass ✓ | |
| TC-AUTH-024 | Login with suspended/deactivated account | Negative | P2 | 1. Enter valid email for suspended account 2. Enter correct password 3. Click Sign In |
Error: Account suspended or Access denied; no session created | Pass ✓ | Account state handling |
| TC-AUTH-025 | Login with deleted account | Negative | P2 | 1. Enter email of deleted account 2. Enter former password 3. Click Sign In |
Error: Invalid email or password (no enumeration) | Pass ✓ | Deleted account |
| TC-AUTH-026 | Re-login after logout | Positive | P1 | 1. Log in successfully 2. Click Logout 3. Log in again with same credentials |
Successful re-login; new session created | Pass ✓ | Session lifecycle |
| TC-AUTH-027 | Already-logged-in user visits /login | Positive | P1 | 1. Log in successfully 2. Navigate to /login in same browser |
Redirect to /dashboard; login page not shown | Pass ✓ | Auth redirect guard |
| TC-AUTH-028 | Password show/hide toggle | UI/UX | P1 | 1. Enter text into password field 2. Click the eye/show icon |
Password characters become visible; icon switches to hide state | Pass ✓ | |
| TC-AUTH-029 | Password hide after show toggle | UI/UX | P1 | 1. Click eye icon again | Password characters masked again; icon reverts | Pass ✓ | |
| TC-AUTH-030 | Submit form via Enter key from password field | UI/UX | P1 | 1. Fill email and password 2. Press Enter key while focus is in password field |
Form submitted; same result as clicking Sign In | Pass ✓ | Keyboard submission |
| TC-AUTH-031 | Submit form via Enter key from email field | UI/UX | P2 | 1. Fill email and password 2. Press Enter key while focus is in email field |
Form submitted or focus moves to password field | Pass ✓ | |
| TC-AUTH-032 | Sign In button disabled during loading | UI/UX | P1 | 1. Click Sign In 2. Immediately observe button state during API call |
Button disabled; no double-submission possible; loading spinner visible | Pass ✓ | Prevent race condition |
| TC-AUTH-033 | Double-click Sign In button rapidly | UI/UX | P1 | 1. Double-click Sign In button very quickly | Only one API request sent; no duplicate session created | Pass ✓ | Race condition guard |
| TC-AUTH-034 | Error toast auto-dismisses | UI/UX | P2 | 1. Submit wrong credentials 2. Observe error message |
Error toast auto-dismisses after 3–5 seconds OR has an X close button | Pass ✓ | |
| TC-AUTH-035 | Forgot Password link navigates correctly | UI/UX | P1 | 1. Click Forgot Password? link | Navigates to /reset-pass without full page reload (SPA routing) | Pass ✓ | |
| TC-AUTH-036 | Sign Up link navigates correctly | UI/UX | P1 | 1. Click Sign Up link / Don't have an account? | Navigates to /signup without full page reload | Pass ✓ | |
| TC-AUTH-037 | Dark theme applied by default | UI/UX | P1 | 1. Open /login in fresh browser with no prior visit | Dark theme applied (dark background); localStorage nabiq-theme=dark set | Pass ✓ | Default dark theme |
| TC-AUTH-038 | Page title correct | UI/UX | P2 | 1. Observe browser tab title | Title: Markopolo - Revenue Agent for Commerce | Pass ✓ | SEO |
| TC-AUTH-039 | No console errors on page load | UI/UX | P1 | 1. Open DevTools Console 2. Navigate to /login 3. Observe console |
Zero console errors; zero unhandled promise rejections | Fail ✓ | DevTools validation |
| TC-AUTH-040 | Login page layout on mobile 375px | Responsive | P1 | 1. Open Chrome DevTools 2. Set viewport to 375px 3. Load /login |
No horizontal overflow; form fits screen; all elements visible and accessible | Pass ✓ | Mobile layout |
| TC-AUTH-041 | Login page layout on tablet 768px | Responsive | P2 | 1. Set viewport to 768px 2. Load /login |
Clean layout; no clipping | Pass ✓ | |
| TC-AUTH-042 | Login on Firefox latest | Cross-Browser | P1 | 1. Open /login in Firefox 2. Complete login flow |
Full login flow works; no browser-specific issues | Skip ✓ | |
| TC-AUTH-043 | Login on Safari latest (macOS) | Cross-Browser | P1 | 1. Open /login in Safari 2. Complete login flow including Google OAuth |
Full login flow works; OAuth popup behaves correctly | Skip ✓ | |
| TC-AUTH-044 | Login on Edge latest | Cross-Browser | P2 | 1. Open /login in Edge 2. Complete login flow |
Login works; no layout issues | Pass ✓ | |
| TC-AUTH-045 | Login on Mobile Safari (iOS) | Cross-Browser | P1 | 1. Open /login on iOS Safari 2. Tap email field; complete login |
No unwanted zoom on input focus; form submits correctly | Skip ✓ | iOS zoom bug check |
| TC-AUTH-046 | Keyboard-only navigation (Accessibility) | Accessibility | P1 | 1. Use Tab key only to navigate all fields 2. Use Enter to submit |
Focus moves: Email → Password → Show/Hide toggle → Forgot Password → Sign In → Continue with Google → Sign Up; Tab order is logical | Fail ✓ | WCAG 2.1 |
| TC-AUTH-047 | Screen reader announces field labels | Accessibility | P1 | 1. Navigate to /login with screen reader on 2. Focus on each input field |
Screen reader announces correct label: Email address and Password for respective fields | Fail ✓ | ARIA labels |
| TC-AUTH-048 | Screen reader announces validation errors | Accessibility | P1 | 1. Click Sign In with empty fields 2. Listen to screen reader |
Validation errors announced via aria-live region immediately after form submission | Pass ✓ | aria-live |
| TC-AUTH-049 | Focus indicator visible on all elements | Accessibility | P1 | 1. Tab through all interactive elements | Visible focus ring (outline) on every element — email field, password field, toggle, links, button | Pass ✓ | WCAG 2.4.7 |
| TC-AUTH-050 | Colour contrast — text on background | Accessibility | P2 | 1. Use browser DevTools accessibility panel or axe extension 2. Check contrast ratios |
All text meets minimum 4.5:1 contrast ratio (WCAG AA Level) | Pass ✓ | |
| TC-AUTH-051 | Zoom to 200% — no layout break | Accessibility | P1 | 1. Set browser zoom to 200% 2. Observe layout |
No horizontal scrollbar; all form elements visible; form fully functional at 200% zoom | Fail ✓ | WCAG 1.4.4 |
| TC-AUTH-052 | SQL injection in email field | Security | P1 | 1. Enter ' OR '1'='1 in email field 2. Enter any password 3. Click Sign In |
Validation error or 401; no SQL error message exposed; login NOT bypassed | Pass ✓ | OWASP A03 Injection |
| TC-AUTH-053 | SQL injection in password field | Security | P1 | 1. Enter valid email 2. Enter ' OR '1'='1'-- in password field 3. Click Sign In |
401 Invalid credentials; no SQL error; login NOT bypassed | Fail ✓ | |
| TC-AUTH-054 | XSS in email field | Security | P1 | 1. Enter @test.com in email 2. Click Sign In |
Input sanitized; validation error shown; no alert popup executed | Pass ✓ | OWASP A07 XSS |
| TC-AUTH-055 | XSS via img onerror in email | Security | P1 | 1. Enter@test.com in email 2. Click Sign In |
Input sanitized; no JavaScript executed in browser | Fail ✓ | |
| TC-AUTH-056 | NoSQL injection in email | Security | P1 | 1. Enter {"$gt": ""} in email field 2. Click Sign In |
Sanitized; 401 returned; login NOT bypassed | Pass ✓ | |
| TC-AUTH-057 | Open redirect via return URL parameter | Security | P1 | 1. Navigate to /login?return=https://evil.com 2. Log in successfully |
Redirect goes to /dashboard ONLY; NOT to evil.com or any external URL | Fail ✓ | Open redirect vulnerability |
| TC-AUTH-058 | CSRF — form submitted from external origin | Security | P1 | 1. Craft a POST request to /api/auth/login from a different origin 2. Submit request |
403 Forbidden or CSRF token mismatch; login rejected | Fail ✓ | OWASP A01 CSRF |
| TC-AUTH-059 | JWT or session token not stored in localStorage | Security | P1 | 1. Log in successfully 2. Open DevTools → Application → Local Storage 3. Inspect all keys |
No JWT or session token visible in localStorage; token should be in HttpOnly cookie only | Fail ✓ | Token storage security |
| TC-AUTH-060 | Session cookie has HttpOnly + Secure + SameSite | Security | P1 | 1. Open DevTools → Application → Cookies 2. Inspect the session/auth cookie attributes |
Cookie has: HttpOnly=true; Secure=true; SameSite=Strict (or Lax) | Pass ✓ | Cookie security |
| TC-AUTH-061 | HTTPS enforced — HTTP redirects to HTTPS | Security | P1 | 1. Type http://beta-stg.markopolo.ai/login in browser 2. Observe redirect |
Automatically redirected to HTTPS; HSTS header present in response | Fail ✓ | Transport security |
| TC-AUTH-062 | Clickjacking — login page not renderable in iframe | Security | P1 | 1. Create a test HTML page with: <br>2. Open in browser | Login page NOT rendered in iframe; X-Frame-Options: DENY header present | Pass ✓ | Clickjacking protection |
| TC-AUTH-063 | Content-Security-Policy header present | Security | P2 | 1. Open DevTools → Network 2. Click on the main document request 3. Check Response Headers |
Content-Security-Policy header is present in the response | Fail ✓ | CSP required |
| TC-AUTH-064 | Password not visible in network request URL | Security | P1 | 1. Enter valid credentials 2. Click Sign In 3. Inspect the login network request |
Password appears in POST request body (HTTPS encrypted); NOT in URL query parameters | Pass ✓ | Credential in URL |
| TC-AUTH-065 | Login API response does not expose sensitive data | Security | P1 | 1. Log in successfully 2. Inspect the API response body in Network tab |
Response does NOT contain: plaintext password; raw JWT in body; internal user IDs | Fail ✓ | |
| TC-AUTH-066 | Token replay after logout | Security | P1 | 1. Log in; capture the auth cookie/token value 2. Log out 3. Manually replay the captured token in a new request |
401 Unauthorized; token is invalidated after logout | Skip ✓ | Token invalidation |
| TC-AUTH-067 | Brute force protection — 50 rapid API requests | Security | P1 | 1. Use a script or Postman to send 50 rapid POST requests to /api/auth/login with wrong credentials | 429 Too Many Requests returned after threshold; Retry-After header present; IP throttled | Skip ✓ | Rate limiting |
| TC-AUTH-068 | Login API — GET method rejected | API | P2 | 1. Send a GET request to /api/auth/login | 405 Method Not Allowed returned | Fail ✓ | |
| TC-AUTH-069 | Login API — empty JSON body | API | P2 | 1. Send POST /api/auth/login with body: {} | 422 Unprocessable Entity; validation error returned | Fail ✓ | |
| TC-AUTH-070 | Login API — null values in body | API | P2 | 1. Send POST /api/auth/login with body: {"email":null,"password":null} | 422 Validation error; both fields required | Pass ✓ | |
| TC-AUTH-071 | Login API — malformed JSON body | API | P2 | 1. Send POST /api/auth/login with body: {email: user (invalid JSON)} | 400 Bad Request returned | Pass ✓ | |
| TC-AUTH-072 | Login API — 500 error shows friendly message | API | P1 | 1. Simulate or intercept to force a 500 response from /api/auth/login 2. Observe browser UI |
User sees friendly error message; no stack trace or internal error details exposed | Pass ✓ | Error handling |
| TC-AUTH-073 | Login API — response time under SLA | Performance | P2 | 1. Send POST /api/auth/login with valid credentials 2. Measure response time |
Response received in under 2000ms | Pass ✓ | Performance SLA |
| TC-AUTH-074 | Login page loads under 3 seconds | Performance | P2 | 1. Open DevTools → Network → Throttle to Fast 3G 2. Hard reload /login 3. Observe LCP metric |
Page fully interactive in under 3 seconds on average connection | Fail ✓ | Core Web Vitals |
| TC-AUTH-075 | Offline mode — friendly error shown | Performance | P2 | 1. Enable offline mode in DevTools 2. Enter credentials 3. Click Sign In |
Friendly error shown: No internet connection. Please try again. | Fail ✓ | Network resilience |
| TC-AUTH-076 | Login with email containing unicode characters | Character | P2 | 1. Enter üser@example.com in email field 2. Click Sign In |
Validation error: Invalid email format | Fail ✓ | Unicode email |
| TC-AUTH-077 | Login with email containing emoji | Character | P2 | 1. Enter user😀@test.com in email field 2. Click Sign In |
Validation error: Invalid email format; no crash | Pass ✓ | Emoji in email |
| TC-AUTH-078 | Login with password containing Unicode characters | Character | P2 | 1. Enter valid email 2. Enter Müñõs@Pass1 as password 3. Click Sign In |
Login succeeds if account was created with same Unicode password | Pass ✓ | Unicode password |
| TC-AUTH-079 | Login with password containing zero-width spaces | Character | P1 | 1. Enter valid email 2. Paste password with embedded zero-width space (U+200B): Password1! 3. Click Sign In |
Sanitized; 401 or validation error; not treated as match | Pass ✓ | Invisible characters |
| TC-AUTH-080 | Login with plus-addressed email | Positive | P2 | 1. Enter user+tag@gmail.com 2. Enter correct password 3. Click Sign In |
Login succeeds; plus addressing supported | Fail ✓ | RFC 5321 |
Auth - Forgot Password
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-AUTH-081 | Request password reset with valid registered email | Functional | P1 | 1. Navigate to /reset-pass (or click Forgot Password on login) 2. Enter registered@markopolo.ai 3. Click Send Reset Link |
Success message: If this email is registered, you'll receive a reset link shortly | Pass ✓ | Core flow — email must not enumerate |
| TC-AUTH-082 | Request reset with unregistered email — no enumeration | Security | P1 | 1. Navigate to /reset-pass 2. Enter ghost@test.com (not registered) 3. Click Send Reset Link |
SAME success message as TC-AUTH-081: If this email is registered, you'll receive a reset link; no indication if email exists or not | Pass ✓ | OWASP: prevent email enumeration |
| TC-AUTH-083 | Empty email field — submit | Negative | P2 | 1. Leave email field empty 2. Click Send Reset Link |
Inline validation: Email is required | Pass ✓ | |
| TC-AUTH-084 | Invalid email format in reset form | Negative | P2 | 1. Enter notanemail 2. Click Send Reset Link |
Inline validation: Please enter a valid email address | Fail ✓ | |
| TC-AUTH-085 | Reset email received in inbox | Functional | P1 | 1. Check registered email inbox 2. Locate the password reset email 3. Verify: sender address; subject line; reset link is clickable and valid |
Email received; link is clickable; link contains valid token | Skip ✓ | Email delivery verification |
| TC-AUTH-086 | Reset link expires after 24 hours | Functional | P2 | 1. Wait 24+ hours after receiving reset email 2. Click the reset link |
Page shows: This link has expired. Request a new reset link. | Fail ✓ | Token expiry |
| TC-AUTH-087 | Valid token — set new password successfully | Functional | P1 | 1. Click reset link from email (opens /reset-pass?token=xxxx) 2. Enter new password: NewSecure@1 3. Enter same in confirm password 4. Click Reset Password |
Password reset successfully; redirect to /login with success message | Skip ✓ | Step 2 core flow |
| TC-AUTH-088 | Login with new password after reset | Functional | P1 | 1. Navigate to /login 2. Enter email and new password 3. Click Sign In |
Login succeeds with new password | Skip ✓ | Post-reset verification |
| TC-AUTH-089 | Old password rejected after reset | Security | P1 | 1. Navigate to /login 2. Enter email and OLD password 3. Click Sign In |
Error: Invalid email or password; old password does not work | Skip ✓ | Old password invalidation |
| TC-AUTH-090 | Expired reset token shows error | Negative | P1 | 1. Open /reset-pass?token=expired_token 2. Enter new password 3. Submit |
Error: This link has expired. Please request a new password reset. | Fail ✓ | |
| TC-AUTH-091 | Invalid/tampered reset token shows error | Security | P1 | 1. Open /reset-pass?token=abc123fakexyz 2. Enter new password 3. Submit |
Error: Invalid or expired reset link | Fail ✓ | Token validation |
| TC-AUTH-092 | Already-used reset token rejected (single-use) | Security | P1 | 1. Use the same reset link a second time 2. Enter new password 3. Submit |
Error: This link has already been used. Please request a new reset link. | Fail ✓ | One-time token enforcement |
| TC-AUTH-093 | Multiple reset requests — old tokens invalidated | Security | P1 | 1. Request reset email — Email #1 arrives 2. Request reset email again — Email #2 arrives 3. Use link from Email #1 |
Error: Invalid or expired link; only latest token is valid | Fail ✓ | Token rotation |
| TC-AUTH-094 | New password same as old password | Negative | P2 | 1. Open valid reset link 2. Enter old password in new password field 3. Confirm and submit |
Error: New password cannot be the same as your previous password OR accepted depending on policy | Skip ✓ | Password reuse policy |
| TC-AUTH-095 | New password and confirm password do not match | Negative | P1 | 1. Open reset link 2. Enter NewPass@1 as new password 3. Enter DiffPass@1 as confirm password 4. Submit |
Error: Passwords do not match; form not submitted | Pass ✓ | |
| TC-AUTH-096 | Weak new password rejected | Negative | P1 | 1. Open reset link 2. Enter 123456 as new password 3. Submit |
Error: Password does not meet requirements (min 8 chars / complexity) | Fail ✓ | Password policy on reset |
| TC-AUTH-097 | Empty new password fields on reset page | Negative | P2 | 1. Open reset link 2. Leave password and confirm fields empty 3. Submit |
Password is required error shown | Pass ✓ | |
| TC-AUTH-098 | Rate limiting on reset requests | Security | P1 | 1. Submit valid email 10 times rapidly in under 1 minute 2. Observe response after threshold |
429 Too Many Requests; message: Please wait before requesting another reset link | Skip ✓ | Prevent email flooding |
| TC-AUTH-099 | SQL injection in reset email field | Security | P1 | 1. Enter ' OR '1'='1 in email field 2. Submit |
Input sanitized; no SQL error exposed; generic success or validation error returned | Fail ✓ | |
| TC-AUTH-100 | XSS in new password on reset page | Security | P1 | 1. Open reset link 2. Enter as new password 3. Submit |
Input sanitized; no script executed; validation error or accepted as plain text | Pass ✓ | |
| TC-AUTH-101 | Direct access to /reset-pass with no token | Negative | P2 | 1. Navigate to /reset-pass directly (no query param) | Step 1 email form shown; no crash; no blank/broken page | Pass ✓ | |
| TC-AUTH-102 | Token single-character tamper | Security | P1 | 1. Copy valid reset link 2. Change one character in the token 3. Submit new password |
Error: Invalid or expired reset link; password NOT changed | Skip ✓ | Token integrity |
| TC-AUTH-103 | Loading state during email submission | UI/UX | P2 | 1. Enter valid email 2. Click Send Reset Link 3. Observe button during request |
Loading spinner or disabled button shown; cannot click twice | Pass ✓ | |
| TC-AUTH-104 | Back to Login link navigates correctly | UI/UX | P2 | 1. Click Back to Login link | Navigates to /login; no full page reload | Pass ✓ | |
| TC-AUTH-105 | Reset API response time under SLA | Performance | P3 | 1. Submit valid email via /api/auth/forgot-password 2. Measure response time |
Response received in under 2000ms | Pass ✓ |
Auth - Sign Up
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-AUTH-106 | New user registration with all valid data | Functional | P1 | 1. Navigate to /signup 2. Enter Full Name: John Doe 3. Enter email: newtester@test.com 4. Enter password: Secure@Pass1 5. Accept Terms & Conditions 6. Click Create Account / Sign Up |
Account created successfully; redirect to /dashboard or email verification page; welcome email sent | Fail ✓ | Core happy path |
| TC-AUTH-107 | Google OAuth signup — new user | Functional | P1 | 1. Navigate to /signup 2. Click Continue with Google 3. Select Google account 4. Authorize |
Redirect to /dashboard; profile pre-filled from Google; new user created | Fail ✓ | OAuth signup |
| TC-AUTH-108 | All signup fields empty — submit | Negative | P1 | 1. Leave all fields empty 2. Click Create Account / Sign Up |
Required validation errors shown for all mandatory fields; form not submitted | Skip ✓ | |
| TC-AUTH-109 | Missing Full Name — submit | Negative | P2 | 1. Leave name empty 2. Fill email and password 3. Accept terms; submit |
Error: Name is required | Skip ✓ | |
| TC-AUTH-110 | Missing Email — submit | Negative | P2 | 1. Fill name and password 2. Leave email empty 3. Accept terms; submit |
Error: Email is required | Skip ✓ | |
| TC-AUTH-111 | Missing Password — submit | Negative | P2 | 1. Fill name and email 2. Leave password empty 3. Accept terms; submit |
Error: Password is required | Skip ✓ | |
| TC-AUTH-112 | Terms & Conditions not accepted | Negative | P1 | 1. Fill all fields with valid data 2. Leave Terms & Conditions checkbox unchecked 3. Click Sign Up |
Error: You must accept the Terms & Conditions to continue OR button remains disabled until checkbox is checked | Skip ✓ | Terms requirement |
| TC-AUTH-113 | Duplicate email registration | Negative | P1 | 1. Navigate to /signup 2. Enter already-registered email 3. Fill other valid fields 4. Submit |
Error: An account with this email already exists | Skip ✓ | 409 Conflict |
| TC-AUTH-114 | Invalid email format in signup | Negative | P2 | 1. Enter invalid-email as email 2. Fill other valid fields; submit |
Inline validation: Please enter a valid email address | Fail ✓ | |
| TC-AUTH-115 | Weak password — too short (less than 8 chars) | Negative | P1 | 1. Enter 7-character password: weak1!x 2. Fill other valid fields; submit |
Error: Password must be at least 8 characters | Skip ✓ | Min length policy |
| TC-AUTH-116 | Weak password — no uppercase letter | Negative | P2 | 1. Enter password with no uppercase: lowercase1! 2. Submit |
Error or warning: Password must contain at least one uppercase letter | Skip ✓ | Complexity policy |
| TC-AUTH-117 | Weak password — no number | Negative | P2 | 1. Enter password with no number: NoNumbers! 2. Submit |
Error or warning: Password must contain at least one number | Skip ✓ | |
| TC-AUTH-118 | Weak password — no special character | Negative | P2 | 1. Enter password with no special char: NoSpecial1 2. Submit |
Error or warning: Password must contain at least one special character | Skip ✓ | |
| TC-AUTH-119 | Password and confirm password do not match | Negative | P1 | 1. Enter Password: NewPass@1 2. Enter Confirm Password: DiffPass@2 3. Submit |
Error: Passwords do not match; form not submitted | Pass ✓ | |
| TC-AUTH-120 | Password strength indicator — weak | UI/UX | P2 | 1. Type: password in password field 2. Observe indicator |
Password strength indicator shows Weak or Very Weak | Pass ✓ | |
| TC-AUTH-121 | Password strength indicator — strong | UI/UX | P2 | 1. Type: Str0ng!P@ssW0rd in password field 2. Observe indicator |
Password strength indicator shows Strong or Very Strong | Pass ✓ | |
| TC-AUTH-122 | Name with hyphen accepted | Positive | P2 | 1. Enter name: Mary-Jane Watson 2. Fill valid email and password; submit |
Account created successfully | Pass ✓ | |
| TC-AUTH-123 | Name with apostrophe accepted | Positive | P2 | 1. Enter name: O'Brien 2. Fill valid email and password; submit |
Account created successfully | Pass ✓ | |
| TC-AUTH-124 | Email with plus addressing accepted | Positive | P2 | 1. Enter email: user+tag@gmail.com 2. Fill other valid fields; submit |
Account created; plus-addressed email supported | Pass ✓ | Plus addressing |
| TC-AUTH-125 | Name with only spaces — rejected | Negative | P2 | 1. Enter only spaces as name 2. Fill valid email and password; submit |
Error: Name is required or Name cannot be blank | Skip ✓ | |
| TC-AUTH-126 | Email with spaces — trimmed or rejected | Negative | P2 | 1. Enter ' user@test.com ' with leading and trailing spaces 2. Submit |
Spaces automatically trimmed and account created; OR validation error shown | Skip ✓ | |
| TC-AUTH-127 | Name too long — 1000 characters | Boundary | P2 | 1. Paste 1000-character string into name field 2. Submit |
Validation error: Name exceeds maximum length; no crash or 500 error | Pass ✓ | |
| TC-AUTH-128 | Password exactly 8 characters — accepted (min boundary) | Boundary | P1 | 1. Enter password: Abcd1!xy (exactly 8 chars) 2. Submit |
Account created; 8-char password accepted as minimum | Skip ✓ | Min boundary |
| TC-AUTH-129 | Password exactly 7 characters — rejected (min-1) | Boundary | P1 | 1. Enter password: Abcd1!x (exactly 7 chars) 2. Submit |
Error: Password must be at least 8 characters | Skip ✓ | Min-1 boundary |
| TC-AUTH-130 | Disposable/temporary email | Negative | P2 | 1. Enter temp@mailinator.com or temp-mail.org address 2. Submit |
Error: Disposable email addresses are not allowed OR account created (per policy) | Pass ✓ | Disposable email policy |
| TC-AUTH-131 | XSS in Full Name field | Security | P1 | 1. Enter in name field 2. Fill valid email and password; submit |
Input sanitized; no script executed in browser; account created or rejected with error | Pass ✓ | Stored XSS prevention |
| TC-AUTH-132 | SQL injection in Full Name field | Security | P1 | 1. Enter ' OR '1'='1 in name field 2. Submit |
Sanitized; no SQL error; account created or validation error | Skip ✓ | |
| TC-AUTH-133 | SQL injection in Email field | Security | P1 | 1. Enter ' OR '1'='1 in email field 2. Submit |
Validation error: Invalid email format; no SQL executed | Pass ✓ | |
| TC-AUTH-134 | Mass assignment — inject role:admin in payload | Security | P1 | 1. Intercept POST /api/auth/register 2. Add "role":"admin" to request body 3. Submit |
Account created with role: user (default); admin role injection ignored | Pass ✓ | Mass assignment OWASP A01 |
| TC-AUTH-135 | Mass assignment — inject isAdmin:true | Security | P1 | 1. Intercept POST /api/auth/register 2. Add "isAdmin":true to body 3. Submit |
isAdmin flag ignored; user created with default permissions | Pass ✓ | |
| TC-AUTH-136 | Race condition — concurrent duplicate signups | Security | P1 | 1. Open 5 browser tabs or Postman 2. Submit same email registration simultaneously in all 5 |
Only 1 account created; remaining 4 receive 409 Conflict; no duplicate user records in DB | Fail ✓ | Race condition / DB unique constraint |
| TC-AUTH-137 | Signup API — missing name field | API | P2 | 1. Send POST /api/auth/register with body: {"email":"x@x.com","password":"Valid1!"} | 422 Unprocessable Entity; error: name is required | Fail ✓ | |
| TC-AUTH-138 | Signup API — missing password field | API | P2 | 1. Send POST /api/auth/register with body: {"name":"John","email":"x@x.com"} | 422 Unprocessable Entity; error: password is required | Fail ✓ | |
| TC-AUTH-139 | Signup API — 201 response does not include password | Security | P1 | 1. Submit valid registration 2. Inspect the API response body in Network tab |
201 Created; response body contains user object WITHOUT password field | Fail ✓ | |
| TC-AUTH-140 | Signup API rate limiting | Security | P1 | 1. Send 30 registration POST requests rapidly 2. Observe responses |
429 Too Many Requests returned after threshold | Skip ✓ | |
| TC-AUTH-141 | Already logged-in user visits /signup | Negative | P1 | 1. Log in successfully 2. Navigate to /signup |
Redirect to /dashboard; signup page not shown | Pass ✓ | Auth redirect guard |
| TC-AUTH-142 | Welcome or verification email received | Functional | P2 | 1. Complete signup 2. Check inbox of registered email |
Welcome or email verification email received promptly | Fail ✓ | Email delivery |
| TC-AUTH-143 | Signup form keyboard navigation | Accessibility | P1 | 1. Tab through all fields and submit via keyboard only | Tab order: Name → Email → Password → Confirm → Terms Checkbox → Sign Up button; all reachable by keyboard | Skip ✓ | WCAG 2.1 |
| TC-AUTH-144 | Screen reader announces signup errors | Accessibility | P1 | 1. Click Sign Up with empty fields 2. Listen to screen reader |
All validation errors announced via aria-live region | Pass ✓ | |
| TC-AUTH-145 | Sign Up layout on mobile 375px | Responsive | P1 | 1. Open /signup at 375px viewport 2. Fill all fields |
No overflow; all fields visible; keyboard does not break layout | Fail ✓ | |
| TC-AUTH-146 | Password field type=password (characters masked) | Security | P1 | 1. Type in password field 2. Inspect the input element type attribute |
Input type is password; characters are masked as dots/asterisks | Pass ✓ | |
| TC-AUTH-147 | Sign Up performance — API response under SLA | Performance | P2 | 1. Submit valid registration 2. Measure time until 201 response received |
Registration API responds in under 3000ms | Skip ✓ | |
| TC-AUTH-148 | Name with Arabic characters | Character | P2 | 1. Enter اسم المستخدم as name 2. Submit |
Accepted as valid Unicode name | Skip ✓ | International characters |
| TC-AUTH-149 | Name with Bangla characters | Character | P2 | 1. Enter আমার নাম as name 2. Submit |
Accepted as valid Unicode name | Pass ✓ | |
| TC-AUTH-150 | Name with Japanese characters | Character | P2 | 1. Enter 名前 as name 2. Submit |
Accepted as valid Unicode name | Skip ✓ |
Auth - Session
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-AUTH-151 | Session timeout after idle | Functional | P2 | 1. Log in successfully 2. Leave browser idle for the session timeout period (e.g. 30–60 min) 3. Attempt to navigate or click any action |
Redirect to /login with message: Your session has expired. Please log in again. | Pass ✓ | |
| TC-AUTH-152 | Logout clears session and redirects to login | Functional | P1 | 1. Click user avatar or profile menu 2. Click Logout |
Session cookie cleared; localStorage cleared; redirect to /login; cannot navigate back to protected routes | Pass ✓ | Logout to auth loop |
| TC-AUTH-153 | Back button after logout does not restore session | Security | P1 | 1. Log out 2. Press browser Back button |
Protected page NOT shown; redirect to /login; session fully cleared | Pass ✓ | |
| TC-AUTH-154 | Directly accessing /dashboard without login | Security | P1 | 1. Open browser to /dashboard URL directly without logging in | Redirect to /login; protected route inaccessible | Fail ✓ | Route guard |
| TC-AUTH-155 | Token refresh on activity near expiry | Functional | P3 | 1. Keep session active with periodic actions near expiry window | Session refreshed silently; user not logged out or interrupted | Pass ✓ | |
| TC-AUTH-156 | Logout in Tab A — Tab B redirected | Security | P2 | 1. Log out in Tab A 2. Perform action in Tab B |
Tab B detects session loss and redirects to /login | Pass ✓ | Multi-tab session |
| TC-AUTH-157 | Concurrent sessions from two different browsers | Security | P2 | 1. Log in on Chrome 2. Log in on Firefox with same credentials 3. Use both sessions |
Both sessions active (per policy) OR browser A session invalidated — result depends on documented policy; expected behavior should be consistent | Pass ✓ | |
| TC-AUTH-158 | localStorage empty after logout | Security | P1 | 1. Log out 2. Open DevTools → Application → Local Storage 3. Check all keys |
No auth tokens; no sensitive data in localStorage | Pass ✓ | |
| TC-AUTH-159 | sessionStorage empty after logout | Security | P1 | 1. Log out 2. Open DevTools → Application → Session Storage |
No auth tokens or sensitive data in sessionStorage | Pass ✓ | |
| TC-AUTH-160 | Auth cookie deleted after logout | Security | P1 | 1. Log out 2. Open DevTools → Application → Cookies |
Session/auth cookie removed or expired (Max-Age=0) | Pass ✓ |
Auth - Security Deep Dive
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-AUTH-161 | HSTS header present on all auth pages | Security | P1 | 1. Load /login; /signup; /reset-pass 2. Inspect response headers for each page |
Strict-Transport-Security header present: max-age=31536000; includeSubDomains | Fail ✓ | Transport security |
| TC-AUTH-162 | X-Content-Type-Options header present | Security | P2 | 1. Load /login 2. Inspect response headers |
X-Content-Type-Options: nosniff header present | Pass ✓ | MIME sniffing prevention |
| TC-AUTH-163 | X-Frame-Options DENY on auth pages | Security | P1 | 1. Load /login; /signup; /reset-pass 2. Inspect response headers |
X-Frame-Options: DENY present on all auth pages | Pass ✓ | Clickjacking |
| TC-AUTH-164 | No password exposed in any log or response | Security | P1 | 1. Log in; sign up; reset password 2. Check Console; Network responses; Application storage |
No plaintext password visible in any browser-accessible location | Pass ✓ | |
| TC-AUTH-165 | Google OAuth state parameter validated | Security | P1 | 1. Begin Google OAuth login 2. Intercept and modify the state parameter 3. Complete OAuth |
OAuth flow fails; CSRF state mismatch detected; redirect blocked | Pass ✓ | OAuth CSRF protection |
| TC-AUTH-166 | Google OAuth cancel returns gracefully | Security | P2 | 1. Click Continue with Google 2. On Google consent screen click Cancel/Back |
Graceful return to /login; no error page; no crash | Pass ✓ | |
| TC-AUTH-167 | Path traversal in email field | Security | P1 | 1. Enter ../../etc/passwd@test.com in email 2. Submit |
Validation error: Invalid email format; no file system access | Pass ✓ | |
| TC-AUTH-168 | Template injection in name field (signup) | Security | P1 | 1. Enter {{7*7}} in name field 2. Submit |
{{7*7}} treated as literal text; result NOT 49; no template evaluated | Pass ✓ | SSTI prevention |
| TC-AUTH-169 | URL manipulation — ?admin=true on login | Security | P1 | 1. Navigate to /login?admin=true 2. Log in normally |
Parameter ignored; no admin privileges granted; normal user session | Pass ✓ | |
| TC-AUTH-170 | Sensitive data not exposed in page source | Security | P2 | 1. View Page Source (Ctrl+U) 2. Search for: password; token; secret; apiKey |
No sensitive credentials or tokens in page HTML source | Pass ✓ |
Auth - UI & UX
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-AUTH-171 | All auth pages render without console errors | UI/UX | P1 | 1. Open /login 2. Open /signup 3. Open /reset-pass 4. Check DevTools Console on each page |
Zero JavaScript console errors on all three pages | Fail ✓ | |
| TC-AUTH-172 | No broken network requests on auth pages | UI/UX | P1 | 1. Load /login; /signup; /reset-pass 2. Filter Network by Status: Failed |
Zero failed/blocked network requests (no 404; 405; 500 on initial load) | Fail ✓ | |
| TC-AUTH-173 | GTM script loads asynchronously | UI/UX | P2 | 1. Load /login 2. Check if GTM (GTM-M5NB8JK) request is present |
GTM loads asynchronously (defer/async); does NOT block initial page render | Pass ✓ | Third-party performance |
| TC-AUTH-174 | Tolt affiliate script loads asynchronously | UI/UX | P3 | 1. Load /login 2. Check for cdn.tolt.io request |
Tolt script loads with async attribute; does NOT block render | Pass ✓ | |
| TC-AUTH-175 | Login form alignment on desktop | UI/UX | P2 | 1. Open /login at full desktop resolution 2. Inspect form layout |
Form centered; email and password fields aligned; consistent padding and spacing | Fail ✓ | |
| TC-AUTH-176 | Signup form alignment on desktop | UI/UX | P2 | 1. Open /signup at full desktop resolution 2. Inspect form layout |
All fields aligned; no overflow; consistent spacing | Pass ✓ | |
| TC-AUTH-177 | Dark theme persists on page refresh | UI/UX | P2 | 1. Confirm dark theme is active 2. Refresh the page (F5) |
Dark theme maintained after refresh; no flash of light theme | Pass ✓ | Theme persistence |
| TC-AUTH-178 | Auth pages redirect after login with deep link | UI/UX | P2 | 1. Open /dashboard while not logged in 2. Redirected to /login 3. Log in successfully |
After login redirect goes to originally-requested /dashboard (not always to homepage) | Fail ✓ | Deep link redirect |
| TC-AUTH-179 | Sign In button shows loading text during request | UI/UX | P2 | 1. Click Sign In 2. Observe button label during API call |
Button shows Loading... or spinner; text changes from Sign In | Pass ✓ | |
| TC-AUTH-180 | Page load performance — login page LCP | Performance | P2 | 1. Open Chrome DevTools → Performance tab 2. Reload /login 3. Observe Largest Contentful Paint |
LCP under 3 seconds on standard broadband | Pass ✓ | Core Web Vitals |
| TC-AUTH-181 | Auth pages print layout (Ctrl+P) | UI/UX | P4 | 1. Press Ctrl+P to open print preview on /login | No sensitive data prominently printed; graceful print layout | Pass ✓ | |
| TC-AUTH-182 | Login in Incognito mode | UI/UX | P2 | 1. Open /login in incognito 2. Log in with valid credentials |
Login works correctly in incognito; no interference from prior session data | Pass ✓ | |
| TC-AUTH-183 | Auth page with JavaScript disabled | UI/UX | P2 | 1. Disable JavaScript 2. Open /login |
Noscript fallback message shown; or graceful degradation; no broken blank page | Pass ✓ | noscript fallback |
| TC-AUTH-184 | Network disconnect mid-form submission | UI/UX | P2 | 1. Enter credentials 2. Enable offline mode in DevTools 3. Click Sign In |
Friendly error shown: Connection lost. Please check your internet and try again. | Pass ✓ | |
| TC-AUTH-185 | Touch targets meet 44x44px minimum on mobile | Accessibility | P1 | 1. Inspect all buttons and interactive elements on /login; /signup; /reset-pass 2. Check computed size |
All interactive elements (buttons; links; toggles) are minimum 44x44px clickable area | Fail ✓ | WCAG 2.5.5 |
| TC-AUTH-186 | High contrast mode compatibility | Accessibility | P2 | 1. Enable Windows/macOS high contrast mode 2. Open /login |
UI adapts; text readable; buttons visible; form functional | Pass ✓ |
Auth - Exploratory & Edge Cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-AUTH-187 | Email with zero-width space character in field | Exploratory | P1 | 1. Copy-paste: valid@test.com (contains invisible U+200B zero-width space) 2. Submit |
Sanitized or flagged; login NOT bypassed; no silent acceptance of corrupted input | Pass ✓ | Invisible Unicode injection |
| TC-AUTH-188 | Register then immediately attempt login before email verification | Exploratory | P2 | 1. Register new account 2. Immediately attempt login without clicking verification link |
Per policy: login blocked (if verification required) with clear message; OR login allowed (if no verification); consistent with product spec | Skip ✓ | Email verification gate |
| TC-AUTH-189 | Request reset → change password manually → use reset link | Exploratory | P1 | 1. Request reset email 2. Manually change password from /account settings while logged in 3. Click the original reset link and try to set password |
Reset link is invalidated after manual password change; error: Link expired or already used | Pass ✓ | Token invalidation on pw change |
| TC-AUTH-190 | Request reset for account → account deleted → use link | Exploratory | P1 | 1. Request reset link 2. Delete account via admin/API 3. Click reset link and try to set new password |
Error: Invalid or expired link; no ghost account created | Pass ✓ | Account deletion edge case |
| TC-AUTH-191 | Sign Up then immediately sign up again with same email (rapid) | Exploratory | P1 | 1. Complete valid signup 2. Immediately go back and submit same email again |
409 Conflict; second signup rejected; no duplicate account | Fail ✓ | |
| TC-AUTH-192 | Resize window during API call in progress | Exploratory | P2 | 1. Click Sign In 2. Immediately drag-resize the browser window |
No layout break; spinner still visible; request completes normally | Pass ✓ | |
| TC-AUTH-193 | Long session — use app for 4+ hours | Exploratory | P3 | 1. Log in 2. Use the app with occasional actions over 4+ hours |
Session remains valid for documented session length; graceful expiry message if session ends | Pass ✓ | Long session |
| TC-AUTH-194 | Password with CRLF injection characters | Security | P1 | 1. Enter valid email 2. Enter password: Pass\r\nword1! 3. Submit |
Sanitized; 401; no CRLF header injection | Pass ✓ | Header injection |
| TC-AUTH-195 | Signup with role embedded in name field | Security | P1 | 1. Enter name: Admin Role:superadmin 2. Submit |
HTML sanitized; no role escalation; stored and displayed as plain text | Pass ✓ | |
| TC-AUTH-196 | Login API — extra unexpected fields ignored | API | P2 | 1. POST to /api/auth/login with {email; password; role:admin; isSuperAdmin:true} | Extra fields silently ignored; normal 200 or 422 depending on strict validation mode | Pass ✓ | |
| TC-AUTH-197 | Reset link in email is HTTPS — not HTTP | Security | P2 | 1. Request password reset 2. Open email 3. Inspect the reset link URL |
Reset link uses HTTPS protocol; not HTTP; no mixed content | Skip ✓ | |
| TC-AUTH-198 | og:url meta tag does not expose staging URL in production | UI/UX | P3 | 1. View page source (Ctrl+U) 2. Find |
og:url should NOT point to beta-stg.markopolo.ai in production; should be beta.markopolo.ai | Pass ✓ | Staging URL leak in meta |
| TC-AUTH-199 | Sign Up on 2G throttled network | Performance | P2 | 1. Set DevTools Network to Slow 2G 2. Complete signup flow |
Form functional; loader shown; API timeout handled gracefully; no blank/broken page | Fail ✓ | Slow network |
| TC-AUTH-200 | Login page renders correctly with ad-blocker enabled | Exploratory | P3 | 1. Enable uBlock Origin or similar ad-blocker 2. Open /login and complete login |
Page renders; GTM/Tolt may be blocked but core login form functional; no broken layout | Pass ✓ | Ad-blocker compatibility |
Dashboard 15 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-DASH-001 | Dashboard loads welcome message | Functional | P1 | 1. Open beta-stg.markopolo.ai/login 2. Log in with imtiaz@markopolo.ai / Markopolo@2025 3. Navigate to Dashboard root |
Dashboard loads; displays: 'Welcome back, Imtiaz!' heading and subheading: 'Let’s recover your lost revenue, automatically.' | Fail ✓ | |
| TC-DASH-002 | Book a 1:1 session button link works | Functional | P2 | 1. Open Dashboard 2. Click 'Book a 1:1 session with our team to get started!' button |
Opens booking scheduler/modal or external Calendly link in a new browser tab | Pass ✓ | |
| TC-DASH-003 | Verify MarkTag resource link opens correct guide | Functional | P2 | 1. Open Dashboard 2. Scroll to 'Browse our most helpful resources' section 3. Click 'How to verify MarkTag is tracking correctly?' |
Redirects to documentation/help page explaining MarkTag verification steps | Pass ✓ | Help section link |
| TC-DASH-004 | Browse vs Cart vs Checkout abandonment link opens correct guide | Functional | P3 | 1. Open Dashboard 2. Scroll to resources 3. Click 'Browse vs Cart vs Checkout abandonment: which to start with?' |
Redirects to guide detailing abandonment types and best practices | Pass ✓ | |
| TC-DASH-005 | How recovery sequences work link opens correct guide | Functional | P3 | 1. Open Dashboard 2. Click 'How recovery sequences work (timing, channels, fallbacks)?' link |
Redirects to the sequence setup documentation guide | Pass ✓ | |
| TC-DASH-006 | Setting up Voice AI link opens correct guide | Functional | P2 | 1. Open Dashboard 2. Click 'Setting up Voice AI for your first recovery campaign!' link |
Redirects to the Voice AI documentation | Pass ✓ | |
| TC-DASH-007 | WhatsApp Business approval link opens guide | Functional | P2 | 1. Open Dashboard 2. Click 'WhatsApp Business approval: what you need to know?' link |
Redirects to the WhatsApp Business verification guide | Pass ✓ | |
| TC-DASH-008 | How Markopolo attributes recovered revenue link opens guide | Functional | P3 | 1. Open Dashboard 2. Click 'How Markopolo attributes recovered revenue?' link |
Redirects to the attribution model documentation | Pass ✓ | |
| TC-DASH-009 | Dashboard metric cards display correctly | Functional | P1 | 1. Open Dashboard 2. Verify the recovered revenue, lost revenue, and conversion rate cards load |
Metrics show up-to-date values fetched from backend; no placeholder labels | Pass ✓ | |
| TC-DASH-010 | No N+1 API polling issues on Dashboard | Performance | P1 | 1. Open Dashboard 2. Stay idle on page for 1 minute 3. Count API requests to /workspaces, /credits, and /usage |
Requests are debounced/cached; no N+1 query loop or high request spikes | Pass ✓ | BUG-006 regression check |
| TC-DASH-011 | User profile menu dropdown options | UI | P2 | 1. Click the button containing profile info 'Imtiaz' 2. Observe dropdown content |
Dropdown reveals: 'Imtiaz', 'imtiaz@markopolo.ai', and navigation links | Fail ✓ | |
| TC-DASH-012 | Support widget button triggers help desk | Functional | P2 | 1. Click the 'Support' button in bottom left sidebar | Opens the client support chat widget/window successfully | Pass ✓ | |
| TC-DASH-013 | Sidebar navigation to all routes | Functional | P1 | 1. Click: Data room, Memory, Analytics, Leads, Campaigns, Content, Integrations, Plan and billing, Settings | Successfully navigates to each route in the SPA context without full page reloads | Fail ✓ | |
| TC-DASH-014 | Dashboard mobile responsive view | UI | P2 | 1. Set viewport to 375px wide 2. Observe Dashboard layout |
Sidebar collapses into hamburger menu; cards stack vertically; no horizontal overflow | Fail ✓ | |
| TC-DASH-015 | Dashboard loads skeletons on slow network | UI | P2 | 1. Set network throttling to Slow 3G 2. Load Dashboard |
Skeletons / placeholders are shown during load; no broken UI glitches | Pass ✓ |
Dataroom 20 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-DATA-001 | Data room loads successfully | Functional | P1 | 1. Navigate to /data-room | Page renders successfully; displays heading 'Data room' and subtitle 'Unify all your data — from MarkTag, content, and integrations in one place.' | Pass ✓ | |
| TC-DATA-002 | E-commerce tab default selection | UI | P2 | 1. Open /data-room | E-commerce segment tab is active by default; Shopify, Salla, WooCommerce, WordPress, Odoo cards visible | Pass ✓ | |
| TC-DATA-003 | E-commerce integrations list contains expected platforms | Functional | P1 | 1. Observe the available cards under E-commerce tab | Cards are visible for: Shopify, Salla, WooCommerce, WordPress, and Odoo with their names and descriptions | Fail ✓ | |
| TC-DATA-004 | Toggle to Website tab displays website integrations | Functional | P1 | 1. Click the 'Website' tab button | Tab switches; E-commerce cards are hidden; 'Server side' and 'Client side' cards are displayed | Fail ✓ | |
| TC-DATA-005 | Website integration details visible | Functional | P1 | 1. Go to Website tab 2. Observe Server side and Client side cards |
Server side shows: 'Capture backend events...' Client side shows: 'Track user actions...' |
Pass ✓ | |
| TC-DATA-006 | Advanced Pixel Setup Guide opens guide | Functional | P2 | 1. Click 'Advanced Pixel Setup Guide' button | Opens instructions modal or redirects to the Advanced Pixel Setup instructions guide | Pass ✓ | |
| TC-DATA-007 | Disconnect Shopify integration successfully (Positive) | Functional | P1 | 1. Go to /data-room 2. Locate Shopify integration card 3. Click 'Disconnect' button 4. Confirm disconnect in popup |
Shopify disconnects successfully; success toast shown; card button changes to 'Connect' | Pass ✓ | CRITICAL: Must use alternate credentials for disconnect actions |
| TC-DATA-008 | Disconnect WooCommerce integration successfully (Positive) | Functional | P1 | 1. Go to /data-room 2. Click 'Disconnect' button on WooCommerce card 3. Confirm disconnect in popup |
WooCommerce disconnects successfully; status changes to disconnected; button becomes 'Connect' | Pass ✓ | CRITICAL: Must use alternate credentials for disconnect |
| TC-DATA-009 | Connect Shopify store successfully (Positive) | Functional | P1 | 1. Go to /data-room 2. Click 'Connect' on Shopify card 3. Enter valid store URL 4. Complete OAuth flow on Shopify site |
Shopify connects successfully; redirects back to /data-room with Success toast; button changes to 'Disconnect' | Pass ✓ | |
| TC-DATA-010 | Connect WooCommerce store successfully (Positive) | Functional | P1 | 1. Click 'Connect' on WooCommerce card 2. Fill Consumer Key, Consumer Secret, and site URL 3. Click Save |
WooCommerce connects; redirects with Success toast; status changes to Connected | Pass ✓ | |
| TC-DATA-011 | Connect with empty credentials fields | Negative | P2 | 1. Click Connect on Salla card 2. Click Save/Connect with fields empty |
Validation errors shown on empty fields; form not submitted; no API call | Timeout ✓ | |
| TC-DATA-012 | Connect with invalid URL format | Negative | P2 | 1. Click Connect on WooCommerce 2. Enter invalid URL structure (e.g. 'not-a-url') 3. Click Save |
Frontend validation error shown: Please enter a valid URL; request not sent | Pass ✓ | |
| TC-DATA-013 | Shopify connection API failure handling | API | P1 | 1. Click Connect on Shopify 2. Enter store URL 3. Complete flow where server returns 500 error |
Displays toast error: Connection failed. Please check your shop URL and try again. | Pass ✓ | |
| TC-DATA-014 | Disconnection API failure handling | API | P1 | 1. Go to /data-room 2. Click Disconnect on Shopify 3. Trigger flow where server returns 500 |
Displays toast error: Unable to disconnect. Please try again later. Shopify remains connected. | Pass ✓ | CRITICAL: Must use alternate credentials for disconnect |
| TC-DATA-015 | Connect client-side website tag snippet | Functional | P1 | 1. Click 'Connect' on Client side card 2. Complete setup steps |
Client side tracking connects; script tag snippet displays for copy | Fail ✓ | |
| TC-DATA-016 | Connect server-side website setup | Functional | P1 | 1. Click 'Connect' on Server side card 2. Follow prompts to generate credentials |
Server-side connection active; webhook URL and Access Token shown | Fail ✓ | |
| TC-DATA-017 | No JavaScript console errors on Dataroom | UI | P1 | 1. Navigate to /data-room 2. Switch tabs; click Connect modals |
Zero console errors or unhandled warnings displayed | Pass ✓ | |
| TC-DATA-018 | Double click Connect button rapidly | Functional | P2 | 1. Click Connect on Odoo card twice rapidly | Only one connection modal triggered; no double submission errors | Pass ✓ | |
| TC-DATA-019 | Dataroom responsive layout on mobile viewport | UI | P2 | 1. Resize browser viewport to 375px 2. Observe integration cards |
Cards stack vertically; segment buttons adapt to screen width; no overflow | Pass ✓ | |
| TC-DATA-020 | Cross-Origin request blocked on Dataroom disconnect endpoint | Security | P0 | 1. Craft a POST request to /api/dataroom/disconnect from external origin with active session cookie 2. Submit |
Request blocked with 403 Forbidden; CSRF token validation active; Shopify remains connected | Pass ✓ | CRITICAL: Must use alternate credentials for disconnect |
Memory 21 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Memory - Knowledgebase
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-MEM-001 | Memory page loads successfully | Functional | P1 | 1. Open beta-stg.markopolo.ai/login 2. Log in with imtiaz@markopolo.ai / Markopolo@2025 3. Navigate to /memory |
Page loads successfully; displays 'Knowledgebase' and 'Product' tabs and heading description: 'Manage the knowledge and products...' | Pass ✓ | |
| TC-MEM-002 | Default tab is Knowledgebase | UI | P2 | 1. Navigate to /memory | Knowledgebase sub-tab is active by default; shows 'Files list' header and 'File upload' button | Pass ✓ | |
| TC-MEM-003 | Upload valid file to Knowledgebase (Positive) | Functional | P1 | 1. Click 'File upload' button 2. Select a valid PDF, DOCX, or XLSX file 3. Click Upload |
File uploads successfully; displayed in files list with correct filename, upload timestamp, and size | Fail ✓ | Supports PDF, CSV, XLSX, PPTX, etc. |
| TC-MEM-004 | Upload unsupported file type (Negative) | Negative | P2 | 1. Click 'File upload' 2. Choose unsupported file (e.g. .mp3, .exe) 3. Click Upload |
Validation error shown: 'Unsupported file type. Please upload PDF, DOCX, CSV, or XLSX.' | Fail ✓ | |
| TC-MEM-005 | Upload file exceeding size limit (Negative) | Negative | P2 | 1. Click 'File upload' 2. Select file > 10MB limit 3. Click Upload |
Validation error shown: 'File size exceeds maximum limit of 10MB.' | Pass ✓ | |
| TC-MEM-006 | Delete file from Knowledgebase successfully (Positive) | Functional | P1 | 1. Go to /memory 2. Click Delete icon on any file card in list 3. Confirm deletion in popup |
File is deleted successfully; removed from list; success toast shown | Fail ✓ | CRITICAL: Must use alternate credentials for delete actions |
| TC-MEM-007 | Search files by name in list | Functional | P2 | 1. Enter 'Liquidity' in search bar | Files list filters to show only files matching 'Liquidity' (e.g. Topic 5- Managing Liquidity.pptx-1.pdf) | Fail ✓ | |
| TC-MEM-008 | Knowledgebase mobile responsive view | UI | P2 | 1. Resize viewport to 375px 2. Observe elements on Knowledgebase tab |
Layout scales correctly; upload button accessible; files list readable without clipping | Fail ✓ | |
| TC-MEM-009 | API delete file failure handling | API | P1 | 1. Go to /memory 2. Click delete on any file 3. Intercept API response to return 500 |
Toast error shown: 'Unable to delete file. Please try again later.' | Pass ✓ | CRITICAL: Must use alternate credentials for delete actions |
| TC-MEM-010 | Cross-Origin request blocked on delete file endpoint | Security | P0 | 1. Craft a DELETE request to /api/memory/files/[fileId] from external origin with active session cookie 2. Submit |
Request blocked with 403 Forbidden; file remains intact in list | Fail ✓ | CRITICAL: Must use alternate credentials for delete actions |
Memory - Product
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-MEM-011 | Toggle to Product tab | Functional | P1 | 1. Navigate to /memory 2. Click 'Product' tab button |
Tab switches; Files list hidden; 'Product list' header, 'Fetch from Shopify', and 'Product Upload' buttons visible | Fail ✓ | |
| TC-MEM-012 | Product list renders expected items | Functional | P1 | 1. Observe the product list card elements | Products render displaying name (e.g. Gift Card, Snowboards), descriptions, prices, and USD currency | Pass ✓ | |
| TC-MEM-013 | Fetch products from Shopify successfully (Positive) | Functional | P1 | 1. Go to /memory 2. Click 'Product' tab 3. Click 'Fetch from Shopify' button |
Sync triggered; success message 'Products synced successfully' shown; product list updates | Pass ✓ | |
| TC-MEM-014 | Fetch from Shopify when disconnected (Negative) | Negative | P2 | 1. Go to Product tab in Memory 2. Click 'Fetch from Shopify' |
Error message: 'Please connect your Shopify store in the Data room first.' | Pass ✓ | |
| TC-MEM-015 | Upload products CSV successfully (Positive) | Functional | P1 | 1. Click 'Product Upload' button 2. Select a valid product CSV template file 3. Click Upload |
CSV uploaded; products imported successfully and visible in Product list | Pass ✓ | |
| TC-MEM-016 | Upload CSV with invalid schema (Negative) | Negative | P2 | 1. Click 'Product Upload' 2. Choose a CSV with invalid headers/data structure 3. Click Upload |
Validation error shown: 'Invalid CSV schema. Please use the standard template.' | Pass ✓ | |
| TC-MEM-017 | Delete product from list successfully (Positive) | Functional | P1 | 1. Go to /memory 2. Click 'Product' tab 3. Click Delete icon on any product in list 4. Confirm deletion |
Product removed successfully; status updates in list; success toast shown | Pass ✓ | CRITICAL: Must use alternate credentials for delete actions |
| TC-MEM-018 | Search products by name in list | Functional | P2 | 1. Enter 'Snowboard' in product search bar | List filters instantly to show only products matching 'Snowboard' | Pass ✓ | |
| TC-MEM-019 | Product tab mobile responsive view | UI | P2 | 1. Resize browser viewport to 375px 2. Observe elements on Product tab |
Layout adapts; buttons block and scroll properly; list items render cleanly | Fail ✓ | |
| TC-MEM-020 | API delete product failure handling | API | P1 | 1. Go to /memory 2. Click Product tab 3. Attempt to delete a product 4. Intercept API response to return 500 |
Toast error shown: 'Unable to delete product. Please try again later.' Product remains in list. | Pass ✓ | CRITICAL: Must use alternate credentials for delete actions |
| TC-MEM-021 | Cross-Origin request blocked on delete product endpoint | Security | P0 | 1. Craft a DELETE request to /api/memory/products/[productId] from external origin with active session cookie 2. Submit |
Request blocked with 403 Forbidden; product remains intact in list | Fail ✓ | CRITICAL: Must use alternate credentials for delete actions |
Analytics 8 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-ANA-001 | Analytics page loads | Functional | P2 | 1. Navigate to /analytics | Page renders: Audience Analytics, Total events, Active users chart | Pass ✓ |
Analytics - Audience
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-ANA-002 | Total events count displays | Functional | P2 | 1. Open Analytics | 2. Observe Total Events metric | Correct event count shown | Pass ✓ | |
| TC-ANA-003 | Active users metric displays | Functional | P2 | 1. Open Analytics | 2. Observe Active Users | Active user count with trend indicator | Pass ✓ | |
| TC-ANA-004 | Date range filter | Functional | P2 | 1. Open Analytics | 2. Change date range | 3. Select Last 30 days | Charts and metrics update to reflect period | Pass ✓ | |
| TC-ANA-005 | Export analytics data | Functional | P3 | 1. Click Export | 2. Select CSV format | CSV downloaded with analytics data | Pass ✓ | |
| TC-ANA-006 | Chart renders correctly | UI | P3 | 1. Open Analytics | 2. Observe all charts | All charts render; tooltips work on hover; no blank areas | Pass ✓ | |
| TC-ANA-007 | Analytics empty state (no MarkTag) | UI | P3 | 1. Open Analytics on fresh account | Empty state with CTA to install MarkTag pixel | Pass ✓ | |
| TC-ANA-008 | Real-time data update | Functional | P4 | 1. Keep Analytics tab open | 2. Fire events on tracked site | Metrics update without full page reload | Fail ✓ |
Analytics - Conversions
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Analytics - Revenue Attribution
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Leads 10 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Leads - Leads
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-LEAD-001 | Leads page loads | Functional | P2 | 1. Navigate to /leads | Leads list table renders: Name, Email, Source, Status, Date | Pass ✓ | |
| TC-LEAD-002 | Lead list displays all leads | Functional | P2 | 1. Open Leads page | 2. Observe table | All leads shown with pagination if >20 entries | Pass ✓ | |
| TC-LEAD-003 | Search leads by name or email | Functional | P2 | 1. Type name in search input | Table filters to matching leads in real-time | Pass ✓ | |
| TC-LEAD-004 | Filter leads by status | Functional | P3 | 1. Use filter dropdown | 2. Select a status | Table shows only matching leads | Pass ✓ | |
| TC-LEAD-005 | View lead detail | Functional | P2 | 1. Click on a lead row | Lead detail: full info, activity timeline, campaign association | Fail ✓ | |
| TC-LEAD-006 | Export leads as CSV | Functional | P2 | 1. Click Export | 2. Select CSV | CSV downloaded with all lead columns | Pass ✓ | |
| TC-LEAD-007 | Import leads from CSV | Functional | P3 | 1. Click Import | 2. Upload CSV | 3. Map columns | 4. Confirm | Leads imported; success count shown | Pass ✓ | |
| TC-LEAD-008 | Update lead status | Functional | P3 | 1. Open lead detail | 2. Change status | 3. Save | Status updated; reflected in list immediately | Pass ✓ | |
| TC-LEAD-009 | Delete lead | Functional | P3 | 1. Select lead | 2. Click delete | 3. Confirm | Lead removed; count decrements | Pass ✓ | |
| TC-LEAD-010 | Leads empty state | UI | P4 | 1. Open Leads on fresh account | Empty state with CTA to run campaign or import leads | Pass ✓ |
Leads - Audiences
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Campaign 42 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Campaign - Audience-based
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-CAMP-001 | Create audience-based campaign - full E2E flow | E2E | P1 | 1. Click Create Campaign 2. Select 'Audience Based' trigger 3. Enter campaign name 4. Select 'English (US)' language 5. Select 'User with email user@gmail.com - Part 1' from audience list 6. Select 'Direct sales' objective 7. Click Continue 8. Select 'Autosend' channel and platform 9. Click Continue 10. Confirm AI content generation and launch |
Campaign launched successfully; status = Active; contacts in audience start receiving messages | Fail ✓ | |
| TC-CAMP-002 | Campaign name - empty validation (Negative) | Negative | P2 | 1. Clear campaign name field 2. Fill other fields (language, trigger, audience, objective) 3. Click Continue |
Inline validation error: 'Campaign name is required'; wizard does not proceed to Step 2 | Fail ✓ | |
| TC-CAMP-003 | Campaign name - duplicate warning (Negative) | Negative | P2 | 1. Enter an existing campaign name (e.g. 'Untitled campaign 7/19/2026') 2. Click Continue |
Warning shown: 'A campaign with this name already exists'; proceeds but prompts for confirmation or appends suffix | Pass ✓ | |
| TC-CAMP-004 | Language selection dropdown options | UI | P2 | 1. Click 'Content language' dropdown | Dropdown expands showing supported options (e.g., English (US), English (UK), Spanish, French, etc.) | Pass ✓ | |
| TC-CAMP-005 | Select Audience - Search audiences by name/description | Functional | P2 | 1. Enter 'FCM' in the audience search input | Audience list filters instantly to show only audiences matching 'FCM' (e.g., User by FCM Token - Part 1) | Pass ✓ | |
| TC-CAMP-006 | Select Audience - Pagination in audience list | UI | P2 | 1. Scroll down to bottom of Select audience container 2. Click '2' or 'More pages' |
Audience list paginates successfully; displays next set of audiences | Fail ✓ | |
| TC-CAMP-007 | Select Audience - Create audience redirection link | Functional | P2 | 1. Click 'Create audience' button | Navigates to /leads page or opens Create Audience modal; wizard state preserved | Fail ✓ | |
| TC-CAMP-008 | Select Audience - Selected count limit validation | UI | P2 | 1. Select an audience (e.g. User with email user@gmail.com - Part 1) | Selected audiences display changes to 'Selected audiences (1)' and limits badge reads '1 / 50K' | Timeout ✓ | |
| TC-CAMP-009 | Objective - Select Direct sales objective | Functional | P2 | 1. Click 'Direct sales' objective option card | Direct sales card is highlighted; subtitle indicates 'Drive purchases faster with limited-time offers...' | Fail ✓ | |
| TC-CAMP-010 | Objective - Select Promotional objective | Functional | P2 | 1. Click 'Promotional' objective option card | Promotional card is highlighted; subtitle indicates 'Announce new products, sales events...' | Fail ✓ | |
| TC-CAMP-011 | Objective - Select Call booking objective | Functional | P2 | 1. Click 'Call booking' objective option card | Call booking card is highlighted; subtitle indicates 'Encourage users to book a time...' | Fail ✓ | |
| TC-CAMP-012 | Objective - Select Follow-up sequence objective | Functional | P2 | 1. Click 'Follow-up sequence' objective option card | Follow-up sequence card is highlighted; subtitle indicates 'Continue the conversation with users...' | Fail ✓ | |
| TC-CAMP-013 | Objective - Select Custom objective and enter text | Functional | P2 | 1. Click 'Custom objective' 2. Enter custom campaign prompt or goals |
Custom objective card highlighted; custom text input field enabled and accepts text | Fail ✓ | |
| TC-CAMP-014 | Additional settings - Upload valid knowledge base content file | Functional | P1 | 1. Click 'Upload file' under knowledge base section 2. Select 'sample-brand.pdf' 3. Complete upload |
File uploaded and displayed as 'sample-brand.pdf' with a 'Clear' option | Pass ✓ | |
| TC-CAMP-015 | Additional settings - Clear/remove uploaded knowledge base file | Functional | P1 | 1. Click 'Clear' next to 'sample-brand.pdf' | File is removed immediately; upload container reverts to default empty state | Pass ✓ | |
| TC-CAMP-016 | Schedule future campaign | Functional | P1 | 1. Fill campaign configuration details 2. Set Schedule for later date/time in the future 3. Complete wizard and confirm |
Campaign scheduled; status in list shows 'Waiting for Launch' | Pass ✓ | |
| TC-CAMP-017 | Save campaign as draft | Functional | P1 | 1. Start campaign configuration wizard 2. Fill Step 1 details 3. Click Close button 4. Select 'Save as Draft' |
Campaign saved; status in list shows 'Draft' or 'Ready to Launch' | Pass ✓ | |
| TC-CAMP-018 | Step 1 validation - Proceed without selecting an audience (Negative) | Negative | P2 | 1. Do not select any target audience 2. Click Continue |
Validation error: 'Please select at least one target audience'; form not submitted | Pass ✓ |
Campaign - Event-based
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-CAMP-019 | Create event-based campaign - full E2E flow | E2E | P1 | 1. Click Create Campaign 2. Select 'Event Based' trigger 3. Select event (e.g. cart_abandoned) 4. Select communication channel (Email - Autosend) 5. Continue and launch |
Event campaign activated; status = Active; listener responds to web abandoned cart events | Pass ✓ | |
| TC-CAMP-020 | Event trigger selection list options | UI | P2 | 1. Click trigger selection dropdown | Dropdown lists all tracked store events: Page View, Add to Cart, Cart Abandoned, Purchase, etc. | Pass ✓ | |
| TC-CAMP-021 | Event trigger selection empty validation (Negative) | Negative | P2 | 1. Do not select any trigger event 2. Click Continue |
Validation error: 'Trigger event is required'; wizard does not proceed | Pass ✓ | |
| TC-CAMP-022 | Configure dispatch delay for event-based campaign | Functional | P2 | 1. Select event trigger 2. Set delay timer to '30 minutes' 3. Click Continue |
Delay configuration saved successfully; triggers are fired exactly 30 minutes post-event | Pass ✓ | |
| TC-CAMP-023 | Test event trigger (dry run) | Functional | P2 | 1. Click 'Send test trigger' on event campaign detail page 2. Enter test email address |
Test payload sent successfully; campaign action executes immediately for the test user | Fail ✓ | |
| TC-CAMP-024 | Activate event-based campaign | Functional | P1 | 1. Open a ready event campaign 2. Click Activate/Launch |
Campaign status updates to Active; event-based marketing trigger is live | Fail ✓ | |
| TC-CAMP-025 | Pause active campaign | Functional | P2 | 1. Open active campaign 2. Click Pause button |
Status updates to Paused; message dispatching stops immediately | Fail ✓ | CRITICAL: Must use alternate credentials for pause/disconnect actions |
| TC-CAMP-026 | Resume paused campaign | Functional | P2 | 1. Open paused campaign 2. Click Resume button |
Campaign status updates back to Active; message queue resumes | Fail ✓ | |
| TC-CAMP-027 | Deactivate campaign | Functional | P2 | 1. Open active event campaign 2. Click Deactivate button |
Status changes to Deactive; event listener disabled; status badge updated in campaigns list | Fail ✓ | CRITICAL: Must use alternate credentials for deactivate/disconnect actions |
Campaign - Channel Selection
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-CAMP-028 | Channel select - Email platforms display | UI | P2 | 1. Look at 'Email' channel section | Email platforms options shown: Autosend (logo), Resend (logo), Sendgrid (logo); shows Connect button for disconnected services | Pass ✓ | |
| TC-CAMP-029 | Channel select - Connect button redirect | Functional | P2 | 1. Click 'Connect' under Sendgrid | Redirects/navigates to Integrations page to set up API keys; wizard state is saved as draft | Fail ✓ | |
| TC-CAMP-030 | Channel select - SMS platforms display | UI | P2 | 1. Look at 'SMS' channel section | SMS platform options shown: Mark-sms, Twilio, Revesms, Boomcast | Fail ✓ | |
| TC-CAMP-031 | Channel select - Push notification platform display | UI | P2 | 1. Look at 'Push notification' channel section | Firebase platform option is shown with status | Fail ✓ | |
| TC-CAMP-032 | Channel select - WhatsApp platform connected toggle | Functional | P1 | 1. Observe WhatsApp section showing status: 'Connected. Toggle on to use WhatsApp in this campaign.' 2. Toggle WhatsApp switch to ON |
WhatsApp channel is selected for campaign delivery; configuration highlights Meta/Twilio options | Fail ✓ | |
| TC-CAMP-033 | Channel select - Select multiple channels/providers | Functional | P2 | 1. Select Email (Autosend) 2. Select WhatsApp (Meta) 3. Click Continue |
Wizard saves multi-channel options and proceeds to Step 3 workflow preview | Fail ✓ | |
| TC-CAMP-034 | Channel select - Proceed without selecting any channel/platform (Negative) | Negative | P2 | 1. Do not select/toggle any platform 2. Click Continue |
Validation error: 'Please select at least one active communication channel'; form not submitted | Fail ✓ |
Campaign - AI Generation & Management
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-CAMP-035 | Wizard Step 3 - AI content generation workflow review text | UI | P2 | 1. Look at Step 3 header and details | Displays review prompt: 'Review this workflow, then confirm to have AI write the content... Nothing is generated until you confirm.' | Fail ✓ | |
| TC-CAMP-036 | Wizard Step 3 - Confirm and trigger AI content generation | Functional | P1 | 1. Review workflow steps 2. Click 'Confirm and Generate' |
AI starts writing content for every step; loader shown; once completed, campaign goes live or draft updates | Fail ✓ | |
| TC-CAMP-037 | Wizard Navigation - Go back navigation preserves settings | Functional | P2 | 1. Click 'Go back' button | Returns to Step 1; all entered settings (name, trigger, selected audience, objective, knowledge file) remain preserved | Fail ✓ | |
| TC-CAMP-038 | Wizard Navigation - Close wizard confirmation prompt | UI | P2 | 1. Click 'Close' button in header | Prompt opens: 'Do you want to discard changes or save this campaign as draft?'; provides Draft/Discard/Cancel options | Fail ✓ | |
| TC-CAMP-039 | Campaign list - Filter campaigns by status | Functional | P2 | 1. Click 'Draft' filter tab 2. Click 'Live' filter tab 3. Click 'Deactive' filter tab |
Campaign table filters immediately to show only campaigns matching the selected status tab | Fail ✓ | |
| TC-CAMP-040 | Campaign list - Edit existing campaign draft | Functional | P1 | 1. Find draft campaign in list 2. Click 'Edit' in Actions column |
Wizard opens pre-filled with draft configurations; allows editing and proceeding to next steps | Pass ✓ | |
| TC-CAMP-041 | Campaign list - Duplicate campaign | Functional | P2 | 1. Find any campaign in list 2. Click 'Duplicate' icon/button |
A duplicate campaign with suffix '- Copy' is created and displayed in drafts list | Fail ✓ | |
| TC-CAMP-042 | Campaign list - Delete campaign | Functional | P1 | 1. Navigate to campaigns dashboard 2. Click 'Delete' in Actions column 3. Confirm deletion in popup |
Campaign removed from list; success toast shown; deleted state updated in database | Pass ✓ | CRITICAL: Must use alternate credentials for delete actions |
Content 10 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Content - Autonomous
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-CONT-001 | Content page loads | Functional | P2 | 1. Navigate to /content | Content editor/list renders without error | Fail ✓ | |
| TC-CONT-002 | Generate AI content | Functional | P1 | 1. Select content type | 2. Enter prompt | 3. Click Generate | AI content appears in editor within 10 seconds | Pass ✓ | |
| TC-CONT-003 | Use content template | Functional | P2 | 1. Click Templates | 2. Select template | 3. Customise | Template loads in editor; fields editable | Fail ✓ | |
| TC-CONT-004 | Edit generated content | Functional | P2 | 1. Click inside content | 2. Edit text | Content editable; changes reflect in real-time | Pass ✓ | |
| TC-CONT-005 | Save content piece | Functional | P2 | 1. Click Save | 2. Name the content | Content saved; appears in content list | Fail ✓ | |
| TC-CONT-006 | Generate with tone selection | Functional | P3 | 1. Select tone (Professional/Casual/Persuasive) | 2. Generate | Output matches selected tone | Pass ✓ | |
| TC-CONT-007 | Generate with language selection | Functional | P3 | 1. Select language | 2. Generate | Output in selected language | Pass ✓ | |
| TC-CONT-008 | Export content | Functional | P3 | 1. Open saved content | 2. Export | 3. Select format (PDF/HTML) | Content exported in selected format | Pass ✓ | |
| TC-CONT-009 | Content version history | Functional | P4 | 1. Open content | 2. View version history | Previous versions listed; can restore | Pass ✓ | |
| TC-CONT-010 | Empty prompt submission | Negative | P3 | 1. Leave prompt blank | 2. Click Generate | Validation: Enter a topic or description | Pass ✓ |
Content - Self-written
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Integration 50 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Integration - Email apps
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-INT-001 | Autosend card loads with description | UI | P2 | 1. Open /integrations 2. Observe Autosend card |
Card visible with title 'Autosend' and description: 'Send emails with a custom @markopoloai.com address using your unique username' | Pass ✓ | |
| TC-INT-002 | Connect Autosend with valid username | Functional | P1 | 1. Click Integrate on Autosend card 2. Modal opens 3. Enter valid username 4. Click Confirm |
Autosend connected; status = Connected; custom email address activated | Fail ✓ | |
| TC-INT-003 | Autosend empty username field (Negative) | Negative | P2 | 1. Leave username field empty 2. Click Confirm |
Inline validation: Username is required; form not submitted | Fail ✓ | |
| TC-INT-004 | Autosend duplicate username rejected (Negative) | Negative | P2 | 1. Enter a username already taken by another account 2. Click Confirm |
Error: Username is already taken. Please choose a different one. | Pass ✓ | |
| TC-INT-005 | Disconnect Autosend | Functional | P2 | 1. Open /integrations 2. Click Disconnect on Autosend 3. Confirm disconnect |
Autosend disconnected; status badge removed; custom email deactivated | Fail ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-006 | Connect SendGrid with valid API key | Functional | P1 | 1. Click Integrate 2. Modal opens 3. Enter valid API key 4. Click Confirm (green btn) |
SendGrid connected; status = Connected | Pass ✓ | Help link: How to find your SendGrid API Key |
| TC-INT-007 | SendGrid invalid API key (Negative) | Negative | P1 | 1. Enter invalid API key 2. Click Confirm |
Error: Invalid API key — verify and try again | Fail ✓ | |
| TC-INT-008 | SendGrid empty API key field (Negative) | Negative | P2 | 1. Leave API key field empty 2. Click Confirm |
Inline validation: API key is required; form not submitted | Fail ✓ | |
| TC-INT-009 | Disconnect SendGrid | Functional | P2 | 1. Open settings 2. Click Disconnect 3. Confirm |
SendGrid disconnected; status badge removed | Pass ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-010 | Connect Resend with valid API key | Functional | P1 | 1. Click Integrate 2. Enter API key 3. Confirm |
Resend connected; status = Connected | Fail ✓ | Key from Resend dashboard |
| TC-INT-011 | Resend invalid API key (Negative) | Negative | P2 | 1. Enter invalid API key 2. Click Confirm |
Error: Invalid API key | Fail ✓ | |
| TC-INT-012 | Resend empty API key field (Negative) | Negative | P2 | 1. Leave API key empty 2. Click Confirm |
Inline validation: API key is required | Timeout ✓ | |
| TC-INT-013 | Disconnect Resend | Functional | P2 | 1. Click Disconnect on Resend 2. Confirm |
Resend disconnected; Connected badge removed | Pass ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-014 | Pending payment banner shown when plan inactive | UI | P1 | 1. Open /integrations > Email apps | Banner shown: 'You have a pending payment. Please complete the payment to access this feature.' | Pass ✓ | |
| TC-INT-015 | Complete payment button navigates to billing | Functional | P2 | 1. Click 'Complete payment' button in the banner | Navigates to /plan-and-billing or payment checkout flow | Pass ✓ | |
| TC-INT-016 | Only one email provider connected at a time | Functional | P2 | 1. Try to connect Resend while SendGrid is active | User prompted to disconnect existing provider first OR only one Connect button active at a time | Pass ✓ |
Integration - SMS apps
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-INT-017 | SMS apps tab loads correctly | Functional | P1 | 1. Click 'SMS apps' tab button | Tab activates; SMS integration cards displayed with correct names and descriptions | Pass ✓ | |
| TC-INT-018 | Connect Twilio with valid credentials | Functional | P1 | 1. Click Integrate on Twilio card 2. Modal opens 3. Enter Account SID and Auth Token 4. Click Confirm |
Twilio connected; status = Connected; SMS channel available in campaigns | Skip ✓ | Credentials from Twilio Console |
| TC-INT-019 | Twilio invalid Account SID (Negative) | Negative | P1 | 1. Enter invalid Account SID 2. Enter valid Auth Token 3. Click Confirm |
Error: Invalid credentials — please check your Account SID and Auth Token | Fail ✓ | |
| TC-INT-020 | Twilio empty credentials (Negative) | Negative | P2 | 1. Leave Account SID and Auth Token fields empty 2. Click Confirm |
Inline validation errors shown on both fields; form not submitted | Fail ✓ | |
| TC-INT-021 | Disconnect Twilio | Functional | P2 | 1. Click Disconnect on Twilio 2. Confirm |
Twilio disconnected; SMS channel deactivated; badge removed | Pass ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-022 | SMS apps pending payment banner shown when plan inactive | UI | P1 | 1. Click SMS apps tab | Pending payment banner visible; Integrate buttons disabled or payment CTA shown | Pass ✓ | |
| TC-INT-023 | SMS send triggers after campaign activation | Functional | P2 | 1. Activate campaign 2. Trigger a test SMS event |
SMS delivered to test number; delivery status shown in campaign analytics | Pass ✓ |
Integration - Push Notification
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-INT-024 | Push notification tab loads correctly | Functional | P1 | 1. Click 'Push notification' tab button | Tab activates; Push notification integration cards displayed | Pass ✓ | |
| TC-INT-025 | Connect Firebase FCM with valid Server Key | Functional | P1 | 1. Click Integrate on Firebase card 2. Enter valid Server Key 3. Click Confirm |
Firebase connected; status = Connected; push channel available in campaigns | Pass ✓ | Key from Firebase Console > Project Settings > Cloud Messaging |
| TC-INT-026 | Firebase invalid Server Key (Negative) | Negative | P1 | 1. Enter invalid Server Key 2. Click Confirm |
Error: Invalid Server Key — please verify from Firebase Console | Pass ✓ | |
| TC-INT-027 | Firebase empty Server Key (Negative) | Negative | P2 | 1. Leave Server Key field empty 2. Click Confirm |
Inline validation: Server Key is required | Pass ✓ | |
| TC-INT-028 | Disconnect Firebase FCM | Functional | P2 | 1. Click Disconnect on Firebase 2. Confirm |
Firebase disconnected; push channel deactivated; badge removed | Pass ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-029 | Push notification fires after campaign activation | Functional | P2 | 1. Activate campaign 2. Trigger push event on a subscribed device |
Push notification received on device; title and body match campaign config | Pass ✓ | |
| TC-INT-030 | Push notification pending payment banner | UI | P1 | 1. Click Push notification tab | Pending payment banner visible; Integrate buttons disabled | Pass ✓ |
Integration - Social
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-INT-031 | Social tab loads correctly | Functional | P1 | 1. Click 'Social' tab button | Tab activates; Social integration cards displayed (WhatsApp, Telegram, Facebook Messenger, etc.) | Pass ✓ | |
| TC-INT-032 | Connect WhatsApp Business API | Functional | P1 | 1. Click Integrate on WhatsApp card 2. Enter WhatsApp Business API credentials 3. Click Confirm |
WhatsApp connected; status = Connected; WhatsApp channel available in campaigns | Pass ✓ | Requires Meta Business Manager approval |
| TC-INT-033 | WhatsApp invalid API credentials (Negative) | Negative | P1 | 1. Enter invalid Phone Number ID or Token 2. Click Confirm |
Error: Invalid credentials — verify from Meta Business Manager | Pass ✓ | |
| TC-INT-034 | WhatsApp empty credentials (Negative) | Negative | P2 | 1. Leave all fields empty 2. Click Confirm |
Inline validation errors on all required fields; form not submitted | Pass ✓ | |
| TC-INT-035 | Disconnect WhatsApp | Functional | P2 | 1. Click Disconnect on WhatsApp 2. Confirm |
WhatsApp disconnected; badge removed; channel deactivated in campaigns | Pass ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-036 | Connect Telegram Bot with valid Bot Token | Functional | P1 | 1. Click Integrate on Telegram card 2. Enter valid Bot Token from BotFather 3. Click Confirm |
Telegram bot connected; status = Connected; bot visible in campaign channel options | Pass ✓ | Token from @BotFather on Telegram |
| TC-INT-037 | Telegram invalid Bot Token (Negative) | Negative | P1 | 1. Enter invalid Bot Token 2. Click Confirm |
Error: Invalid Bot Token — verify from BotFather | Pass ✓ | |
| TC-INT-038 | Telegram empty Bot Token (Negative) | Negative | P2 | 1. Leave Bot Token empty 2. Click Confirm |
Inline validation: Bot Token is required | Pass ✓ | |
| TC-INT-039 | Disconnect Telegram Bot | Functional | P2 | 1. Click Disconnect on Telegram 2. Confirm |
Telegram disconnected; bot removed; badge cleared | Pass ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-040 | Connect Facebook Messenger via OAuth | Functional | P2 | 1. Click Connect on Facebook Messenger card 2. OAuth → Facebook login 3. Authorize Messenger permissions |
Facebook Messenger connected; status = Connected; Messenger channel available | Pass ✓ | Requires Facebook Business Page |
| TC-INT-041 | Facebook Messenger OAuth cancel returns gracefully | Negative | P2 | 1. Click Cancel on Facebook OAuth consent screen | Graceful return to /integrations; no error page; no crash | Pass ✓ | |
| TC-INT-042 | Disconnect Facebook Messenger | Functional | P2 | 1. Click Disconnect on Facebook Messenger 2. Confirm |
Facebook Messenger disconnected; badge removed | Pass ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-043 | Social integration pending payment banner | UI | P1 | 1. Click Social tab | Pending payment banner shown; Integrate buttons disabled | Pass ✓ | |
| TC-INT-044 | WhatsApp message fires after campaign activation | Functional | P2 | 1. Activate campaign 2. Trigger WhatsApp event for test lead |
WhatsApp message received by test number; delivery status shown in analytics | Pass ✓ |
Integration - General
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-INT-045 | Integrations page loads successfully | Functional | P1 | 1. Navigate to /integrations | Page renders; heading 'Integrations' and subtitle 'Integrate email, sms and push notification apps...' visible; 4 tabs shown: Email apps, SMS apps, Push notification, Social | Pass ✓ | |
| TC-INT-046 | Default tab is Email apps | UI | P2 | 1. Open /integrations | Email apps tab is active by default; Email integration cards visible | Pass ✓ | |
| TC-INT-047 | No console errors on Integrations page load | UI | P1 | 1. Navigate to /integrations 2. Switch between all 4 tabs 3. Observe console |
Zero JavaScript errors or unhandled exceptions in console | Pass ✓ | |
| TC-INT-048 | Disconnect API failure shows friendly error | API | P1 | 1. Click Disconnect 2. Intercept API call to return 500 |
Toast error: 'Unable to disconnect. Please try again later.' Integration remains connected. | Pass ✓ | CRITICAL: Use alternate credentials for disconnect |
| TC-INT-049 | Connect API failure shows friendly error | API | P1 | 1. Click Integrate on any card 2. Enter valid credentials 3. Intercept API to return 500 |
Toast error: 'Connection failed. Please try again later.' | Fail ✓ | |
| TC-INT-050 | Integration page mobile responsive view | UI | P2 | 1. Resize viewport to 375px 2. Check all 4 tabs |
Tab buttons wrap cleanly; integration cards stack vertically; no overflow | Pass ✓ |
Plan & Billing 12 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-BILL-001 | Current plan display | Functional | P2 | 1. Navigate to /billing | Shows: Starter plan badge (Monthly); usage bars | Pass ✓ | |
| TC-BILL-002 | Usage bars display accurately | Functional | P2 | 1. Open Plan & Billing | 2. Observe usage bars | Bars show used/limit (e.g. 500/1000); correct % | Pass ✓ | |
| TC-BILL-003 | Explore Plans opens plan comparison | Functional | P1 | 1. Click Explore Plans | 3 plan cards: Starter (Free), Growth, Pro | Pass ✓ | |
| TC-BILL-004 | Plan cards show correct features | Functional | P2 | 1. View all 3 cards | Each card: price, contacts limit, features, CTA button | Fail ✓ | Starter=Free |
| TC-BILL-005 | Upgrade Starter to Growth | Functional | P1 | 1. Click Upgrade on Growth | 2. Payment | 3. Confirm | Plan = Growth; limits updated; invoice generated | Fail ✓ | |
| TC-BILL-006 | Upgrade Starter to Pro | Functional | P1 | 1. Click Upgrade on Pro | 2. Payment | 3. Confirm | Plan = Pro; all Pro features unlocked | Fail ✓ | |
| TC-BILL-007 | Switch Monthly to Annual | Functional | P2 | 1. Click Switch to Annual | 2. Confirm | Annual billing; discount applied | Pass ✓ | |
| TC-BILL-008 | Add / update payment method | Functional | P2 | 1. Click Payment Method | 2. Add card | 3. Save | Card added; shown as active method | Pass ✓ | |
| TC-BILL-009 | Download invoice | Functional | P3 | 1. Open Billing History | 2. Click Download | Invoice PDF: correct amount, plan, date | Pass ✓ | |
| TC-BILL-010 | Downgrade plan | Functional | P3 | 1. Click Downgrade | 2. Select P4er plan | 3. Confirm | Plan scheduled for downgrade at period end | Pass ✓ | |
| TC-BILL-011 | Cancel subscription | Functional | P3 | 1. Click Cancel Subscription | 2. Confirm | Subscription scheduled for cancel; access until period end | Pass ✓ | Warning dialog shown |
| TC-BILL-012 | Enforce contact limit on Starter | Negative | P2 | 1. Import leads exceeding limit | Error: Contact limit reached — upgrade plan | Pass ✓ |
Settings 25 test cases
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
Settings - Brand
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-SET-001 | Save valid business details successfully | Functional | P1 | 1. Enter 'Acme Corporation' in Business name 2. Enter 'acme.com' in Website URL 3. Select 'Technology' from Industry dropdown 4. Enter 'Quality road runner catching equipment' in Tagline 5. Enter '123 Desert Road' in Address 6. Click Save changes |
Toast notification shows 'Settings saved successfully'; Last saved timestamp updates; new values persist on reload | Pass ✓ | |
| TC-SET-002 | Validate business name is required (Negative) | Negative | P2 | 1. Clear the Business name field 2. Make a change in another field (e.g. Tagline) to enable Save changes button 3. Click Save changes |
Validation error: 'Business name is required'; form is not saved | Pass ✓ | |
| TC-SET-003 | Validate website URL format (Negative) | Negative | P2 | 1. Enter 'invalid-url' in Website URL 2. Click Save changes |
Validation error: 'Please enter a valid URL'; form not submitted | Pass ✓ | |
| TC-SET-004 | Validate tagline character limit (Negative) | Negative | P2 | 1. Try typing a tagline longer than 100 characters | Input is truncated or blocked at 100 characters due to maxlength='100' | Pass ✓ | |
| TC-SET-005 | Industry dropdown lists all correct industry options | UI | P2 | 1. Click the Industry dropdown/combobox | Dropdown opens; lists options: Apparel, Auto, B2B, Beauty, Consumer Service, Finance Insurance, Fitness, Home Improvement, Healthcare, Industrial Services, Legal, Retail, Technology, Travel & Hospitality, Real estate, Mobile app | Fail ✓ | |
| TC-SET-006 | Switch to Visual sub-tab | Functional | P1 | 1. Click 'Visual' sub-tab button | Tab switches successfully; fields for Sender Display Name, Sender Description, Profile Picture, Logo, and Brand Colors are visible | Pass ✓ | |
| TC-SET-007 | Save Visual settings successfully | Functional | P1 | 1. Enter 'Acme Support' in Sender Display Name 2. Enter description in Sender Description 3. Select a brand color using color picker 4. Click Save changes |
Visual settings saved successfully; details updated and email preview panel on the right updates to reflect the new sender display name and description | Pass ✓ | |
| TC-SET-008 | Upload valid profile picture asset | Functional | P1 | 1. Click upload on Profile Picture field 2. Select a valid PNG/JPG image (e.g. 500KB) 3. Click Save changes |
Asset uploads successfully; thumbnail preview shown; saved successfully | Pass ✓ | |
| TC-SET-009 | Upload invalid profile picture asset format (Negative) | Negative | P2 | 1. Click upload on Profile Picture field 2. Select an unsupported file type (e.g. .pdf or .mp3) 3. Click Save changes |
Validation error: 'Invalid file format. Please upload an image (PNG, JPG, or SVG).' | Fail ✓ | |
| TC-SET-010 | Switch to Social sub-tab | Functional | P1 | 1. Click 'Social' sub-tab button | Tab switches successfully; Social links input fields (Facebook, Twitter, Instagram, LinkedIn, TikTok, YouTube) and Custom Links fields are visible | Pass ✓ | |
| TC-SET-011 | Save valid Social profile links | Functional | P1 | 1. Enter 'https://facebook.com/acme' in Facebook link 2. Enter 'https://linkedin.com/company/acme' in LinkedIn link 3. Click Save changes |
Social links saved successfully; links persist on reload | Pass ✓ | |
| TC-SET-012 | Validate social links are valid URLs (Negative) | Negative | P2 | 1. Enter 'invalid-facebook-url' in Facebook link 2. Click Save changes |
Validation error: 'Please enter a valid URL'; form not saved | Fail ✓ | |
| TC-SET-013 | Save Custom links in Social tab | Functional | P2 | 1. Enter 'Shop Now' in Link 1 Title 2. Enter 'https://acme.com/shop' in Link 1 URL 3. Click Save changes |
Custom links saved successfully; email preview updates to show new footer links | Timeout ✓ |
Settings - Account
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-SET-014 | Switch to Account tab | Functional | P1 | 1. Click 'Account' top-level tab button | Tab switches; Brand sub-navigation hidden; fields for User Name (userName), Email Address (userEmail), Profile Image, and timezone/language dropdown are visible | Pass ✓ | |
| TC-SET-015 | Update User Name successfully | Functional | P1 | 1. Enter 'Imtiaz Ahmed' in User Name field 2. Click Save changes |
User Name updated successfully; user profile info in the sidebar footer and top header changes to reflect the new name 'Imtiaz Ahmed' | Pass ✓ | |
| TC-SET-016 | Email Address field is read-only | UI | P2 | 1. Try to click and edit the Email address field (userEmail) | Field is disabled or read-only; text cannot be changed; cursor shows not-allowed | Pass ✓ | |
| TC-SET-017 | Upload User Profile Image | Functional | P1 | 1. Click upload on Profile Image field 2. Choose a valid image 3. Click Save changes |
Profile image updated successfully; sidebar and header user avatars update immediately | Pass ✓ |
Settings - Misc
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-SET-018 | Switch to Misc tab | Functional | P1 | 1. Click 'Misc' top-level tab button | Tab switches; Brand/Account fields hidden; custom Cart Path (cartPath) input is visible | Pass ✓ | |
| TC-SET-019 | Save valid Custom Cart Path | Functional | P1 | 1. Enter '/checkout/cart' in Cart Path field 2. Click Save changes |
Cart Path saved successfully; headless cart setup uses the new path in Shopify integrations | Pass ✓ | |
| TC-SET-020 | Validate Cart Path prefix (Negative) | Negative | P2 | 1. Enter 'checkout/cart' (missing leading slash) in Cart Path field 2. Click Save changes |
Validation error: 'Cart path must start with a forward slash (/)'; form not saved | Pass ✓ |
Settings - General
ID
Title
Type
Priority
Steps
Expected Result
Status
Notes
| TC-SET-021 | Save changes button state is reactive | UI | P2 | 1. Load settings page 2. Observe Save changes button state 3. Make a change in any input field 4. Observe button state 5. Click Save changes and observe button state after success |
1. Button is disabled initially 2. Button becomes enabled after a change is made 3. Button becomes disabled again after changes are saved successfully |
Pass ✓ | |
| TC-SET-022 | Example email preview desktop/mobile toggle | UI | P2 | 1. Click 'Mobile view' icon in the Example email header 2. Click 'Desktop view' icon |
1. Iframe width shrinks to mobile viewport width (e.g. 375px) 2. Iframe expands back to full container width |
Pass ✓ | |
| TC-SET-023 | Settings page mobile responsiveness | UI | P2 | 1. Resize viewport to 375px 2. Switch between all tabs and sub-tabs |
Form elements stack vertically; email preview panel moves below the form or is hidden; no horizontal scroll or layout clipping | Fail ✓ | |
| TC-SET-024 | API save failure handling | API | P1 | 1. Make a change in any field 2. Click Save changes 3. Intercept save API request to return 500 Internal Server Error |
Toast error: 'Failed to save settings. Please try again later.'; input fields keep the edited values; Save changes button remains enabled | Pass ✓ | |
| TC-SET-025 | Cross-Origin request blocked on settings update endpoint | Security | P0 | 1. Craft a PUT request to /api/settings from external origin with active session cookie 2. Submit |
Request blocked with 403 Forbidden by CORS policy; settings remain unchanged | Fail ✓ | CRITICAL: Must verify origin validation |
No test cases found
No matches for the current filter. Try a different status or clear the search.