11// Copyright 2025-26 The MathWorks, Inc.
22
3- import { readFileSync , unlinkSync , existsSync } from "fs" ;
3+ import { readFileSync , unlinkSync , existsSync , readdirSync } from "fs" ;
44import * as path from "path" ;
55import * as core from "@actions/core" ;
66import { getCoverageResults , getCoverageTable , CoverageData } from "./codeCoverageSummary.js" ;
@@ -57,58 +57,105 @@ export interface TestStatistics {
5757 Duration : number ;
5858}
5959
60- export interface TestResultsData {
61- TestResults : MatlabTestFile [ ] [ ] ;
60+ export interface TestSession {
61+ FileName : string ;
62+ TestResults : MatlabTestFile [ ] ;
6263 Stats : TestStatistics ;
6364}
6465
66+ export interface TestResultsData {
67+ TestSessions : TestSession [ ] ;
68+ OverallStats : TestStatistics ;
69+ }
70+
6571export function processAndAddTestSummary ( runnerTemp : string , runId : string , workspace : string ) {
6672 const testResultsData = getTestResults ( runnerTemp , runId , workspace ) ;
6773 const coverageResultsData = getCoverageResults ( runnerTemp , runId ) ;
6874 if ( testResultsData || coverageResultsData ) {
6975 addSummary ( testResultsData , coverageResultsData ) ;
7076 }
7177}
72-
7378export function getTestResults (
7479 runnerTemp : string ,
7580 runId : string ,
7681 workspace : string ,
7782) : TestResultsData | null {
7883 let testResultsData = null ;
79- const resultsPath = path . join ( runnerTemp , `matlabTestResults${ runId } .json` ) ;
84+ const filePrefix = `matlabTestResults_` ;
85+ const fileSuffix = `.json` ;
86+
87+ // Find all test result files matching the pattern
88+ let testResultFiles : string [ ] = [ ] ;
89+ try {
90+ testResultFiles = readdirSync ( runnerTemp ) . filter (
91+ ( file ) => file . startsWith ( filePrefix ) && file . endsWith ( fileSuffix ) ,
92+ ) ;
93+ } catch ( e ) {
94+ console . error ( `An error occurred while reading directory ${ runnerTemp } :` , e ) ;
95+ return null ;
96+ }
97+
98+ if ( testResultFiles . length === 0 ) {
99+ return null ;
100+ }
101+
102+ const testSessions : TestSession [ ] = [ ] ;
103+ const overallStats : TestStatistics = {
104+ Total : 0 ,
105+ Passed : 0 ,
106+ Failed : 0 ,
107+ Incomplete : 0 ,
108+ NotRun : 0 ,
109+ Duration : 0 ,
110+ } ;
111+
112+ testResultsData = {
113+ TestSessions : testSessions ,
114+ OverallStats : overallStats ,
115+ } ;
116+
117+ // Process each test result file
118+ for ( const fileName of testResultFiles ) {
119+ const resultsPath = path . join ( runnerTemp , fileName ) ;
80120
81- if ( existsSync ( resultsPath ) ) {
82121 try {
83122 const testArtifact = JSON . parse ( readFileSync ( resultsPath , "utf8" ) ) ;
84- const testResults : MatlabTestFile [ ] [ ] = [ ] ;
85- const stats : TestStatistics = {
123+ const sessionResults : MatlabTestFile [ ] = [ ] ;
124+ const sessionStats : TestStatistics = {
86125 Total : 0 ,
87126 Passed : 0 ,
88127 Failed : 0 ,
89128 Incomplete : 0 ,
90129 NotRun : 0 ,
91130 Duration : 0 ,
92131 } ;
93- testResultsData = {
94- TestResults : testResults ,
95- Stats : stats ,
96- } ;
97132
98133 for ( const jsonTestSessionResults of testArtifact ) {
99- const testSessionResults : MatlabTestFile [ ] = [ ] ;
100134 const map = new Map < string , MatlabTestFile > ( ) ;
101135
102136 const testCases = Array . isArray ( jsonTestSessionResults )
103137 ? jsonTestSessionResults
104138 : [ jsonTestSessionResults ] ;
105139
106140 for ( const jsonTestCase of testCases ) {
107- processTestCase ( testSessionResults , jsonTestCase , map , stats , workspace ) ;
141+ processTestCase ( sessionResults , jsonTestCase , map , sessionStats , workspace ) ;
108142 }
109-
110- testResults . push ( testSessionResults ) ;
111143 }
144+
145+ // Add this session to the list
146+ testSessions . push ( {
147+ FileName : fileName ,
148+ TestResults : sessionResults ,
149+ Stats : sessionStats ,
150+ } ) ;
151+
152+ // Update overall stats
153+ overallStats . Total += sessionStats . Total ;
154+ overallStats . Passed += sessionStats . Passed ;
155+ overallStats . Failed += sessionStats . Failed ;
156+ overallStats . Incomplete += sessionStats . Incomplete ;
157+ overallStats . NotRun += sessionStats . NotRun ;
158+ overallStats . Duration += sessionStats . Duration ;
112159 } catch ( e ) {
113160 console . error (
114161 `An error occurred while reading the test results summary file ${ resultsPath } :` ,
@@ -128,7 +175,6 @@ export function getTestResults(
128175
129176 return testResultsData ;
130177}
131-
132178export function addSummary (
133179 testResultsData : TestResultsData | null ,
134180 coverageResultsData : CoverageData | null ,
@@ -139,21 +185,35 @@ export function addSummary(
139185 const helpLink =
140186 `<a href="https://github.com/matlab-actions/run-tests/blob/main/README.md#view-test-results"` +
141187 ` target="_blank" title="View documentation">ℹ️</a>` ;
142- const header = getTestHeader ( testResultsData . Stats ) ;
143188
144- core . summary . addHeading ( "MATLAB Test Results " + helpLink ) . addRaw ( header , true ) ;
189+ // Add overall header
190+ const overallHeader = getTestHeader ( testResultsData . OverallStats ) ;
191+ core . summary . addHeading ( "MATLAB Test Results " + helpLink ) . addRaw ( overallHeader , true ) ;
145192 }
193+
146194 // Add coverage table if available
147195 if ( coverageResultsData ) {
148196 core . summary
149197 . addHeading ( "MATLAB Code Coverage" , 3 )
150198 . addRaw ( getCoverageTable ( coverageResultsData ) , true ) ;
151199 }
152200
153- // Add detailed test results
201+ // Add detailed test results for each session
154202 if ( testResultsData ) {
155- const detailedResults = getDetailedResults ( testResultsData . TestResults ) ;
156- core . summary . addHeading ( "All tests" , 3 ) . addRaw ( detailedResults , true ) ;
203+ for ( let i = 0 ; i < testResultsData . TestSessions . length ; i ++ ) {
204+ const session = testResultsData . TestSessions [ i ] ;
205+ const sessionNumber =
206+ testResultsData . TestSessions . length > 1 ? ` (Session ${ i + 1 } )` : "" ;
207+
208+ // Add session header with stats
209+ core . summary
210+ . addHeading ( `Test Session${ sessionNumber } ` , 3 )
211+ . addRaw ( getTestHeader ( session . Stats ) , true ) ;
212+
213+ // Add detailed results for this session
214+ const detailedResults = getDetailedResults ( [ session . TestResults ] ) ;
215+ core . summary . addRaw ( detailedResults , true ) ;
216+ }
157217 }
158218 } catch ( e ) {
159219 console . error ( "An error occurred while adding the test results to the summary:" , e ) ;
0 commit comments