/** * API Test Script for AutoSite Application * * This script provides functions to test the backend API endpoints * that support the AskAI component functionality. */ // Configuration const API_BASE_URL = 'http://localhost:3000'; const TEST_HTML = ` Test Page

Hello World

This is a test page.

`; // Test prompts for different scenarios const TEST_PROMPTS = { initial: "Create a simple landing page with a header and footer", followUp: "Add a contact form to the page", complex: "Create a responsive portfolio page with navigation, hero section, project gallery, and contact form" }; // Helper function for making API requests async function makeRequest(endpoint, method = 'GET', body = null) { const options = { method, headers: { 'Content-Type': 'application/json' } }; if (body) { options.body = JSON.stringify(body); } try { const response = await fetch(`${API_BASE_URL}${endpoint}`, options); const contentType = response.headers.get('Content-Type'); // Log response headers for debugging console.log('Response headers:', { 'Content-Type': contentType, 'X-Response-Type': response.headers.get('X-Response-Type') }); // Handle different response types if (contentType && contentType.includes('application/json')) { return { status: response.status, headers: response.headers, body: await response.json() }; } else { return { status: response.status, headers: response.headers, body: await response.text() }; } } catch (error) { console.error('API request failed:', error); return { error: error.message }; } } // Test the /api/ask-ai endpoint with initial prompt (full HTML mode) async function testAskAiInitial() { console.log('\n--- Testing /api/ask-ai with initial prompt ---'); const requestBody = { prompt: TEST_PROMPTS.initial }; console.log('Request:', requestBody); // For streaming endpoints, we need to handle the response differently try { const response = await fetch(`${API_BASE_URL}/api/ask-ai`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }); console.log('Response status:', response.status); console.log('Response headers:', { 'Content-Type': response.headers.get('Content-Type'), 'X-Response-Type': response.headers.get('X-Response-Type') }); if (!response.ok) { const errorText = await response.text(); console.error('Error response:', errorText); return false; } // Handle streaming response const reader = response.body.getReader(); const decoder = new TextDecoder('utf-8'); let receivedChunks = 0; let receivedContent = ''; while (true) { const { done, value } = await reader.read(); if (done) { console.log('Stream complete after', receivedChunks, 'chunks'); break; } const chunk = decoder.decode(value, { stream: true }); receivedContent += chunk; receivedChunks++; // Log progress if (receivedChunks % 5 === 0) { console.log(`Received ${receivedChunks} chunks, total length: ${receivedContent.length}`); } } // Validate response content const hasHtmlStructure = receivedContent.includes('') || (receivedContent.includes('')); if (hasHtmlStructure) { console.log('Response contains valid HTML structure'); // Log a sample of the response console.log('Sample of response:', receivedContent.substring(0, 200) + '...'); return true; } else { console.error('Response does not contain valid HTML structure'); console.log('Response content:', receivedContent); return false; } } catch (error) { console.error('Test failed:', error); return false; } } // Test the /api/ask-ai endpoint with follow-up prompt (diff mode) async function testAskAiFollowUp() { console.log('\n--- Testing /api/ask-ai with follow-up prompt (diff mode) ---'); const requestBody = { prompt: TEST_PROMPTS.followUp, html: TEST_HTML, previousPrompt: TEST_PROMPTS.initial }; console.log('Request:', requestBody); try { const response = await fetch(`${API_BASE_URL}/api/ask-ai`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }); console.log('Response status:', response.status); console.log('Response headers:', { 'Content-Type': response.headers.get('Content-Type'), 'X-Response-Type': response.headers.get('X-Response-Type') }); if (!response.ok) { const errorText = await response.text(); console.error('Error response:', errorText); return false; } // Verify response type header indicates diff mode const responseType = response.headers.get('X-Response-Type'); if (responseType !== 'diff') { console.warn(`Expected response type 'diff', but got '${responseType}'`); } // Handle streaming response const reader = response.body.getReader(); const decoder = new TextDecoder('utf-8'); let receivedChunks = 0; let receivedContent = ''; while (true) { const { done, value } = await reader.read(); if (done) { console.log('Stream complete after', receivedChunks, 'chunks'); break; } const chunk = decoder.decode(value, { stream: true }); receivedContent += chunk; receivedChunks++; // Log progress if (receivedChunks % 5 === 0) { console.log(`Received ${receivedChunks} chunks, total length: ${receivedContent.length}`); } } // For diff mode, check if response contains search/replace blocks const hasDiffBlocks = receivedContent.includes('<<<<<<< SEARCH') && receivedContent.includes('======= REPLACE') && receivedContent.includes('>>>>>>> END'); if (hasDiffBlocks) { console.log('Response contains valid diff blocks'); // Log a sample of the response console.log('Sample of response:', receivedContent.substring(0, 200) + '...'); return true; } else { console.warn('Response may not contain valid diff blocks'); console.log('Response content:', receivedContent); return false; } } catch (error) { console.error('Test failed:', error); return false; } } // Test the /api/apply-diffs endpoint async function testApplyDiffs() { console.log('\n--- Testing /api/apply-diffs endpoint ---'); // Create a sample diff response const sampleDiff = `Here are the changes to add a contact form: <<<<<<< SEARCH

