#!/bin/bash # Table Stakes Features - Automated QA Test Script # Tests all implemented features end-to-end # set -e # Don't exit on error - show all test results # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration BASE_URL="http://localhost:3000" API_BASE="$BASE_URL/api" TEST_PROJECT_NAME="QA Test Project $(date +%s)" TEST_WORKSPACE="test-workspace" # Test results TESTS_PASSED=0 TESTS_FAILED=0 FAILED_TESTS=() # Helper functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[PASS]${NC} $1" ((TESTS_PASSED++)) } log_error() { echo -e "${RED}[FAIL]${NC} $1" ((TESTS_FAILED++)) FAILED_TESTS+=("$1") } log_warning() { echo -e "${YELLOW}[WARN]${NC} $1" } # Check if server is running check_server() { log_info "Checking if server is running at $BASE_URL..." if curl -s -o /dev/null -w "%{http_code}" "$BASE_URL" | grep -q "200\|404"; then log_success "Server is running" return 0 else log_error "Server is not running at $BASE_URL" exit 1 fi } # Test 1: Create a new project test_create_project() { log_info "Test 1: Creating new project..." # Note: This requires authentication, so we'll check the endpoint exists response=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$API_BASE/projects/create" \ -H "Content-Type: application/json" \ -d '{}') if [ "$response" = "401" ]; then log_success "Project creation endpoint exists (401 Unauthorized as expected without token)" else log_warning "Project creation endpoint returned $response (expected 401)" fi } # Test 2: Check extensionLinked field initialization test_extension_field() { log_info "Test 2: Checking extensionLinked field in project creation..." # Check the code has the field if grep -q "extensionLinked: false" app/api/projects/create/route.ts; then log_success "extensionLinked field present in project creation" else log_error "extensionLinked field missing from project creation" fi } # Test 3: Check collector handoff type includes 'collector' test_collector_handoff_type() { log_info "Test 3: Checking collector handoff type definition..." if grep -q "'collector' |" lib/server/chat-context.ts; then log_success "Collector phase included in phaseHandoffs type" else log_error "Collector phase missing from phaseHandoffs type" fi } # Test 4: Check auto-transition logic exists test_auto_transition() { log_info "Test 4: Checking auto-transition logic..." if grep -q "Auto-transitioning project to extraction phase" app/api/ai/chat/route.ts; then log_success "Auto-transition logic present in chat route" else log_error "Auto-transition logic missing from chat route" fi if grep -q "currentPhase === 'analyzed'" lib/server/chat-mode-resolver.ts; then log_success "Mode resolver checks currentPhase field" else log_error "Mode resolver doesn't check currentPhase" fi } # Test 5: Check extension linking API exists test_extension_api() { log_info "Test 5: Checking extension linking API..." response=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$API_BASE/extension/link-project" \ -H "Content-Type: application/json" \ -d '{}') if [ "$response" = "401" ]; then log_success "Extension link API exists (401 Unauthorized as expected)" else log_warning "Extension link API returned $response (expected 401)" fi } # Test 6: Check chunking API exists test_chunking_api() { log_info "Test 6: Checking extraction chunking API..." # Check if the file exists if [ -f "app/api/projects/[projectId]/knowledge/chunk-insight/route.ts" ]; then log_success "Chunk insight API endpoint file exists" else log_error "Chunk insight API endpoint missing" fi } # Test 7: Check auto-chunking is disabled on upload test_no_auto_chunking() { log_info "Test 7: Checking auto-chunking is disabled on upload..." if grep -q "Store whole document as single knowledge_item" app/api/projects/[projectId]/knowledge/upload-document/route.ts; then log_success "Upload stores whole document (no auto-chunking)" else log_error "Upload may still be auto-chunking" fi if grep -q "// import { chunkDocument }" app/api/projects/[projectId]/knowledge/upload-document/route.ts; then log_success "chunkDocument import commented out" else log_warning "chunkDocument import may still be active" fi } # Test 8: Check collector checklist component exists test_checklist_component() { log_info "Test 8: Checking collector checklist component..." if [ -f "components/ai/collector-checklist.tsx" ]; then log_success "Collector checklist component exists" else log_error "Collector checklist component missing" fi if grep -q "CollectorChecklist" app/[workspace]/project/[projectId]/v_ai_chat/page.tsx; then log_success "Checklist integrated into AI chat page" else log_error "Checklist not integrated into AI chat page" fi } # Test 9: Check Gemini role mapping fix test_gemini_role_fix() { log_info "Test 9: Checking Gemini role mapping fix..." if grep -q "role === 'assistant' ? 'model'" lib/ai/gemini-client.ts; then log_success "Gemini client translates assistant → model role" else log_error "Gemini client missing role translation" fi } # Test 10: Check conversation history persistence test_conversation_history() { log_info "Test 10: Checking conversation history loading..." if grep -q "Load existing conversation history" app/api/ai/chat/route.ts; then log_success "Chat route loads conversation history" else log_error "Chat route doesn't load conversation history" fi if grep -q "conversationHistory.map" app/api/ai/chat/route.ts; then log_success "Conversation history included in messages" else log_error "Conversation history not included in messages" fi } # Test 11: Check extensionLinked in context test_extension_in_context() { log_info "Test 11: Checking extensionLinked in project context..." if grep -q "extensionLinked?: boolean" lib/server/chat-context.ts; then log_success "extensionLinked field in ProjectChatContext type" else log_error "extensionLinked field missing from context type" fi if grep -q "extensionLinked: projectData.extensionLinked" lib/server/chat-context.ts; then log_success "extensionLinked passed to AI in context" else log_error "extensionLinked not passed to AI" fi } # Test 12: Check collector prompt mentions extensionLinked test_collector_prompt() { log_info "Test 12: Checking collector prompt..." if grep -q "projectContext.project.extensionLinked" lib/ai/prompts/collector.ts; then log_success "Collector prompt checks extensionLinked field" else log_error "Collector prompt doesn't check extensionLinked" fi } # Test 13: Check UI text update test_ui_text() { log_info "Test 13: Checking UI text reflects no auto-chunking..." if grep -q "stored for the Extractor AI to review" app/[workspace]/project/[projectId]/context/page.tsx; then log_success "UI text updated (no mention of auto-chunking)" else log_error "UI text may still mention auto-chunking" fi } # Test 14: Verify linter passes test_linter() { log_info "Test 14: Running linter check..." # This is a simplified check - just verify key files exist and are not empty files_to_check=( "app/api/ai/chat/route.ts" "lib/server/chat-context.ts" "lib/ai/gemini-client.ts" "components/ai/collector-checklist.tsx" ) all_good=true for file in "${files_to_check[@]}"; do if [ ! -f "$file" ]; then log_error "File missing: $file" all_good=false elif [ ! -s "$file" ]; then log_error "File is empty: $file" all_good=false fi done if $all_good; then log_success "All critical files exist and are not empty" fi } # Test 15: Check documentation exists test_documentation() { log_info "Test 15: Checking documentation..." docs=( "TABLE_STAKES_IMPLEMENTATION.md" "QA_FIXES_APPLIED.md" "PROJECT_CREATION_FIX.md" "UPLOAD_CHUNKING_REMOVED.md" ) for doc in "${docs[@]}"; do if [ -f "$doc" ]; then log_success "Documentation exists: $doc" else log_warning "Documentation missing: $doc" fi done } # Main test execution main() { echo "" echo "==========================================" echo " TABLE STAKES FEATURES - QA TEST SUITE" echo "==========================================" echo "" check_server echo "" test_create_project test_extension_field test_collector_handoff_type test_auto_transition test_extension_api test_chunking_api test_no_auto_chunking test_checklist_component test_gemini_role_fix test_conversation_history test_extension_in_context test_collector_prompt test_ui_text test_linter test_documentation echo "" echo "==========================================" echo " TEST RESULTS" echo "==========================================" echo -e "${GREEN}Passed:${NC} $TESTS_PASSED" echo -e "${RED}Failed:${NC} $TESTS_FAILED" echo "" if [ $TESTS_FAILED -gt 0 ]; then echo -e "${RED}Failed tests:${NC}" for test in "${FAILED_TESTS[@]}"; do echo " - $test" done echo "" exit 1 else echo -e "${GREEN}✅ ALL TESTS PASSED!${NC}" echo "" exit 0 fi } # Run tests cd "$(dirname "$0")" main