Skip to content
Merged
21 changes: 21 additions & 0 deletions jest.js.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = {
testEnvironment: "node",
testMatch: ["**/test/**/*.js"],
testPathIgnorePatterns: [
"/node_modules/",
"/test/index.js",
"/test/config.js",
"/test/sync_config.js",
"/test/.*/utils.js",
"/test/sync/",
],
reporters: ["default", ["jest-html-reporters",
{
"filename": "tap-html.html",
"expand": true,
"inlineSource": true,
"includeFailureMsg": true, // Includes error messages in JSON
"includeConsoleLog": true
}
]],
};
58 changes: 27 additions & 31 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"_id": "contentstack@3.19.3",
"scripts": {
"test": "npm run test:e2e && npm run test:typescript",
"test:e2e": "tape test/index.js | tap-html --out ./tap-html.html",
"test:e2e": "jest --config jest.js.config.js",
"test:typescript": "jest --config jest.config.js --testPathPattern=test/typescript",
"automate": "node test.js",
"build:node": "webpack --config webpack/webpack.node.js",
Expand Down Expand Up @@ -100,10 +100,10 @@
"webpack-node-externals": "^3.0.0"
},
"dependencies": {
"@contentstack/utils": "^1.3.15",
"@fetch-mock/jest": "^0.2.10",
"@contentstack/utils": "^1.3.18",
"@fetch-mock/jest": "^0.2.12",
"es6-promise": "^4.2.8",
"fetch-mock": "^12.2.0",
"fetch-mock": "^12.4.0",
"localStorage": "1.0.4",
"qs": "^6.14.0"
}
Expand Down
129 changes: 76 additions & 53 deletions sanity-report-dev11.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const fs = require("fs");
const { App } = require("@slack/bolt");
const { JSDOM } = require("jsdom");
const dotenv = require("dotenv");
const path = require("path");

dotenv.config();

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

const tapHtmlContent = fs.readFileSync("./tap-html.html", "utf8");
const dom = new JSDOM(tapHtmlContent);
const $ = require("jquery")(dom.window);

const totalCount = $(".nav a:nth-child(2)")
.text()
.trim()
.replace("Total Count", "");
const totalPass = $(".nav a:nth-child(3)")
.text()
.trim()
.replace("Total Pass", "");
const totalFail = $(".nav a:nth-child(4)")
.text()
.trim()
.replace("Total Fail", "");

const totalTime = $(".nav a:nth-child(1)")
.text()
.trim()
.replace("Total Time", "");

const milliseconds = parseInt(totalTime.replace(/\D/g, ''), 10);
const totalSeconds = Math.floor(milliseconds / 1000);
const durationInMinutes = Math.floor(totalSeconds / 60);
const durationInSeconds = totalSeconds % 60;

const passedTests = parseInt(totalPass, 10);
const totalTests = parseInt(totalCount, 10);
const data = fs.readFileSync(path.join(__dirname, "tap-html.html"), "utf8");
const dom = new JSDOM(data);
const textarea = dom.window.document.querySelector(
"#jest-html-reports-result-data"
);
const testResults = JSON.parse(textarea.textContent.trim());

const startTime = testResults.startTime;
const endTime = Math.max(
...testResults.testResults.map((t) => t.perfStats.end)
);
const totalSeconds = (endTime - startTime) / 1000;
const minutes = Math.floor(totalSeconds / 60);
const seconds = (totalSeconds % 60).toFixed(2);
const duration = `${minutes}m ${seconds}s`;

const summary = {
totalSuites: testResults.numTotalTestSuites,
passedSuites: testResults.numPassedTestSuites,
failedSuites: testResults.numFailedTestSuites,
totalTests: testResults.numTotalTests,
passedTests: testResults.numPassedTests,
failedTests: testResults.numFailedTests,
skippedTests: testResults.numPendingTests + testResults.numTodoTests,
pendingTests: testResults.numPendingTests,
duration: duration,
};

const resultMessage =
passedTests === totalTests
? `:white_check_mark: Success (${passedTests} / ${totalTests} Passed)`
: `:x: Failure (${passedTests} / ${totalTests} Passed)`;
summary.passedTests === summary.totalTests
? `:white_check_mark: Success (${summary.passedTests} / ${summary.totalTests} Passed)`
: `:x: Failure (${summary.passedTests} / ${summary.totalTests} Passed)`;

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

let tagUsers = ``;
if (totalFail > 0) {
if (summary.failedTests > 0) {
tagUsers = `<@${user1}> <@${user2}> <@${user3}> <@${user4}>`;
}

const slackMessage = {
text: `Dev11, SDK-CDA Sanity
*Result:* ${resultMessage}. ${durationInMinutes}m ${durationInSeconds}s
*Failed Tests:* ${totalFail}
*Result:* ${resultMessage}. ${summary.duration}s
*Failed Tests:* ${summary.failedTests + summary.skippedTests}
<${reportUrl}|View Report>
${tagUsers}`,
};

const slackWebhookUrl = process.env.SLACK_WEBHOOK_URL;

const sendSlackMessage = async (message) => {
const payload = {
text: message,
};
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
});

const sendSlackMessage = async () => {
try {
const response = await fetch(slackWebhookUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
const result = await app.client.chat.postMessage({
token: process.env.SLACK_BOT_TOKEN,
channel: process.env.SLACK_CHANNEL2,
text: slackMessage.text, // Ensure this is the full object
});

if (!response.ok) {
throw new Error(`Error sending message to Slack: ${response.statusText}`);
if (summary.failedTests > 0) {
await sendFailureDetails(result.ts); // Pass the correct thread timestamp
}

console.log("Message sent to Slack successfully");
} catch (error) {
console.error("Error:", error);
console.error("Error sending Slack message:", error);
}
};

const sendFailureDetails = async (threadTs) => {
const failedTestSuites = testResults.testResults.filter(
(suite) => suite.numFailingTests > 0
);
if (failedTestSuites.length > 0) {
let failureDetails = "*Failed Test Modules:*\n";
for (const suite of failedTestSuites) {
let modulePath = suite.testFilePath;
let formattedModuleName = path
.relative(__dirname, modulePath)
.replace(/^test\//, "")
.replace(/\.js$/, "")
.replace(/\//g, " ");
failureDetails += ` - ${formattedModuleName}: ${suite.numFailingTests} failed\n`;
}
try {
await app.client.chat.postMessage({
token: process.env.SLACK_BOT_TOKEN,
channel: process.env.SLACK_CHANNEL,
text: failureDetails,
thread_ts: threadTs,
});
} catch (error) {
console.error("Error sending failure details:", error);
}
}
};

sendSlackMessage(slackMessage.text);
sendSlackMessage(slackMessage.text);
Loading
Loading