first commit

This commit is contained in:
Kajal Thakur 2025-06-23 11:45:54 +05:30
commit deabbc5635
55 changed files with 3578 additions and 0 deletions

20
Dockerfile Normal file
View File

@ -0,0 +1,20 @@
# Use an official Node.js image from the Docker Hub
FROM node:18
# Set the working directory inside the container
WORKDIR /app
# Copy package.json and package-lock.json (if available)
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the application code
COPY . .
# Expose the port the app will run on
EXPOSE 8080
# Command to start the application
CMD ["node", "index.js"]

10
boltic.yaml Normal file
View File

@ -0,0 +1,10 @@
app: test-report
region: asia-south1
entrypoint: index.js
build:
builtin: dockerfile
ignorefile: .gitignore
env:
PORT: '8080'

271
index.js Normal file
View File

@ -0,0 +1,271 @@
const express = require("express");
const path = require("path");
const fs = require("fs");
const app = express();
app.use(express.static("public"));
// Set up EJS as the templating engine
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "views"));
// Utility to get directories sorted by datetime
function getSortedReportDirectories(reportDir, env) {
const dirents = fs
.readdirSync(reportDir, { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => {
const folderName = dirent.name;
const parts = folderName.split("-");
if (parts.length >= 6) {
const metadata = extractMetadata(folderName);
const datetime = new Date(`${metadata.date} ${metadata.time}`);
const link = path.join(env, folderName, "index.html");
return {
folderName,
date: metadata.date,
time: metadata.time,
datetime,
buildId: metadata.buildId,
link,
};
}
return null;
})
.filter(Boolean)
.sort((a, b) => b.datetime - a.datetime); // Sort in descending order of datetime
return dirents;
}
// Utility to extract metadata from folder names
function extractMetadata(str) {
const regex =
/^([a-z]+)-([a-z]+-[a-z0-9]+)-(\d+)-(\d{4})-(\d{2})-(\d{2})_(\d{2})-(\d{2})-(\d{2})$/;
const match = str.match(regex);
if (!match) {
return "Invalid string format";
}
const [_, env, region, buildId, year, month, day, hours, minutes, seconds] =
match;
// Create a date object in UTC
const utcDate = new Date(
Date.UTC(year, month - 1, day, hours, minutes, seconds)
);
// Convert to IST using toLocaleString with the appropriate timezone
const istDate = utcDate.toLocaleString("en-IN", { timeZone: "Asia/Kolkata" });
// Separate the date and time from the IST conversion
const [istDateOnly, istTimeOnly] = istDate.split(", ");
return {
env,
region,
buildId: parseInt(buildId),
date: istDateOnly,
time: istTimeOnly,
datetime: utcDate,
};
}
// Route to serve the main index.html
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, "public", "index.html"), (err) => {
if (err) {
res.status(err.status).end();
}
});
});
// Dynamic route to serve specific folder's index.html for PROD-ASIA-SOUTH1
app.get("/uat-asia-south1/:folderId/index.html", async (req, res) => {
const folderId = req.params.folderId;
const reportDir = path.join(
__dirname,
"public",
"uat-asia-south1",
folderId,
"index.html"
);
// Serve the index.html from the specific folder
fs.readFile(reportDir, "utf8", (err, data) => {
if (err) {
return res
.status(404)
.send("Index file not found for the requested folder.");
}
res.send(data);
});
});
// Dynamic route to serve specific folder's index.html for PROD-US-CENTRAL1
app.get("/uat-us-central1/:folderId/index.html", (req, res) => {
const folderId = req.params.folderId;
const reportDir = path.join(
__dirname,
"public",
"uat-us-central1",
folderId,
"index.html"
);
// Serve the index.html from the specific folder
fs.readFile(reportDir, "utf8", (err, data) => {
if (err) {
return res
.status(404)
.send("Index file not found for the requested folder.");
}
res.send(data);
});
});
// Dynamic route to serve specific folder's index.html for PROD-ASIA-SOUTH1
app.get("/prod-asia-south1/:folderId/index.html", async (req, res) => {
const folderId = req.params.folderId;
const reportDir = path.join(
__dirname,
"public",
"prod-asia-south1",
folderId,
"index.html"
);
// Serve the index.html from the specific folder
fs.readFile(reportDir, "utf8", (err, data) => {
if (err) {
return res
.status(404)
.send("Index file not found for the requested folder.");
}
res.send(data);
});
});
// Dynamic route to serve specific folder's index.html for PROD-US-CENTRAL1
app.get("/prod-us-central1/:folderId/index.html", (req, res) => {
const folderId = req.params.folderId;
const reportDir = path.join(
__dirname,
"public",
"prod-us-central1",
folderId,
"index.html"
);
// Serve the index.html from the specific folder
fs.readFile(reportDir, "utf8", (err, data) => {
if (err) {
return res
.status(404)
.send("Index file not found for the requested folder.");
}
res.send(data);
});
});
// Dynamic route to serve specific folder's index.html for DEV-ASIA-SOUTH1
app.get("/dev-asia-south1/:folderId/index.html", (req, res) => {
const folderId = req.params.folderId;
const reportDir = path.join(
__dirname,
"public",
"dev-asia-south1",
folderId,
"index.html"
);
// Serve the index.html from the specific folder
fs.readFile(reportDir, "utf8", (err, data) => {
if (err) {
return res
.status(404)
.send("Index file not found for the requested folder.");
}
res.send(data);
});
});
// Dynamic route to serve specific folder's index.html for DEV-US-CENTRAL1
app.get("/dev-us-central1/:folderId/index.html", (req, res) => {
const folderId = req.params.folderId;
const reportDir = path.join(
__dirname,
"public",
"dev-us-central1",
folderId,
"index.html"
);
// Serve the index.html from the specific folder
fs.readFile(reportDir, "utf8", (err, data) => {
if (err) {
return res
.status(404)
.send("Index file not found for the requested folder.");
}
res.send(data);
});
});
// Dynamic route for UAT-ASIA-SOUTH1
app.get("/uat-asia", (req, res) => {
console.log("came here");
const reportDir = path.join(__dirname, "public", "uat-asia-south1");
const reportDirs = getSortedReportDirectories(reportDir, "uat-asia-south1");
res.render("reportPage", { reportDirs });
});
// Dynamic route for PROD-US-CENTRAL1 (for all subfolders)
app.get("/uat-us", (req, res) => {
const reportDir = path.join(__dirname, "public", "uat-us-central1");
const reportDirs = getSortedReportDirectories(reportDir, "uat-us-central1");
res.render("reportPage", { reportDirs });
});
// Dynamic route for PROD-ASIA-SOUTH1
app.get("/prod-asia", (req, res) => {
console.log("came here");
const reportDir = path.join(__dirname, "public", "prod-asia-south1");
const reportDirs = getSortedReportDirectories(reportDir, "prod-asia-south1");
res.render("reportPage", { reportDirs });
});
// Dynamic route for PROD-US-CENTRAL1 (for all subfolders)
app.get("/prod-us", (req, res) => {
const reportDir = path.join(__dirname, "public", "prod-us-central1");
const reportDirs = getSortedReportDirectories(reportDir, "prod-us-central1");
res.render("reportPage", { reportDirs });
});
// Dynamic route for DEV-ASIA-SOUTH1
app.get("/dev-asia", (req, res) => {
const reportDir = path.join(__dirname, "public", "dev-asia-south1");
const reportDirs = getSortedReportDirectories(reportDir, "dev-asia-south1");
res.render("reportPage", { reportDirs });
});
// Dynamic route for DEV-US-CENTRAL1
app.get("/dev-us", (req, res) => {
const reportDir = path.join(__dirname, "public", "dev-us-central1");
const reportDirs = getSortedReportDirectories(reportDir, "dev-us-central1");
res.render("reportPage", { reportDirs });
});
// Handle 404 errors
app.use((req, res) => {
res.status(404).send("404 Not Found");
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});

