1
1
const fs = require ( "fs" ) ;
2
+ const { App } = require ( "@slack/bolt" ) ;
2
3
const { JSDOM } = require ( "jsdom" ) ;
3
4
const dotenv = require ( "dotenv" ) ;
5
+ const path = require ( "path" ) ;
4
6
5
7
dotenv . config ( ) ;
6
8
@@ -9,40 +11,38 @@ const user2 = process.env.USER2;
9
11
const user3 = process . env . USER3 ;
10
12
const user4 = process . env . USER4 ;
11
13
12
- const tapHtmlContent = fs . readFileSync ( "./tap-html.html" , "utf8" ) ;
13
- const dom = new JSDOM ( tapHtmlContent ) ;
14
- const $ = require ( "jquery" ) ( dom . window ) ;
15
-
16
- const totalCount = $ ( ".nav a:nth-child(2)" )
17
- . text ( )
18
- . trim ( )
19
- . replace ( "Total Count" , "" ) ;
20
- const totalPass = $ ( ".nav a:nth-child(3)" )
21
- . text ( )
22
- . trim ( )
23
- . replace ( "Total Pass" , "" ) ;
24
- const totalFail = $ ( ".nav a:nth-child(4)" )
25
- . text ( )
26
- . trim ( )
27
- . replace ( "Total Fail" , "" ) ;
28
-
29
- const totalTime = $ ( ".nav a:nth-child(1)" )
30
- . text ( )
31
- . trim ( )
32
- . replace ( "Total Time" , "" ) ;
33
-
34
- const milliseconds = parseInt ( totalTime . replace ( / \D / g, '' ) , 10 ) ;
35
- const totalSeconds = Math . floor ( milliseconds / 1000 ) ;
36
- const durationInMinutes = Math . floor ( totalSeconds / 60 ) ;
37
- const durationInSeconds = totalSeconds % 60 ;
38
-
39
- const passedTests = parseInt ( totalPass , 10 ) ;
40
- const totalTests = parseInt ( totalCount , 10 ) ;
14
+ const data = fs . readFileSync ( path . join ( __dirname , "tap-html.html" ) , "utf8" ) ;
15
+ const dom = new JSDOM ( data ) ;
16
+ const textarea = dom . window . document . querySelector (
17
+ "#jest-html-reports-result-data"
18
+ ) ;
19
+ const testResults = JSON . parse ( textarea . textContent . trim ( ) ) ;
20
+
21
+ const startTime = testResults . startTime ;
22
+ const endTime = Math . max (
23
+ ...testResults . testResults . map ( ( t ) => t . perfStats . end )
24
+ ) ;
25
+ const totalSeconds = ( endTime - startTime ) / 1000 ;
26
+ const minutes = Math . floor ( totalSeconds / 60 ) ;
27
+ const seconds = ( totalSeconds % 60 ) . toFixed ( 2 ) ;
28
+ const duration = `${ minutes } m ${ seconds } s` ;
29
+
30
+ const summary = {
31
+ totalSuites : testResults . numTotalTestSuites ,
32
+ passedSuites : testResults . numPassedTestSuites ,
33
+ failedSuites : testResults . numFailedTestSuites ,
34
+ totalTests : testResults . numTotalTests ,
35
+ passedTests : testResults . numPassedTests ,
36
+ failedTests : testResults . numFailedTests ,
37
+ skippedTests : testResults . numPendingTests + testResults . numTodoTests ,
38
+ pendingTests : testResults . numPendingTests ,
39
+ duration : duration ,
40
+ } ;
41
41
42
42
const resultMessage =
43
- passedTests === totalTests
44
- ? `:white_check_mark: Success (${ passedTests } / ${ totalTests } Passed)`
45
- : `:x: Failure (${ passedTests } / ${ totalTests } Passed)` ;
43
+ summary . passedTests === summary . totalTests
44
+ ? `:white_check_mark: Success (${ summary . passedTests } / ${ summary . totalTests } Passed)`
45
+ : `:x: Failure (${ summary . passedTests } / ${ summary . totalTests } Passed)` ;
46
46
47
47
const pipelineName = process . env . GO_PIPELINE_NAME ;
48
48
const pipelineCounter = process . env . GO_PIPELINE_COUNTER ;
@@ -51,42 +51,65 @@ const goCdServer = process.env.GOCD_SERVER;
51
51
const reportUrl = `http://${ goCdServer } /go/files/${ pipelineName } /${ pipelineCounter } /sanity/1/sanity/test-results/tap-html.html` ;
52
52
53
53
let tagUsers = `` ;
54
- if ( totalFail > 0 ) {
54
+ if ( summary . failedTests > 0 ) {
55
55
tagUsers = `<@${ user1 } > <@${ user2 } > <@${ user3 } > <@${ user4 } >` ;
56
56
}
57
57
58
58
const slackMessage = {
59
59
text : `Dev11, SDK-CDA Sanity
60
- *Result:* ${ resultMessage } . ${ durationInMinutes } m ${ durationInSeconds } s
61
- *Failed Tests:* ${ totalFail }
60
+ *Result:* ${ resultMessage } . ${ summary . duration } s
61
+ *Failed Tests:* ${ summary . failedTests + summary . skippedTests }
62
62
<${ reportUrl } |View Report>
63
63
${ tagUsers } `,
64
64
} ;
65
65
66
- const slackWebhookUrl = process . env . SLACK_WEBHOOK_URL ;
67
-
68
- const sendSlackMessage = async ( message ) => {
69
- const payload = {
70
- text : message ,
71
- } ;
66
+ const app = new App ( {
67
+ token : process . env . SLACK_BOT_TOKEN ,
68
+ signingSecret : process . env . SLACK_SIGNING_SECRET ,
69
+ } ) ;
72
70
71
+ const sendSlackMessage = async ( ) => {
73
72
try {
74
- const response = await fetch ( slackWebhookUrl , {
75
- method : "POST" ,
76
- headers : {
77
- "Content-Type" : "application/json" ,
78
- } ,
79
- body : JSON . stringify ( payload ) ,
73
+ const result = await app . client . chat . postMessage ( {
74
+ token : process . env . SLACK_BOT_TOKEN ,
75
+ channel : process . env . SLACK_CHANNEL2 ,
76
+ text : slackMessage . text , // Ensure this is the full object
80
77
} ) ;
81
78
82
- if ( ! response . ok ) {
83
- throw new Error ( `Error sending message to Slack: ${ response . statusText } ` ) ;
79
+ if ( summary . failedTests > 0 ) {
80
+ await sendFailureDetails ( result . ts ) ; // Pass the correct thread timestamp
84
81
}
85
-
86
- console . log ( "Message sent to Slack successfully" ) ;
87
82
} catch ( error ) {
88
- console . error ( "Error:" , error ) ;
83
+ console . error ( "Error sending Slack message:" , error ) ;
84
+ }
85
+ } ;
86
+
87
+ const sendFailureDetails = async ( threadTs ) => {
88
+ const failedTestSuites = testResults . testResults . filter (
89
+ ( suite ) => suite . numFailingTests > 0
90
+ ) ;
91
+ if ( failedTestSuites . length > 0 ) {
92
+ let failureDetails = "*Failed Test Modules:*\n" ;
93
+ for ( const suite of failedTestSuites ) {
94
+ let modulePath = suite . testFilePath ;
95
+ let formattedModuleName = path
96
+ . relative ( __dirname , modulePath )
97
+ . replace ( / ^ t e s t \/ / , "" )
98
+ . replace ( / \. j s $ / , "" )
99
+ . replace ( / \/ / g, " " ) ;
100
+ failureDetails += ` - ${ formattedModuleName } : ${ suite . numFailingTests } failed\n` ;
101
+ }
102
+ try {
103
+ await app . client . chat . postMessage ( {
104
+ token : process . env . SLACK_BOT_TOKEN ,
105
+ channel : process . env . SLACK_CHANNEL2 ,
106
+ text : failureDetails ,
107
+ thread_ts : threadTs ,
108
+ } ) ;
109
+ } catch ( error ) {
110
+ console . error ( "Error sending failure details:" , error ) ;
111
+ }
89
112
}
90
113
} ;
91
114
92
- sendSlackMessage ( slackMessage . text ) ;
115
+ sendSlackMessage ( slackMessage . text ) ;
0 commit comments