Testing Overview
Complete walkthrough for testing all SDK features in a local development environment.
Prerequisites
- Node.js installed
- Dependencies installed (
npm install) - SDK built (
npm run build) - Test keys generated (
npm run generate-keys)
Quick Start (5 Minutes)
Step 1: Start the Test Server
npm run test-server-p2
You should see:
Phase 2 Test Server Running!
Endpoints:
React Example: http://localhost:3000/provider
Vanilla Example: http://localhost:3000/example
JWKS: http://localhost:3000/.well-known/jwks.json
Mock Backend:
POST /sessions/validate - Validate JWT
POST /sessions/:id/heartbeat - Receive heartbeats
POST /sessions/:id/complete - Complete session
PUT /sessions/:id/renew - Extend session
Step 2: Generate a Test JWT
Open a new terminal (keep the server running):
npm run generate-jwt 5
Five minutes is ideal for testing — you can observe heartbeats, extensions, early completion, and the warning modal within a single session.
Step 3: Open the Test App
React Example (Recommended):
http://localhost:3000/provider?gwSession=<PASTE_YOUR_JWT_HERE>
Vanilla JS Example:
http://localhost:3000/example?gwSession=<PASTE_YOUR_JWT_HERE>
Step 4: Open Browser DevTools
Press F12 and check the Console tab. You should see initialization logs:
[MarketplaceSDK] Initializing with Phase 2 features enabled
[MarketplaceSDK] Heartbeat enabled: true
[MarketplaceSDK] Tab sync enabled: true
[MarketplaceSDK] JWT validated successfully
[HeartbeatManager] Starting heartbeat system (interval: 30s)
[TabSyncManager] Initializing tab sync
[TabSyncManager] Elected as master tab
[MarketplaceSDK] Session started
Feature Tests
Heartbeat System
What it does: Sends a heartbeat to the backend every 30 seconds to sync remaining time.
How to test:
- Keep the Console tab open
- Wait 30 seconds
- Watch for heartbeat logs:
[HeartbeatManager] Sending heartbeat...
[HeartbeatManager] Heartbeat acknowledged: 240 seconds remaining
- Check the Network tab:
- Filter by
heartbeat - POST requests to
/sessions/:id/heartbeatshould appear - Response body:
{"acknowledged": true,"remaining_seconds": 240,"status": "active"}
- Filter by
Success criteria:
- Heartbeat logs appear every 30 seconds
- Network shows POST requests
- Timer stays in sync with server
- 3 heartbeat failures triggers graceful stop
- Only master tab sends heartbeats (verify with multiple tabs)
Session Extension
What it does: Extends your session by adding minutes (charges tokens).
How to test:
- Note current remaining time (e.g., "3:45")
- Click "Extend Session" button
- Select duration (5, 15, 30, or 60 minutes)
- Click "Confirm"
Console logs:
[MarketplaceSDK] Extending session by 15 minutes
[MarketplaceSDK] Session extended successfully
[MarketplaceSDK] New expiration: <timestamp>
[TabSyncManager] Broadcasted: extend (15 minutes)
Network tab:
- PUT request to
/sessions/:id/renew - Response:
{"session_id": "sess_...","new_expires_at": 1730004000,"additional_cost": 75,"total_tokens_spent": 225}
Success criteria:
- Timer updates immediately
- All tabs sync the new time (if multi-tab open)
- Network request succeeds
Multi-Tab Synchronization
What it does: Syncs session state (pause, resume, extension) across all open tabs.
How to test:
-
Open the same URL in two browser tabs
-
Open Console in both tabs (F12)
-
In Tab 1, click "Pause":
Tab 1 console:
[MarketplaceSDK] Timer paused[TabSyncManager] Broadcasted: pauseTab 2 console:
[TabSyncManager] Received message: pause[MarketplaceSDK] Timer paused (synced from another tab) -
Tab 2 timer should pause automatically
-
Close Tab 1 — Tab 2 becomes the master tab:
[TabSyncManager] Master tab closed, electing new master
[TabSyncManager] Elected as master tab
[HeartbeatManager] Starting heartbeat system
Success criteria:
- Pause in one tab pauses all tabs
- Resume in one tab resumes all tabs
- Extend in one tab syncs new time to all tabs
- Close master tab triggers new master election
- Only master tab sends heartbeats
Visibility API
What it does: Auto-pauses timer when you switch tabs/minimize (battery-friendly).
How to test:
- Make sure timer is running
- Note the current time
- Minimize the browser window (or switch to another tab)
- Wait 10 seconds
- Restore the window (or switch back)
Console logs:
[MarketplaceSDK] Tab hidden, pausing timer
[MarketplaceSDK] Tab visible, resuming timer
Success criteria:
- Timer pauses when tab is hidden
- Timer resumes when tab is visible
- Time does not advance while hidden
Early Completion
What it does: Ends the session early and calculates a refund for unused time.
How to test:
- Note current remaining time
- Click "Complete Early" button
- Confirm the dialog
Console logs:
[MarketplaceSDK] Completing session early
[MarketplaceSDK] Actual usage: 2 minutes
[MarketplaceSDK] Session completed successfully
Network tab:
- POST request to
/sessions/:id/complete - Response:
{"session_id": "sess_...","tokens_refunded": 50,"final_cost": 125,"actual_usage_minutes": 2}
Success criteria:
- Session ends immediately
- Backend calculates refund
- Network request succeeds
- Cleanup happens properly
Warning Modal
How to test:
- Generate a 5-minute JWT:
npm run generate-jwt 5
- Open app and wait until 5 minutes remaining (default threshold)
- Modal appears with options to Extend or Continue
Success criteria:
- Modal appears at threshold
- Extension flow works from modal
- Dismiss functionality works
Error Scenarios
Network Failure Handling
- Open DevTools Network tab
- Select "Offline" from throttling dropdown
- Wait 30 seconds for heartbeat attempt
[HeartbeatManager] Heartbeat failed: Network error
[HeartbeatManager] Retry attempt 1/3
[HeartbeatManager] Retry attempt 2/3
[HeartbeatManager] Retry attempt 3/3
[HeartbeatManager] Max heartbeat failures reached, stopping heartbeat system
After going back online, heartbeat does not resume (by design).
Expired JWT
- Generate 1-minute JWT:
npm run generate-jwt 1 - Open app and wait for expiration
- Session ends cleanly with redirect option
Invalid JWT
Open app with an invalid token:
http://localhost:3000/provider?gwSession=invalid_jwt_token
[MarketplaceSDK] JWT validation failed: Invalid token format
[MarketplaceSDK] Triggering onError
Clear error message shown, no crash.
What to Check in Each Test
Console Tab
- No errors (red text)
- Heartbeat logs every 30s
- Tab sync messages
- Visibility API logs
- Extension/completion logs
Network Tab
- POST
/sessions/:id/heartbeatevery 30s - PUT
/sessions/:id/renewfor extensions - POST
/sessions/:id/completefor completion - All requests return 200 OK
Application Tab (Storage)
marketplace_jwtin sessionStorage- Tab sync messages in localStorage (if using fallback)
Performance
- No memory leaks (check Memory tab)
- No excessive CPU usage
- Smooth UI interactions
Common Issues
"No JWT token found"
Check URL has ?gwSession=<JWT> parameter. The JWT must be in the URL, not just copied.
Heartbeat not appearing
- Verify
enableHeartbeat: truein config - Wait the full 30-second interval
- Check console for initialization logs
Multi-tab sync not working
- Open in the same browser (not different browsers)
- Verify
enableTabSync: truein config - Both tabs must use the same origin
"Server responded with 500"
- Restart test server:
npm run test-server-p2 - Regenerate JWT:
npm run generate-jwt 5 - Check server console for errors
Visibility API not working
- Verify
pauseOnHidden: truein config - Try minimizing the entire browser (not just switching tabs)
- Some browsers need focus change
Testing Checklist
Core Features:
[ ] SDK initializes without errors
[ ] Timer counts down correctly
[ ] JWT validation works
[ ] Session data displays correctly
Heartbeat System:
[ ] Heartbeat sends every 30 seconds
[ ] Console shows heartbeat logs
[ ] Network shows POST requests
[ ] Server time syncs correctly
[ ] Handles 3 failures gracefully
Multi-Tab Sync:
[ ] Opens in 2 tabs successfully
[ ] Pause in Tab 1 → Tab 2 pauses
[ ] Resume in Tab 2 → Tab 1 resumes
[ ] Extension syncs across tabs
[ ] Master tab election works
[ ] Only master sends heartbeats
Session Extension:
[ ] Extension dialog opens
[ ] Can select duration (5/15/30/60 min)
[ ] Timer updates immediately
[ ] Network request succeeds
[ ] All tabs sync new time
Early Completion:
[ ] Complete button works
[ ] Confirmation dialog shows
[ ] Session ends on confirm
[ ] Refund calculation shown
[ ] Network request succeeds
Visibility API:
[ ] Pause when tab hidden
[ ] Resume when tab visible
[ ] Time does not advance while hidden
Error Handling:
[ ] Invalid JWT shows error
[ ] Expired JWT handled gracefully
[ ] Network failures handled
[ ] No crashes or freezes