branch:
testing.md
25718 bytesRaw
# Playground Testing Guide

This document describes how to test every feature in the Agents SDK Playground. Each section covers a demo page with specific test steps and expected results.

## Prerequisites

1. Start the dev server: `npm run start`
2. Open http://localhost:5173 in your browser
3. Verify the home page loads with the feature grid

---

## Core Demos

### State Management (`/core/state`)

Tests real-time state synchronization between server and clients.

#### Test 1: Connection Status

- **Action**: Navigate to `/core/state`
- **Expected**: Connection status shows "Connected" with a green dot

#### Test 2: Counter Increment

- **Action**: Click the **+1** button
- **Expected**:
  - Counter value increases by 1
  - Event log shows `call → increment()` followed by `result ←`
  - "Current State" JSON updates with new counter value

#### Test 3: Counter Decrement

- **Action**: Click the **-1** button
- **Expected**: Counter value decreases by 1

#### Test 4: Set Counter (Server)

- **Action**: Enter `42` in the number input, click **Set (Server)**
- **Expected**:
  - Counter changes to 42
  - Log shows `call → setCounter(42)` and `result ←`

#### Test 5: Set Counter (Client)

- **Action**: Enter `100` in the number input, click **Set (Client)**
- **Expected**:
  - Counter changes to 100
  - Log shows `setState →` (client-side update, no server call)

#### Test 6: Add Item

- **Action**: Type "Test Item" in the New Item input, click **Add**
- **Expected**:
  - Item appears in the Items list
  - Items count increments

#### Test 7: Remove Item

- **Action**: Click **Remove** next to an item
- **Expected**: Item disappears from the list

#### Test 8: Reset State

- **Action**: Click the red **Reset** button
- **Expected**: Counter returns to 0, items list clears

#### Test 9: Multi-Tab Sync

- **Action**: Open the same URL in a new tab, modify state in one tab
- **Expected**: Both tabs show the same state (real-time sync)

---

### Callable Methods (`/core/callable`)

Tests the `@callable` decorator and RPC functionality.

#### Test 1: Math Operations

- **Action**: Enter `5` and `3`, click **add(5, 3)**
- **Expected**:
  - Log shows `call → { method: "add", args: [5, 3] }`
  - Result shows `8`

#### Test 2: Multiply

- **Action**: Click **multiply(5, 3)**
- **Expected**: Result shows `15`

#### Test 3: Echo

- **Action**: Type "Hello World", click **Echo**
- **Expected**: Log shows result `"Hello World"`

#### Test 4: Async Operation

- **Action**: Set delay to `2000`, click **slowOperation(2000)**
- **Expected**:
  - Takes ~2 seconds to complete
  - Result shows "Completed after 2000ms"

#### Test 5: Error Handling

- **Action**: Type "Something broke", click **Throw Error**
- **Expected**:
  - Log shows error entry in red
  - Error message contains "Something broke"

#### Test 6: Get Timestamp

- **Action**: Click **getTimestamp()**
- **Expected**: Returns current ISO timestamp string

#### Test 7: List Methods

- **Action**: Click **listMethods()**
- **Expected**:
  - "Available Methods" card appears
  - Shows all callable methods with descriptions

---

### Streaming RPC (`/core/streaming`)

Tests streaming responses from agent to client.

#### Test 1: Stream Numbers

- **Action**: Set count to `10`, click **Stream 10 numbers**
- **Expected**:
  - Chunks appear one by one: `{"number":1}`, `{"number":2}`, etc.
  - Log shows multiple `chunk ←` entries
  - Final result shows `{"total":10}`

#### Test 2: Countdown with Delay

- **Action**: Set countdown to `5`, click **Countdown from 5**
- **Expected**:
  - Numbers stream in with ~500ms delay between each
  - Shows "5...", "4...", "3...", "2...", "1...", "Liftoff!"
  - Takes approximately 2.5 seconds total

#### Test 3: Stream with Error

- **Action**: Set "Error after" to `3`, click **Error after 3 chunks**
- **Expected**:
  - First 3 chunks arrive successfully
  - Error entry appears in log
  - Stream terminates

#### Test 4: Button State During Stream

- **Action**: Start a stream
- **Expected**: Button shows "Streaming..." and is disabled until complete

---

### Scheduling (`/core/schedule`)

Tests delayed and recurring task scheduling.

#### Test 1: One-Time Task

