- Comprehensive image extraction architecture design - Database schema for document_images table - Migration 004: Add document_images table with indexes - Migration runner script - Design and status documentation Prepares foundation for image extraction feature with OCR on images. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
11 KiB
Testing Requirements - Preventing Production Bugs
Purpose: Ensure all bugs are caught during testing, not discovered by users in production.
Last Updated: 2025-10-19
Critical Rule: Test Like a User, Not Like a Developer
❌ DON'T:
- Test only via API with curl
- Assume API tests cover UI functionality
- Skip browser testing because "the API works"
- Test individual components in isolation
- Use hardcoded correct values that bypass validation
✅ DO:
- Test through the actual UI in a real browser
- Complete full user workflows start-to-finish
- Test in the target environment (Windows accessing WSL2)
- Open browser DevTools and check for errors
- Verify network requests match backend expectations
Testing Levels Required
Level 1: API Contract Testing (Baseline) ✅
What to test:
# Test all endpoints with curl
curl -X POST /api/upload -F "file=@test.pdf" -F "title=Test" ...
curl -X POST /api/search -d '{"q":"test"}'
curl -X GET /api/documents/:id
curl -X GET /api/documents/:id/pdf
What this catches:
- Backend logic errors
- Database constraints
- Authentication issues
- API response format
What this DOESN'T catch:
- UI field name mismatches (upload bug)
- Frontend integration issues (PDF.js CDN)
- User experience problems
- Browser compatibility issues
Level 2: UI Integration Testing (REQUIRED) ✅
Critical Instruction:
For every feature, you must test the ACTUAL UI in a browser, not just the API.
Specific Requirements:
1. Browser Testing Checklist
Before marking ANY feature complete:
- Open http://172.29.75.55:8080 in Windows browser
- Open DevTools (F12) and check Console tab
- Open DevTools Network tab to see actual requests
- Complete the user workflow manually
- Verify no console errors (red messages)
- Verify network requests have correct field names
- Check that responses are 200/201, not 400/500
2. Upload Feature Test Protocol
WRONG way (only API):
curl -X POST /api/upload -F "file=@test.pdf" ... # ✅ Passes
# But UI sends 'pdf' not 'file' → User sees broken upload ❌
RIGHT way (UI + API):
1. Open browser → http://172.29.75.55:8080
2. Click "Upload Document" button
3. Select a PDF file (or drag & drop)
4. Fill in metadata form
5. Click "Upload and Process"
6. ✅ Watch DevTools Network tab:
- Request should be multipart/form-data
- Field name should be 'file' (not 'pdf')
- Response should be 201 with jobId
7. ✅ Watch UI:
- Progress modal should appear
- Progress bar should move to 100%
- Success message should show
8. ✅ Check console:
- No red errors
- No 400/500 responses
What this would have caught:
- ✅ Upload field name mismatch (would see 400 error in Network tab)
- ✅ Missing organizationId field
- ✅ Timeout issues
- ✅ Progress bar not updating
3. Document Viewer Test Protocol
WRONG way:
curl http://localhost:8001/api/documents/:id # ✅ Passes
curl http://localhost:8001/api/documents/:id/pdf # ✅ Passes
# But PDF.js worker fails to load in browser ❌
RIGHT way:
1. Upload a multi-page PDF (5+ pages recommended)
2. Click on the uploaded document to open viewer
3. ✅ Test initial load:
- PDF page 1 should render
- No error messages
- Page counter shows "Page 1 / N"
4. ✅ Test page navigation:
- Click "Next" button → Page 2 should display
- Click "Next" again → Page 3 should display
- Click "Previous" → Page 2 should display
- Enter page number and click "Go" → That page displays
- Test rapid clicking (Next/Next/Next quickly)
5. ✅ Check DevTools Console:
- No "Failed to fetch" errors
- No "Failed to render page" errors
- No CDN loading failures
- Worker loads successfully
- No RenderingCancelledException (or it's handled gracefully)
6. ✅ Check DevTools Network:
- pdf.worker.min.mjs loads (not from CDN)
- Status 200, not 404
- PDF document loads (/api/documents/:id/pdf)
What this would have caught:
- ✅ PDF.js CDN failure
- ✅ Worker loading errors
- ✅ CORS issues
- ✅ Page navigation render conflicts
- ✅ Concurrent render task failures
Comprehensive Testing Checklist
For Every PR/Feature:
Phase 1: Component Verification (5 min)
- Read component source code
- Verify field names match API expectations
- Check external dependencies (CDNs, etc.)
- Look for hardcoded values
Phase 2: API Testing (5 min)
# Test with actual values the UI would send
curl -X POST /api/upload \
-F "file=@test.pdf" \
-F "title=Test" \
-F "documentType=owner-manual" \
-F "organizationId=test-org-123"
# Verify response is 201, not 400
Phase 3: UI Browser Testing (10 min)
- Open Windows browser → http://172.29.75.55:8080
- Open DevTools (F12)
- Clear console
- Complete user workflow
- Check console for errors
- Check Network tab for failed requests
- Verify UI shows correct feedback
Phase 4: Edge Case Testing (5 min)
- Test with large file (near 50MB limit)
- Test with invalid file type
- Test with network disconnected (offline)
- Test with slow connection (throttling)
Specific Instructions for AI/Automation
When testing a feature, follow this exact sequence:
Step 1: Verify Source Code
# Check actual field names in form submission
grep -A 10 "FormData" client/src/components/*.vue
grep "append.*file\|append.*pdf" client/src/**/*.vue
# Check for CDN dependencies
grep -r "cdnjs\|unpkg\|cdn.jsdelivr" client/src/
Step 2: API Contract Test
# Use exact field names from source code
curl -v -X POST /api/upload -F "file=@test.pdf" ...
# Look for: 201 Created (good) or 400 Bad Request (bad)
Step 3: Browser Simulation Test
// If you can't open a real browser, at least simulate it:
const formData = new FormData()
formData.append('file', selectedFile) // Use EXACT field name from code
// Then verify backend expects 'file' not something else
Step 4: Integration Verification
# After "successful" API test, verify UI actually works:
echo "⚠️ API test passed, but UI MUST be tested in browser"
echo "Open: http://172.29.75.55:8080"
echo "Test: Complete upload workflow manually"
echo "Check: DevTools Console and Network tabs"
Common Testing Mistakes That Let Bugs Through
Mistake 1: Testing API with correct values, UI sends wrong values
# Test uses correct field name:
curl -F "file=@test.pdf" # ✅ Works
# But UI code has:
formData.append('pdf', file) # ❌ Wrong field name
# Bug reaches user because test didn't use UI
Fix: Always grep the actual UI code for field names before testing.
Mistake 2: Assuming local files work the same as CDN
// Works in dev (CDN accessible):
workerSrc = "//cdnjs.cloudflare.com/..." // ✅ Works
// Breaks in production (CDN blocked):
// Browser: Failed to fetch // ❌ Fails
// Bug reaches user because test didn't check browser console
Fix: Always test in actual browser with DevTools open.
Mistake 3: Testing one step at a time, not full workflow
# Test upload: ✅ Works
curl -X POST /api/upload ...
# Test document get: ✅ Works
curl /api/documents/:id
# Test PDF stream: ✅ Works
curl /api/documents/:id/pdf
# But full workflow in UI: ❌ Breaks
# Upload → Search → Click → View PDF → Worker fails
# Bug reaches user because full workflow wasn't tested
Fix: Test complete user journeys end-to-end.
Automated Testing Requirements
Unit Tests (Component Level)
// ✅ Good test - checks actual field name
test('upload form uses correct field name', () => {
const formData = component.createFormData()
expect(formData.has('file')).toBe(true) // Not 'pdf'
expect(formData.has('organizationId')).toBe(true)
})
Integration Tests (Cypress/Playwright)
// ✅ Good test - uses real browser
cy.visit('http://localhost:8080')
cy.get('[data-testid=upload-button]').click()
cy.get('input[type=file]').selectFile('test.pdf')
cy.get('input[name=title]').type('Test Document')
cy.get('[data-testid=submit-upload]').click()
// Verify no console errors
cy.window().then((win) => {
expect(win.console.error).not.to.be.called
})
// Verify network request has correct field name
cy.intercept('POST', '/api/upload').as('upload')
cy.wait('@upload').then((interception) => {
expect(interception.request.body.get('file')).to.exist
})
E2E Tests (Full User Workflow)
// ✅ Complete workflow test
test('user can upload, search, and view document', async () => {
// 1. Upload
await page.goto('http://localhost:8080')
await page.click('[data-testid=upload-button]')
await page.setInputFiles('input[type=file]', 'test.pdf')
await page.fill('input[name=title]', 'Test Doc')
await page.click('[data-testid=submit]')
await page.waitForSelector('[data-testid=success-message]')
// 2. Search
await page.fill('input[placeholder*=Search]', 'Test Doc')
await page.press('input[placeholder*=Search]', 'Enter')
await page.waitForSelector('.search-result')
// 3. View
await page.click('.search-result:first-child')
await page.waitForSelector('canvas') // PDF canvas
// 4. Verify no errors
const errors = await page.evaluate(() => window.consoleErrors || [])
expect(errors).toHaveLength(0)
})
Pre-Deployment Checklist
Before marking ANYTHING as "ready" or "tested":
- Source code reviewed for field name mismatches
- API endpoints tested with curl
- UI tested in actual Windows browser
- DevTools Console checked (no red errors)
- DevTools Network checked (no 400/500 errors)
- Full user workflow completed manually
- All external dependencies verified (no CDN failures)
- Tested on actual target environment (WSL2 → Windows)
Quick Reference: Testing Commands
Verify UI Field Names Match Backend
# Check what UI sends:
grep -r "formData.append" client/src/
# Check what backend expects:
grep -r "upload.single\|upload.array" server/routes/
# They MUST match!
Test in Browser with DevTools
1. Open: http://172.29.75.55:8080
2. Press F12 (DevTools)
3. Click Console tab
4. Click Network tab
5. Perform user action
6. Check for red errors in Console
7. Check for 400/500 in Network
Verify External Dependencies
# Find all CDN/external URLs:
grep -r "http.*cdn\|//cdn" client/src/
# For each one, verify it's necessary and accessible
# Better: Replace with local files from node_modules
Summary: The One Rule to Remember
"If you didn't test it in a real browser with DevTools open, you didn't test it."
API tests are necessary but NOT sufficient. They catch backend bugs but miss frontend integration issues.
The bugs you found were caused by:
- ✅ API tested with curl (passed)
- ❌ UI not tested in browser (bug slipped through)
- ❌ DevTools not checked (errors not seen)
- ❌ Network tab not inspected (field mismatch not caught)
Prevent this by:
- ✅ Test API with curl
- ✅ ALSO test UI in browser ← This was missing
- ✅ Check DevTools Console
- ✅ Check DevTools Network tab
- ✅ Complete full user workflows
Remember: A passing API test does NOT mean the feature works. You must test the UI.