async function makeRequest(test) { const apiUrl = document.getElementById('apiUrl').value; const endpoint = typeof test.endpoint === 'function' ? test.endpoint() : test.endpoint; const url = `${apiUrl}${endpoint}`; const options = { method: test.method, headers: { 'Content-Type': 'application/json', } }; if (test.auth && authToken) { options.headers['Authorization'] = `Bearer ${authToken}`; } if (test.body) { options.body = JSON.stringify(typeof test.body === 'function' ? test.body() : test.body); } const response = await fetch(url, options); const data = await response.json().catch(() => ({})); return { data, status: response.status }; } async function runTest(categoryIdx, testIdx) { const test = tests[categoryIdx].tests[testIdx]; const testId = `test-${categoryIdx}-${testIdx}`; const testEl = document.getElementById(testId); const contentEl = document.getElementById(`${testId}-content`); const toggleEl = document.getElementById(`${testId}-toggle`); const resultEl = testEl.querySelector('.test-result'); if (test.skip && test.skip()) { testEl.querySelector('.test-status').textContent = 'SKIPPED'; testEl.querySelector('.test-status').className = 'test-status pending'; resultEl.style.display = 'block'; resultEl.className = 'test-result'; resultEl.innerHTML = '⚠️ Prerequisites not met'; return 'skip'; } testEl.className = 'test-case running'; testEl.querySelector('.test-status').textContent = 'RUNNING'; testEl.querySelector('.test-status').className = 'test-status running'; resultEl.style.display = 'none'; try { const { data, status } = await makeRequest(test); const expectFail = test.expectFail || false; const passed = test.expect(data, status); const success = expectFail ? !passed || status >= 400 : passed; testEl.className = success ? 'test-case pass' : 'test-case fail'; testEl.querySelector('.test-status').textContent = success ? 'PASS' : 'FAIL'; testEl.querySelector('.test-status').className = `test-status ${success ? 'pass' : 'fail'}`; // Determine status code class let statusClass = 'status-5xx'; if (status >= 200 && status < 300) statusClass = 'status-2xx'; else if (status >= 300 && status < 400) statusClass = 'status-3xx'; else if (status >= 400 && status < 500) statusClass = 'status-4xx'; // Check expected fields if defined let expectedFieldsHTML = ''; if (test.expectedFields) { const fieldChecks = test.expectedFields.map(field => { const exists = field.split('.').reduce((obj, key) => obj?.[key], data) !== undefined; const icon = exists ? '✓' : '✗'; const className = exists ? 'pass' : 'fail'; return `
${icon} ${field}
`; }).join(''); expectedFieldsHTML = `
Expected Fields:
${fieldChecks}
`; } resultEl.style.display = 'block'; resultEl.className = 'test-result'; resultEl.innerHTML = `
HTTP ${status} ${success ? '✓ Test passed' : '✗ Test failed'}
${expectedFieldsHTML}
Response:
${JSON.stringify(data, null, 2)}
`; if (success && test.onSuccess) { test.onSuccess(data); } return success ? 'pass' : 'fail'; } catch (error) { testEl.className = 'test-case fail'; testEl.querySelector('.test-status').textContent = 'ERROR'; testEl.querySelector('.test-status').className = 'test-status fail'; resultEl.style.display = 'block'; resultEl.className = 'test-error'; resultEl.innerHTML = `
❌ Network/Request Error
${error.message}
${error.stack ? `
${error.stack}
` : ''} `; return 'fail'; } } async function runAllTests(event) { resetState(); const button = event.target; button.disabled = true; button.textContent = '⏳ Running Tests...'; let totalTests = 0; let passedTests = 0; let failedTests = 0; for (let i = 0; i < tests.length; i++) { for (let j = 0; j < tests[i].tests.length; j++) { const result = await runTest(i, j); if (result !== 'skip') { totalTests++; if (result === 'pass') passedTests++; if (result === 'fail') failedTests++; } } } document.getElementById('summary').style.display = 'flex'; document.getElementById('totalTests').textContent = totalTests; document.getElementById('passedTests').textContent = passedTests; document.getElementById('failedTests').textContent = failedTests; button.disabled = false; button.textContent = '▶ Run All Tests'; }