Node.js Quickstart
Create a job, wait for a human tester, and print a structured bug report — in ~60 lines of JavaScript with no runtime dependencies (uses native fetch, Node 18+).
Setup
# Clone git clone https://github.com/ErlisK/openclaw-workspace cd openclaw-workspace/startup-87-betawindow-human-in-the-loop-e2e-testing-for-ai-built/examples/node-quickstart # No dependencies to install (uses native fetch) export AGENTQA_TOKEN="eyJ..." export APP_URL="https://your-app.vercel.app" node index.js
Full source
/**
* BetaWindow — Node.js Quickstart
* Create a job, poll until done, print the report.
*
* export AGENTQA_TOKEN="eyJ..."
* export APP_URL="https://your-app.vercel.app"
* node index.js
*/
const BASE_URL = process.env.AGENTQA_BASE_URL
|| 'https://betawindow.com'
const TOKEN = process.env.AGENTQA_TOKEN
const headers = { 'Authorization': `Bearer ${TOKEN}`, 'Content-Type': 'application/json' }
async function createJob({ url, tier, title, instructions }) {
const res = await fetch(`${BASE_URL}/api/jobs`, {
method: 'POST', headers,
body: JSON.stringify({ url, tier, title, instructions }),
})
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`)
return res.json()
}
async function pollJob(jobId, intervalMs = 10_000, timeoutMs = 30 * 60_000) {
const start = Date.now()
while (Date.now() - start < timeoutMs) {
const res = await fetch(`${BASE_URL}/api/jobs/${jobId}`, { headers })
const job = await res.json()
process.stdout.write(`\r Status: ${job.status}`)
if (job.status === 'complete' || job.status === 'cancelled') return job
if (job.status === 'failed') throw new Error(job.error)
await new Promise(r => setTimeout(r, intervalMs))
}
throw new Error('Timeout')
}
async function main() {
const job = await createJob({
url: process.env.APP_URL,
tier: 'quick', // quick | standard | deep
title: 'Smoke test',
instructions: 'Load homepage, sign up, verify dashboard loads.',
})
console.log('Job created:', job.id)
const done = await pollJob(job.id)
console.log('\nRating:', done.rating, '/ 5')
console.log('Summary:', done.summary)
if (done.bugs?.length > 0) {
console.log('Bugs:')
done.bugs.forEach(b => console.log(` [${b.severity}] ${b.title}`))
process.exit(1) // fail CI on bugs
}
}
main().catch(e => { console.error(e.message); process.exit(1) })What it does
- Creates a
quicktier job (10 min, $5) - Polls every 10 seconds until the session completes
- Prints rating, summary, and bug list
- Exits 1 if any bugs are found (CI-friendly)
CI integration
# .github/workflows/qa.yml
- name: Human QA
env:
AGENTQA_TOKEN: ${{ secrets.AGENTQA_TOKEN }}
APP_URL: ${{ steps.deploy.outputs.url }}
run: node examples/node-quickstart/index.jsNext steps
- TypeScript pipeline — typed client + quality gate assertions
- Webhook receiver — get notified async instead of polling
- Sample report — see what the completed job looks like
- Full API reference