UNPKG

haven-playwright-integration

Version:

Seamless Playwright integration with HAVEN test case management

94 lines (83 loc) 4 kB
const fs = require('fs'); const path = require('path'); const https = require('https'); // Shared paths provided by HAVEN runner const automationCasesPath = "/shared/automation-cases.json"; const postBaseUrlPath = "/shared/result-post-url.txt"; const triggeredByPath = "/shared/triggered-by.txt"; const baseUrl = fs.readFileSync(postBaseUrlPath, "utf-8").trim(); let triggeredBy = null; try { if (fs.existsSync(triggeredByPath)) triggeredBy = fs.readFileSync(triggeredByPath, 'utf-8').trim(); } catch { } function parsePlaywrightJson(jsonPath) { if (!jsonPath || !fs.existsSync(jsonPath)) return []; const data = JSON.parse(fs.readFileSync(jsonPath, 'utf-8')); const results = []; // Playwright JSON format: look into tests/suites function walk(node) { if (!node) return; if (node.title && typeof node.title === 'string') { const m = node.title.match(/@TC-AUTO-\d+/); if (m) { const status = (node.status || node.outcome || 'passed').toLowerCase().includes('pass') ? 'pass' : (node.status || 'fail'); results.push({ automation_id: m[0], status }); } } for (const key of ['suites', 'tests', 'specs', 'entries', 'children']) { const arr = node[key]; if (Array.isArray(arr)) arr.forEach(walk); } } walk(data); return results; } async function postJson(url, payload) { return new Promise((resolve, reject) => { const data = JSON.stringify(payload); const req = https.request(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) } }, res => { let body = ''; res.on('data', c => body += c); res.on('end', () => resolve({ statusCode: res.statusCode, body })); }); req.on('error', reject); req.write(data); req.end(); }); } async function main() { const planId = process.env.PLAN_ID || 'unknown_plan'; const runId = process.env.RUN_ID || 'unknown_run'; const testEnvironment = process.env.TEST_ENVIRONMENT || 'QA'; const jsonReportPath = process.argv[2]; const formattedResults = parsePlaywrightJson(jsonReportPath); console.log(`Looking for results in: ${jsonReportPath}`); console.log(`📄 Found ${formattedResults.length} result(s).`); // not_found from automation-cases.json (optional) let notFoundList = []; try { const automationCases = JSON.parse(fs.readFileSync(automationCasesPath, 'utf-8')); const expected = new Set((automationCases || []).map(a => a.automation_id)); const found = new Set(formattedResults.map(r => r.automation_id)); notFoundList = [...expected].filter(id => !found.has(id)); } catch { } const resultsUrl = baseUrl; // already full endpoint const payload = { planId, runId, environment: testEnvironment, results: formattedResults, not_found: notFoundList, triggered_by: triggeredBy }; console.log('📤 Posting result payload:', JSON.stringify(payload, null, 2)); console.log(`🔗 Posting to URL: ${resultsUrl}`); try { const res = await postJson(resultsUrl, payload); console.log('✅ Post status:', res.statusCode, res.body); } catch (e) { console.error('❌ Failed to post results:', e.message); } // Post summary const summaryUrl = baseUrl.replace('/api/test-results', '/api/test-run-summary'); const summary = { planId, runId, environment: testEnvironment, total: formattedResults.length, passed: formattedResults.filter(r => r.status === 'pass').length }; console.log(`📤 Posting summary to: ${summaryUrl}`); try { const res = await postJson(summaryUrl, summary); console.log('✅ Summary status:', res.statusCode, res.body); } catch (e) { console.error('❌ Failed to post summary:', e.message); } } main().catch(e => { console.error(e); process.exit(1); });