- **Action**: Set delay to `5` seconds, enter a message, click **Schedule Task**
- **Expected**:
  - "Active Schedules" shows the new schedule
  - After 5 seconds, log shows `schedule_executed ←` with the message

#### Test 2: Recurring Task

- **Action**: Set interval to `10` seconds, enter a label, click **Schedule Recurring**
- **Expected**:
  - Schedule appears in Active Schedules
  - Every 10 seconds, log shows `recurring_executed ←`

#### Test 3: Cancel Task

- **Action**: Click **Cancel** next to an active schedule
- **Expected**:
  - Schedule disappears from Active Schedules
  - No more executions occur

#### Test 4: Refresh Schedules

- **Action**: Click **Refresh** link
- **Expected**: Active Schedules list updates

---

### Connections (`/core/connections`)

Tests WebSocket connection management and broadcasting.

#### Test 1: Connection Count

- **Action**: Navigate to `/core/connections`
- **Expected**: Connected Clients shows `1`

#### Test 2: Multi-Tab Count

- **Action**: Click **Open New Tab** (or manually open another tab to same URL)
- **Expected**:
  - Both tabs update to show `2` connected clients
  - Log shows `connection_count ← 2`

#### Test 3: Broadcast Message

- **Action**: Type a message, click **Broadcast**
- **Expected**:
  - Message appears in "Received Broadcasts" on ALL connected tabs
  - Includes timestamp

#### Test 4: Tab Close

- **Action**: Close one of the tabs
- **Expected**: Remaining tab updates to show `1` connected client

---

### SQL Queries (`/core/sql`)

Tests direct SQL interaction with agent's SQLite database.

#### Test 1: List Tables

- **Action**: Navigate to `/core/sql`
- **Expected**: Tables list shows internal tables (e.g., `cf_agents_state`, `cf_agents_schedules`)

#### Test 2: View Table Schema

- **Action**: Click on a table name (e.g., `cf_agents_state`)
- **Expected**:
  - Schema card shows columns, types, and nullability
  - Query input updates to `SELECT * FROM cf_agents_state LIMIT 10`

#### Test 3: Execute Query

- **Action**: Click **Execute**
- **Expected**: Results card shows query results as JSON

#### Test 4: Insert Custom Data

- **Action**: Enter a key (e.g., "test-key") and value (e.g., "test-value"), click **Insert**
- **Expected**:
  - Record appears in the Custom Data list below
  - Tables list now includes `playground_data`

---

### Routing Strategies (`/core/routing`)

Tests different agent naming patterns.

#### Test 1: Per-User Strategy

- **Action**:
  1. Note your User ID (e.g., "user-abc123")
  2. Open a new tab with the same User ID
- **Expected**:
  - Both tabs connect to the same agent instance
  - Connected Clients shows `2`

#### Test 2: Change User ID

