ortoni-report 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,120 +1,34 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en" data-theme="{{preferredTheme}}">
3
-
4
3
  <head>
5
4
  <meta charset="UTF-8">
6
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <meta name="description" content="Playwright HTML report by LetCode Koushik - V2.0.3">
6
+ <meta name="description" content="Playwright HTML report by LetCode Koushik - V2.0.5">
8
7
  <title>{{title}}</title>
9
- <link rel="icon" href="https://raw.githubusercontent.com/ortoniKC/ortoni-report/refs/heads/main/favicon.png" type="image/x-icon">
8
+ <link rel="icon" href="https://raw.githubusercontent.com/ortoniKC/ortoni-report/refs/heads/main/favicon.png"
9
+ type="image/x-icon">
10
10
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css"
11
11
  integrity="sha512-Kc323vGBEqzTmouAECnVceyQqyqdsSiqLQISBL29aUW4U/M7pSPA/gEUZQqv1cwx4OnYxTxve5UMg5GT6L4JJg=="
12
12
  crossorigin="anonymous" referrerpolicy="no-referrer" />
13
13
  </head>
14
14
  <style>
15
15
  {{{inlineCss}}}
16
- </style>
16
+ </style>
17
17
  <body>
18
- {{> navbar}}
18
+ {{> navbar }}
19
19
  <section class="section">
20
20
  <main class="container">
21
21
  <div class="columns">
22
22
  <aside class="column is-two-fifths">
23
23
  {{> testPanel}}