This is a test page.

======= REPLACE

This is a test page.

Contact Us

>>>>>>> END`; const requestBody = { originalHtml: TEST_HTML, aiResponseContent: sampleDiff }; console.log('Request:', requestBody); try { const response = await fetch(`${API_BASE_URL}/api/apply-diffs`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }); console.log('Response status:', response.status); if (!response.ok) { const errorText = await response.text(); console.error('Error response:', errorText); return false; } const responseText = await response.text(); // Verify the response contains the applied changes const hasContactForm = responseText.includes('

Contact Us

') && responseText.includes('
') && responseText.includes('
'); if (hasContactForm) { console.log('Diff was successfully applied'); console.log('Modified HTML:', responseText); return true; } else { console.error('Diff was not applied correctly'); console.log('Response:', responseText); return false; } } catch (error) { console.error('Test failed:', error); return false; } } // Test error handling for /api/ask-ai endpoint async function testAskAiErrorHandling() { console.log('\n--- Testing /api/ask-ai error handling ---'); // Test with empty prompt (should return 400) const requestBody = { prompt: "" }; console.log('Request with empty prompt:', requestBody); try { const response = await fetch(`${API_BASE_URL}/api/ask-ai`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }); console.log('Response status:', response.status); if (response.status === 400) { console.log('Server correctly returned 400 for empty prompt'); const errorJson = await response.json(); console.log('Error response:', errorJson); return true; } else { console.error('Expected 400 status, but got', response.status); return false; } } catch (error) { console.error('Test failed:', error); return false; } } // Test error handling for /api/apply-diffs endpoint async function testApplyDiffsErrorHandling() { console.log('\n--- Testing /api/apply-diffs error handling ---'); // Test with malformed diff (should return 400) const requestBody = { originalHtml: TEST_HTML, aiResponseContent: "This is not a valid diff format" }; console.log('Request with invalid diff format:', requestBody); try { const response = await fetch(`${API_BASE_URL}/api/apply-diffs`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }); console.log('Response status:', response.status); // The server should either return 400 or successfully process with no changes if (response.status === 400) { console.log('Server correctly returned 400 for invalid diff format'); const errorJson = await response.json(); console.log('Error response:', errorJson); return true; } else if (response.ok) { const responseText = await response.text(); // If server didn't error, it should return the original HTML unchanged if (responseText === TEST_HTML) { console.log('Server returned original HTML unchanged (acceptable fallback)'); return true; } else { console.warn('Server did not error but returned modified HTML'); console.log('Response:', responseText); return false; } } else { console.error('Unexpected response status:', response.status); return false; } } catch (error) { console.error('Test failed:', error); return false; } } // Run all tests async function runAllTests() { console.log('Starting API tests for AutoSite application...'); const results = { askAiInitial: await testAskAiInitial(), askAiFollowUp: await testAskAiFollowUp(), applyDiffs: await testApplyDiffs(), askAiErrorHandling: await testAskAiErrorHandling(), applyDiffsErrorHandling: await testApplyDiffsErrorHandling() }; console.log('\n--- Test Results Summary ---'); Object.entries(results).forEach(([test, passed]) => { console.log(`${test}: ${passed ? '✅ PASSED' : '❌ FAILED'}`); }); const passedCount = Object.values(results).filter(Boolean).length; const totalCount = Object.values(results).length; console.log(`\nTests passed: ${passedCount}/${totalCount} (${Math.round(passedCount/totalCount*100)}%)`); return results; } // Execute tests when run in Node.js if (typeof window === 'undefined') { console.log('AutoSite API Test Script running in Node.js'); runAllTests().catch(console.error); } else { console.log('AutoSite API Test Script loaded in browser'); console.log('Run tests by calling: runAllTests()'); }