Skip to main content

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:

  1. Keep the Console tab open
  2. Wait 30 seconds
  3. Watch for heartbeat logs:
[HeartbeatManager] Sending heartbeat...
[HeartbeatManager] Heartbeat acknowledged: 240 seconds remaining
  1. Check the Network tab:
    • Filter by heartbeat
    • POST requests to /sessions/:id/heartbeat should appear
    • Response body:
      {
      "acknowledged": true,
      "remaining_seconds": 240,
      "status": "active"
      }

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:

  1. Note current remaining time (e.g., "3:45")
  2. Click "Extend Session" button
  3. Select duration (5, 15, 30, or 60 minutes)
  4. 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:

  1. Open the same URL in two browser tabs

  2. Open Console in both tabs (F12)

  3. In Tab 1, click "Pause":

    Tab 1 console:

    [MarketplaceSDK] Timer paused
    [TabSyncManager] Broadcasted: pause

    Tab 2 console:

    [TabSyncManager] Received message: pause
    [MarketplaceSDK] Timer paused (synced from another tab)
  4. Tab 2 timer should pause automatically

  5. 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:

  1. Make sure timer is running
  2. Note the current time
  3. Minimize the browser window (or switch to another tab)
  4. Wait 10 seconds
  5. 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:

  1. Note current remaining time
  2. Click "Complete Early" button
  3. 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:

  1. Generate a 5-minute JWT:
    npm run generate-jwt 5
  2. Open app and wait until 5 minutes remaining (default threshold)
  3. 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

  1. Open DevTools Network tab
  2. Select "Offline" from throttling dropdown
  3. 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

  1. Generate 1-minute JWT: npm run generate-jwt 1
  2. Open app and wait for expiration
  3. 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/heartbeat every 30s
  • PUT /sessions/:id/renew for extensions
  • POST /sessions/:id/complete for completion
  • All requests return 200 OK

Application Tab (Storage)

  • marketplace_jwt in 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: true in 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: true in 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: true in 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