UNPKG

mocha-multiple-sessions-detailed-runner

Version:
3 lines (2 loc) 19.1 kB
var MultiSessionDetailedRunner=function(e){"use strict";class t{constructor(){this.sessions=new Map}save(e){this.sessions.set(e.label,e)}findByLabel(e){return this.sessions.get(e)||null}findAll(){return Array.from(this.sessions.values())}delete(e){return this.sessions.delete(e)}clear(){this.sessions.clear()}exists(e){return this.sessions.has(e)}updateState(e,t){const s=this.sessions.get(e);s&&Object.assign(s,t)}getStates(){const e={};return this.sessions.forEach(((t,s)=>{e[s]={label:t.label,status:t.status,...t.timestamp&&{timestamp:t.timestamp},...t.duration&&{duration:t.duration}}})),e}markAsRunning(e){this.updateState(e,{status:"running",timestamp:new Date})}markAsCompleted(e,t){this.updateState(e,{status:"passed",timestamp:new Date,duration:t.duration})}markAsFailed(e,t){const s=this.sessions.get(e);s&&(s.status="failed",s.error=t,s.timestamp=new Date)}getByStatus(e){return this.findAll().filter((t=>t.status===e))}getExecutionSummary(){const e=this.findAll(),t=e.reduce(((e,t)=>t.timestamp&&(!e||t.timestamp>e)?t.timestamp:e),void 0);return{totalSessions:e.length,readySessions:e.filter((e=>"ready"===e.status)).length,runningSessions:e.filter((e=>"running"===e.status)).length,completedSessions:e.filter((e=>"passed"===e.status)).length,failedSessions:e.filter((e=>"failed"===e.status)).length,...t&&{lastExecutionTime:t}}}}class s{constructor(){this.PREFIX="mochaSession__"}generateResultKey(e){return`${this.PREFIX}${e.replace(/\s+/g,"_").replace(/-/g,"_")}`}getReportData(e){return this.getWindowVariable(e)}hasReport(e){return void 0!==this.getWindowVariable(e)}clearReport(e){this.deleteWindowVariable(e)}getAllReports(){const e={};for(const t in window)if(t.startsWith(this.PREFIX)){const s=this.getWindowVariable(t);s&&(e[t]=s)}return e}getReportMetadata(e){const t=this.getReportData(e);if(!t)return null;const s=e.replace(this.PREFIX,"").replace(/_/g,"-");return{size:JSON.stringify(t).length,generatedAt:t.timestamp?new Date(t.timestamp):new Date,sessionLabel:s,stats:t.stats||{},isValid:this.validateReport(t)}}async waitForReport(e,t=3e4){return new Promise(((s,i)=>{const n=Date.now(),r=setInterval((()=>{const o=this.getReportData(e);if(o)return clearInterval(r),void s(o);Date.now()-n>t&&(clearInterval(r),i(new Error(`Timeout waiting for report: ${e}`)))}),100)}))}watchReport(e,t){let s=!0;const i=setInterval((()=>{if(!s)return void clearInterval(i);const n=this.getReportData(e);n&&(t(n),clearInterval(i),s=!1)}),100);return()=>{s=!1,clearInterval(i)}}getWindowVariable(e){return window[e]}setWindowVariable(e,t){window[e]=t}deleteWindowVariable(e){delete window[e]}getReportSize(e){const t=this.getReportData(e);return t?JSON.stringify(t).length:0}validateReport(e){return!(!e||"object"!=typeof e)&&!(!e.stats||"object"!=typeof e.stats||"number"!=typeof e.stats.tests)}}class i{constructor(){this.runnerListeners=new Map,this.sessionListeners=new Map,this.anyEventListeners=new Set,this.eventHistory=[],this.maxHistorySize=1e3}emitRunnerEvent(e){this.addToHistory(e);const t=this.runnerListeners.get(e.type);t&&t.forEach((t=>{try{t(e)}catch(e){console.error("Error in runner event listener:",e)}})),this.anyEventListeners.forEach((t=>{try{t(e)}catch(e){console.error("Error in universal event listener:",e)}}))}onRunnerEvent(e,t){return this.runnerListeners.has(e)||this.runnerListeners.set(e,new Set),this.runnerListeners.get(e).add(t),()=>{const s=this.runnerListeners.get(e);s&&(s.delete(t),0===s.size&&this.runnerListeners.delete(e))}}emitSessionEvent(e){this.addToHistory(e);const t=this.sessionListeners.get(e.type);t&&t.forEach((t=>{try{t(e)}catch(e){console.error("Error in session event listener:",e)}})),this.anyEventListeners.forEach((t=>{try{t(e)}catch(e){console.error("Error in universal event listener:",e)}}))}onSessionEvent(e,t){return this.sessionListeners.has(e)||this.sessionListeners.set(e,new Set),this.sessionListeners.get(e).add(t),()=>{const s=this.sessionListeners.get(e);s&&(s.delete(t),0===s.size&&this.sessionListeners.delete(e))}}onAnyEvent(e){return this.anyEventListeners.add(e),()=>{this.anyEventListeners.delete(e)}}getEventHistory(e){let t=[...this.eventHistory];return e&&(e.eventTypes&&(t=t.filter((t=>e.eventTypes.includes(t.type)))),e.sessionLabel&&(t=t.filter((t=>"sessionLabel"in t&&t.sessionLabel===e.sessionLabel))),e.timeRange&&(t=t.filter((t=>{const s=new Date(t.timestamp);return s>=e.timeRange.start&&s<=e.timeRange.end}))),e.maxEvents&&(t=t.slice(-e.maxEvents))),t}clearEventHistory(){this.eventHistory=[]}hasListeners(e){return e?(this.runnerListeners.get(e)?.size||0)>0||(this.sessionListeners.get(e)?.size||0)>0:this.runnerListeners.size>0||this.sessionListeners.size>0||this.anyEventListeners.size>0}getListenerCount(e){if(!e){let e=this.anyEventListeners.size;return this.runnerListeners.forEach((t=>e+=t.size)),this.sessionListeners.forEach((t=>e+=t.size)),e}return(this.runnerListeners.get(e)?.size||0)+(this.sessionListeners.get(e)?.size||0)}destroy(){this.runnerListeners.clear(),this.sessionListeners.clear(),this.anyEventListeners.clear(),this.eventHistory=[]}addToHistory(e){this.eventHistory.push(e),this.eventHistory.length>this.maxHistorySize&&(this.eventHistory=this.eventHistory.slice(-this.maxHistorySize))}}class n{constructor(){this.isConfiguredFlag=!1,this.currentConfig=null}setupTestEnvironment(e){this.validateEnvironment();const t={createMochaInstance:t=>{const s=e.windowVariablePrefix+t.replace(/\s+/g,"_").replace(/-/g,"_");if(!window.MochaDetailedReporter)throw new Error("MochaDetailedReporter not available");return new window.Mocha({ui:"bdd",reporter:window.MochaDetailedReporter.DetailedJsonReporter,reporterOptions:{outputToWindow:"true",windowVariableName:s,captureConsoleLog:e.captureConsoleLog?"true":"false",sourceCode:e.sourceCode?"true":"false",attachStats:e.attachStats?"true":"false"}})},injectGlobals:e=>{e.suite.emit("pre-require",window,null,e),window.chai&&(window.expect=window.chai.expect)}},s={createMochaInstance:e.createMochaInstance||t.createMochaInstance,injectGlobals:e.injectGlobals||t.injectGlobals};if(!window.MochaMultipleSessions?.testSessionSetup)throw new Error("MochaMultipleSessions library not available");window.MochaMultipleSessions.testSessionSetup(s),this.currentConfig=s,this.isConfiguredFlag=!0}isConfigured(){return this.isConfiguredFlag}getConfiguration(){return this.currentConfig}integrateWithExistingLibrary(){if(!window.MochaMultipleSessions)throw new Error("MochaMultipleSessions library not found")}setupDefaultReporter(e){const t=`mochaSession__${e.replace(/\s+/g,"_").replace(/-/g,"_")}`;if(!window.MochaDetailedReporter)throw new Error("MochaDetailedReporter not available");return new window.Mocha({ui:"bdd",reporter:window.MochaDetailedReporter.DetailedJsonReporter,reporterOptions:{outputToWindow:"true",windowVariableName:t,captureConsoleLog:"true",sourceCode:"true",attachStats:"true"}})}bridgeSessionEvents(){}validateEnvironment(){const e=[],t=[],s=[],i=this.checkDependencies();i.mocha||(e.push("Mocha library not found"),s.push("mocha")),i.chai||(t.push("Chai library not found - tests may not work properly"),s.push("chai")),i.detailedReporter||(e.push("MochaDetailedReporter not found"),s.push("mocha-detailed-json-reporter")),i.multipleSessionsLibrary||(e.push("MochaMultipleSessions library not found"),s.push("mocha-multiple-sessions-ts"));const n={isValid:0===e.length,errors:e,warnings:t,missingDependencies:s};if(!n.isValid)throw new Error(`Environment validation failed: ${e.join(", ")}`);return n}checkDependencies(){return{mocha:void 0!==window.Mocha&&void 0!==window.mocha,chai:void 0!==window.chai,detailedReporter:void 0!==window.MochaDetailedReporter,multipleSessionsLibrary:void 0!==window.MochaMultipleSessions,reporterUI:void 0!==window.MochaDetailedReporterUI}}}class r{constructor(e,t,s){this.reportRepository=e,this.sessionRepository=t,this.eventBus=s}getSessionReport(e){const t=this.sessionRepository.findByLabel(e);if(!t)return null;const s=this.reportRepository.getReportData(t.resultKey);if(!s)return null;return{data:s,stats:s.stats||{tests:0,passes:0,failures:0,pending:0},timestamp:s.timestamp?new Date(s.timestamp):new Date,sessionLabel:e,size:JSON.stringify(s).length}}async waitForSessionReport(e,t=3e4){const s=this.sessionRepository.findByLabel(e);if(!s)throw new Error(`Session '${e}' not found`);const i=await this.reportRepository.waitForReport(s.resultKey,t);return{data:i,stats:i.stats||{tests:0,passes:0,failures:0,pending:0},timestamp:i.timestamp?new Date(i.timestamp):new Date,sessionLabel:e,size:JSON.stringify(i).length}}hasSessionReport(e){const t=this.sessionRepository.findByLabel(e);return!!t&&this.reportRepository.hasReport(t.resultKey)}generateCombinedReport(){const e=this.sessionRepository.findAll(),t={};let s=0,i=0,n=0,r=0,o=0,a=0;for(const l of e){const e=this.getSessionReport(l.label);e&&(t[l.label]=e,s+=e.stats.tests,i+=e.stats.passes,n+=e.stats.failures,r+=e.stats.pending,0===e.stats.failures?o++:a++)}const l={generatedAt:(new Date).toISOString(),summary:{totalTests:s,totalPasses:i,totalFailures:n,totalPending:r,totalSessions:e.length,successfulSessions:o,failedSessions:a},sessions:t};return this.eventBus.emitRunnerEvent({type:"runner:combined-report-generated",timestamp:new Date,data:{reportType:"combined",totalSessions:e.length,reportSize:JSON.stringify(l).length,generatedAt:new Date,summary:l.summary}}),l}async getCombinedReportAsync(){return this.generateCombinedReport()}watchSessionReport(e,t){const s=this.sessionRepository.findByLabel(e);if(!s)throw new Error(`Session '${e}' not found`);return this.reportRepository.watchReport(s.resultKey,(s=>{const i={data:s,stats:s.stats||{tests:0,passes:0,failures:0,pending:0},timestamp:s.timestamp?new Date(s.timestamp):new Date,sessionLabel:e,size:JSON.stringify(s).length};t(i)}))}watchAllReports(e){const t=[],s=this.sessionRepository.findAll();for(const i of s){const s=this.watchSessionReport(i.label,(t=>{e(i.label,t)}));t.push(s)}return()=>{t.forEach((e=>e()))}}getReportSummary(){const e=this.sessionRepository.findAll(),t={};let s,i,n=0,r=0,o=0,a=0;for(const l of e){const e=this.getSessionReport(l.label);e&&(n++,r+=e.stats.tests,o+=e.stats.passes,a+=e.stats.failures,t[l.label]=e.size||0,(!s||e.timestamp<s)&&(s=e.timestamp),(!i||e.timestamp>i)&&(i=e.timestamp))}return{totalReports:n,totalTests:r,totalPasses:o,totalFailures:a,reportSizes:t,...s&&{oldestReport:s},...i&&{newestReport:i}}}async exportReports(e){const t=this.generateCombinedReport();return"json"===e?JSON.stringify(t,null,2):`\n <html>\n <head><title>Test Report</title></head>\n <body>\n <h1>Combined Test Report</h1>\n <p>Generated: ${t.generatedAt}</p>\n <h2>Summary</h2>\n <pre>${JSON.stringify(t.summary,null,2)}</pre>\n <h2>Sessions</h2>\n <pre>${JSON.stringify(t.sessions,null,2)}</pre>\n </body>\n </html>\n `}clearAllReports(){const e=this.sessionRepository.findAll();for(const t of e)this.reportRepository.hasReport(t.resultKey)&&this.reportRepository.clearReport(t.resultKey)}validateSessionReport(e){const t=this.getSessionReport(e);return null!==t&&this.reportRepository.validateReport(t.data)}getReportValidationErrors(e){const t=[],s=this.getSessionReport(e);return s?(s.data||t.push("Report data is missing"),s.stats?("number"!=typeof s.stats.tests&&t.push("Invalid test count"),"number"!=typeof s.stats.passes&&t.push("Invalid pass count"),"number"!=typeof s.stats.failures&&t.push("Invalid failure count")):t.push("Report stats are missing"),t):(t.push("Report not found"),t)}}class o{constructor(e,t){this.mochaIntegration=e,this.eventBus=t}execute(e){const t={windowVariablePrefix:"mochaSession__",autoInit:!0,captureConsoleLog:!0,sourceCode:!0,attachStats:!0,...e};try{this.mochaIntegration.setupTestEnvironment(t),this.eventBus.emitRunnerEvent({type:"runner:initialized",timestamp:new Date,data:{configUsed:t,sessionCount:0,timestamp:new Date}})}catch(e){throw this.eventBus.emitRunnerEvent({type:"runner:config-updated",timestamp:new Date,data:{oldConfig:{},newConfig:t,changes:["initialization_failed"]}}),e}}}class a{constructor(e,t,s){this.sessionRepository=e,this.reportRepository=t,this.eventBus=s}execute(e,t){const s={label:e,resultKey:this.reportRepository.generateResultKey(e),setupFn:t,status:"ready",timestamp:new Date};this.sessionRepository.save(s),this.eventBus.emitRunnerEvent({type:"runner:session-defined",timestamp:new Date,data:{sessionLabel:e,sessionMeta:s,totalSessions:this.sessionRepository.findAll().length}})}}class l{constructor(e,t,s){this.sessionRepository=e,this.reportRepository=t,this.eventBus=s}async execute(e){const t=this.sessionRepository.findByLabel(e);if(!t)throw new Error(`Session '${e}' not found`);try{if(this.sessionRepository.markAsRunning(e),!window.MochaMultipleSessions)throw new Error("MochaMultipleSessions library not available");try{await window.MochaMultipleSessions.testSession(e,t.setupFn),console.log(`Session '${e}' created successfully`)}catch(t){throw console.error(`Failed to create session '${e}':`,t),new Error(`Session creation failed for '${e}': ${t}`)}let s;try{s=await window.MochaMultipleSessions.runSession(e),console.log(`Session '${e}' execution completed:`,s)}catch(t){throw console.error(`Failed to run session '${e}':`,t),new Error(`Session execution failed for '${e}': ${t}`)}try{await this.reportRepository.waitForReport(t.resultKey,5e3),console.log(`Detailed report available for '${e}'`)}catch(t){console.warn(`Timeout waiting for detailed report for ${e}:`,t)}this.sessionRepository.markAsCompleted(e,s);const i={label:e,status:s.success?"passed":"failed",success:s.success,timestamp:new Date,duration:s.duration,stats:s.stats};return console.log(`Session '${e}' result:`,i),i}catch(t){console.error(`Error in session '${e}':`,t),this.sessionRepository.markAsFailed(e,t);return{label:e,status:"failed",success:!1,timestamp:new Date,error:t}}}}class u{constructor(e,t,s){this.sessionRepository=e,this.runSingleSessionUseCase=t,this.eventBus=s}async execute(e){const t=this.sessionRepository.findAll();if(0===t.length)throw new Error("No sessions defined");const s=t.map((e=>e.label)),i=Date.now();this.eventBus.emitRunnerEvent({type:"runner:batch-started",timestamp:new Date,data:{sessionLabels:s,totalSessions:s.length,executionMode:e?.mode||"sequential",options:e}});const n={};let r=0;try{if("parallel"===e?.mode){const e=s.map((async e=>{const t=await this.runSingleSessionUseCase.execute(e);return n[e]=t,r++,this.eventBus.emitRunnerEvent({type:"runner:batch-progress",timestamp:new Date,data:{completed:r,total:s.length,currentSession:e,completedSessions:Object.keys(n),failedSessions:Object.keys(n).filter((e=>!n[e]?.success)),progress:Math.round(r/s.length*100)}}),t}));await Promise.all(e)}else for(const t of s){if(e?.stopOnFirstFailure&&r>0){if(Object.values(n).some((e=>!e.success)))break}const i=await this.runSingleSessionUseCase.execute(t);n[t]=i,r++,this.eventBus.emitRunnerEvent({type:"runner:batch-progress",timestamp:new Date,data:{completed:r,total:s.length,currentSession:t,completedSessions:Object.keys(n),failedSessions:Object.keys(n).filter((e=>!n[e]?.success)),progress:Math.round(r/s.length*100)}})}const t=Date.now()-i,o=Object.values(n).filter((e=>e.success)).length,a=Object.values(n).filter((e=>!e.success)).length;return this.eventBus.emitRunnerEvent({type:"runner:batch-completed",timestamp:new Date,data:{totalSessions:s.length,successfulSessions:o,failedSessions:a,duration:t,sessionResults:n,overallSuccess:0===a}}),n}catch(e){throw this.eventBus.emitRunnerEvent({type:"runner:batch-failed",timestamp:new Date,data:{error:e,completedSessions:Object.keys(n),partialResults:n}}),e}}}class h{constructor(e,t,s){this.sessionRepository=e,this.reportRepository=t,this.eventBus=s}async execute(){const e=this.sessionRepository.findAll(),t=e.map((e=>e.label)),s=[];for(const t of e)this.reportRepository.hasReport(t.resultKey)&&(this.reportRepository.clearReport(t.resultKey),s.push(t.resultKey));this.sessionRepository.clear(),this.eventBus.emitRunnerEvent({type:"runner:cleared",timestamp:new Date,data:{clearedSessions:t,clearedReports:s}})}}class c{constructor(e,t){this.clearAllSessionsUseCase=e,this.eventBus=t}async execute(){await this.clearAllSessionsUseCase.execute(),this.eventBus.emitRunnerEvent({type:"runner:destroyed",timestamp:new Date}),this.eventBus.destroy()}}class p{constructor(){this.initialized=!1,this.destroyed=!1,this.sessionRepository=new t,this.reportRepository=new s,this.eventBus=new i,this.mochaIntegration=new n,this.reportService=new r(this.reportRepository,this.sessionRepository,this.eventBus),this.initializeUseCase=new o(this.mochaIntegration,this.eventBus),this.defineSessionUseCase=new a(this.sessionRepository,this.reportRepository,this.eventBus),this.runSingleSessionUseCase=new l(this.sessionRepository,this.reportRepository,this.eventBus),this.runAllSessionsUseCase=new u(this.sessionRepository,this.runSingleSessionUseCase,this.eventBus),this.clearAllSessionsUseCase=new h(this.sessionRepository,this.reportRepository,this.eventBus),this.destroyRunnerUseCase=new c(this.clearAllSessionsUseCase,this.eventBus),this.bridgeExistingSessionEvents()}init(e){if(this.destroyed)throw new Error("Runner has been destroyed");this.initialized=!0;try{this.initializeUseCase.execute(e)}catch(e){throw this.initialized=!1,e}}define(e,t){this.ensureInitialized(),this.defineSessionUseCase.execute(e,t)}async run(e){return this.ensureInitialized(),this.runSingleSessionUseCase.execute(e)}async runAll(e){return this.ensureInitialized(),this.runAllSessionsUseCase.execute(e)}getReport(e){return this.ensureInitialized(),this.reportService.getSessionReport(e)}getSessionStates(){return this.ensureInitialized(),this.sessionRepository.getStates()}getCombinedReport(){return this.ensureInitialized(),this.reportService.generateCombinedReport()}onRunnerEvent(e,t){return this.eventBus.onRunnerEvent(e,t)}onSessionEvent(e,t){return this.eventBus.onSessionEvent(e,t)}onAnyEvent(e){return this.eventBus.onAnyEvent(e)}isInitialized(){return this.initialized&&!this.destroyed}hasSession(e){return this.sessionRepository.exists(e)}getSessionCount(){return this.sessionRepository.findAll().length}async clear(){this.ensureInitialized(),await this.clearAllSessionsUseCase.execute()}async destroy(){this.destroyed||(await this.destroyRunnerUseCase.execute(),this.destroyed=!0,this.initialized=!1)}ensureInitialized(){if(this.destroyed)throw new Error("Runner has been destroyed");if(!this.initialized)throw new Error("Runner not initialized. Call init() first.")}bridgeExistingSessionEvents(){"undefined"!=typeof window&&window.MochaMultipleSessions?.onAnySessionEvent&&window.MochaMultipleSessions.onAnySessionEvent((e=>{const t={type:e.type,sessionLabel:e.sessionLabel,timestamp:e.timestamp||new Date,data:e.data,source:"mocha-multiple-sessions"};this.eventBus.emitSessionEvent(t)}))}}return e.MultiSessionDetailedRunner=p,e.createMultiSessionDetailedRunner=function(e){const t=new p;return!1!==e?.autoInit&&t.init(e),t},e}({}); //# sourceMappingURL=multi-session-detailed-runner.min.js.map