UNPKG

check-tests

Version:

Static analysis for tests. Prints all tests in console and fails when exclusive or skipped tests found.

205 lines (169 loc) 6 kB
const URL = process.env.TESTOMATIO_URL || 'https://app.testomat.io'; const isHttps = URL.startsWith('https'); const debug = require('debug')('testomatio:ids'); const { request } = isHttps ? require('https') : require('http'); const path = require('path'); const fs = require('fs'); class Reporter { constructor(apiKey, framework) { if (!framework) { console.error('Framework cannot be empty'); } if (!apiKey) { console.error('Cant send report, api key not set'); } this.apiKey = apiKey; this.framework = framework; this.tests = []; this.files = {}; } addTests(tests) { this.tests = this.tests.concat(tests); } attachFiles() { this.files = {}; const uniqueFiles = [...new Set(this.tests.map(test => test.file).filter(f => !!f))]; for (const fileName of uniqueFiles) { try { this.files[fileName] = fs.readFileSync(path.resolve(fileName), 'utf8'); } catch (err) { debug(`Error reading file ${fileName}: ${err.message}`); } } } getFilesFromServer() { return new Promise((res, rej) => { debug('Getting files from Testomat.io...'); const req = request( `${URL.trim()}/api/test_data?with_files=true&api_key=${this.apiKey}`, { method: 'GET' }, resp => { // The whole response has been received. Print out the result. let message = ''; resp.on('end', () => { debug('Files fetched from Testomat.io', message); if (resp.statusCode !== 200) { debug('Files fetch failed', resp.statusCode, resp.statusMessage, message); rej(message); } else { res(JSON.parse(message)); } }); resp.on('data', chunk => { message += chunk.toString(); }); resp.on('aborted', () => { console.log(' ✖️ Files were not fetched from Testomat.io'); }); }, ); req.on('error', err => { console.log(`Error: ${err.message}`); rej(err); }); req.end(); }); } parseLabels(labelsString) { if (!labelsString) return []; // Handle comma-separated values like "label1,label2,label3" return labelsString .split(',') .map(label => label.trim()) .filter(label => label.length > 0); } getIds() { return new Promise((res, rej) => { debug('Getting ids from Testomat.io...'); const req = request(`${URL.trim()}/api/test_data?api_key=${this.apiKey}`, { method: 'GET' }, resp => { // The whole response has been received. Print out the result. let message = ''; resp.on('end', () => { debug('Data fetched from Testomat.io', message); if (resp.statusCode !== 200) { debug('Data fetch failed', resp.statusCode, resp.statusMessage, message); rej(message); } else { res(JSON.parse(message)); } }); resp.on('data', chunk => { message += chunk.toString(); }); resp.on('aborted', () => { console.log(' ✖️ Data was not sent to Testomat.io'); }); }); req.on('error', err => { console.log(`Error: ${err.message}`); rej(err); }); req.end(); }); } send(opts = {}) { return new Promise((resolve, reject) => { console.log('\n 🚀 Sending data to testomat.io\n'); // Parse labels from environment variable (supports both TESTOMATIO_LABELS and TESTOMATIO_SYNC_LABELS) const labelsFromEnv = this.parseLabels(process.env.TESTOMATIO_LABELS || process.env.TESTOMATIO_SYNC_LABELS); const tests = this.tests.map(test => { // make file path relative to TESTOMATIO_WORKDIR if provided if (process.env.TESTOMATIO_WORKDIR && test.file) { const workdir = path.resolve(process.env.TESTOMATIO_WORKDIR); const absoluteTestPath = path.resolve(test.file); test.file = path.relative(workdir, absoluteTestPath); } // unify path to use slashes (prevent backslashes on windows) test.file = test.file?.replace(/\\/g, '/'); // Apply labels to each test if (labelsFromEnv.length > 0) { test.labels = labelsFromEnv; } return test; }); this.tests = tests; if (process.env.TESTOMATIO_PREPEND_DIR) opts.dir = process.env.TESTOMATIO_PREPEND_DIR; if (process.env.TESTOMATIO_SUITE) opts.suite = process.env.TESTOMATIO_SUITE; this.attachFiles(); const data = JSON.stringify({ ...opts, tests: this.tests, framework: this.framework, files: this.files }); debug('Sending test data to Testomat.io', data); const req = request( `${URL.trim()}/api/load?api_key=${this.apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data), }, }, resp => { // The whole response has been received. Print out the result. let message = ''; resp.on('end', () => { if (resp.statusCode >= 400) { console.log(' ✖️ ', message, `(${resp.statusCode}: ${resp.statusMessage})`); } else { console.log(' 🎉 Data received at Testomat.io'); } resolve(); }); resp.on('data', chunk => { message += chunk.toString(); }); resp.on('aborted', () => { console.log(' ✖️ Data was not sent to Testomat.io'); // eslint-disable-next-line prefer-promise-reject-errors reject('aborted'); }); }, ); req.on('error', err => { console.log(`Error: ${err.message}`); reject(err); }); req.write(data); req.end(); }); } } module.exports = Reporter;