UNPKG

jasmine-bamboo-reporter

Version:

A reporter for Jasmine which produces a report compatible with Atlassian Bamboo Mocha Test Parser.

178 lines 5.41 kB
// src/index.ts import fs from "fs"; function format(result) { const msg = []; let counter = 1; let formatted; if (result.failedExpectations.length === 1) { formatted = "1 Failure: "; } else { formatted = `${result.failedExpectations.length} Failures: `; } result.failedExpectations.forEach(function iterator(expectation) { msg.push(`${counter}. : ${expectation.message}`); counter++; }); formatted += msg.join("\n"); return formatted; } function shallowMerge(obj1, obj2) { const mergedObj = {}; Object.keys(obj1).forEach(function iterator(key) { if (!obj2[key]) { mergedObj[key] = obj1[key]; } else { mergedObj[key] = obj2[key]; } }); return mergedObj; } function sleep(ms) { Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms); } function acquireLock(lockPath, waitMs) { const deadline = Date.now() + waitMs; for (; ; ) { try { fs.closeSync(fs.openSync(lockPath, "wx")); return true; } catch (err) { if (err.code !== "EEXIST") { throw err; } if (Date.now() >= deadline) { return false; } sleep(100); } } } function releaseLock(lockPath) { try { fs.unlinkSync(lockPath); } catch (err) { if (err.code !== "ENOENT") { throw err; } } } var Reporter = class { options; spec; specStart; output; constructor(opts) { const defaultOpts = { file: "jasmine.json", beautify: true, indentationLevel: 4 }; this.options = shallowMerge( defaultOpts, typeof opts === "object" ? opts : {} ); this.spec = {}; this.specStart = 0; this.output = { stats: { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0, start: 0, // this is the overall time for everything. - all suites. end: 0, duration: 0, time: 0 // bamboo + mocha seem to be using "time", not duration. }, failures: [], passes: [], skipped: [] }; } suiteDone() { this.output.stats.suites++; } specStarted() { this.specStart = /* @__PURE__ */ new Date(); } specDone(result) { this.spec.duration = Math.floor( (Date.now() - this.specStart.getTime()) / 1e3 ); this.spec.time = this.spec.duration; this.spec.title = result.fullName; this.spec.fullTitle = result.description; this.output.stats.tests++; if (result.status === "passed") { this.output.stats.passes++; this.output.passes.push(this.spec); } else if (result.status === "failed") { this.output.stats.failures++; this.spec.error = format(result); this.output.failures.push(this.spec); } else { this.output.stats.pending++; this.output.skipped.push(this.spec); } this.spec = {}; } jasmineStarted() { this.output.stats.start = /* @__PURE__ */ new Date(); } mergeOutput(previous) { this.output.stats.suites = this.output.stats.suites + previous.stats.suites; this.output.stats.tests = this.output.stats.tests + previous.stats.tests; this.output.stats.passes = this.output.stats.passes + previous.stats.passes; this.output.stats.pending = this.output.stats.pending + previous.stats.pending; this.output.stats.failures = this.output.stats.failures + previous.stats.failures; this.output.start = previous.start; this.output.failures = this.output.failures.concat(previous.failures); this.output.passes = this.output.passes.concat(previous.passes); this.output.skipped = this.output.skipped.concat(previous.skipped); } // jasmineDone gets called multiple times, once for each process (thread) we are executing. Normally this would // just be one thread, but protractor can "shard" tests which really just runs multiple processes with one // to rule them all. // // Since that code is running in separate processes, it isn't easy to use a global/static class variable to // handle a single instance of the jasmine reporter - nor is it easy to aggregate the results. So the trick here // is to lock, read any file that exists, merge, write results to file, and then release lock. jasmineDone() { const lockname = `${this.options.file}.lock`; this.output.stats.end = /* @__PURE__ */ new Date(); if (!acquireLock(lockname, 2e3)) { console.error( `Jasmine bamboo reporter unable to acquire a file lock for ${lockname}` ); return; } try { if (fs.existsSync(this.options.file)) { const raw = fs.readFileSync(this.options.file, { encoding: "utf8" }); const previous = JSON.parse(raw); this.mergeOutput(previous); } this.output.stats.duration = Math.floor( (this.output.stats.end.getTime() - this.output.stats.start.getTime()) / 1e3 ); this.output.stats.time = this.output.stats.duration; const resultsOutput = this.options.beautify ? JSON.stringify(this.output, null, this.options.indentationLevel) : JSON.stringify(this.output); fs.writeFileSync(this.options.file, resultsOutput); } finally { try { releaseLock(lockname); } catch { console.error( `Jasmine bamboo reporter could not unlock file ${lockname}` ); } } } }; export { Reporter as default }; //# sourceMappingURL=index.mjs.map