@@ -45,18 +45,18 @@ export default class Teams extends SfdxCommand {
45
45
let coverageHeader = '"Apex Class"' + this . flags . separator + '"Coverage (%)"\n' ;
46
46
47
47
for ( let test of failedTests ) {
48
- failCsvContent += '"' + test . FullName + '"' + this . flags . separator + '"' + test . Message + '\n' + test . StackTrace + '"\n' ;
48
+ failCsvContent += '"' + test . name + '"' + this . flags . separator + '"' + test . message + '\n' + test . stackTrace + '"\n' ;
49
49
}
50
50
51
51
await writeFile ( failTestCsvPath , failCsvContent ) ;
52
52
53
53
let goodCoverageContent = coverageHeader ;
54
54
let badCoverageContent = coverageHeader ;
55
55
for ( let coverage of coverageData ) {
56
- if ( coverage . coveredPercent >= 85 ) {
57
- goodCoverageContent += '"' + coverage . name + '"' + this . flags . separator + '"' + coverage . coveredPercent + '"\n' ;
56
+ if ( coverage . coverage >= 85 ) {
57
+ goodCoverageContent += '"' + coverage . name + '"' + this . flags . separator + '"' + coverage . coverage + '"\n' ;
58
58
} else {
59
- badCoverageContent += '"' + coverage . name + '"' + this . flags . separator + '"' + coverage . coveredPercent + '"\n' ;
59
+ badCoverageContent += '"' + coverage . name + '"' + this . flags . separator + '"' + coverage . coverage + '"\n' ;
60
60
}
61
61
}
62
62
await writeFile ( goodCoverageFilePath , goodCoverageContent ) ;
@@ -124,40 +124,64 @@ export default class Teams extends SfdxCommand {
124
124
let fileContent = await readFile ( this . flags . path ) ;
125
125
let testResult = JSON . parse ( fileContent ) ;
126
126
127
- let statusColor = testResult . result . summary . outcome == 'Passed' ? 'green' : 'red' ;
128
- let summaryTitle = 'Test Execution in ' + this . flags . env + ' - ' + testResult . result . summary . testStartTime ;
129
- let summaryContent = '<strong>TestRunId: </strong>' + testResult . result . summary . testRunId + ' (Execution Time: ' + this . formatMilliseconds ( testResult . result . summary . testExecutionTime . replace ( ' ms' , '' ) ) + ')'
130
- + '\n\n' + '<strong>Status: </strong><span style="color:' + statusColor + ';">' + testResult . result . summary . outcome + '</span>'
131
- + '\n\n' + '<strong>Coverage: </strong>' + testResult . result . summary . testRunCoverage + ' (Test Run Coverage) ' + testResult . result . summary . orgWideCoverage + ' (Org Wide Coverage)'
132
- + '\n\n' + '<strong>Tests Ran: </strong>' + testResult . result . summary . testsRan
133
- + '\n\n' + '<strong>Tests Passed: </strong>' + testResult . result . summary . passing + ' (' + testResult . result . summary . passRate + ')'
134
- + '\n\n' + '<strong>Tests Failed: </strong>' + testResult . result . summary . failing + ' (' + testResult . result . summary . failRate + ')' ;
135
-
136
- let failedTests = new Array ( ) ;
137
- let coverageApexClasses = testResult . result . coverage . coverage ;
138
-
139
- for ( let test of testResult . result . tests ) {
140
- if ( test . Outcome == 'Fail' || test . Outcome == 'CompileFail' ) {
127
+ let failedTests = new Array ( ) ;
128
+ let coverageApexClasses = new Array ( ) ;
129
+
130
+ // Calculate Code Coverage
131
+ this . ux . startSpinner ( 'Calculate code coverage' ) ;
132
+ let globalNumLines = 0 ;
133
+ let globalNumLinesNotCovered = 0 ;
134
+ let mapCoverageByClass = new Map < string , number > ( ) ;
135
+ for ( let codeCoverageObj of testResult . result . details . runTestResult . codeCoverage ) {
136
+ globalNumLines += codeCoverageObj . numLocations ;
137
+ globalNumLinesNotCovered += codeCoverageObj . numLocationsNotCovered ;
138
+
139
+ let currentCoverage = Math . round ( ( 1 - ( codeCoverageObj . numLocationsNotCovered / codeCoverageObj . numLocations ) ) * 100 ) ;
140
+ mapCoverageByClass . set ( codeCoverageObj . name , currentCoverage ) ;
141
+
142
+ let currentClass = {
143
+ name : codeCoverageObj . name ,
144
+ coverage : currentCoverage
145
+ } ;
146
+ coverageApexClasses . push ( currentClass ) ;
147
+ }
148
+ let globalCoverage = Math . round ( ( 1 - ( globalNumLinesNotCovered / globalNumLines ) ) * 100 ) ;
149
+ this . ux . stopSpinner ( 'done' ) ;
150
+
151
+ // Generate Global information
152
+ let status = testResult . result . numberTestErrors > 0 ? 'Failed' : 'Passed' ;
153
+ let statusColor = status == 'Passed' ? 'green' : 'red' ;
154
+ let summaryTitle = 'Test Execution in ' + this . flags . env + ' - ' + testResult . result . startDate ;
155
+ let summaryContent = '<strong>TestRunId: </strong>' + testResult . result . id + ' (Execution Time: ' + this . formatMilliseconds ( testResult . result . details . runTestResult . totalTime ) + ')'
156
+ + '\n\n' + '<strong>Status: </strong><span style="color:' + statusColor + ';">' + status + '</span>'
157
+ + '\n\n' + '<strong>Code Coverage: </strong>' + globalCoverage + '%'
158
+ + '\n\n' + '<strong>Tests Ran: </strong>' + testResult . result . numberTestsTotal
159
+ + '\n\n' + '<strong>Tests Passed: </strong>' + testResult . result . numberTestsCompleted
160
+ + '\n\n' + '<strong>Tests Failed: </strong>' + testResult . result . numberTestErrors ;
161
+
162
+
163
+
164
+ for ( let test of testResult . result . details . runTestResult . failures ) {
165
+ test . coverage = mapCoverageByClass . get ( test . name ) ;
141
166
failedTests . push ( test ) ;
142
- }
143
167
}
144
168
145
169
// Create files
146
170
this . ux . startSpinner ( 'Generate coverage files' ) ;
147
171
148
172
// Sort
149
173
failedTests . sort ( ( obj1 , obj2 ) => {
150
- if ( obj1 . FullName > obj2 . FullName ) {
174
+ if ( obj1 . name > obj2 . name ) {
151
175
return 1 ;
152
- } if ( obj1 . FullName < obj2 . FullName ) {
176
+ } if ( obj1 . name < obj2 . name ) {
153
177
return - 1 ;
154
178
}
155
179
return 0 ;
156
180
} ) ;
157
181
coverageApexClasses . sort ( ( obj1 , obj2 ) => {
158
- if ( obj1 . FullName > obj2 . FullName ) {
182
+ if ( obj1 . name > obj2 . name ) {
159
183
return 1 ;
160
- } if ( obj1 . FullName < obj2 . FullName ) {
184
+ } if ( obj1 . name < obj2 . name ) {
161
185
return - 1 ;
162
186
}
163
187
return 0 ;
@@ -178,7 +202,7 @@ export default class Teams extends SfdxCommand {
178
202
break ;
179
203
}
180
204
}
181
- this . ux . stopSpinner ( 'Done! ' ) ;
205
+ this . ux . stopSpinner ( 'done ' ) ;
182
206
183
207
// Generate URLs
184
208
let failedTestsUrl = this . flags . hosturl . toString ( ) . concat ( failTestFilePath ) ;
0 commit comments