- Modified loadChatHistory() to check for active project before fetching all sessions - When active project exists, use project.sessions instead of fetching from API - Added detailed console logging to debug session filtering - This prevents ALL sessions from appearing in every project's sidebar Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
344 lines
9.1 KiB
Markdown
344 lines
9.1 KiB
Markdown
# Approval Flow Integration Test Guide
|
|
|
|
This document provides step-by-step instructions for manually testing the approval flow fix.
|
|
|
|
## Test Environment Setup
|
|
|
|
1. Start the server:
|
|
```bash
|
|
cd /home/uroma/obsidian-web-interface
|
|
node server.js
|
|
```
|
|
|
|
2. Open browser to: `http://localhost:3000/claude-ide`
|
|
|
|
3. Open browser DevTools (F12) and go to Console tab
|
|
|
|
## Test Scenario 1: Basic Approval Flow
|
|
|
|
### Step 1: Initiate Command
|
|
- Type in chat: `run ping google.com`
|
|
- Press Enter
|
|
|
|
**Expected Result:**
|
|
- Message appears in chat
|
|
- Claude responds with approval request
|
|
- Approval card appears with Approve/Reject buttons
|
|
|
|
**Console Should Show:**
|
|
```
|
|
[ApprovalCard] Component loaded
|
|
```
|
|
|
|
### Step 2: Verify Approval Request
|
|
- Check that approval card shows:
|
|
- Robot emoji (🤖)
|
|
- Command: `ping google.com`
|
|
- Explanation (if provided)
|
|
- Approve button
|
|
- Custom Instructions button (if explanation provided)
|
|
- Reject button
|
|
|
|
**In DevTools Console, type:**
|
|
```javascript
|
|
window._pendingApprovals
|
|
```
|
|
|
|
**Expected:** Object with approval ID containing:
|
|
- `command`: "ping google.com"
|
|
- `sessionId`: current session ID
|
|
- `originalMessage`: user's message
|
|
|
|
### Step 3: Click Approve
|
|
- Click the "Approve" button
|
|
|
|
**Expected Result:**
|
|
- Approval card disappears
|
|
- System message appears: "✅ Approval sent - continuing execution..."
|
|
- "yes" message sent to Claude
|
|
|
|
**Console Should Show:**
|
|
```javascript
|
|
// Check WebSocket message in Network tab
|
|
// Should see message with:
|
|
{
|
|
type: 'command',
|
|
sessionId: '<session-id>',
|
|
command: 'yes',
|
|
metadata: {
|
|
isApprovalResponse: true,
|
|
approvalId: '<approval-id>',
|
|
originalCommand: 'ping google.com'
|
|
}
|
|
}
|
|
```
|
|
|
|
**Verify Pending Approval Cleaned:**
|
|
```javascript
|
|
window._pendingApprovals
|
|
```
|
|
Should be empty or not contain the approval ID
|
|
|
|
### Step 4: Verify Execution
|
|
- Claude should continue execution
|
|
- Ping output should appear in chat
|
|
|
|
**Console Should Show:**
|
|
```
|
|
[ApprovalCard] Sending AI-conversational approval as chat message
|
|
[ApprovalCard] Sent approval response via WebSocket: yes
|
|
```
|
|
|
|
## Test Scenario 2: Custom Command Modification
|
|
|
|
### Step 1: Initiate Command
|
|
- Type: `run ping google.com -c 100`
|
|
- Wait for approval card
|
|
|
|
### Step 2: Click Custom Instructions
|
|
- Click "Custom Instructions" button
|
|
- Custom input field should appear
|
|
|
|
### Step 3: Enter Modified Command
|
|
- Type in custom input: `ping google.com -c 5`
|
|
- Click "Execute Custom"
|
|
|
|
**Expected Result:**
|
|
- Approval card disappears
|
|
- System message: "✅ Approval sent - continuing execution..."
|
|
- Custom command sent as WebSocket message
|
|
|
|
**Console Should Show:**
|
|
```javascript
|
|
// WebSocket message should be:
|
|
{
|
|
type: 'command',
|
|
command: 'ping google.com -c 5', // Custom command
|
|
metadata: {
|
|
isApprovalResponse: true,
|
|
approvalId: '<approval-id>',
|
|
originalCommand: 'ping google.com -c 100'
|
|
}
|
|
}
|
|
```
|
|
|
|
## Test Scenario 3: Reject Command
|
|
|
|
### Step 1: Initiate Command
|
|
- Type: `run rm -rf /` (or any dangerous command)
|
|
- Wait for approval card
|
|
|
|
### Step 2: Click Reject
|
|
- Click "Reject" button
|
|
|
|
**Expected Result:**
|
|
- Approval card disappears
|
|
- "no" message sent to Claude
|
|
- Claude should acknowledge rejection
|
|
|
|
**Console Should Show:**
|
|
```javascript
|
|
// WebSocket message:
|
|
{
|
|
type: 'command',
|
|
command: 'no',
|
|
metadata: {
|
|
isApprovalResponse: true,
|
|
approvalId: '<approval-id>'
|
|
}
|
|
}
|
|
```
|
|
|
|
## Test Scenario 4: Multiple Pending Approvals
|
|
|
|
### Step 1: Send Multiple Commands
|
|
- Type: `run ping google.com`
|
|
- Before approving, type: `run ls -la`
|
|
- Before approving, type: `run date`
|
|
|
|
**Expected Result:**
|
|
- Multiple approval cards appear
|
|
- Each has unique approval ID
|
|
|
|
**Verify Pending Approvals:**
|
|
```javascript
|
|
Object.keys(window._pendingApprovals).length
|
|
```
|
|
Should show 3
|
|
|
|
### Step 2: Approve Each Individually
|
|
- Click "Approve" on first card
|
|
- Verify only that card disappears
|
|
- Verify other cards remain
|
|
|
|
**Expected:** Each approval is independent
|
|
|
|
## Test Scenario 5: WebSocket Disconnected
|
|
|
|
### Step 1: Disconnect WebSocket
|
|
- In DevTools Console, type:
|
|
```javascript
|
|
window.ws.close()
|
|
```
|
|
|
|
### Step 2: Try to Approve
|
|
- Type: `run ping google.com`
|
|
- Wait for approval card
|
|
- Click "Approve"
|
|
|
|
**Expected Result:**
|
|
- Approval card disappears
|
|
- Error message: "❌ Failed to send approval: WebSocket not connected"
|
|
|
|
**Console Should Show:**
|
|
```
|
|
[ApprovalCard] WebSocket not connected for approval response
|
|
```
|
|
|
|
### Step 3: Reconnect and Try Again
|
|
- Refresh page to reconnect WebSocket
|
|
- Send command again
|
|
- Approve should work
|
|
|
|
## Test Scenario 6: Empty Custom Command
|
|
|
|
### Step 1: Initiate Command
|
|
- Type: `run ping google.com`
|
|
- Wait for approval card
|
|
|
|
### Step 2: Try Empty Custom Command
|
|
- Click "Custom Instructions"
|
|
- Leave custom input empty
|
|
- Click "Execute Custom"
|
|
|
|
**Expected Result:**
|
|
- Error message: "Please enter a command"
|
|
- Input field regains focus
|
|
- Approval card remains visible
|
|
|
|
## Test Scenario 7: Approval Expiration
|
|
|
|
### Step 1: Initiate Command
|
|
- Type: `run ping google.com`
|
|
- Wait for approval card
|
|
|
|
### Step 2: Wait for Expiration (5 minutes)
|
|
- Wait 5 minutes without approving
|
|
|
|
**Expected Result:**
|
|
- Approval card shows "⏱️ Expired"
|
|
- Buttons are hidden
|
|
- Custom input is hidden
|
|
|
|
**Note:** This test takes 5 minutes. For faster testing, you can modify the expiration time in server.js temporarily.
|
|
|
|
## Test Scenario 8: XSS Prevention
|
|
|
|
### Step 1: Send Command with HTML
|
|
- Type: `run <script>alert('XSS')</script>`
|
|
- Wait for approval card
|
|
|
|
### Step 2: Verify Escaping
|
|
- Check that command is displayed as text, not rendered HTML
|
|
- No alert should appear
|
|
|
|
**Expected:** Command is escaped using `escapeHtml()` function
|
|
|
|
## Automated Verification Commands
|
|
|
|
Run these in DevTools Console to verify the implementation:
|
|
|
|
```javascript
|
|
// 1. Verify ApprovalCard is loaded
|
|
console.log('ApprovalCard loaded:', typeof window.ApprovalCard === 'object');
|
|
|
|
// 2. Verify required methods exist
|
|
const methods = ['handleApprove', 'handleReject', 'handleCustom', 'executeCustom', 'sendApprovalResponse', 'handleExpired'];
|
|
const hasAllMethods = methods.every(m => typeof window.ApprovalCard[m] === 'function');
|
|
console.log('All required methods present:', hasAllMethods);
|
|
|
|
// 3. Verify pending approvals storage
|
|
console.log('Pending approvals initialized:', typeof window._pendingApprovals === 'object');
|
|
|
|
// 4. Verify WebSocket connection
|
|
console.log('WebSocket connected:', window.ws && window.ws.readyState === WebSocket.OPEN);
|
|
|
|
// 5. Verify session ID
|
|
console.log('Session ID:', window.attachedSessionId || window.chatSessionId);
|
|
```
|
|
|
|
## Server-Side Verification
|
|
|
|
Check server logs for:
|
|
|
|
```
|
|
[WebSocket] Sending command to session <session-id>: yes...
|
|
[WebSocket] ✓ Command sent successfully to session <session-id>
|
|
```
|
|
|
|
Verify that the metadata is preserved:
|
|
```
|
|
metadata: {
|
|
isApprovalResponse: true,
|
|
approvalId: 'approval-<timestamp>-<random>',
|
|
originalCommand: 'ping google.com'
|
|
}
|
|
```
|
|
|
|
## Common Issues and Solutions
|
|
|
|
### Issue 1: Approval card doesn't appear
|
|
**Check:**
|
|
- Is approval-card.js loaded? (Check Network tab)
|
|
- Is ApprovalCard defined? (`console.log(window.ApprovalCard)`)
|
|
|
|
### Issue 2: Clicking Approve does nothing
|
|
**Check:**
|
|
- Is WebSocket connected? (`window.ws.readyState === WebSocket.OPEN`)
|
|
- Is there a pending approval? (`window._pendingApprovals`)
|
|
- Check console for errors
|
|
|
|
### Issue 3: "yes" message appears in chat instead of executing
|
|
**Check:**
|
|
- Is the server receiving the command type correctly?
|
|
- Check server logs for "Sending command to session"
|
|
|
|
### Issue 4: Approval appears but Claude doesn't continue
|
|
**Check:**
|
|
- Did Claude receive "yes" message?
|
|
- Check server logs for command delivery
|
|
- Verify sessionId matches current session
|
|
|
|
## Success Criteria
|
|
|
|
The approval flow fix is working correctly if:
|
|
|
|
1. ✅ Approval card appears when Claude requests approval
|
|
2. ✅ Clicking "Approve" sends "yes" as WebSocket command
|
|
3. ✅ WebSocket message includes `isApprovalResponse: true` metadata
|
|
4. ✅ Claude receives the "yes" message and continues execution
|
|
5. ✅ Custom commands work correctly
|
|
6. ✅ Reject button sends "no" message
|
|
7. ✅ Pending approvals are cleaned up after response
|
|
8. ✅ Multiple approvals can be handled independently
|
|
9. ✅ Error handling works for disconnected WebSocket
|
|
10. ✅ HTML escaping prevents XSS
|
|
|
|
## Test Results Checklist
|
|
|
|
- [ ] Test Scenario 1: Basic Approval Flow - PASS/FAIL
|
|
- [ ] Test Scenario 2: Custom Command Modification - PASS/FAIL
|
|
- [ ] Test Scenario 3: Reject Command - PASS/FAIL
|
|
- [ ] Test Scenario 4: Multiple Pending Approvals - PASS/FAIL
|
|
- [ ] Test Scenario 5: WebSocket Disconnected - PASS/FAIL
|
|
- [ ] Test Scenario 6: Empty Custom Command - PASS/FAIL
|
|
- [ ] Test Scenario 7: Approval Expiration - PASS/FAIL
|
|
- [ ] Test Scenario 8: XSS Prevention - PASS/FAIL
|
|
|
|
**Overall Result:** _____ PASS/FAIL
|
|
|
|
**Tester Notes:**
|
|
_______________________________________________________________
|
|
_______________________________________________________________
|
|
_______________________________________________________________
|