24
- <div class="content sidebar">
25
- {{#if showProject}}
26
- {{#each groupedResults}}
27
- <details class="box">
28
- <summary class="is-size-5 has-icon-right">
29
- <div class="icon-text">
30
- <span class="icon has-text-info">
31
- <svg class="image is-16x16" height="512" viewBox="0 0 32 32" width="512" xmlns="http://www.w3.org/2000/svg"><g data-name="Layer 2"><path d="M11.612 30.945a3.986 3.986 0 01-2.829-1.17l-5.209-5.208a4.006 4.006 0 010-5.657l3.955-3.954a1 1 0 011.414 1.414l-3.955 3.954a2.003 2.003 0 000 2.829l5.21 5.208a2.004 2.004 0 002.828 0l7.235-7.234a2.003 2.003 0 000-2.828l-4.63-4.63a1 1 0 011.414-1.414l4.63 4.63a4.006 4.006 0 010 5.657l-7.235 7.233a3.988 3.988 0 01-2.828 1.17z" fill="#232323"/><path d="M15.662 20.038a.997.997 0 01-.707-.293l-4.63-4.63a4.006 4.006 0 010-5.656l7.235-7.234a4.004 4.004 0 015.657 0l5.209 5.208a4.006 4.006 0 010 5.657l-3.955 3.954a1 1 0 01-1.414-1.414l3.955-3.954a2.003 2.003 0 000-2.829l-5.21-5.208a2.002 2.002 0 00-2.828 0l-7.235 7.234a2.003 2.003 0 000 2.828l4.63 4.63a1 1 0 01-.707 1.707z" fill="#7fbde7"/></g></svg>
32
- </span>
33
- <span>{{@key}}</span>
34
- </div>
35
- </summary>
36
- <ul class="mt-4 mb-4">
37
- {{#each this}}
38
- <details class="mt-2 mb-2">
39
- <summary class="is-size-5 is-capitalized">
40
- <div class="icon-text">
41
- <span class="icon has-text-info">
42
- <svg class="image is-16x16"xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M181.344 42.656v394.671C181.344 478.562 214.781 512 256 512c41.25 0 74.672-33.438 74.672-74.673V42.656H181.344z" fill="#e6e9ed"/><path d="M352 32c0 17.672-14.312 32-32 32H192c-17.656 0-32-14.328-32-32s14.344-32 32-32h128c17.688 0 32 14.328 32 32z" fill="#ccd1d9"/><path d="M181.344 192v245.327C181.344 478.562 214.781 512 256 512c41.25 0 74.672-33.438 74.672-74.673V192H181.344z" fill="#a0d468"/><g fill="#434a54"><path d="M245.344 266.655c0-5.89-4.781-10.655-10.672-10.655h-53.328v21.328h53.328c5.89 0 10.672-4.781 10.672-10.673zM234.672 319.999h-53.328v21.328h53.328c5.891 0 10.672-4.781 10.672-10.671s-4.782-10.657-10.672-10.657zM245.344 202.656c0-5.891-4.781-10.656-10.672-10.656h-53.328v21.328h53.328c5.89 0 10.672-4.781 10.672-10.672z"/></g></svg>
43
- </span>
44
- <span>{{@key}}</span>
45
- </div>
46
- </summary>
47
- <ul class="mt-4 mb-4">
48
- {{#each this}}
49
- <details class="mt-2 mb-2">
50
- <summary class="is-capitalized is-size-6">{{@key}}</summary>
51
- <ul class="mt-4 mb-4">
52
- {{#each this}}
53
- <li class="media {{#if (eq status 'skipped')}}is-hidden{{/if}}" data-suite-name="{{suite}}"
54
- data-test-duration="{{duration}}" data-test-tags="{{joinWithSpace testTags}}"
55
- data-project-name="{{projectName}}" data-test-id="{{index}}"
56
- data-test-status="{{status}} {{retry}}">
57
- {{> testStatus}}
58
- </li>
59
- {{/each}}
60
- </ul>
61
- </details>
62
- {{/each}}
63
- </ul>
64
- </details>
65
- {{/each}}
66
- </ul>
67
- </details>
68
- {{/each}}
69
- {{else}}
70
- {{#each groupedResults}}
71
- <details class="box">
72
- <summary class="is-size-5 has-icon-right">
73
- <div class="icon-text">
74
- <span class="icon has-text-info">
75
- <svg class="image is-16x16" height="512" viewBox="0 0 32 32" width="512" xmlns="http://www.w3.org/2000/svg"><g data-name="Layer 2"><path d="M11.612 30.945a3.986 3.986 0 01-2.829-1.17l-5.209-5.208a4.006 4.006 0 010-5.657l3.955-3.954a1 1 0 011.414 1.414l-3.955 3.954a2.003 2.003 0 000 2.829l5.21 5.208a2.004 2.004 0 002.828 0l7.235-7.234a2.003 2.003 0 000-2.828l-4.63-4.63a1 1 0 011.414-1.414l4.63 4.63a4.006 4.006 0 010 5.657l-7.235 7.233a3.988 3.988 0 01-2.828 1.17z" fill="#232323"/><path d="M15.662 20.038a.997.997 0 01-.707-.293l-4.63-4.63a4.006 4.006 0 010-5.656l7.235-7.234a4.004 4.004 0 015.657 0l5.209 5.208a4.006 4.006 0 010 5.657l-3.955 3.954a1 1 0 01-1.414-1.414l3.955-3.954a2.003 2.003 0 000-2.829l-5.21-5.208a2.002 2.002 0 00-2.828 0l-7.235 7.234a2.003 2.003 0 000 2.828l4.63 4.63a1 1 0 01-.707 1.707z" fill="#7fbde7"/></g></svg>
76
- </span>
77
- <span>{{@key}}</span>
78
- </div>
79
- </summary>
80
- <ul class="mt-4 mb-4">
81
- {{#each this}}
82
- <details class="mt-2 mb-2">
83
- <summary class="is-size-5 is-capitalized">
84
- <div class="icon-text">
85
- <span class="icon has-text-info">
86
- <svg class="image is-16x16"xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M181.344 42.656v394.671C181.344 478.562 214.781 512 256 512c41.25 0 74.672-33.438 74.672-74.673V42.656H181.344z" fill="#e6e9ed"/><path d="M352 32c0 17.672-14.312 32-32 32H192c-17.656 0-32-14.328-32-32s14.344-32 32-32h128c17.688 0 32 14.328 32 32z" fill="#ccd1d9"/><path d="M181.344 192v245.327C181.344 478.562 214.781 512 256 512c41.25 0 74.672-33.438 74.672-74.673V192H181.344z" fill="#a0d468"/><g fill="#434a54"><path d="M245.344 266.655c0-5.89-4.781-10.655-10.672-10.655h-53.328v21.328h53.328c5.89 0 10.672-4.781 10.672-10.673zM234.672 319.999h-53.328v21.328h53.328c5.891 0 10.672-4.781 10.672-10.671s-4.782-10.657-10.672-10.657zM245.344 202.656c0-5.891-4.781-10.656-10.672-10.656h-53.328v21.328h53.328c5.89 0 10.672-4.781 10.672-10.672z"/></g></svg>
87
- </span>
88
- <span>{{@key}}</span>
89
- </div>
90
- </summary>
91
- <ul class="mt-4 mb-4">
92
- {{#each this}}
93
- <li class="media {{#if (eq status 'skipped')}}is-hidden{{/if}}" data-suite-name="{{suite}}"
94
- data-test-duration="{{duration}}" data-test-tags="{{joinWithSpace testTags}}"
95
- data-project-name="{{projectName}}" data-test-id="{{index}}"
96
- data-test-status="{{status}} {{retry}}">
97
- {{> testStatus}}
98
- </li>
99
- {{/each}}
100
- </ul>
101
- </details>
102
- {{/each}}
103
- </ul>
104
- </details>
105
- {{/each}}
106
- {{/if}}
107
- </div>
24
+ {{> project}}
108
25
  </aside>
109
26
  <section class="column is-three-fifths">
110
- {{!-- Overall summary --}}
111
27
  <div id="summary">
112
- <div class="columns is-multiline">
28
+ <div class="columns is-multiline has-text-centered">
113
29
  {{> summaryCard bg="primary" status="all" statusHeader="All Tests" statusCount=totalCount}}
114
30
  {{> summaryCard bg="success" status="passed" statusHeader="Passed" statusCount=passCount}}
115
31
  {{> summaryCard bg="danger" status="failed" statusHeader="Failed" statusCount=failCount}}
116
- </div>
117
- <div class="columns is-multiline">
118
32
  {{> summaryCard bg="info" status="skipped" statusHeader="Skipped" statusCount=skipCount}}
119
33
  {{> summaryCard bg="warning" status="flaky" statusHeader="Flaky" statusCount=flakyCount}}
120
34
  {{> summaryCard bg="retry" status="retry" statusHeader="Retry" statusCount=retryCount}}
@@ -123,33 +37,14 @@
123
37
  {{> userInfo}}
124
38
  </div>
125
39
  </div>
126
- {{!-- Test details --}}
127
- <div id="testDetails" style="display: none;">
128
- <!-- Back button should be outside the dynamic content -->
129
- <button class="button content" id="back-to-summary" onclick="showSummary()">Back to
130
- Summary</button>
131
- <!-- Test Details will be displayed here -->
132
- </div>
40
+ <div id="testDetails" style="display: none;"></div>
133
41
  </section>
134
42
  </div>
135
43
  </main>
136
44
  </section>
137
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
138
45
  <script>
139
- function escapeHtml(unsafe) {
140
- return unsafe.replace(/[&<"']/g, function (match) {
141
- const escapeMap = {
142
- '&': '&amp;',
143
- '<': '&lt;',
144
- '>': '&gt;',
145
- '"': '&quot;',
146
- "'": '&#039;'
147
- };
148
- return escapeMap[match];
149
- });
150
- }
151
46
  document.addEventListener('DOMContentLoaded', () => {
152
- const testData = {{{ json results }}};
47
+ let testData = {{{ json results }}};
153
48
  const testDetails = document.getElementById('testDetails');
154
49
  const summary = document.getElementById('summary');
155
50
  const backButton = document.querySelector('button#back-to-summary');
@@ -158,21 +53,21 @@
158
53
  const preferredTheme = themeButton.getAttribute("data-theme-status");
159
54
  const themeIcon = document.getElementById("theme-icon");
160
55
  const htmlElement = document.documentElement;
161
-
56
+
162
57
  if (preferredTheme === 'dark') {
163
58
  htmlElement.setAttribute('data-theme', 'dark');
164
- themeIcon.classList='';
165
- themeIcon.classList.add("fa","fa-moon");
59
+ themeIcon.classList = '';
60
+ themeIcon.classList.add("fa", "fa-moon");
166
61
  } else if (preferredTheme === 'light') {
167
62
  htmlElement.setAttribute('data-theme', 'light');
168
- themeIcon.classList='';
169
- themeIcon.classList.add("fa","fa-sun");
63
+ themeIcon.classList = '';
64
+ themeIcon.classList.add("fa", "fa-sun");
170
65
  } else {
171
- if(window.matchMedia('(prefers-color-scheme: light)').matches){
172
- themeIcon.classList.add("fa","fa-sun");
66
+ if (window.matchMedia('(prefers-color-scheme: light)').matches) {
67
+ themeIcon.classList.add("fa", "fa-sun");
173
68
  }
174
- else{
175
- themeIcon.classList.add("fa","fa-moon");
69
+ else {
70
+ themeIcon.classList.add("fa", "fa-moon");
176
71
  }
177
72
  }
178
73
  themeButton.addEventListener('click', () => {
@@ -180,22 +75,29 @@
180
75
  const newTheme = currentTheme === 'light' ? 'dark' : 'light';
181
76
  htmlElement.setAttribute('data-theme', newTheme);
182
77
  if (newTheme === 'dark') {
183
- themeIcon.classList='';
184
- themeIcon.classList.add("fa","fa-moon");
78
+ themeIcon.classList = '';
79
+ themeIcon.classList.add("fa", "fa-moon");
185
80
  } else {
186
- themeIcon.classList='';
187
- themeIcon.classList.add("fa","fa-sun");
81
+ themeIcon.classList = '';
82
+ themeIcon.classList.add("fa", "fa-sun");
188
83
  }
189
84
  });
190
85
 
191
86
  function showSummary() {
192
87
  summary.style.display = 'block';
193
88
  testDetails.style.display = 'none';
194
- backButton.style.display = 'none';
195
89
  }
196
90
  window.showSummary = showSummary;
197
91
 
198
92
  function displayTestDetails(test) {
93
+ const summary = document.getElementById('summary');
94
+ const testDetails = document.getElementById('testDetails');
95
+ summary.style.display = 'none';
96
+ testDetails.style.opacity = '0';
97
+ testDetails.style.display = 'block';
98
+ setTimeout(() => {
99
+ testDetails.style.opacity = '1';
100
+ }, 50);
199
101
  let currentScreenshotIndex = 0;
200
102
  function changeScreenshot(direction) {
201
103
  const screenshots = test.screenshots;
@@ -221,85 +123,83 @@
221
123
  }
222
124
  });
223
125
  }
224
- const summary = document.getElementById('summary');
225
- const testDetails = document.getElementById('testDetails');
226
- const backButton = document.querySelector('button#back-to-summary');
227
- summary.style.display = 'none';
228
- testDetails.style.opacity = '0';
229
- testDetails.style.display = 'block';
230
- setTimeout(() => {
231
- testDetails.style.opacity = '1';
232
- backButton.style.opacity = '1';
233
- }, 50);
234
-
235
126
  let statusClass = '';
127
+ let statusIcon = '';
236
128
  let statusText = test.status.toUpperCase();
129
+
237
130
  if (test.status.startsWith('passed')) {
238
- statusClass = 'tag is-success';
131
+ statusClass = 'success';
132
+ statusIcon = 'check-circle';
239
133
  } else if (test.status === 'flaky') {
240
- statusClass = 'tag is-warning';
134
+ statusClass = 'warning';
135
+ statusIcon = 'exclamation-triangle';
241
136
  } else if (test.status === 'failed') {
242
- statusClass = 'tag is-danger';
137
+ statusClass = 'danger';
138
+ statusIcon = 'times-circle';
243
139
  } else {
244
- statusClass = 'tag is-info';
140
+ statusClass = 'info';
141
+ statusIcon = 'question-circle';
245
142
  }
246
-
247
143
  testDetails.innerHTML = `
248
- <button class="button content" id="back-to-summary" style="display: block"
249
- onclick="showSummary()">
250
- <span class="icon"><i class="fa-solid fa-chevron-left" style="color: #63E6BE;"></i></span>
251
- <span>Back to Summary</span></button>
252
- <div class="content has-text-centered">
253
- <p class="title">${test.title}</p>
254
- <p class="subtitle" id="filepath">${test.location}</p>
255
- </div>
256
- <div class="columns">
257
- <div class="column content">
258
- <h4 class="title is-4">Status</h4>
259
- <p class="${statusClass}">${statusText}</p>
260
- ${test.duration.length > 0 ? `
261
- <h4 class="title is-4">Duration</h4>
262
- <p class="${statusClass}">${test.duration}</p>` : ""}
263
- ${test.projectName.length > 0 ? `
264
- <div class="control">
265
- <div class="tags has-addons">
266
- <span class="tag is-dark">Project</span>
267
- <span class="tag is-info is-capitalized">${test.projectName}</span>
144
+ <div class="sticky-header">
145
+ <div class="card mb-3">
146
+ <button class="button is-info is-light mb-3" id="back-to-summary" onclick="showSummary()">
147
+ <span class="icon"><i class="fa fa-chevron-left" style="color: #63E6BE;"></i></span>
148
+ <span>Back to Summary</span>
149
+ </button>
150
+ <div class="card-content">
151
+ <div class="content has-text-centered">
152
+ <h1 class="title is-2">${test.title}</h1>
153
+ <p class="subtitle is-5" id="filepath">${test.location}</p>
154
+ </div>
155
+ </div>
156
+ <footer class="card-footer">
157
+ <div class="card-footer-item">
158
+ <div class="columns is-mobile">
159
+ <div class="column is-half">
160
+ <div class="is-flex is-align-items-center">
161
+ <span class="icon status-icon has-text-${statusClass}">
162
+ <i class="fa fa-${statusIcon}"></i>
163
+ </span>
164
+ <span class="has-text-weight-bold is-uppercase has-text-${statusClass}">${test.status}</span>
268
165
  </div>
269
- </div>`: ""}
270
- ${test.testTags.length > 0 ? `
271
- <div class="control mt-4">
272
- <div class="tags has-addons">
273
- <span class="tag is-dark">Test Tags</span>
274
- <span class="tag is-info">${test.testTags.join(" ")}</span>
275
166
  </div>
276
- </div>`: ""}
277
- ${test.videoPath ? `
278
- <div id="testVideo" class="modal">
279
- <div class="modal-background"></div>
280
- <div class="modal-content">
281
- <figure>
282
- <video controls>
283
- <source src="file://${test.videoPath}" type="video/webm">
284
- Your browser does not support the video tag.
285
- </video>
286
- </figure>
287
- </div>
288
- <button onclick="closeVideo()" class="modal-close is-large" aria-label="close"></button>
289
167
  </div>
290
- <button class="button mt-4" onclick="openVideo()">Attachment: Video</button>
291
- `: ''}
292
- ${test.tracePath ? `
293
- <div class="trace-viewer mt-4">
294
- <a href="${test.tracePath}" target="_blank" class="button is-small is-link">
295
- View Trace
296
- </a>
168
+ </div>
169
+ ${test.duration ? `
170
+ <div class="card-footer-item">
171
+ <div class="column is-half">
172
+ <div class="is-flex is-align-items-center">
173
+ <span class="icon status-icon has-text-info">
174
+ <i class="fa fa-clock"></i>
175
+ </span>
176
+ <span class="has-text-info has-text-weight-semibold">${test.duration}</span>
177
+ </div>
178
+ </div>
179
+ </div>
180
+ ` : ''}
181
+ ${test.projectName ? `
182
+ <div class="card-footer-item">
183
+ <div class="is-flex is-align-items-center">
184
+ <span class="icon status-icon has-text-info">
185
+ <i class="fa fa-window-maximize" style="color: #B197FC;"></i>
186
+ </span>
187
+ <span class="" style="color: #B197FC;"> ${test.projectName}</span>
188
+ </div>
297
189
  </div>
298
190
  ` : ''}
191
+ </footer>
299
192
  </div>
300
- <div class="column content">
301
- ${test.screenshots && test.screenshots.length > 0 ? `
302
- <div id="testImage" class="modal">
193
+ </div>
194
+
195
+ <div class="content-wrapper">
196
+ ${test.status != "skipped" ?
197
+ `<div class="card mb-5">
198
+ <div class="card-content">
199
+ <div class="columns is-multiline">
200
+ ${test.screenshots && test.screenshots.length > 0 ? `
201
+ <div class="column is-half">
202
+ <div id="testImage" class="modal">
303
203
  <div class="modal-background"></div>
304
204
  <div class="modal-content">
305
205
  <p class="image">
@@ -309,10 +209,10 @@
309
209
  <button onclick="closeModal()" class="modal-close is-large" aria-label="close"></button>
310
210
  </div>
311
211
 
312
- <figure class="image box">
212
+ <figure class="image">
313
213
  <img id="screenshot-main-img" onclick="openModal()" src="${test.screenshots[0]}" alt="Screenshot">
314
214
  </figure>
315
- <nav class="pagination is-small is-centered ${test.screenshots.length > 1 ? '' : 'is-hidden'}" role="navigation" aria-label="pagination">
215
+ <nav class="mt-4 pagination is-small is-centered ${test.screenshots.length > 1 ? '' : 'is-hidden'}" role="navigation" aria-label="pagination">
316
216
  <a class="pagination-previous" >Previous</a>
317
217
  <a class="pagination-next" >Next</a>
318
218
  <ul class="pagination-list">
@@ -322,50 +222,122 @@
322
222
  </li>`).join('')}
323
223
  </ul>
324
224
  </nav>
225
+ </div>
226
+ ` : ''}
227
+ ${test.videoPath ? `
228
+ <div class="column is-half">
229
+ <div class="video-preview" onclick="openVideo()">
230
+ <video controls width="100%" height="auto" preload="metadata">
231
+ <source src="${test.videoPath}" type="video/webm">
232
+ Your browser does not support the video tag.
233
+ </video>
234
+ </div>
235
+ </div>
236
+ ` : ''}
237
+ </div>
238
+ ${test.tracePath ? `
239
+ <div class="columns is-centered">
240
+ <div class="column is-3">
241
+ <a href="trace/index.html?trace=http://localhost:${test.port}/${test.tracePath}" target="_blank" class="button is-link is-fullwidth mt-3">
242
+ <span class="icon"><i class="fa-solid fa-tv" style="color: #FFD43B;"></i></span>
243
+ <span class="has-text-white pl-2">View Trace</span>
244
+ </a>
245
+ </div>
246
+ </div>
247
+ ` : ''}
248
+ </div>
249
+ </div>` : ''}
250
+ ${test.annotations.length || test.testTags.length > 0 ? `
251
+ <div class="card mb-5">
252
+ <header class="card-header">
253
+ <p class="card-header-title">Additional Information</p>
254
+ </header>
255
+ <div class="card-content">
256
+ <div class="content">
257
+ ${test.testTags.length > 0 ? `
258
+ <div class="control mb-4">
259
+ <div class="tags is-rounded">
260
+ ${test.testTags.map(tag => `<span class="tag is-primary is-medium">${tag}</span>`).join('')}
261
+ </div>
262
+ </div>` : ""}
263
+ ${test.annotations
264
+ .filter(annotation => annotation !== null && annotation !== undefined)
265
+ .map(annotation => `
266
+ <div class="mb-4">
267
+ ${annotation?.type ? `<strong class="has-text-link">Type: </strong><span>${annotation.type}</span>` : ''}
268
+ <br>
269
+ ${annotation?.description ? `<strong class="has-text-link">Description: </strong><span>${annotation.description}</span>` : ''}
270
+ </div>
271
+ `).join('')}
272
+ </div>
273
+ </div>
274
+ </div>
325
275
  ` : ''}
326
- </div>
327
-
328
- </div>
329
- <div class="content">
330
276
  ${test.steps.length > 0 ? `
331
- <details id="stepopen">
332
- <summary><h4 class="title is-4">Steps</h4></summary>
333
- <span id="stepDetails" class="content"></span>
334
- </details>
335
- `: ``}
336
- </div class="content">
337
- <div>
277
+ <div class="card">
278
+ <header class="card-header">
279
+ <p class="card-header-title">Steps</p>
280
+ </header>
281
+ <div class="card-content">
282
+ <div class="content">
283
+ <span id="stepDetails" class="content"></span>
284
+ </div>
285
+ </div>
286
+ </div>
287
+ ` : ''}
338
288
  ${test.errors.length ? `
339
- <h4 class="title is-4">Errors</h4>
340
- <div class="content">
341
- <pre><code class="data-lang=js">${escapeHtml(test.errors.join('\n'))}</code></pre>
342
- </div>` : ''}
343
- </div>
344
- <div>
289
+ <div class="card mt-5">
290
+ <header class="card-header">
291
+ <p class="card-header-title">Errors</p>
292
+ </header>
293
+ <div class="card-content">
294
+ <div class="content">
295
+ <pre><code class="data-lang=js">${test.errors.join('\n')}</code></pre>
296
+ </div>
297
+ </div>
298
+ </div>
299
+ ` : ''}
345
300
  ${test.logs ? `
346
- <h4 class="title is-4">Logs</h4>
347
- <div class="box">
348
- <pre>${escapeHtml(test.logs)}</pre>
349
- </div>` : ''}
350
- </div>
351
- `;
352
- document.querySelector('.pagination-previous').addEventListener('click', () => changeScreenshot(-1));
353
- document.querySelector('.pagination-next').addEventListener('click', () => changeScreenshot(1));
354
- document.querySelectorAll('.pagination-link').forEach((link, index) => {
355
- link.addEventListener('click', () => gotoScreenshot(index));
356
- });
301
+ <div class="card mt-5">
302
+ <header class="card-header">
303
+ <p class="card-header-title">Logs</p>
304
+ </header>
305
+ <div class="card-content">
306
+ <div class="content">
307
+ <pre>${test.logs}</pre>
308
+ </div>
309
+ </div>
310
+ </div>
311
+ ` : ''}
312
+ ${test.videoPath ? `
313
+ <div id="testVideo" class="modal">
314
+ <div class="modal-background"></div>
315
+ <div class="modal-content">
316
+ <div class="box">
317
+ <video controls style="width: 100%;">
318
+ <source src="${test.videoPath}" type="video/webm">
319
+ Your browser does not support the video tag.
320
+ </video>
321
+ </div>
322
+ </div>
323
+ <button class="modal-close is-large" aria-label="close" onclick="closeVideo()"></button>
324
+ </div>
325
+ ` : ''}
326
+ </div>`
327
+ if (test.screenshots.length > 0) {
328
+ document.querySelector('.pagination-previous').addEventListener('click', () => changeScreenshot(-1));
329
+ document.querySelector('.pagination-next').addEventListener('click', () => changeScreenshot(1));
330
+ document.querySelectorAll('.pagination-link').forEach((link, index) => {
331
+ link.addEventListener('click', () => gotoScreenshot(index));
332
+ });
333
+ }
357
334
  const stepDetailsDiv = document.getElementById('stepDetails');
358
335
  if (stepDetailsDiv) {
359
336
  const stepsList = attachSteps(test);
360
337
  const detail = document.getElementById("stepopen");
361
- if (test.errors.length > 0) {
362
- detail.setAttribute("open", "");
363
- }
364
338
  stepDetailsDiv.appendChild(stepsList);
365
339
  }
366
-
367
340
  }
368
-
369
341
  function attachSteps(test) {
370
342
  const stepsList = document.createElement("ul");
371
343
  stepsList.setAttribute("id", "steps");
@@ -377,7 +349,7 @@
377
349
  const pre = document.createElement('pre');
378
350
  const code = document.createElement('code');
379
351
  const locationText = step.location ? `\n\nat: ${step.location}` : '';
380
- code.textContent = `${step.snippet}${locationText}`;
352
+ code.innerHTML = `${step.snippet}${locationText}`;
381
353
  code.setAttribute('data-lang', 'js');
382
354
  pre.appendChild(code);
383
355
  li.appendChild(pre);
@@ -555,28 +527,8 @@
555
527
 
556
528
  searchInput.addEventListener('input', debouncedSearch);
557
529
 
558
- const ctx = document.getElementById('testChart');
559
- new Chart(ctx, {
560
- type: 'doughnut',
561
- data: {
562
- labels: ['Passed', 'Failed', 'Skipped', 'Flaky'],
563
- datasets: [{
564
- data: [{{ passCount }}, {{ failCount }}, {{ skipCount }}, {{ flakyCount }}],
565
- backgroundColor: ['#28a745', '#ff6685', '#66d1ff', '#ffb70f']
566
- }]
567
- },
568
- options: {
569
- responsive: true,
570
- maintainAspectRatio: false,
571
- plugins: {
572
- legend: {
573
- display: false
574
- }
575
- }
576
- }
577
- });
578
530
  attachEventListeners();
579
- });
531
+ });
580
532
  </script>
581
533
  </body>
582
534