117117 font-weight : bold;
118118 }
119119
120+ /* Adjust sticky headings when progress panel is visible */
121+ # progress-panel .show ~ # tests h2 {
122+ top : 158px ; /* 78px + 80px to account for progress panel */
123+ }
124+
120125 /* Style for h2 checkboxes */
121126 # tests h2 input [type = "checkbox" ] {
122127 margin-right : 18px ;
136141 margin-right : 10px ;
137142 font-size : 20px ;
138143 }
144+
145+ /* Progress panel styles */
146+ # progress-panel {
147+ position : fixed;
148+ top : 78px ;
149+ left : 0 ;
150+ right : 0 ;
151+ background : linear-gradient (135deg , # 667eea 0% , # 764ba2 100% );
152+ color : white;
153+ padding : 15px 20px ;
154+ z-index : 999 ;
155+ box-shadow : 0 2px 10px rgba (0 , 0 , 0 , 0.1 );
156+ transform : translateY (-100% );
157+ transition : transform 0.3s ease-in-out;
158+ border-bottom : 3px solid # 4c84af ;
159+ }
160+
161+ # progress-panel .show {
162+ transform : translateY (0 );
163+ }
164+
165+ # progress-panel .show ~ # tests {
166+ padding-top : 120px !important ;
167+ }
168+
169+ .progress-content {
170+ display : flex;
171+ justify-content : space-between;
172+ align-items : center;
173+ max-width : 1200px ;
174+ margin : 0 auto;
175+ }
176+
177+ .progress-left {
178+ flex : 1 ;
179+ }
180+
181+ .progress-right {
182+ display : flex;
183+ gap : 30px ;
184+ align-items : center;
185+ }
186+
187+ .progress-stats {
188+ display : flex;
189+ gap : 20px ;
190+ margin-top : 8px ;
191+ }
192+
193+ .progress-stat {
194+ display : flex;
195+ flex-direction : column;
196+ align-items : center;
197+ min-width : 80px ;
198+ }
199+
200+ .progress-stat-number {
201+ font-size : 24px ;
202+ font-weight : bold;
203+ line-height : 1 ;
204+ }
205+
206+ .progress-stat-label {
207+ font-size : 11px ;
208+ opacity : 0.9 ;
209+ text-transform : uppercase;
210+ letter-spacing : 0.5px ;
211+ }
212+
213+ .current-test {
214+ font-size : 16px ;
215+ font-weight : 500 ;
216+ margin-bottom : 5px ;
217+ }
218+
219+ .progress-bar-container {
220+ background : rgba (255 , 255 , 255 , 0.2 );
221+ border-radius : 10px ;
222+ height : 8px ;
223+ overflow : hidden;
224+ margin-top : 10px ;
225+ }
226+
227+ .progress-bar {
228+ background : linear-gradient (90deg , # 00c851 0% , # 00ff88 100% );
229+ height : 100% ;
230+ border-radius : 10px ;
231+ transition : width 0.3s ease;
232+ width : 0% ;
233+ }
234+
235+ .progress-percentage {
236+ font-size : 28px ;
237+ font-weight : bold;
238+ color : # fff ;
239+ }
240+
241+ .stat-passed {
242+ color : # 00ff88 ;
243+ }
244+
245+ .stat-failed {
246+ color : # ff6b6b ;
247+ }
248+
249+ .stat-total {
250+ color : # fff ;
251+ }
252+
253+ .elapsed-time {
254+ font-size : 12px ;
255+ opacity : 0.8 ;
256+ margin-top : 2px ;
257+ }
139258 </ style >
140259 < script >
141260 document . addEventListener ( "DOMContentLoaded" , ( ) => {
142261
262+ // Progress tracking variables
263+ let testProgress = {
264+ total : 0 ,
265+ completed : 0 ,
266+ passed : 0 ,
267+ failed : 0 ,
268+ startTime : null ,
269+ currentTest : '' ,
270+ timerInterval : null
271+ } ;
272+
273+ // Progress panel functions
274+ function showProgressPanel ( ) {
275+ $ ( '#progress-panel' ) . addClass ( 'show' ) ;
276+ $ ( '#run-tests' ) . prop ( 'disabled' , true ) . text ( 'Running Tests...' ) ;
277+ startProgressTimer ( ) ;
278+ }
279+
280+ function hideProgressPanel ( ) {
281+ $ ( '#progress-panel' ) . removeClass ( 'show' ) ;
282+ $ ( '#run-tests' ) . prop ( 'disabled' , false ) . text ( 'Run Tests' ) ;
283+ stopProgressTimer ( ) ;
284+ }
285+
286+ function updateProgressPanel ( ) {
287+ const { total, completed, passed, failed, currentTest } = testProgress ;
288+ const percentage = total > 0 ? Math . round ( ( completed / total ) * 100 ) : 0 ;
289+
290+ $ ( '#current-test' ) . text ( currentTest || 'Preparing tests...' ) ;
291+ $ ( '#progress-bar' ) . css ( 'width' , percentage + '%' ) ;
292+ $ ( '#progress-percentage' ) . text ( percentage + '%' ) ;
293+ $ ( '#passed-count' ) . text ( passed ) ;
294+ $ ( '#failed-count' ) . text ( failed ) ;
295+ $ ( '#total-count' ) . text ( total ) ;
296+ }
297+
298+ function startProgressTimer ( ) {
299+ testProgress . startTime = Date . now ( ) ;
300+ testProgress . timerInterval = setInterval ( ( ) => {
301+ const elapsed = Math . floor ( ( Date . now ( ) - testProgress . startTime ) / 1000 ) ;
302+ $ ( '#elapsed-time' ) . text ( `Elapsed: ${ elapsed } s` ) ;
303+ } , 1000 ) ;
304+ }
305+
306+ function stopProgressTimer ( ) {
307+ if ( testProgress . timerInterval ) {
308+ clearInterval ( testProgress . timerInterval ) ;
309+ testProgress . timerInterval = null ;
310+ }
311+ }
312+
313+ function resetProgress ( ) {
314+ testProgress . total = 0 ;
315+ testProgress . completed = 0 ;
316+ testProgress . passed = 0 ;
317+ testProgress . failed = 0 ;
318+ testProgress . currentTest = '' ;
319+ testProgress . startTime = null ;
320+ }
321+
322+ function getSelectedTestsCount ( ) {
323+ return $ ( '.test-checkbox:checked' ) . length ;
324+ }
325+
326+ // Small delay to make progress visible
327+ function delay ( ms ) {
328+ return new Promise ( resolve => setTimeout ( resolve , ms ) ) ;
329+ }
330+
143331 window . pass = function ( msg ) {
144332 // $('#tests').append(`<p style="color:green;">${msg}</p>`);
145333 }
341529 window . runSingleTest = runSingleTest ;
342530
343531 async function runTests ( ) {
532+ // Reset and initialize progress tracking
533+ resetProgress ( ) ;
534+ testProgress . total = getSelectedTestsCount ( ) ;
535+
536+ // Show progress panel
537+ showProgressPanel ( ) ;
538+ updateProgressPanel ( ) ;
539+
540+ // Clear previous test results
541+ $ ( '.test-container' ) . css ( 'background-color' , '' ) ;
542+ $ ( '.test-container pre' ) . remove ( ) ;
543+
344544 // go through fsTests and run each test
345545 for ( let i = 0 ; i < fsTests . length ; i ++ ) {
346546 if ( document . getElementById ( `fsTests${ i } ` ) . checked ) {
547+ const testInfo = getTestInfo ( fsTests [ i ] ) ;
548+ testProgress . currentTest = `FileSystem: ${ testInfo . name } ` ;
549+ updateProgressPanel ( ) ;
550+
347551 try {
348552 await executeTest ( fsTests [ i ] ) ;
349553 // make this test's container green
350554 $ ( `#fsTests-container-${ i } ` ) . css ( 'background-color' , '#85e085' ) ;
351-
555+ testProgress . passed ++ ;
352556 } catch ( e ) {
353- const testInfo = getTestInfo ( fsTests [ i ] ) ;
354557 console . error ( 'FS Test failed:' , testInfo . name , e ) ;
355558 // make this test's container red
356559 $ ( `#fsTests-container-${ i } ` ) . css ( 'background-color' , '#ffbfbf' ) ;
360563 errorMessage += '\n\nOriginal Error:\n' + JSON . stringify ( e . originalError , null , 2 ) ;
361564 }
362565 $ ( `#fsTests-container-${ i } ` ) . append ( `<pre style="color:#c00000; white-space: pre-wrap; font-size: 12px; margin: 5px 0; padding: 10px; background-color: #f8f8f8; border-radius: 3px;">${ errorMessage } </pre>` ) ;
566+ testProgress . failed ++ ;
363567 }
568+
569+ testProgress . completed ++ ;
570+ updateProgressPanel ( ) ;
571+
572+ // Small delay to make progress visible
573+ await delay ( 100 ) ;
364574 }
365575 }
366576
367577 for ( let i = 0 ; i < kvTests . length ; i ++ ) {
368578 if ( document . getElementById ( `kvTests${ i } ` ) . checked ) {
579+ const testInfo = getTestInfo ( kvTests [ i ] ) ;
580+ testProgress . currentTest = `Key-Value Store: ${ testInfo . name } ` ;
581+ updateProgressPanel ( ) ;
582+
369583 try {
370584 await executeTest ( kvTests [ i ] ) ;
371585 // make this test's container green
372586 $ ( `#kvTests-container-${ i } ` ) . css ( 'background-color' , '#85e085' ) ;
373-
587+ testProgress . passed ++ ;
374588 } catch ( e ) {
375- const testInfo = getTestInfo ( kvTests [ i ] ) ;
376589 console . error ( 'KV Test failed:' , testInfo . name , e ) ;
377590 // make this test's container red
378591 $ ( `#kvTests-container-${ i } ` ) . css ( 'background-color' , '#ff8484' ) ;
382595 errorMessage += '\n\nOriginal Error:\n' + JSON . stringify ( e . originalError , null , 2 ) ;
383596 }
384597 $ ( `#kvTests-container-${ i } ` ) . append ( `<pre style="color:red; white-space: pre-wrap; font-size: 12px; margin: 5px 0; padding: 10px; background-color: #f8f8f8; border-radius: 3px;">${ errorMessage } </pre>` ) ;
598+ testProgress . failed ++ ;
385599 }
600+
601+ testProgress . completed ++ ;
602+ updateProgressPanel ( ) ;
603+
604+ // Small delay to make progress visible
605+ await delay ( 100 ) ;
386606 }
387607 }
388608
389609 for ( let i = 0 ; i < aiTests . length ; i ++ ) {
390610 if ( document . getElementById ( `aiTests${ i } ` ) . checked ) {
611+ const testInfo = getTestInfo ( aiTests [ i ] ) ;
612+ testProgress . currentTest = `AI: ${ testInfo . name } ` ;
613+ updateProgressPanel ( ) ;
614+
391615 try {
392616 await executeTest ( aiTests [ i ] ) ;
393617 // make this test's container green
394618 $ ( `#aiTests-container-${ i } ` ) . css ( 'background-color' , '#85e085' ) ;
395-
619+ testProgress . passed ++ ;
396620 } catch ( e ) {
397- const testInfo = getTestInfo ( aiTests [ i ] ) ;
398621 console . error ( 'AI Test failed:' , testInfo . name , e ) ;
399622 // make this test's container red
400623 $ ( `#aiTests-container-${ i } ` ) . css ( 'background-color' , '#ff8484' ) ;
404627 errorMessage += '\n\nOriginal Error:\n' + JSON . stringify ( e . originalError , null , 2 ) ;
405628 }
406629 $ ( `#aiTests-container-${ i } ` ) . append ( `<pre style="color:red; white-space: pre-wrap; font-size: 12px; margin: 5px 0; padding: 10px; background-color: #f8f8f8; border-radius: 3px;">${ errorMessage } </pre>` ) ;
630+ testProgress . failed ++ ;
407631 }
632+
633+ testProgress . completed ++ ;
634+ updateProgressPanel ( ) ;
635+
636+ // Small delay to make progress visible
637+ await delay ( 100 ) ;
408638 }
409639 }
640+
641+ // Show completion message
642+ testProgress . currentTest = `Complete! ${ testProgress . passed } passed, ${ testProgress . failed } failed` ;
643+ updateProgressPanel ( ) ;
644+
645+ // Stop the elapsed timer but keep panel visible
646+ stopProgressTimer ( ) ;
647+
648+ // Re-enable the run tests button
649+ $ ( '#run-tests' ) . prop ( 'disabled' , false ) . text ( 'Run Tests' ) ;
410650 }
411651
412652 $ ( '#run-tests' ) . click ( ( ) => {
467707 < button id ="run-tests " style ="margin-right: 30px; "> Run Tests</ button >
468708 </ div >
469709 </ nav >
710+
711+ < div id ="progress-panel ">
712+ < div class ="progress-content ">
713+ < div class ="progress-left ">
714+ < div class ="current-test " id ="current-test "> Preparing tests...</ div >
715+ < div class ="progress-bar-container ">
716+ < div class ="progress-bar " id ="progress-bar "> </ div >
717+ </ div >
718+ < div class ="elapsed-time " id ="elapsed-time "> Elapsed: 0s</ div >
719+ </ div >
720+ < div class ="progress-right ">
721+ < div class ="progress-stats ">
722+ < div class ="progress-stat ">
723+ < div class ="progress-stat-number stat-passed " id ="passed-count "> 0</ div >
724+ < div class ="progress-stat-label "> Passed</ div >
725+ </ div >
726+ < div class ="progress-stat ">
727+ < div class ="progress-stat-number stat-failed " id ="failed-count "> 0</ div >
728+ < div class ="progress-stat-label "> Failed</ div >
729+ </ div >
730+ < div class ="progress-stat ">
731+ < div class ="progress-stat-number stat-total " id ="total-count "> 0</ div >
732+ < div class ="progress-stat-label "> Total</ div >
733+ </ div >
734+ </ div >
735+ < div class ="progress-percentage " id ="progress-percentage "> 0%</ div >
736+ </ div >
737+ </ div >
738+ </ div >
739+
470740 < div id ="tests "> </ div >
471741</ body >
472742</ html >
0 commit comments