Skip to content

Commit 77b71c8

Browse files
committed
Update html-template.mjs
1 parent 07fc6e3 commit 77b71c8

File tree

1 file changed

+93
-42
lines changed

1 file changed

+93
-42
lines changed

src/reporters/html-template.mjs

Lines changed: 93 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ export const template = ({
2929
numTodo = 0,
3030
results,
3131
}) => {
32-
const percent = (count) => getPercent(count, numTests)
33-
3432
return `
3533
<!DOCTYPE html>
3634
<html>
@@ -40,19 +38,43 @@ export const template = ({
4038
body { font-family: system-ui, -apple-system, sans-serif; background: #f5f5f5; margin: 0; padding: 2rem; }
4139
.container { max-width: 1200px; margin: 0 auto; background: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.08); padding: 2rem; }
4240
.header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; }
43-
.main-flex { display: flex; align-items: center; gap: 3rem; margin-bottom: 2.5rem; }
41+
.main-flex { display: flex; align-items: center; gap: 3rem; margin-bottom: 0.5rem; }
4442
.pie-chart-container { position: relative; width: 200px; height: 200px; background: #fff; border-radius: 50%; box-shadow: 0 2px 8px rgba(0,0,0,0.07); display: flex; align-items: center; justify-content: center; }
45-
.pie-legend { display: flex; flex-direction: column; gap: 0.7rem; margin-top: 1.5rem; font-size: 1.1rem; }
46-
.pie-legend-item { display: flex; align-items: center; gap: 0.6rem; }
47-
.dot { width: 18px; height: 18px; border-radius: 50%; display: inline-block; }
48-
.pie-passed { background: #4caf50; }
49-
.pie-failed { background: #f44336; }
50-
.pie-todo { background: #ff9800; }
51-
.pie-stat-label { font-weight: 600; min-width: 60px; display: inline-block; }
52-
.pie-stat-value { font-weight: 700; margin-left: 0.5em; }
53-
.summary-tiles { display: flex; flex-direction: row; gap: 1.5rem; align-items: center; height: 200px; }
54-
.stat { padding: 1.2rem 1.5rem; border-radius: 12px; min-width: 120px; background: #f5f5f5; box-shadow: 0 1px 2px rgba(0,0,0,0.03); display: flex; flex-direction: column; align-items: center; justify-content: center; height: 120px; }
55-
.stat.total { background: #e3f2fd; }
43+
.summary-tiles {
44+
display: flex;
45+
flex-direction: row;
46+
gap: 1.2rem;
47+
align-items: center;
48+
justify-content: center;
49+
height: 200px;
50+
}
51+
.stat {
52+
padding: 1.2rem 1.5rem;
53+
border-radius: 12px;
54+
min-width: 120px;
55+
background: #f5f5f5;
56+
box-shadow: 0 1px 2px rgba(0,0,0,0.03);
57+
display: flex;
58+
flex-direction: column;
59+
align-items: center;
60+
justify-content: center;
61+
height: 70px;
62+
cursor: pointer;
63+
transition: box-shadow 0.2s;
64+
border: 2px solid transparent;
65+
}
66+
.stat-percent {
67+
font-size: 1.1em;
68+
font-weight: 600;
69+
margin-top: 0.3em;
70+
text-align: center;
71+
}
72+
.stat.active {
73+
box-shadow: 0 2px 8px rgba(33,150,243,0.13);
74+
border: 2px solid #2196f3;
75+
background: #e3f2fd;
76+
}
77+
.stat.total { background: #e3f2fd; cursor: default; border: 2px solid transparent; }
5678
.stat.passed { background: #e8f5e9; }
5779
.stat.failed { background: #ffebee; }
5880
.stat.todo { background: #fff3e0; }
@@ -61,6 +83,13 @@ export const template = ({
6183
.stat.passed h3, .stat.passed p { color: #4caf50; }
6284
.stat.failed h3, .stat.failed p { color: #f44336; }
6385
.stat.todo h3, .stat.todo p { color: #ff9800; }
86+
.stat.total h3, .stat.total p { color: #2196f3; }
87+
.dot { width: 18px; height: 18px; border-radius: 50%; display: inline-block; }
88+
.pie-passed { background: #4caf50; }
89+
.pie-failed { background: #f44336; }
90+
.pie-todo { background: #ff9800; }
91+
.pie-stat-label { font-weight: 600; min-width: 60px; display: inline-block; }
92+
.pie-stat-value { font-weight: 700; margin-left: 0.5em; }
6493
.test-case { padding: 0.75rem 1rem; border-bottom: 1px solid #eee; }
6594
.test-case:last-child { border-bottom: none; }
6695
.test-name { display: flex; align-items: center; gap: 0.5rem; }
@@ -85,6 +114,7 @@ export const template = ({
85114
.api-table th, .api-table td { text-align: left; padding: 0.5rem; border: 1px solid #e0e0e0; }
86115
.api-table th { background: #f3f4f6; font-weight: 600; }
87116
pre.api-data { margin: 0.5rem 0; padding: 0.5rem; background: #f5f5f5; border-radius: 4px; max-height: 200px; overflow-y: auto; white-space: pre-wrap; }
117+
.hidden { display: none !important; }
88118
</style>
89119
</head>
90120
<body>
@@ -98,50 +128,31 @@ export const template = ({
98128
<div class="pie-chart-container">
99129
<canvas id="pieChart" width="200" height="200"></canvas>
100130
</div>
101-
<div class="pie-legend">
102-
<div class="pie-legend-item">
103-
<span class="dot pie-passed"></span>
104-
<span class="pie-stat-label">Passed</span>
105-
<span class="pie-stat-value" id="percent-passed">${percent(
106-
numPassed
107-
)}%</span>
108-
</div>
109-
<div class="pie-legend-item">
110-
<span class="dot pie-failed"></span>
111-
<span class="pie-stat-label">Failed</span>
112-
<span class="pie-stat-value" id="percent-failed">${percent(
113-
numFailed
114-
)}%</span>
115-
</div>
116-
<div class="pie-legend-item">
117-
<span class="dot pie-todo"></span>
118-
<span class="pie-stat-label">Todo</span>
119-
<span class="pie-stat-value" id="percent-todo">${percent(
120-
numTodo
121-
)}%</span>
122-
</div>
123-
</div>
124131
</div>
125132
<div class="summary-tiles">
126-
<div class="stat total">
133+
<div class="stat total" data-filter="all">
127134
<h3>Total</h3>
128135
<p>${numTests}</p>
136+
<div class="stat-percent" style="color:#2196f3;">${getPercent(numTests, numTests)}%</div>
129137
</div>
130-
<div class="stat passed">
138+
<div class="stat passed" data-filter="passed">
131139
<h3>Passed</h3>
132140
<p>${numPassed}</p>
141+
<div class="stat-percent" style="color:#4caf50;">${getPercent(numPassed, numTests)}%</div>
133142
</div>
134-
<div class="stat failed">
143+
<div class="stat failed" data-filter="failed">
135144
<h3>Failed</h3>
136145
<p>${numFailed}</p>
146+
<div class="stat-percent" style="color:#f44336;">${getPercent(numFailed, numTests)}%</div>
137147
</div>
138-
<div class="stat todo">
148+
<div class="stat todo" data-filter="todo">
139149
<h3>Todo</h3>
140150
<p>${numTodo}</p>
151+
<div class="stat-percent" style="color:#ff9800;">${getPercent(numTodo, numTests)}%</div>
141152
</div>
142153
</div>
143154
</div>
144-
<div class="results">
155+
<div class="results" id="results-root">
145156
${renderDescribeGroup(groupByDescribe(results))}
146157
</div>
147158
</div>
@@ -177,6 +188,46 @@ export const template = ({
177188
});
178189
})();
179190
191+
document.querySelectorAll('.stat[data-filter]').forEach(tile => {
192+
tile.addEventListener('click', function() {
193+
document.querySelectorAll('.stat[data-filter]').forEach(t => t.classList.remove('active'));
194+
this.classList.add('active');
195+
const filter = this.getAttribute('data-filter');
196+
filterResults(filter);
197+
});
198+
});
199+
200+
function filterResults(filter) {
201+
const root = document.getElementById('results-root');
202+
if (!root) return;
203+
if (filter === 'all') {
204+
root.querySelectorAll('.test-case').forEach(tc => tc.classList.remove('hidden'));
205+
root.querySelectorAll('.describe-group').forEach(dg => dg.classList.remove('hidden'));
206+
return;
207+
}
208+
root.querySelectorAll('.test-case').forEach(tc => tc.classList.add('hidden'));
209+
root.querySelectorAll('.test-case').forEach(tc => {
210+
if (
211+
(filter === 'passed' && tc.querySelector('.test-name.passed')) ||
212+
(filter === 'failed' && tc.querySelector('.test-name.failed')) ||
213+
(filter === 'todo' && tc.querySelector('.test-name.todo'))
214+
) {
215+
tc.classList.remove('hidden');
216+
}
217+
});
218+
root.querySelectorAll('.describe-group').forEach(dg => {
219+
const hasVisible = dg.querySelectorAll('.test-case:not(.hidden)').length > 0 ||
220+
dg.querySelectorAll('.describe-group:not(.hidden)').length > 0;
221+
if (hasVisible) {
222+
dg.classList.remove('hidden');
223+
} else {
224+
dg.classList.add('hidden');
225+
}
226+
});
227+
}
228+
229+
document.querySelector('.stat.total').classList.add('active');
230+
180231
function toggleDescribeContent(element) {
181232
const content = element.nextElementSibling;
182233
content.classList.toggle('hide');

0 commit comments

Comments
 (0)