1192
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

17
package.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "test-report",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"ejs": "^3.1.10",
"express": "^4.21.1",
"nodemon": "^3.1.7"
}
}

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DEV-ASIA-SOUTH1 Automation Reports</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #201715;
color: white;
text-align: center;
}
h1 {
margin-top: 20px;
font-size: 24px;
}
.report-list {
list-style-type: none;
padding: 0;
margin: 20px;
}
.report-item {
background-color: #ff592f;
color: white;
padding: 12px;
margin: 10px 0;
border-radius: 8px;
display: inline-block;
width: 300px;
text-align: center;
text-decoration: none;
}
.report-item:hover {
background-color: #cc4826;
}
</style>
</head>
<body>
<header>
<h1>Automation Reports - DEV-ASIA-SOUTH1</h1>
</header>
<main>
<ul class="report-list" id="reportList">
<!-- Report links will be populated by JavaScript -->
</ul>
</main>
<footer>
<p>&copy; 2024 Boltic Automation. All rights reserved.</p>
</footer>
<!-- Link to the external JavaScript file -->
<script src="script.js"></script>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DEV-US-CENTRAL1 Automation Reports</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #201715;
color: white;
text-align: center;
}
h1 {
margin-top: 20px;
font-size: 24px;
}
.report-list {
list-style-type: none;
padding: 0;
margin: 20px;
}
.report-item {
background-color: #ff592f;
color: white;
padding: 12px;
margin: 10px 0;
border-radius: 8px;
display: inline-block;
width: 300px;
text-align: center;
text-decoration: none;
}
.report-item:hover {
background-color: #cc4826;
}
</style>
</head>
<body>
<header>
<h1>Automation Reports - DEV-US-CENTRAL1</h1>
</header>
<main>
<ul class="report-list" id="reportList">
<!-- Report links will be populated by JavaScript -->
</ul>
</main>
<footer>
<p>&copy; 2024 Boltic Automation. All rights reserved.</p>
</footer>
<!-- Link to the external JavaScript file -->
<script src="script.js"></script>
</body>
</html>

