Skip to content

Commit 3d50877

Browse files
Merge pull request #309 from contentstack/staging
DX | 01-04-2025 | Release
2 parents 09ac25e + cb95614 commit 3d50877

16 files changed

+6534
-6121
lines changed

jest.js.config.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module.exports = {
2+
testEnvironment: "node",
3+
testMatch: ["**/test/**/*.js"],
4+
testPathIgnorePatterns: [
5+
"/node_modules/",
6+
"/test/index.js",
7+
"/test/config.js",
8+
"/test/sync_config.js",
9+
"/test/.*/utils.js",
10+
"/test/sync/",
11+
],
12+
reporters: ["default", ["jest-html-reporters",
13+
{
14+
"filename": "tap-html.html",
15+
"expand": true,
16+
"inlineSource": true,
17+
"includeFailureMsg": true, // Includes error messages in JSON
18+
"includeConsoleLog": true
19+
}
20+
]],
21+
};

package-lock.json

+27-31
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
1515
"scripts": {
1616
"test": "npm run test:e2e && npm run test:typescript",
17-
"test:e2e": "tape test/index.js | tap-html --out ./tap-html.html",
17+
"test:e2e": "jest --config jest.js.config.js",
1818
"test:typescript": "jest --config jest.config.js --testPathPattern=test/typescript",
1919
"automate": "node test.js",
2020
"build:node": "webpack --config webpack/webpack.node.js",
@@ -100,10 +100,10 @@
100100
"webpack-node-externals": "^3.0.0"
101101
},
102102
"dependencies": {
103-
"@contentstack/utils": "^1.3.15",
104-
"@fetch-mock/jest": "^0.2.10",
103+
"@contentstack/utils": "^1.3.18",
104+
"@fetch-mock/jest": "^0.2.12",
105105
"es6-promise": "^4.2.8",
106-
"fetch-mock": "^12.2.0",
106+
"fetch-mock": "^12.4.0",
107107
"localStorage": "1.0.4",
108108
"qs": "^6.14.0"
109109
}

sanity-report-dev11.js

+76-53
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const fs = require("fs");
2+
const { App } = require("@slack/bolt");
23
const { JSDOM } = require("jsdom");
34
const dotenv = require("dotenv");
5+
const path = require("path");
46

57
dotenv.config();
68

@@ -9,40 +11,38 @@ const user2 = process.env.USER2;
911
const user3 = process.env.USER3;
1012
const user4 = process.env.USER4;
1113

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+
};
4141

4242
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)`;
4646

4747
const pipelineName = process.env.GO_PIPELINE_NAME;
4848
const pipelineCounter = process.env.GO_PIPELINE_COUNTER;
@@ -51,42 +51,65 @@ const goCdServer = process.env.GOCD_SERVER;
5151
const reportUrl = `http://${goCdServer}/go/files/${pipelineName}/${pipelineCounter}/sanity/1/sanity/test-results/tap-html.html`;
5252

5353
let tagUsers = ``;
54-
if (totalFail > 0) {
54+
if (summary.failedTests > 0) {
5555
tagUsers = `<@${user1}> <@${user2}> <@${user3}> <@${user4}>`;
5656
}
5757

5858
const slackMessage = {
5959
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}
6262
<${reportUrl}|View Report>
6363
${tagUsers}`,
6464
};
6565

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+
});
7270

71+
const sendSlackMessage = async () => {
7372
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
8077
});
8178

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
8481
}
85-
86-
console.log("Message sent to Slack successfully");
8782
} 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(/^test\//, "")
98+
.replace(/\.js$/, "")
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+
}
89112
}
90113
};
91114

92-
sendSlackMessage(slackMessage.text);
115+
sendSlackMessage(slackMessage.text);

0 commit comments

Comments
 (0)