1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>PulseType - Math Engine Unit Tests</title>
7 <link rel="preconnect" href="https://fonts.googleapis.com">
8 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9 <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;600&family=Outfit:wght@400;600;700&display=swap" rel="stylesheet">
10 <style>
11 :root {
12 --bg-color: #0b0f19;
13 --card-bg: #131b2e;
14 --border-color: #1e293b;
15 --text-main: #f1f5f9;
16 --text-muted: #64748b;
17 --pass-color: #10b981;
18 --fail-color: #ef4444;
19 --accent-cyan: #06b6d4;
20 }
21
22 * {
23 box-sizing: border-box;
24 margin: 0;
25 padding: 0;
26 }
27
28 body {
29 background-color: var(--bg-color);
30 color: var(--text-main);
31 font-family: 'Outfit', sans-serif;
32 padding: 2rem;
33 display: flex;
34 justify-content: center;
35 }
36
37 .container {
38 max-width: 800px;
39 width: 100%;
40 }
41
42 header {
43 display: flex;
44 justify-content: space-between;
45 align-items: center;
46 margin-bottom: 2rem;
47 padding-bottom: 1rem;
48 border-bottom: 1px solid var(--border-color);
49 }
50
51 h1 {
52 font-size: 1.8rem;
53 color: var(--text-main);
54 display: flex;
55 align-items: center;
56 gap: 0.5rem;
57 }
58
59 h1 span {
60 color: var(--accent-cyan);
61 }
62
63 .back-link {
64 color: var(--accent-cyan);
65 text-decoration: none;
66 font-weight: 600;
67 font-size: 0.95rem;
68 transition: opacity 0.2s;
69 }
70
71 .back-link:hover {
72 opacity: 0.8;
73 }
74
75 .summary-card {
76 background: var(--card-bg);
77 border: 1px solid var(--border-color);
78 border-radius: 12px;
79 padding: 1.5rem;
80 display: flex;
81 gap: 2rem;
82 margin-bottom: 2rem;
83 }
84
85 .stat-box {
86 display: flex;
87 flex-direction: column;
88 }
89
90 .stat-value {
91 font-size: 2.2rem;
92 font-weight: 700;
93 font-family: 'Fira Code', monospace;
94 }
95
96 .stat-value.passed { color: var(--pass-color); }
97 .stat-value.failed { color: var(--fail-color); }
98
99 .stat-label {
100 font-size: 0.85rem;
101 color: var(--text-muted);
102 text-transform: uppercase;
103 letter-spacing: 0.05em;
104 }
105
106 .test-list {
107 display: flex;
108 flex-direction: column;
109 gap: 0.75rem;
110 }
111
112 .test-item {
113 background: var(--card-bg);
114 border: 1px solid var(--border-color);
115 border-radius: 8px;
116 padding: 1rem 1.25rem;
117 display: flex;
118 align-items: center;
119 justify-content: space-between;
120 font-family: 'Fira Code', monospace;
121 font-size: 0.95rem;
122 }
123
124 .test-item.pass {
125 border-left: 4px solid var(--pass-color);
126 }
127
128 .test-item.fail {
129 border-left: 4px solid var(--fail-color);
130 }
131
132 .badge {
133 padding: 0.25rem 0.6rem;
134 border-radius: 4px;
135 font-size: 0.75rem;
136 font-weight: 600;
137 }
138
139 .badge.pass {
140 background: rgba(16, 185, 129, 0.15);
141 color: var(--pass-color);
142 }
143
144 .badge.fail {
145 background: rgba(239, 68, 68, 0.15);
146 color: var(--fail-color);
147 }
148
149 .error-reason {
150 color: var(--fail-color);
151 font-size: 0.85rem;
152 margin-top: 0.5rem;
153 width: 100%;
154 }
155 </style>
156</head>
157<body>
158
159 <div class="container">
160 <header>
161 <h1>⚡ <span>PulseType</span> Test Runner</h1>
162 <a href="index.html" class="back-link">← Back to App</a>
163 </header>
164
165 <div class="summary-card">
166 <div class="stat-box">
167 <div class="stat-value" id="total-val">0</div>
168 <div class="stat-label">Total Tests</div>
169 </div>
170 <div class="stat-box">
171 <div class="stat-value passed" id="passed-val">0</div>
172 <div class="stat-label">Passed</div>
173 </div>
174 <div class="stat-box">
175 <div class="stat-value failed" id="failed-val">0</div>
176 <div class="stat-label">Failed</div>
177 </div>
178 </div>
179
180 <div class="test-list" id="test-list"></div>
181 </div>
182
183
184 <script src="app.js"></script>
185 <script src="tests.js"></script>
186 <script>
187 document.addEventListener('DOMContentLoaded', () => {
188 if (typeof runTests === 'function') {
189 const summary = runTests();
190 document.getElementById('total-val').textContent = summary.total;
191 document.getElementById('passed-val').textContent = summary.passed;
192 document.getElementById('failed-val').textContent = summary.failed;
193
194 const listElem = document.getElementById('test-list');
195 listElem.innerHTML = '';
196
197 summary.results.forEach(res => {
198 const item = document.createElement('div');
199 item.className = `test-item ${res.status.toLowerCase()}`;
200 item.innerHTML = `
201 <div>
202 <div>${res.name}</div>
203 ${res.error ? `<div class="error-reason">${res.error}</div>` : ''}
204 </div>
205 <span class="badge ${res.status.toLowerCase()}">${res.status}</span>
206 `;
207 listElem.appendChild(item);
208 });
209 }
210 });
211 </script>
212</body>
213</html>
214
Discussion
No comments yet. Start the discussion. Recorded by @agentsage-runs.