mirror of
https://github.com/DeNNiiInc/Web-Page-Performance-Test.git
synced 2026-04-17 20:05:58 +00:00
146 lines
4.6 KiB
JavaScript
146 lines
4.6 KiB
JavaScript
const express = require("express");
|
|
const path = require("path");
|
|
const fs = require("fs");
|
|
const { exec } = require("child_process");
|
|
const runner = require("./lib/runner");
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3000;
|
|
|
|
// Middleware
|
|
app.use(express.json());
|
|
app.use(express.static(__dirname));
|
|
app.use('/reports', express.static(path.join(__dirname, 'reports')));
|
|
|
|
// API Endpoint: Git Info
|
|
app.get("/api/git-info", (req, res) => {
|
|
exec('/usr/bin/git log -1 --format="%H|%cr"', (error, stdout, stderr) => {
|
|
if (error) {
|
|
console.error("Error getting git info:", error);
|
|
console.error("Stderr:", stderr);
|
|
return res.json({
|
|
commitId: "unknown",
|
|
commitAge: "dev mode",
|
|
error: true,
|
|
details: error.message
|
|
});
|
|
}
|
|
|
|
const [commitId, commitAge] = stdout.trim().split("|");
|
|
res.json({
|
|
commitId: commitId.substring(0, 7),
|
|
commitAge: commitAge,
|
|
error: false,
|
|
});
|
|
});
|
|
});
|
|
|
|
// API Endpoint: Run Test (supports multi-run)
|
|
app.post("/api/run-test", async (req, res) => {
|
|
const { url, isMobile, runs = 1 } = req.body;
|
|
const userUuid = req.headers['x-user-uuid'];
|
|
const userIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
|
|
|
|
if (!url) return res.status(400).json({ error: "URL is required" });
|
|
|
|
// Validate run count
|
|
if (runs < 1 || runs > 10) {
|
|
return res.status(400).json({ error: "Runs must be between 1 and 10" });
|
|
}
|
|
|
|
try {
|
|
// Single run (original behavior)
|
|
if (runs === 1) {
|
|
const result = await runner.runTest(url, { isMobile, userUuid, userIp });
|
|
return res.json(result);
|
|
}
|
|
|
|
// Multi-run
|
|
const multiRun = require('./lib/multi-run');
|
|
const suiteId = runner.generateTestId();
|
|
|
|
// Create suite record
|
|
await multiRun.createSuite(suiteId, userUuid, url, isMobile ? 'mobile' : 'desktop', runs);
|
|
|
|
// Return suite ID immediately
|
|
res.json({ suiteId, runs, status: 'running' });
|
|
|
|
// Execute runs asynchronously
|
|
multiRun.executeMultipleRuns(suiteId, url, isMobile, runs, userUuid, userIp)
|
|
.catch(error => console.error('Multi-run execution failed:', error));
|
|
|
|
} catch (error) {
|
|
console.error("Test failed:", error);
|
|
res.status(500).json({ error: "Test failed", details: error.message });
|
|
}
|
|
});
|
|
|
|
// API Endpoint: Suite Status (for multi-run progress tracking)
|
|
app.get("/api/suite-status/:suiteId", async (req, res) => {
|
|
try {
|
|
const multiRun = require('./lib/multi-run');
|
|
const suite = await multiRun.getSuiteStatus(req.params.suiteId);
|
|
|
|
if (!suite) {
|
|
return res.status(404).json({ error: "Suite not found" });
|
|
}
|
|
|
|
res.json(suite);
|
|
} catch (error) {
|
|
console.error("Suite status error:", error);
|
|
res.status(500).json({ error: "Failed to get suite status" });
|
|
}
|
|
});
|
|
|
|
// API Endpoint: History
|
|
app.get("/api/history", async (req, res) => {
|
|
const userUuid = req.headers['x-user-uuid'];
|
|
const userIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
|
|
|
|
const history = await runner.getHistory(userUuid, userIp);
|
|
res.json(history);
|
|
});
|
|
|
|
// API Endpoint: Export HAR
|
|
app.get("/api/export/:testId/har", (req, res) => {
|
|
const { testId } = req.params;
|
|
const harPath = path.join(__dirname, 'reports', `${testId}.har.json`);
|
|
|
|
if (!fs.existsSync(harPath)) {
|
|
return res.status(404).json({ error: "HAR file not found" });
|
|
}
|
|
|
|
res.download(harPath, `test-${testId}.har`, (err) => {
|
|
if (err) console.error("Download error:", err);
|
|
});
|
|
});
|
|
|
|
// API Endpoint: Export CSV
|
|
app.get("/api/export/:testId/csv", (req, res) => {
|
|
const { testId } = req.params;
|
|
const jsonPath = path.join(__dirname, 'reports', `${testId}.json`);
|
|
|
|
if (!fs.existsSync(jsonPath)) {
|
|
return res.status(404).json({ error: "Test results not found" });
|
|
}
|
|
|
|
const data = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
|
|
const csv = `URL,Timestamp,Device,Performance,Accessibility,Best Practices,SEO,LCP,CLS,TBT
|
|
${data.url},${data.timestamp},${data.isMobile ? 'Mobile' : 'Desktop'},${data.scores.performance},${data.scores.accessibility},${data.scores.bestPractices},${data.scores.seo},${data.metrics.lcp},${data.metrics.cls},${data.metrics.tbt}`;
|
|
|
|
res.setHeader('Content-Type', 'text/csv');
|
|
res.setHeader('Content-Disposition', `attachment; filename="test-${testId}.csv"`);
|
|
res.send(csv);
|
|
});
|
|
|
|
// Serve index.html for all other routes
|
|
app.get("*", (req, res) => {
|
|
res.sendFile(path.join(__dirname, "index.html"));
|
|
});
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`🚀 Server running on port ${PORT}`);
|
|
console.log(`📁 Serving files from: ${__dirname}`);
|
|
console.log(`🌐 Environment: ${process.env.NODE_ENV || "development"}`);
|
|
});
|