Skip to content

Commit 5f9bf61

Browse files
committed
dashboard: Indicate if a test was rerun
Added code to get rerun information to both fetch scripts. Display the reruns as a superscript in the rowExpansionTemplate with the result/URL. Fixes: #8 Signed-off-by: Anna Finn <[email protected]>
1 parent 7c3834a commit 5f9bf61

File tree

3 files changed

+329
-82
lines changed

3 files changed

+329
-82
lines changed

pages/index.js

+98-28
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ export default function Home() {
7575
skips : job.skips,
7676
required : job.required,
7777
weather : getWeatherIndex(job),
78+
reruns : job.reruns,
79+
total_reruns : job.reruns.reduce((total, r) => total + r, 0),
7880
}))
7981
);
8082
setLoading(false);
@@ -94,6 +96,8 @@ export default function Home() {
9496
skips : check.skips,
9597
required : check.required,
9698
weather : getWeatherIndex(check),
99+
reruns : check.reruns,
100+
total_reruns : check.reruns.reduce((total, r) => total + r, 0),
97101
}))
98102
);
99103
setLoading(false);
@@ -137,21 +141,43 @@ export default function Home() {
137141
};
138142

139143
const maintainRefs = useRef([]);
144+
const rerunRefs = useRef([]);
140145

141146
const rowExpansionTemplate = (data) => {
142147
const job = (display === "nightly"
143148
? jobs
144149
: checks).find((job) => job.name === data.name);
145150

151+
if (!job) return (
152+
<div className="p-3 bg-gray-100">
153+
No data available for this job.
154+
</div>
155+
);
156+
146157
// Prepare run data
147-
const runs = [];
148-
for (let i = 0; i < job.runs; i++) {
149-
runs.push({
150-
run_num: job.run_nums[i],
151-
result: job.results[i],
152-
url: job.urls[i],
153-
});
154-
}
158+
const getRunStatusIcon = (runs) => {
159+
if (Array.isArray(runs)) {
160+
const allPass = runs.every(run => run === "Pass");
161+
const allFail = runs.every(run => run === "Fail");
162+
163+
if (allPass) {return "✅";}
164+
if (allFail) {return "❌";}
165+
} else if (runs === "Pass") {
166+
return "✅";
167+
} else if (runs === "Fail") {
168+
return "❌";
169+
}
170+
return "⚠️"; // return a warning if a mix of results
171+
};
172+
173+
const runEntries = job.run_nums.map((run_num, idx) => ({
174+
run_num,
175+
result: job.results[idx],
176+
reruns: job.reruns[idx],
177+
rerun_result: job.rerun_results[idx],
178+
url: job.urls[idx],
179+
attempt_urls: job.attempt_urls[idx],
180+
}));
155181

156182
// Find maintainers for the given job
157183
const maintainerData = MaintainerMapping.mappings
@@ -177,28 +203,70 @@ export default function Home() {
177203
<div key={`${job.name}-runs`} className="p-3 bg-gray-100">
178204
{/* Display last 10 runs */}
179205
<div className="flex flex-wrap gap-4">
180-
{runs.length > 0 ? (
181-
runs.map((run) => {
182-
const emoji =
183-
run.result === "Pass"
184-
? "✅"
185-
: run.result === "Fail"
186-
? "❌"
187-
: "⚠️";
188-
return (
189-
<span key={`${job.name}-runs-${run.run_num}`}>
190-
<a href={run.url} target="_blank" rel="noopener noreferrer">
191-
{emoji} {run.run_num}
206+
{runEntries.map(({
207+
run_num,
208+
result,
209+
url,
210+
reruns,
211+
rerun_result,
212+
attempt_urls
213+
}, idx) => {
214+
const allResults = rerun_result
215+
? [result, ...rerun_result]
216+
: [result];
217+
218+
const runStatuses = allResults.map((result, idx) =>
219+
`${allResults.length - idx}. ${result === 'Pass'
220+
? '✅ Success'
221+
: result === 'Fail'
222+
? '❌ Fail'
223+
: '⚠️ Warning'}`);
224+
225+
// IDs can't have a '/'...
226+
const sanitizedJobName = job.name.replace(/[^a-zA-Z0-9-_]/g, '');
227+
228+
const badgeReruns = `reruns-${sanitizedJobName}-${run_num}`;
229+
230+
rerunRefs.current[badgeReruns] = rerunRefs.current[badgeReruns]
231+
|| React.createRef();
232+
233+
return (
234+
<div key={run_num} className="flex">
235+
<div key={idx} className="flex items-center">
236+
{/* <a href={url} target="_blank" rel="noopener noreferrer"> */}
237+
<a href={attempt_urls[0]} target="_blank" rel="noopener noreferrer">
238+
{getRunStatusIcon(allResults)} {run_num}
192239
</a>
193-
&nbsp;&nbsp;&nbsp;&nbsp;
194-
</span>
195-
);
196-
})
197-
) : (
198-
<div>No Nightly Runs associated with this job</div>
199-
)}
240+
</div>
241+
{reruns > 0 &&(
242+
<span className="p-overlay-badge">
243+
<sup className="text-xs font-bold align-super ml-1"
244+
onMouseEnter={(e) =>
245+
rerunRefs.current[badgeReruns].current.toggle(e)}>
246+
{reruns+1}
247+
</sup>
248+
<OverlayPanel ref={rerunRefs.current[badgeReruns]} dismissable
249+
onMouseLeave={(e) =>
250+
rerunRefs.current[badgeReruns].current.toggle(e)}>
251+
<ul className="bg-white border rounded shadow-lg p-2">
252+
{runStatuses.map((status, index) => (
253+
<li key={index} className="p-2 hover:bg-gray-200">
254+
<a
255+
href={attempt_urls[index] || `${url}/attempts/${index}`}
256+
target="_blank"
257+
rel="noopener noreferrer">
258+
{status}
259+
</a>
260+
</li>
261+
))}
262+
</ul>
263+
</OverlayPanel>
264+
</span>
265+
)}
266+
</div>
267+
);
268+
})}
200269
</div>
201-
202270
{/* Display Maintainers, if there's any */}
203271
<div className="mt-4 p-2 bg-gray-300 w-full">
204272
{Object.keys(groupedMaintainers).length > 0 ? (
@@ -316,6 +384,7 @@ export default function Home() {
316384
header = "Runs"
317385
className="whitespace-nowrap px-2"
318386
sortable />
387+
<Column field = "total_reruns" header = "Reruns" sortable/>
319388
<Column field = "fails" header = "Fails" sortable/>
320389
<Column field = "skips" header = "Skips" sortable/>
321390
<Column
@@ -352,6 +421,7 @@ export default function Home() {
352421
header = "Runs"
353422
className="whitespace-nowrap px-2"
354423
sortable />
424+
<Column field = "total_reruns" header = "Reruns" sortable/>
355425
<Column field = "fails" header = "Fails" sortable/>
356426
<Column field = "skips" header = "Skips" sortable/>
357427
<Column

0 commit comments

Comments
 (0)