22< html >
33< head >
44 < title > jsPDF Test Report</ title >
5+ < link href ="
https://cdn.jsdelivr.net/npm/[email protected] /dist/tailwind.min.css "
rel ="
stylesheet "
> 56 < style >
6- body {
7- margin : 0 ;
8- font-family : system-ui, -apple-system, sans-serif;
9- }
10- .container {
11- display : grid;
12- grid-template-columns : 300px 1fr ;
13- height : 100vh ;
14- }
15- .sidebar {
16- background : # f5f5f5 ;
17- padding : 20px ;
18- border-right : 1px solid # ddd ;
19- overflow-y : auto;
20- }
21- .main {
22- padding : 20px ;
23- overflow-y : auto;
24- }
25- .summary {
26- margin-bottom : 20px ;
27- padding : 15px ;
28- background : white;
29- border-radius : 8px ;
30- box-shadow : 0 1px 3px rgba (0 , 0 , 0 , 0.1 );
31- }
32- .failure-item {
33- padding : 10px ;
34- margin : 5px 0 ;
35- background : white;
36- border-radius : 4px ;
37- cursor : pointer;
38- border : 1px solid # ddd ;
39- }
40- .failure-item : hover {
41- background : # f0f0f0 ;
42- }
43- .failure-item .selected {
44- background : # e3f2fd ;
45- border-color : # 2196f3 ;
46- }
47- .pdf-view {
48- display : grid;
49- grid-template-columns : 1fr 1fr ;
50- gap : 20px ;
51- margin-top : 20px ;
52- }
53- .pdf-container {
54- border : 1px solid # ddd ;
55- padding : 10px ;
56- border-radius : 4px ;
57- }
58- .pdf-container h3 {
59- margin-top : 0 ;
60- }
61- iframe {
7+ /* Preserve existing styles that are still needed */
8+ .pdf-container iframe {
629 width : 100% ;
6310 height : 800px ;
6411 border : none;
6512 }
6613 .differences {
6714 white-space : pre-wrap;
6815 font-family : monospace;
69- background : # f8f8f8 ;
70- padding : 10px ;
71- border-radius : 4px ;
72- margin-top : 20px ;
7316 }
74- .section {
75- margin-bottom : 30px ;
17+ /* New styles for Shadcn-like look with purple theme */
18+ .sidebar {
19+ background-color : hsl (0 0% 100% );
20+ border-right : 1px solid hsl (240 6% 90% );
7621 }
77- .section h3 {
78- margin-bottom : 10px ;
22+ .main {
23+ background-color : hsl (240 3.7% 97.5% );
24+ }
25+ .card {
26+ background-color : hsl (0 0% 100% );
27+ border : 1px solid hsl (240 6% 90% );
28+ border-radius : 0.5rem ;
29+ box-shadow : 0 1px 2px 0 rgb (0 0 0 / 0.05 );
30+ }
31+ .nav-item {
32+ padding : 0.5rem ;
33+ margin : 0.25rem 0 ;
34+ border-radius : 0.375rem ;
35+ cursor : pointer;
36+ transition : background-color 0.2s ;
37+ display : flex;
38+ align-items : center;
39+ gap : 0.5rem ;
40+ }
41+ .nav-item : hover {
42+ background-color : hsl (240 5% 96% );
43+ }
44+ .nav-item .selected {
45+ background-color : hsl (244.9 40% 97% );
46+ color : hsl (244.9 40% 40% );
47+ font-weight : 500 ;
48+ }
49+ .badge {
50+ display : inline-flex;
51+ align-items : center;
52+ border-radius : 9999px ;
53+ padding : 0.125rem 0.5rem ;
54+ font-size : 0.75rem ;
55+ font-weight : 500 ;
56+ line-height : 1 ;
57+ white-space : nowrap;
58+ }
59+ .badge-success { background-color : hsl (142.1 76.2% 36.3% / 0.1 ); color : hsl (142.1 76.2% 36.3% ); }
60+ .badge-error { background-color : hsl (346.8 77.2% 49.8% / 0.1 ); color : hsl (346.8 77.2% 49.8% ); }
61+ .badge-warning { background-color : hsl (48 96.5% 53.8% / 0.1 ); color : hsl (48 96.5% 53.8% ); }
62+ .icon {
63+ width : 1rem ;
64+ height : 1rem ;
7965 }
8066 </ style >
8167</ head >
82- < body >
83- < div class ="container ">
84- < div class ="sidebar ">
85- < div class ="summary section ">
86- < h2 > Test Summary</ h2 >
87- < div id ="summary "> </ div >
88- </ div >
89- < div class ="section ">
90- < h3 > Failed Tests</ h3 >
91- < div id ="failures "> </ div >
92- </ div >
93- < div class ="section ">
94- < h3 > Actual PDFs</ h3 >
95- < div id ="pdfs "> </ div >
68+ < body class ="antialiased ">
69+ < div class ="flex h-screen ">
70+ <!-- Sidebar -->
71+ < div class ="w-80 flex flex-col sidebar overflow-y-auto p-4 ">
72+ < div class ="space-y-4 ">
73+ <!-- Summary Card -->
74+ < div class ="card p-4 ">
75+ < h2 class ="text-lg font-semibold mb-3 text-purple-900 "> Test Summary</ h2 >
76+ < div id ="summary " class ="space-y-2 "> </ div >
77+ </ div >
78+
79+ <!-- Failed Tests -->
80+ < div class ="space-y-2 ">
81+ < h3 class ="text-sm font-medium text-purple-900 "> Failed Tests</ h3 >
82+ < div id ="failures " class ="space-y-1 "> </ div >
83+ </ div >
84+
85+ <!-- Actual PDFs -->
86+ < div class ="space-y-2 ">
87+ < h3 class ="text-sm font-medium text-purple-900 "> Actual PDFs</ h3 >
88+ < div id ="pdfs " class ="space-y-1 "> </ div >
89+ </ div >
9690 </ div >
9791 </ div >
98- < div class ="main ">
99- < div id ="details "> </ div >
92+
93+ <!-- Main Content -->
94+ < div class ="flex-1 main overflow-y-auto p-6 ">
95+ < div id ="details " class ="max-w-6xl mx-auto "> </ div >
10096 </ div >
10197 </ div >
10298
@@ -106,12 +102,26 @@ <h3>Actual PDFs</h3>
106102 < script >
107103 let selectedItem = null ;
108104
105+ const documentIcon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><line x1="10" y1="9" x2="8" y2="9"></line></svg>` ;
106+
109107 function formatSummary ( results ) {
110108 return `
111- <div>Total: ${ results . total } </div>
112- <div style="color: #4caf50">Passed: ${ results . passed } </div>
113- <div style="color: #f44336">Failed: ${ results . failed } </div>
114- <div style="color: #ff9800">Skipped: ${ results . skipped } </div>
109+ <div class="flex items-center justify-between">
110+ <span class="text-sm">Total</span>
111+ <span class="badge bg-purple-100 text-purple-800">${ results . total } </span>
112+ </div>
113+ <div class="flex items-center justify-between">
114+ <span class="text-sm">Passed</span>
115+ <span class="badge badge-success">${ results . passed } </span>
116+ </div>
117+ <div class="flex items-center justify-between">
118+ <span class="text-sm">Failed</span>
119+ <span class="badge badge-error">${ results . failed } </span>
120+ </div>
121+ <div class="flex items-center justify-between">
122+ <span class="text-sm">Skipped</span>
123+ <span class="badge badge-warning">${ results . skipped } </span>
124+ </div>
115125 ` ;
116126 }
117127
@@ -126,23 +136,43 @@ <h3>Actual PDFs</h3>
126136 selectedItem = item . id ;
127137
128138 details . innerHTML = `
129- <h2>${ item . name } </h2>
130- <div class="pdf-view">
131- <div class="pdf-container">
132- <h3>Actual PDF</h3>
133- <iframe src="/${ item . actualPdf } "></iframe>
139+ <div class="card">
140+ <div class="p-4 border-b">
141+ <h2 class="text-lg font-semibold text-purple-900">${ item . name } </h2>
134142 </div>
135- <div class="pdf-container">
136- <h3>Reference PDF</h3>
137- <iframe src="/${ item . referencePdf } "></iframe>
143+ <div class="p-4">
144+ <div class="grid grid-cols-2 gap-6">
145+ <div class="card">
146+ <div class="p-3 border-b">
147+ <h3 class="font-medium text-purple-900">Actual PDF</h3>
148+ </div>
149+ <div class="pdf-container">
150+ <iframe src="/${ item . actualPdf } "></iframe>
151+ </div>
152+ </div>
153+ <div class="card">
154+ <div class="p-3 border-b">
155+ <h3 class="font-medium text-purple-900">Reference PDF</h3>
156+ </div>
157+ <div class="pdf-container">
158+ <iframe src="/${ item . referencePdf } "></iframe>
159+ </div>
160+ </div>
161+ </div>
162+ ${ item . error ? `
163+ <div class="mt-6">
164+ <div class="card">
165+ <div class="p-3 border-b">
166+ <h3 class="font-medium text-purple-900">Differences</h3>
167+ </div>
168+ <div class="p-4 bg-purple-50 differences">
169+ <pre class="text-sm">${ item . error } </pre>
170+ </div>
171+ </div>
172+ </div>
173+ ` : '' }
138174 </div>
139175 </div>
140- ${ item . error ? `
141- <div class="differences">
142- <h3>Differences</h3>
143- <pre>${ item . error } </pre>
144- </div>
145- ` : '' }
146176 ` ;
147177 }
148178
@@ -155,22 +185,28 @@ <h3>Differences</h3>
155185 // Update failures list
156186 const failures = results . failures || [ ] ;
157187 const failuresHtml = failures . map ( failure => `
158- <div id="failure_${ failure . name . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '_' ) } " class="failure-item" onclick='showPdfComparison(${ JSON . stringify ( { ...failure , id : "failure_" + failure . name . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '_' ) } ) . replace ( / ' / g, "'" ) } )'>
188+ <div id="failure_${ failure . name . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '_' ) } "
189+ class="nav-item text-sm"
190+ onclick='showPdfComparison(${ JSON . stringify ( { ...failure , id : "failure_" + failure . name . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '_' ) } ) . replace ( / ' / g, "'" ) } )'>
191+ ${ documentIcon }
159192 ${ failure . name }
160193 </div>
161194 ` ) . join ( '' ) ;
162- document . getElementById ( 'failures' ) . innerHTML = failuresHtml || '<div class="failure -item">No failures</div>' ;
195+ document . getElementById ( 'failures' ) . innerHTML = failuresHtml || '<div class="nav -item text-sm text-gray-500 ">No failures</div>' ;
163196
164197 // Load and display actual PDFs
165198 try {
166199 const response = await fetch ( '/api/pdfs' ) ;
167200 const pdfs = await response . json ( ) ;
168201 const pdfsHtml = pdfs . map ( pdf => `
169- <div id="pdf_${ pdf . name . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '_' ) } " class="failure-item" onclick='showPdfComparison(${ JSON . stringify ( { ...pdf , id : "pdf_" + pdf . name . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '_' ) } ) . replace ( / ' / g, "'" ) } )'>
202+ <div id="pdf_${ pdf . name . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '_' ) } "
203+ class="nav-item text-sm"
204+ onclick='showPdfComparison(${ JSON . stringify ( { ...pdf , id : "pdf_" + pdf . name . replace ( / [ ^ a - z A - Z 0 - 9 ] / g, '_' ) } ) . replace ( / ' / g, "'" ) } )'>
205+ ${ documentIcon }
170206 ${ pdf . name }
171207 </div>
172208 ` ) . join ( '' ) ;
173- document . getElementById ( 'pdfs' ) . innerHTML = pdfsHtml || '<div class="failure -item">No PDFs found</div>' ;
209+ document . getElementById ( 'pdfs' ) . innerHTML = pdfsHtml || '<div class="nav -item text-sm text-gray-500 ">No PDFs found</div>' ;
174210
175211 // Show first failure by default, or first PDF if no failures
176212 if ( failures . length > 0 ) {
@@ -181,7 +217,7 @@ <h3>Differences</h3>
181217 } catch ( error ) {
182218 console . error ( 'Failed to load PDFs:' , error ) ;
183219 document . getElementById ( 'pdfs' ) . innerHTML = `
184- <div class="failure -item">
220+ <div class="nav -item text-sm text-red-500 ">
185221 Failed to load PDFs: ${ error . message }
186222 </div>
187223 ` ;
0 commit comments