127 lines
3.2 KiB
TypeScript
127 lines
3.2 KiB
TypeScript
|
|
import pool from "@/utils/db";
|
|
|
|
export async function GET() {
|
|
const runResults = await pool.query<{
|
|
run_id: number;
|
|
run_name: string;
|
|
run_date: string;
|
|
totalseconds: string;
|
|
}>(`
|
|
SELECT
|
|
r.id as run_id, r.name as run_name,
|
|
r.created_at as run_date, SUM(td.totalSeconds) as totalSeconds
|
|
FROM runs r
|
|
LEFT JOIN test_durations td ON td.run_id = r.id
|
|
GROUP BY r.id, r.name
|
|
ORDER BY r.id
|
|
`);
|
|
|
|
// Get test results for each run
|
|
// Get start times for each test
|
|
const startTimes = await pool.query<{
|
|
run_id: number;
|
|
test_name: string;
|
|
path: string;
|
|
start_time: Date;
|
|
}>(`
|
|
SELECT
|
|
run_id,
|
|
test_name,
|
|
path,
|
|
created_at as start_time
|
|
FROM test_runs
|
|
WHERE run_type = 'start'
|
|
`);
|
|
|
|
// Get end times and results for each test
|
|
const endResults = await pool.query<{
|
|
run_id: number;
|
|
test_name: string;
|
|
path: string;
|
|
end_time: Date;
|
|
success: boolean;
|
|
pending: boolean;
|
|
}>(`
|
|
SELECT
|
|
run_id,
|
|
test_name,
|
|
path,
|
|
created_at as end_time,
|
|
success,
|
|
COALESCE(pending, false) as pending
|
|
FROM test_runs
|
|
WHERE run_type = 'end'
|
|
`);
|
|
|
|
// Combine the results
|
|
const testResults = {
|
|
rows: endResults.rows.map(end => {
|
|
const start = startTimes.rows.find(
|
|
start =>
|
|
start.run_id === end.run_id &&
|
|
start.test_name === end.test_name &&
|
|
start.path === end.path
|
|
);
|
|
|
|
if (!start) return null;
|
|
|
|
return {
|
|
run_id: end.run_id,
|
|
test_name: end.test_name,
|
|
path: end.path,
|
|
totalseconds: (end.end_time.getTime() - start.start_time.getTime()) / 1000,
|
|
success: end.success,
|
|
pending: end.pending
|
|
};
|
|
}).filter(Boolean)
|
|
};
|
|
|
|
// Add unfinished tests
|
|
const unfinishedTests = startTimes.rows.filter(start =>
|
|
!endResults.rows.some(end =>
|
|
end.run_id === start.run_id &&
|
|
end.test_name === start.test_name &&
|
|
end.path === start.path
|
|
)
|
|
).map(start => ({
|
|
run_id: start.run_id,
|
|
test_name: start.test_name,
|
|
path: start.path,
|
|
totalseconds: 0, // Test hasn't finished yet
|
|
success: false,
|
|
pending: true
|
|
}));
|
|
|
|
testResults.rows.push(...unfinishedTests);
|
|
|
|
// Combine and format results
|
|
const formatted = runResults.rows.map((run) => {
|
|
const runTests = testResults.rows.filter(
|
|
(test): test is NonNullable<typeof test> => test !== null && test.run_id === run.run_id
|
|
)
|
|
|
|
const totalDurationSeconds = Number(run.totalseconds);
|
|
|
|
return {
|
|
run_id: run.run_id,
|
|
run_name: run.run_name,
|
|
date: run.run_date,
|
|
totalseconds: run.totalseconds,
|
|
success_count: runTests.filter((test) => test.success).length,
|
|
failure_count: runTests.filter((test) => !test.success).length,
|
|
children: runTests.map((test) => ({
|
|
test_name: test.test_name,
|
|
path: test.path,
|
|
totalseconds: test.totalseconds,
|
|
percentage_of_total: Number(
|
|
((test.totalseconds / totalDurationSeconds) * 100).toFixed(2)
|
|
),
|
|
status: test.success ? "success" : "failure",
|
|
pending: test.pending,
|
|
})),
|
|
};
|
|
});
|
|
|
|
return Response.json(formatted);
|
|
}
|