142
public/index.html Normal file
View File

@ -0,0 +1,142 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Boltic Automation Reports</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #201715;
/* Body and header background color */
color: white;
/* Text color */
display: flex;
flex-direction: column;
min-height: 100vh;
/* Full viewport height */
}
header {
position: fixed;
/* Stick header to top */
top: 0;
left: 0;
width: 100%;
background-color: #201715;
/* Same background color as body */
color: white;
padding: 10px 20px;
/* Reduced padding for smaller height */
display: flex;
align-items: center;
/* Vertically align items */
z-index: 1000;
/* Above all content */
font-size: 16px;
/* Smaller header font size */
border-bottom: 1px solid #ff592f;
}
.logo-container {
width: 150px;
/* Smaller logo container */
}
header img {
max-width: 100%;
/* Ensure logo fits container */
height: auto;
margin-right: 30px;
}
h1 {
margin: 0 0 0 10px;
/* Reduced margin for spacing */
font-size: 18px;
/* Smaller font size */
font-weight: 300;
/* Reduced font weight */
}
main {
flex-grow: 1;
margin-top: 70px;
/* Adjusted margin for reduced header */
text-align: center;
}
.button-container {
display: flex;
flex-direction: column;
align-items: center;
list-style-type: none;
padding: 0;
}
.btn {
display: block;
width: 250px;
padding: 12px;
margin: 10px 0;
text-align: center;
background-color: #ff592f;
color: white;
text-decoration: none;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
transition: background-color 0.3s, transform 0.2s;
}
.btn:hover {
background-color: #cc4826;
transform: translateY(-2px);
}
footer {
position: fixed;
/* Stick footer to bottom */
bottom: 0;
left: 0;
width: 100%;
text-align: center;
padding: 10px;
/* Reduced padding for smaller height */
background-color: #e9ecef;
color: #201715;
font-size: 12px;
/* Smaller footer font size */
}
</style>
</head>
<body>
<header>
<div class="logo-container">
<img src="https://cdn.pixelbin.io/v2/fyndcloud/fyndst/original/images/svgs/ic_boltic_logo_light.svg"
alt="Boltic Logo">
</div>
<h1>Automation Reports</h1>
</header>
<main>
<ul class="button-container">
<!-- <li><a href="b260fc2c-ab14-4d0b-9542-4c9609fe9d2c-http/dev-asia" class="btn">DEV-ASIA-SOUTH1</a></li> -->
<li><a href="b260fc2c-ab14-4d0b-9542-4c9609fe9d2c-http/prod-asia" class="btn">PROD-ASIA-SOUTH1</a></li>
<!-- <li><a href="b260fc2c-ab14-4d0b-9542-4c9609fe9d2c-http/dev-us" class="btn">DEV-US-CENTRAL1</a></li> -->
<li><a href="b260fc2c-ab14-4d0b-9542-4c9609fe9d2c-http/prod-us" class="btn">PROD-US-CENTRAL1</a></li>
<li><a href="b260fc2c-ab14-4d0b-9542-4c9609fe9d2c-http/uat-asia" class="btn">UAT-ASIA-SOUTH1</a></li>
<li><a href="b260fc2c-ab14-4d0b-9542-4c9609fe9d2c-http/uat-us" class="btn">UAT-US-CENTRAL1</a></li>
</ul>
</main>
<footer>
<p>&copy; 2024 Boltic Automation. All rights reserved.</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PROD-ASIA-SOUTH1 Automation Reports</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #201715;
color: white;
text-align: center;
}
h1 {
margin-top: 20px;
font-size: 24px;
}
.report-list {
list-style-type: none;
padding: 0;
margin: 20px;
}
.report-item {
background-color: #ff592f;
color: white;
padding: 12px;
margin: 10px 0;
border-radius: 8px;
display: inline-block;
width: 300px;
text-align: center;
text-decoration: none;
}
.report-item:hover {
background-color: #cc4826;
}
</style>
</head>
<body>
<header>
<h1>Automation Reports - PROD-ASIA-SOUTH1</h1>
</header>
<main>
<ul class="report-list" id="reportList">
<!-- Report links will be populated by JavaScript -->
</ul>
</main>
<footer>
<p>&copy; 2024 Boltic Automation. All rights reserved.</p>
</footer>
<!-- Link to the external JavaScript file -->
<script src="script.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PROD-US-CENTRAL1 Automation Reports</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #201715;
color: white;
text-align: center;
}
h1 {
margin-top: 20px;
font-size: 24px;
}
.report-list {
list-style-type: none;
padding: 0;
margin: 20px;
}
.report-item {
background-color: #ff592f;
color: white;
padding: 12px;
margin: 10px 0;
border-radius: 8px;
display: inline-block;
width: 300px;
text-align: center;
text-decoration: none;
}
.report-item:hover {
background-color: #cc4826;
}
</style>
</head>
<body>
<header>
<h1>Automation Reports - PROD-US-CENTRAL1</h1>
</header>
<main>
<ul class="report-list" id="reportList">
<!-- Report links will be populated by JavaScript -->
</ul>
</main>
<footer>
<p>&copy; 2024 Boltic Automation. All rights reserved.</p>
</footer>
<!-- Link to the external JavaScript file -->
<script src="script.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UAT-ASIA-SOUTH1 Automation Reports</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #201715;
color: white;
text-align: center;
}
h1 {
margin-top: 20px;
font-size: 24px;
}
.report-list {
list-style-type: none;
padding: 0;
margin: 20px;
}
.report-item {
background-color: #ff592f;
color: white;
padding: 12px;
margin: 10px 0;
border-radius: 8px;
display: inline-block;
width: 300px;
text-align: center;
text-decoration: none;
}
.report-item:hover {
background-color: #cc4826;
}
</style>
</head>
<body>
<header>
<h1>Automation Reports - UAT-ASIA-SOUTH1</h1>
</header>
<main>
<ul class="report-list" id="reportList">
<!-- Report links will be populated by JavaScript -->
</ul>
</main>
<footer>
<p>&copy; 2024 Boltic Automation. All rights reserved.</p>
</footer>
<!-- Link to the external JavaScript file -->
<script src="script.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UAT-ASIA-SOUTH1 Automation Reports</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #201715;
color: white;
text-align: center;
}
h1 {
margin-top: 20px;
font-size: 24px;
}
.report-list {
list-style-type: none;
padding: 0;
margin: 20px;
}
.report-item {
background-color: #ff592f;
color: white;
padding: 12px;
margin: 10px 0;
border-radius: 8px;
display: inline-block;
width: 300px;
text-align: center;
text-decoration: none;
}
.report-item:hover {
background-color: #cc4826;
}
</style>
</head>
<body>
<header>
<h1>Automation Reports - UAT-ASIA-SOUTH1</h1>
</header>
<main>
<ul class="report-list" id="reportList">
<!-- Report links will be populated by JavaScript -->
</ul>
</main>
<footer>
<p>&copy; 2024 Boltic Automation. All rights reserved.</p>
</footer>
<!-- Link to the external JavaScript file -->
<script src="script.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

