Spaces:
Running
Running
/** | |
* 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 = `<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Test Page</title> | |
</head> | |
<body> | |
<h1>Hello World</h1> | |
<p>This is a test page.</p> | |
</body> | |
</html>`; | |
// 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('<!DOCTYPE html>') || | |
(receivedContent.includes('<html') && receivedContent.includes('</html>')); | |
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 | |
<p>This is a test page.</p> | |
</body> | |
======= REPLACE | |
<p>This is a test page.</p> | |
<h2>Contact Us</h2> | |
<form> | |
<div> | |
<label for="name">Name:</label> | |
<input type="text" id="name" name="name" required> | |
</div> | |
<div> | |
<label for="email">Email:</label> | |
<input type="email" id="email" name="email" required> | |
</div> | |
<div> | |
<label for="message">Message:</label> | |
<textarea id="message" name="message" rows="4" required></textarea> | |
</div> | |
<button type="submit">Send</button> | |
</form> | |
</body> | |
>>>>>>> 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('<h2>Contact Us</h2>') && | |
responseText.includes('<form>') && | |
responseText.includes('</form>'); | |
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()'); | |
} |