@ivamuno/cypress-api-coverage
Version:
Cypress plugin to generate API coverage reports
2 lines • 6.06 kB
JavaScript
(()=>{"use strict";var e={n:t=>{var r=t&&t.__esModule?()=>t.default:()=>t;return e.d(r,{a:r}),r},d:(t,r)=>{for(var i in r)e.o(r,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:r[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{ensureBrowserFlags:()=>u.ensureBrowserFlags,install:()=>f});const r=require("tslib"),i=require("@redocly/openapi-core"),o=require("chalk");var s=e.n(o);const n=require("path"),a=require("util");class l{constructor(){this._debug=(0,a.debuglog)("cypress-har-generator")}static get Instance(){return this._instance||(this._instance=new l),this._instance}info(e){this.log(e)}err(e){this.log(JSON.stringify(e,null,2))}warn(e){this.log(e)}debug(e){this._debug(e)}log(e){console.log(e)}}const d=require("fs");class c{static get Instance(){return this._instance||(this._instance=new c),this._instance}readDir(e){return(0,r.__awaiter)(this,void 0,void 0,(function*(){try{return yield(0,a.promisify)(d.readdir)(e)}catch(e){return l.Instance.err(e),[]}}))}readFile(e){return(0,r.__awaiter)(this,void 0,void 0,(function*(){try{return yield(0,a.promisify)(d.readFile)(e,{encoding:"utf-8"})}catch(e){return void l.Instance.err(e)}}))}writeFile(e,t){return(0,r.__awaiter)(this,void 0,void 0,(function*(){try{yield this.removeFile(e),yield(0,a.promisify)(d.writeFile)(e,t)}catch(e){l.Instance.err(e)}}))}appendFile(e,t){return(0,r.__awaiter)(this,void 0,void 0,(function*(){try{yield(0,a.promisify)(d.appendFile)(e,t)}catch(e){l.Instance.err(e)}}))}createFolder(e){return(0,r.__awaiter)(this,void 0,void 0,(function*(){try{if(yield this.exists(e))return;yield(0,a.promisify)(d.mkdir)(e)}catch(e){l.Instance.err(e)}}))}removeFile(e){return(0,r.__awaiter)(this,void 0,void 0,(function*(){try{(yield this.exists(e))&&(yield(0,a.promisify)(d.unlink)(e))}catch(e){l.Instance.err(e)}}))}exists(e){return(0,r.__awaiter)(this,void 0,void 0,(function*(){try{return yield(0,a.promisify)(d.access)(e,d.constants.F_OK),!0}catch(e){return!1}}))}}const u=require("@neuralegion/cypress-har-generator");var h=e.n(u);const p=new class{constructor(e){this.fileManager=e,this.separator="#_#",this.defaultOutputName="api-coverage",this.defaultThresholds={ok:70,warning:50}}saveApiRequests(e){return(0,r.__awaiter)(this,void 0,void 0,(function*(){const t=e.outDir,r=e.fileName,i=(0,n.join)(t,r);this.fileManager.writeFile(i,JSON.stringify(e.log,null,2))}))}computeCoverage(e){return(0,r.__awaiter)(this,void 0,void 0,(function*(){const t=yield this.normalizeHar(e),r=yield this.parseSpecs(e.specsPath);this.computeCoverageResult(t,r);const i=(0,n.join)(e.outDir,(e.outputName||this.defaultOutputName)+".json");yield this.fileManager.writeFile(i,JSON.stringify(r,null,2)),yield this.writeReport(e,r),this.displayReport(r.coverage)}))}normalizeHar(e){var t;return(0,r.__awaiter)(this,void 0,void 0,(function*(){const r=(yield this.fileManager.readDir(e.outDir)).filter((e=>e.endsWith(".har"))),i=[];for(const o of r){const r=yield this.fileManager.readFile((0,n.join)(e.outDir,o));if(!r)continue;const s=JSON.parse(r).log.entries;for(const r of s){const o=null!==(t=r.request.url.split("?")[0])&&void 0!==t?t:"";for(const t of e.includeHosts)if(o.startsWith(t.host)){const e=r.request.method,s=this.buildOperation(o.replace(t.host,t.replacement||""),e);i.includes(s)||i.push(s);break}}}return i}))}parseSpecs(e){return(0,r.__awaiter)(this,void 0,void 0,(function*(){const t=yield(0,i.loadConfig)(),r=(yield(0,i.bundle)({ref:e,config:t})).bundle.parsed.paths||{},o={paths:{},coverage:{total:0,totalCovered:0}};for(const e of Object.keys(r)){const t=r[e];o.paths[e]={coverage:{total:0,totalCovered:0},verbs:{}};for(const r of Object.keys(t)){const t=r.toUpperCase(),i=this.buildOperation(e,t);o.paths[e].verbs[t]={pattern:new RegExp(i.replace(/\{[^}]*\}/g,"[^/]+")),covered:!1},o.paths[e].coverage.total+=1,o.coverage.total+=1}}return o}))}computeCoverageResult(e,t){for(const r of Object.keys(t.paths)){const i=t.paths[r].verbs;for(const o of Object.keys(i)){const s=o.toUpperCase();e.find((e=>i[s].pattern.test(e)))&&(t.paths[r].verbs[s].covered=!0,t.paths[r].coverage.totalCovered+=1,t.coverage.totalCovered+=1)}}}buildOperation(e,t){return`${e}${this.separator}${t}`}appendLine(e,t){return(0,r.__awaiter)(this,void 0,void 0,(function*(){yield this.fileManager.appendFile(e,t)}))}appendProgress(e,t){return(0,r.__awaiter)(this,void 0,void 0,(function*(){const r=Math.round(t.totalCovered/t.total*100),i=r>=this.defaultThresholds.ok?"5cb85c":r>=this.defaultThresholds.warning?"f0ad4e":"d9534f";yield this.appendLine(e,`\r\n\r\n`)}))}writeReport(e,t){return(0,r.__awaiter)(this,void 0,void 0,(function*(){const r=(0,n.join)(e.outDir,(e.outputName||this.defaultOutputName)+".md");yield this.fileManager.writeFile(r,""),yield this.appendLine(r,`# ${e.suiteName}\r\n\r\n`),yield this.appendLine(r,"## Total:\r\n"),yield this.appendProgress(r,t.coverage),yield this.appendLine(r,"## Channels:\r\n");for(const e of Object.keys(t.paths))yield this.appendLine(r,`### ${e}\r\n`),yield this.appendProgress(r,t.paths[e].coverage)}))}displayReport(e){const t=Math.round(e.totalCovered/e.total*100),r=`${t}%`;console.log(s().bold("\n\nCoverage Report")),console.log(s().bold("Total:"),t>=this.defaultThresholds.ok?s().green(r):t>=this.defaultThresholds.warning?s().yellow(r):s().red(r))}}(c.Instance),f=e=>{(0,u.install)(e),e("task",{saveApiRequestsTask:e=>(0,r.__awaiter)(void 0,void 0,void 0,(function*(){return yield p.saveApiRequests(e),null})),computeCoverageTask:e=>(0,r.__awaiter)(void 0,void 0,void 0,(function*(){return yield p.computeCoverage(e),null}))}),e("before:browser:launch",((e,t)=>(h().ensureBrowserFlags(null!=e?e:{},t),t)))};var v=exports;for(var y in t)v[y]=t[y];t.__esModule&&Object.defineProperty(v,"__esModule",{value:!0})})();
//# sourceMappingURL=index.js.map