108
views/reportPage.ejs Normal file
View File

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Automation Reports</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #201715;
color: white;
text-align: center;
}
h1 {
margin-top: 20px;
font-size: 28px;
color: #FFD700; /* Gold color for title */
}
table {
width: 80%;
margin: 20px auto;
border-collapse: collapse;
table-layout: fixed;
}
th, td {
padding: 15px;
border: 1px solid #2E2E2E;
text-align: center;
font-size: 18px; /* Adjusted font size */
}
th {
background-color: #FFD700;
color: #201715;
}
td {
background-color: #3A2A2A; /* Slightly darker background for rows */
}
td a {
color: white;
text-decoration: none;
}
td a:hover {
text-decoration: underline;
}
footer {
margin-top: 20px;
padding: 10px;
background-color: #2E2E2E;
color: white;
bottom: 0;
position: fixed;
width: 100%;
}
footer p {
margin: 0;
font-size: 14px;
}
</style>
</head>
<body>
<header>
<h1>Automation Reports</h1>
</header>
<main>
<table>
<thead>
<tr>
<th>Folder Name</th>
<th>Build ID</th>
<th>Date</th>
<th>Time</th>
<th>Link</th>
</tr>
</thead>
<tbody>
<% reportDirs.forEach(function(report) { %>
<tr>
<td><%= report.folderName %></td>
<td><%= report.buildId %></td>
<td><%= report.date %></td>
<td><%= report.time %></td>
<td><a href="<%= report.link %>">View Report</a></td>
</tr>
<% }) %>
</tbody>
</table>
</main>
<footer>
<p>&copy; 2024 Boltic Automation. All rights reserved.</p>
</footer>
</body>
</html>