- **Action**: Change User ID to something different
- **Expected**:
  - Agent Instance name changes
  - Connection count resets to `1` (you're now on a different agent)

#### Test 3: Shared Strategy

- **Action**: Select **Shared** strategy
- **Expected**:
  - Agent instance changes to `routing-shared`
  - All tabs with Shared strategy connect to the same agent

#### Test 4: Per-Session Strategy

- **Action**: Select **Per-Session** strategy
- **Expected**:
  - Each tab connects to a different agent (based on session ID)
  - Opening new tab creates new session = new agent

#### Test 5: Strategy Persistence

- **Action**: Change User ID, refresh the page
- **Expected**: User ID persists (stored in localStorage)

---

## Multi-Agent Demos

### Supervisor Pattern (`/multi-agent/supervisor`)

Tests the manager-child agent pattern using `getAgentByName()`.

#### Test 1: Connection

- **Action**: Navigate to `/multi-agent/supervisor`
- **Expected**: Connection status shows "Connected", stats show 0 children

#### Test 2: Create Child

- **Action**: Click **+ Create Child**
- **Expected**:
  - New child card appears with ID like `child-abc123`
  - Counter shows `0`
  - Stats update: Children = 1, Total Counter = 0
  - Log shows `call → createChild("child-abc123")` and result

#### Test 3: Increment Single Child

- **Action**: Click **+1** on a child card
- **Expected**:
  - That child's counter increments
  - Total Counter in stats updates
  - Log shows `call → incrementChild("child-abc123")`

#### Test 4: Increment All

- **Action**: Create multiple children, click **+1 to All**
- **Expected**:
  - All children increment by 1
  - Total Counter updates to sum of all counters
  - Log shows `call → incrementAll()`

#### Test 5: Remove Child

- **Action**: Click the **×** button on a child card
- **Expected**:
  - Child disappears from the grid
  - Stats update accordingly

#### Test 6: Clear All

- **Action**: Click **Clear All** link
- **Expected**:
  - All children removed
  - Stats reset to 0

#### Test 7: Persistence

- **Action**: Create children, refresh the page
- **Expected**:
  - Children are preserved (supervisor tracks IDs in state)
  - Stats match previous values

---

### Chat Rooms (`/multi-agent/rooms`)

Tests multi-agent chat with Lobby and Room agents.

#### Test 1: Lobby Connection

- **Action**: Navigate to `/multi-agent/rooms`
- **Expected**: Lobby shows "Connected", room list is empty or shows existing rooms

#### Test 2: Create Room

- **Action**: Type "General" in room name, click **Create**
- **Expected**:
  - Room appears in the list with 0 online
  - Log shows `call → createRoom("General")`

#### Test 3: Join Room

- **Action**: Click on a room in the list
- **Expected**:
  - Chat area shows room name
  - Room header shows "0 members" initially, then "1 members"
  - Log shows `join_room → General`

#### Test 4: Send Message

- **Action**: Type a message, press Enter or click **Send**
- **Expected**:
  - Message appears in chat area
  - Your messages appear on the right with dark background
  - Log shows `send → <message>`

#### Test 5: Multi-User Chat

- **Action**: Click link to open new tab (or manually open same URL)
  1. In new tab, set different username
  2. Join same room
  3. Send messages from both tabs
- **Expected**:
  - Both users see each other's messages in real-time
  - Members list shows both usernames
  - Member count updates in lobby room list

#### Test 6: Leave Room

- **Action**: Click **Leave** button
- **Expected**:
  - Chat area returns to "Select a room to start chatting"
  - Member count decreases for that room

#### Test 7: Room Persistence

- **Action**: Refresh page
- **Expected**:
  - Rooms persist (tracked in LobbyAgent state)
  - Messages persist (stored in RoomAgent)

---

### Workers Pattern (`/multi-agent/workers`)

Documentation-only demo explaining fan-out parallel processing.

#### Test 1: Page Load

- **Action**: Navigate to `/multi-agent/workers`
- **Expected**:
  - Architecture diagram with ManagerAgent → Workers
  - "How It Works" explanation
  - Example code snippet
  - Use cases list

---

### Pipeline Pattern (`/multi-agent/pipeline`)

Documentation-only demo explaining chain of responsibility.

#### Test 1: Page Load

- **Action**: Navigate to `/multi-agent/pipeline`
- **Expected**:
  - Architecture diagram with linear agent chain
  - "How It Works" explanation
  - Example code snippet
  - Variations section (Linear, Branching, Saga, Async)
  - Considerations notes

---

## Workflow Demos

### Workflow Simulation (`/workflow/basic`)

Interactive demo that simulates multi-step workflow execution with automatic step progression.

#### Test 1: Connection

- **Action**: Navigate to `/workflow/basic`
- **Expected**: Connection status shows "Connected", no workflows running

#### Test 2: Start Workflow

- **Action**: Enter a workflow name (e.g., "Data Processing"), set step count to 4, click **Start Workflow**
- **Expected**:
  - Workflow appears in "Running" section
  - Visual step pipeline shows Step 1 as running (spinner icon)
  - Event log shows `startWorkflow →`, `workflow_started ←`

#### Test 3: Watch Step Progression

- **Action**: Wait and observe the workflow
- **Expected**:
  - Steps complete one by one (1-2 seconds each)
  - Completed steps show checkmark, current step shows spinner
  - Connection lines turn solid as steps complete
  - Event log shows `workflow_step_complete ←` for each step
  - When all steps complete, `workflow_complete ←` appears

#### Test 4: Start Multiple Workflows

- **Action**: Start 2-3 workflows with different names
- **Expected**:
  - All workflows appear in Running section
  - Each progresses independently
  - Completed workflows move to History section

#### Test 5: Cancel Workflow

- **Action**: Start a workflow, then click the X button before it completes
- **Expected**:
  - Workflow status changes to "cancelled"
  - Workflow moves to History section
  - Event log shows `cancelWorkflow →`, `workflow_cancelled ←`

#### Test 6: Clear History

- **Action**: After some workflows complete, click **Clear** in the History section
- **Expected**:
  - Resolved workflows are removed
  - Running workflows remain
  - Event log shows `clearWorkflows →`, `cleared ←`

---

### Approval Workflow (`/workflow/approval`)

Interactive demo that simulates human-in-the-loop approval patterns.

#### Test 1: Connection

- **Action**: Navigate to `/workflow/approval`
- **Expected**: Connection status shows "Connected", no pending approvals

#### Test 2: Submit Approval Request

- **Action**: Enter a title and description, click **Submit Request**
- **Expected**:
  - Request appears in "Pending Approval" section with yellow indicator
  - Shows Approve and Reject buttons
  - Event log shows `requestApproval →`, `approval_requested ←`

#### Test 3: Use Quick Presets

- **Action**: Click one of the preset request buttons (e.g., "Deploy v2.0 to Production")
- **Expected**:
  - Title and description fields are populated
  - Can submit the preset request

#### Test 4: Approve Request

- **Action**: Click **Approve** on a pending request
- **Expected**:
  - Request moves to History with green indicator
  - Shows "Approved at [time]"
  - Event log shows `approve →`, `approval_approved ←`

#### Test 5: Reject Request

- **Action**: Click **Reject** on a pending request
- **Expected**:
  - Reject reason input appears
  - After clicking "Confirm Reject", request moves to History with red indicator
  - Shows "Rejected at [time]" with reason
  - Event log shows `reject →`, `approval_rejected ←`

#### Test 6: Multiple Pending Requests

- **Action**: Submit 3-4 requests without approving
- **Expected**:
  - All appear in Pending Approval section
  - Can approve/reject each independently

#### Test 7: Clear History

- **Action**: Resolve several requests, then click **Clear** in History
- **Expected**:
  - Resolved requests are removed from History
  - Pending requests remain

---

## Email Demos

### Receive Emails (`/email/receive`)

Tests receiving emails via Cloudflare Email Routing. Requires deployment for real email testing.

#### Test 1: Connection

- **Action**: Navigate to `/email/receive`
- **Expected**: Connection status shows "Connected", empty inbox, stats show 0

#### Test 2: Local Dev Banner

- **Action**: Observe the page when running locally
- **Expected**: Warning banner indicates email features require deployment

#### Test 3: Stats Display

- **Action**: Observe the Stats panel
- **Expected**: Shows Inbox count and Total received count

#### Test 4: Receive Email (Deployed Only)

- **Action**: Send an email to `receive+demo@yourdomain.com`
- **Expected**:
  - Email appears in Inbox list
  - Stats update (Inbox +1, Total +1)
  - Log shows `state_update ←`

#### Test 5: View Email Detail

- **Action**: Click on an email in the Inbox
- **Expected**:
  - Detail panel shows subject, from, to, date
  - Email body displayed below
  - Headers expandable via details toggle

#### Test 6: Close Email Detail

- **Action**: Click the **×** button on the detail panel
- **Expected**: Detail panel closes

---

### Secure Email Replies (`/email/secure`)

Tests HMAC-signed email replies for secure routing.

#### Test 1: Connection

- **Action**: Navigate to `/email/secure`
- **Expected**: Connection status shows "Connected", Inbox/Outbox tabs visible, stats show 0

#### Test 2: Inbox/Outbox Tabs

- **Action**: Click between **Inbox** and **Outbox** tabs
- **Expected**: Tab content switches, counts shown in tab labels

#### Test 3: Toggle Auto-Reply

- **Action**: Toggle the "Auto-reply with signed headers" switch
- **Expected**:
  - Log shows `toggleAutoReply →`
  - Setting persists in agent state

#### Test 4: Receive Email with Auto-Reply (Deployed Only)

- **Action**: Send an email to `secure+demo@yourdomain.com` with auto-reply enabled
- **Expected**:
  - Email appears in Inbox
  - Signed reply appears in Outbox with green checkmark
  - Reply has "Re:" prefix in subject

#### Test 5: View Signed Reply

- **Action**: Switch to Outbox tab, click on a reply
- **Expected**:
  - Detail shows the reply body
  - Green "Signed" badge displayed
  - Note about X-Agent-\* headers shown

#### Test 6: Secure Reply Routing (Deployed Only)

- **Action**: Reply to a signed email from your email client
- **Expected**:
  - Reply is routed back to the same agent instance
  - Email shows lock icon indicating "Secure Reply"

#### Test 7: Clear Emails

- **Action**: Click **Clear all emails**
- **Expected**:
  - Both inbox and outbox are cleared
  - Log shows `clearEmails →`

---

### Email Setup (Deployment)

To test with real emails:

1. Deploy: `npm run deploy`
2. Set secret: `wrangler secret put EMAIL_SECRET`
3. Configure Cloudflare Dashboard → Email → Email Routing
4. Add routing rule for your domain to this Worker
5. Send emails to:
   - `receive+instanceId@yourdomain.com` for ReceiveEmailAgent
   - `secure+instanceId@yourdomain.com` for SecureEmailAgent

---

### Readonly Connections (`/core/readonly`)

Tests read-only WebSocket connections that can observe but not modify state.

#### Test 1: Dual Panel Layout

- **Action**: Navigate to `/core/readonly`
- **Expected**: Two side-by-side panels — "Editor (read-write)" on the left, "Viewer (readonly)" on the right

#### Test 2: Editor Increment

- **Action**: Click **+1** on the Editor panel
- **Expected**:
  - Counter increases on BOTH panels (state syncs to viewer)
  - "Last updated by" shows the update source

#### Test 3: Viewer Blocked (Callable)

- **Action**: Click **+1** on the Viewer panel
- **Expected**: Error toast appears — readonly connections cannot call methods that write state

#### Test 4: Viewer Blocked (Client setState)

- **Action**: Click **+10** on the Viewer panel
- **Expected**: Error toast appears — client-side setState is also blocked for readonly connections

#### Test 5: Check Permissions (Always Allowed)

- **Action**: Click **Check Permissions** on the Viewer panel
- **Expected**: Info toast shows `canEdit = false` — non-mutating RPCs work on readonly connections

#### Test 6: Toggle Readonly

- **Action**: Uncheck the **Lock** checkbox on the Viewer panel
- **Expected**:
  - Badge changes to "Viewer (read-write)"
  - Viewer can now increment and modify state

---

### Retries (`/core/retry`)

Tests retry operations with exponential backoff and selective retry.

#### Test 1: Flaky Operation (Succeeds)

- **Action**: Set "Succeed on attempt" to `3`, click **Run Flaky Operation**
- **Expected**:
  - Log shows attempts 1 and 2 failing
  - Attempt 3 succeeds
  - Result appears in log

#### Test 2: Flaky Operation (Exhausted)

- **Action**: Set "Succeed on attempt" to `10`, click **Run Flaky Operation**
- **Expected**:
  - Log shows attempts failing (class default is 4 max attempts)
  - Final error after all retries exhausted

#### Test 3: Selective Retry (Transient)

- **Action**: Set "Failures before success" to `2`, leave "Permanent error" unchecked, click **Run Filtered Retry**
- **Expected**:
  - Transient errors are retried
  - Succeeds after 2 failures

#### Test 4: Selective Retry (Permanent)

- **Action**: Check **Permanent error**, click **Run Filtered Retry**
- **Expected**:
  - shouldRetry returns false immediately
  - No retries — error appears after first attempt

#### Test 5: Queue with Retry

- **Action**: Set "Max attempts" to `3`, click **Queue Task**
- **Expected**:
  - Task is queued (log shows queued ID)
  - Retry attempts stream in via log messages
  - Succeeds on last attempt

#### Test 6: Clear Logs

- **Action**: Click **Clear Logs**
- **Expected**: All log entries clear

---

## AI Demos

### AI Chat (`/ai/chat`)

This is a documentation-focused demo explaining `AIChatAgent`.

#### Test 1: Page Load

- **Action**: Navigate to `/ai/chat`
- **Expected**:
  - Feature cards display (Message Persistence, Stream Resumption, etc.)
  - Setup requirements listed
  - useAgentChat hook properties documented

---

### Client-Side Tools (`/ai/tools`)

Documentation demo for client-side tool execution.

#### Test 1: Page Load

- **Action**: Navigate to `/ai/tools`
- **Expected**:
  - Explanation of server-side vs client-side tools
  - Example flow with numbered steps
  - Confirm/Cancel button mockup visible

---

### Codemode (`/ai/codemode`)

Tests AI code generation and execution using the CodeAct pattern.

#### Test 1: Connection

- **Action**: Navigate to `/ai/codemode`
- **Expected**: Connection status shows "Connected", empty state with "Try Codemode" prompt suggestions

#### Test 2: Send Message

- **Action**: Type "What is 17 + 25?" and press Enter
- **Expected**:
  - User message appears on the right
  - Assistant responds with a tool card showing code execution
  - Expanding the tool card shows the generated code and result
  - Text response includes the answer

#### Test 3: Tool Card Expansion

- **Action**: Click on a collapsed tool card (e.g., "Ran code")
- **Expected**:
  - Card expands to show Code, Result, and Console sections
  - Code section shows the generated JavaScript
  - Result shows the output

#### Test 4: Streaming

- **Action**: Send a message and observe
- **Expected**:
  - Send button shows loading spinner during streaming
  - Text streams in progressively
  - Input is disabled while streaming

#### Test 5: Clear History

- **Action**: Click the trash icon
- **Expected**: All messages clear, returns to empty state

---

## MCP Demos

### MCP Server (`/mcp/server`)

Documentation for creating MCP servers.

#### Test 1: Page Load

- **Action**: Navigate to `/mcp/server`
- **Expected**:
  - What is MCP explanation
  - Tools/Resources/Prompts feature cards
  - How It Works steps

---

### MCP Client (`/mcp/client`)

Documentation for connecting to MCP servers.

#### Test 1: Page Load

- **Action**: Navigate to `/mcp/client`
- **Expected**:
  - API method cards (addMcpServer, mcp.listTools, etc.)
  - Connection options code snippet

---

### MCP OAuth (`/mcp/oauth`)

Documentation for OAuth authentication with MCP.

#### Test 1: Page Load

- **Action**: Navigate to `/mcp/oauth`
- **Expected**:
  - OAuth flow steps listed
  - Server states table (not-connected, authenticating, etc.)
  - Client-side handling code snippet

---

## Global UI Tests

### Dark Mode Toggle

#### Test 1: Toggle Dark Mode

- **Action**: Click the theme toggle in the sidebar footer
- **Expected**:
  - Cycles through: System → Light → Dark → System
  - UI immediately updates colors
  - Background, cards, inputs, buttons all change

#### Test 2: Persistence

- **Action**: Set to Dark mode, refresh the page
- **Expected**: Dark mode persists (stored in localStorage)

#### Test 3: System Preference

- **Action**: Set to System, change OS dark mode setting
- **Expected**: App follows system preference

---

### Sidebar Navigation

#### Test 1: Category Collapse

- **Action**: Click on a category header (e.g., "CORE")
- **Expected**: Category collapses/expands

#### Test 2: Active State

- **Action**: Click on a demo link
- **Expected**: Link highlights with active styling

#### Test 3: External Links

- **Action**: Click GitHub or Docs links in footer
- **Expected**: Opens in new tab

---

### Event Log Panel

Present on all interactive demos (State, Callable, Streaming, Schedule, Connections, SQL, Routing, Readonly, Retry, Email Receive, Email Secure).

#### Test 1: Auto-Scroll

- **Action**: Trigger many events rapidly
- **Expected**: Log panel auto-scrolls to bottom

#### Test 2: Clear Logs

- **Action**: Click the trash icon
- **Expected**: All log entries clear, shows "No events yet"

#### Test 3: Log Entry Types

- **Expected Colors**:
  - `→` (outgoing): Blue background
  - `←` (incoming): Green background
  - `✕` (error): Red background
  - `•` (info): No background

---

## Error Scenarios

### Connection Failure

#### Test 1: Server Not Running

- **Action**: Stop the dev server, refresh the page
- **Expected**: Connection status shows "Connecting..." indefinitely

### Invalid Input

#### Test 1: Empty Item

- **Action**: Click Add with empty input
- **Expected**: Nothing happens (validation prevents empty items)

#### Test 2: Non-Numeric Counter

- **Action**: Enter "abc" in counter input, click Set
- **Expected**: Counter becomes `NaN` or 0 (depending on parseInt behavior)

---

## Performance Checks

### Large State

- **Action**: Add 100+ items via the State demo
- **Expected**:
  - No UI lag
  - State syncs correctly
  - JSON display remains responsive

### Rapid Operations

- **Action**: Click increment button rapidly (20+ times)
- **Expected**:
  - All operations complete
  - Final count is accurate
  - Log shows all calls