rapporDeTest.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8"/>
  5. <title>rapporDeTest.html</title>
  6. <style>body {
  7. font-family: Helvetica, Arial, sans-serif;
  8. font-size: 12px;
  9. /* do not increase min-width as some may use split screens */
  10. min-width: 800px;
  11. color: #999;
  12. }
  13. h1 {
  14. font-size: 24px;
  15. color: black;
  16. }
  17. h2 {
  18. font-size: 16px;
  19. color: black;
  20. }
  21. p {
  22. color: black;
  23. }
  24. a {
  25. color: #999;
  26. }
  27. table {
  28. border-collapse: collapse;
  29. }
  30. /******************************
  31. * SUMMARY INFORMATION
  32. ******************************/
  33. #environment td {
  34. padding: 5px;
  35. border: 1px solid #E6E6E6;
  36. }
  37. #environment tr:nth-child(odd) {
  38. background-color: #f6f6f6;
  39. }
  40. /******************************
  41. * TEST RESULT COLORS
  42. ******************************/
  43. span.passed,
  44. .passed .col-result {
  45. color: green;
  46. }
  47. span.skipped,
  48. span.xfailed,
  49. span.rerun,
  50. .skipped .col-result,
  51. .xfailed .col-result,
  52. .rerun .col-result {
  53. color: orange;
  54. }
  55. span.error,
  56. span.failed,
  57. span.xpassed,
  58. .error .col-result,
  59. .failed .col-result,
  60. .xpassed .col-result {
  61. color: red;
  62. }
  63. /******************************
  64. * RESULTS TABLE
  65. *
  66. * 1. Table Layout
  67. * 2. Extra
  68. * 3. Sorting items
  69. *
  70. ******************************/
  71. /*------------------
  72. * 1. Table Layout
  73. *------------------*/
  74. #results-table {
  75. border: 1px solid #e6e6e6;
  76. color: #999;
  77. font-size: 12px;
  78. width: 100%;
  79. }
  80. #results-table th,
  81. #results-table td {
  82. padding: 5px;
  83. border: 1px solid #E6E6E6;
  84. text-align: left;
  85. }
  86. #results-table th {
  87. font-weight: bold;
  88. }
  89. /*------------------
  90. * 2. Extra
  91. *------------------*/
  92. .log {
  93. background-color: #e6e6e6;
  94. border: 1px solid #e6e6e6;
  95. color: black;
  96. display: block;
  97. font-family: "Courier New", Courier, monospace;
  98. height: 230px;
  99. overflow-y: scroll;
  100. padding: 5px;
  101. white-space: pre-wrap;
  102. }
  103. .log:only-child {
  104. height: inherit;
  105. }
  106. div.image {
  107. border: 1px solid #e6e6e6;
  108. float: right;
  109. height: 240px;
  110. margin-left: 5px;
  111. overflow: hidden;
  112. width: 320px;
  113. }
  114. div.image img {
  115. width: 320px;
  116. }
  117. div.video {
  118. border: 1px solid #e6e6e6;
  119. float: right;
  120. height: 240px;
  121. margin-left: 5px;
  122. overflow: hidden;
  123. width: 320px;
  124. }
  125. div.video video {
  126. overflow: hidden;
  127. width: 320px;
  128. height: 240px;
  129. }
  130. .collapsed {
  131. display: none;
  132. }
  133. .expander::after {
  134. content: " (show details)";
  135. color: #BBB;
  136. font-style: italic;
  137. cursor: pointer;
  138. }
  139. .collapser::after {
  140. content: " (hide details)";
  141. color: #BBB;
  142. font-style: italic;
  143. cursor: pointer;
  144. }
  145. /*------------------
  146. * 3. Sorting items
  147. *------------------*/
  148. .sortable {
  149. cursor: pointer;
  150. }
  151. .sort-icon {
  152. font-size: 0px;
  153. float: left;
  154. margin-right: 5px;
  155. margin-top: 5px;
  156. /*triangle*/
  157. width: 0;
  158. height: 0;
  159. border-left: 8px solid transparent;
  160. border-right: 8px solid transparent;
  161. }
  162. .inactive .sort-icon {
  163. /*finish triangle*/
  164. border-top: 8px solid #E6E6E6;
  165. }
  166. .asc.active .sort-icon {
  167. /*finish triangle*/
  168. border-bottom: 8px solid #999;
  169. }
  170. .desc.active .sort-icon {
  171. /*finish triangle*/
  172. border-top: 8px solid #999;
  173. }
  174. </style></head>
  175. <body onLoad="init()">
  176. <script>/* This Source Code Form is subject to the terms of the Mozilla Public
  177. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  178. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  179. function toArray(iter) {
  180. if (iter === null) {
  181. return null;
  182. }
  183. return Array.prototype.slice.call(iter);
  184. }
  185. function find(selector, elem) { // eslint-disable-line no-redeclare
  186. if (!elem) {
  187. elem = document;
  188. }
  189. return elem.querySelector(selector);
  190. }
  191. function findAll(selector, elem) {
  192. if (!elem) {
  193. elem = document;
  194. }
  195. return toArray(elem.querySelectorAll(selector));
  196. }
  197. function sortColumn(elem) {
  198. toggleSortStates(elem);
  199. const colIndex = toArray(elem.parentNode.childNodes).indexOf(elem);
  200. let key;
  201. if (elem.classList.contains('result')) {
  202. key = keyResult;
  203. } else if (elem.classList.contains('links')) {
  204. key = keyLink;
  205. } else {
  206. key = keyAlpha;
  207. }
  208. sortTable(elem, key(colIndex));
  209. }
  210. function showAllExtras() { // eslint-disable-line no-unused-vars
  211. findAll('.col-result').forEach(showExtras);
  212. }
  213. function hideAllExtras() { // eslint-disable-line no-unused-vars
  214. findAll('.col-result').forEach(hideExtras);
  215. }
  216. function showExtras(colresultElem) {
  217. const extras = colresultElem.parentNode.nextElementSibling;
  218. const expandcollapse = colresultElem.firstElementChild;
  219. extras.classList.remove('collapsed');
  220. expandcollapse.classList.remove('expander');
  221. expandcollapse.classList.add('collapser');
  222. }
  223. function hideExtras(colresultElem) {
  224. const extras = colresultElem.parentNode.nextElementSibling;
  225. const expandcollapse = colresultElem.firstElementChild;
  226. extras.classList.add('collapsed');
  227. expandcollapse.classList.remove('collapser');
  228. expandcollapse.classList.add('expander');
  229. }
  230. function showFilters() {
  231. let visibleString = getQueryParameter('visible') || 'all';
  232. visibleString = visibleString.toLowerCase();
  233. const checkedItems = visibleString.split(',');
  234. const filterItems = document.getElementsByClassName('filter');
  235. for (let i = 0; i < filterItems.length; i++) {
  236. filterItems[i].hidden = false;
  237. if (visibleString != 'all') {
  238. filterItems[i].checked = checkedItems.includes(filterItems[i].getAttribute('data-test-result'));
  239. filterTable(filterItems[i]);
  240. }
  241. }
  242. }
  243. function addCollapse() {
  244. // Add links for show/hide all
  245. const resulttable = find('table#results-table');
  246. const showhideall = document.createElement('p');
  247. showhideall.innerHTML = '<a href="javascript:showAllExtras()">Show all details</a> / ' +
  248. '<a href="javascript:hideAllExtras()">Hide all details</a>';
  249. resulttable.parentElement.insertBefore(showhideall, resulttable);
  250. // Add show/hide link to each result
  251. findAll('.col-result').forEach(function(elem) {
  252. const collapsed = getQueryParameter('collapsed') || 'Passed';
  253. const extras = elem.parentNode.nextElementSibling;
  254. const expandcollapse = document.createElement('span');
  255. if (extras.classList.contains('collapsed')) {
  256. expandcollapse.classList.add('expander');
  257. } else if (collapsed.includes(elem.innerHTML)) {
  258. extras.classList.add('collapsed');
  259. expandcollapse.classList.add('expander');
  260. } else {
  261. expandcollapse.classList.add('collapser');
  262. }
  263. elem.appendChild(expandcollapse);
  264. elem.addEventListener('click', function(event) {
  265. if (event.currentTarget.parentNode.nextElementSibling.classList.contains('collapsed')) {
  266. showExtras(event.currentTarget);
  267. } else {
  268. hideExtras(event.currentTarget);
  269. }
  270. });
  271. });
  272. }
  273. function getQueryParameter(name) {
  274. const match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
  275. return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
  276. }
  277. function init () { // eslint-disable-line no-unused-vars
  278. resetSortHeaders();
  279. addCollapse();
  280. showFilters();
  281. sortColumn(find('.initial-sort'));
  282. findAll('.sortable').forEach(function(elem) {
  283. elem.addEventListener('click',
  284. function() {
  285. sortColumn(elem);
  286. }, false);
  287. });
  288. }
  289. function sortTable(clicked, keyFunc) {
  290. const rows = findAll('.results-table-row');
  291. const reversed = !clicked.classList.contains('asc');
  292. const sortedRows = sort(rows, keyFunc, reversed);
  293. /* Whole table is removed here because browsers acts much slower
  294. * when appending existing elements.
  295. */
  296. const thead = document.getElementById('results-table-head');
  297. document.getElementById('results-table').remove();
  298. const parent = document.createElement('table');
  299. parent.id = 'results-table';
  300. parent.appendChild(thead);
  301. sortedRows.forEach(function(elem) {
  302. parent.appendChild(elem);
  303. });
  304. document.getElementsByTagName('BODY')[0].appendChild(parent);
  305. }
  306. function sort(items, keyFunc, reversed) {
  307. const sortArray = items.map(function(item, i) {
  308. return [keyFunc(item), i];
  309. });
  310. sortArray.sort(function(a, b) {
  311. const keyA = a[0];
  312. const keyB = b[0];
  313. if (keyA == keyB) return 0;
  314. if (reversed) {
  315. return keyA < keyB ? 1 : -1;
  316. } else {
  317. return keyA > keyB ? 1 : -1;
  318. }
  319. });
  320. return sortArray.map(function(item) {
  321. const index = item[1];
  322. return items[index];
  323. });
  324. }
  325. function keyAlpha(colIndex) {
  326. return function(elem) {
  327. return elem.childNodes[1].childNodes[colIndex].firstChild.data.toLowerCase();
  328. };
  329. }
  330. function keyLink(colIndex) {
  331. return function(elem) {
  332. const dataCell = elem.childNodes[1].childNodes[colIndex].firstChild;
  333. return dataCell == null ? '' : dataCell.innerText.toLowerCase();
  334. };
  335. }
  336. function keyResult(colIndex) {
  337. return function(elem) {
  338. const strings = ['Error', 'Failed', 'Rerun', 'XFailed', 'XPassed',
  339. 'Skipped', 'Passed'];
  340. return strings.indexOf(elem.childNodes[1].childNodes[colIndex].firstChild.data);
  341. };
  342. }
  343. function resetSortHeaders() {
  344. findAll('.sort-icon').forEach(function(elem) {
  345. elem.parentNode.removeChild(elem);
  346. });
  347. findAll('.sortable').forEach(function(elem) {
  348. const icon = document.createElement('div');
  349. icon.className = 'sort-icon';
  350. icon.textContent = 'vvv';
  351. elem.insertBefore(icon, elem.firstChild);
  352. elem.classList.remove('desc', 'active');
  353. elem.classList.add('asc', 'inactive');
  354. });
  355. }
  356. function toggleSortStates(elem) {
  357. //if active, toggle between asc and desc
  358. if (elem.classList.contains('active')) {
  359. elem.classList.toggle('asc');
  360. elem.classList.toggle('desc');
  361. }
  362. //if inactive, reset all other functions and add ascending active
  363. if (elem.classList.contains('inactive')) {
  364. resetSortHeaders();
  365. elem.classList.remove('inactive');
  366. elem.classList.add('active');
  367. }
  368. }
  369. function isAllRowsHidden(value) {
  370. return value.hidden == false;
  371. }
  372. function filterTable(elem) { // eslint-disable-line no-unused-vars
  373. const outcomeAtt = 'data-test-result';
  374. const outcome = elem.getAttribute(outcomeAtt);
  375. const classOutcome = outcome + ' results-table-row';
  376. const outcomeRows = document.getElementsByClassName(classOutcome);
  377. for(let i = 0; i < outcomeRows.length; i++){
  378. outcomeRows[i].hidden = !elem.checked;
  379. }
  380. const rows = findAll('.results-table-row').filter(isAllRowsHidden);
  381. const allRowsHidden = rows.length == 0 ? true : false;
  382. const notFoundMessage = document.getElementById('not-found-message');
  383. notFoundMessage.hidden = !allRowsHidden;
  384. }
  385. </script>
  386. <h1>rapporDeTest.html</h1>
  387. <p>Report generated on 11-Jan-2024 at 11:58:04 by <a href="https://pypi.python.org/pypi/pytest-html">pytest-html</a> v3.2.0</p>
  388. <h2>Summary</h2>
  389. <p>1 tests ran in 6.46 seconds. </p>
  390. <p class="filter" hidden="true">(Un)check the boxes to filter the results.</p><input checked="true" class="filter" data-test-result="passed" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="passed">1 passed</span>, <input checked="true" class="filter" data-test-result="skipped" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="skipped">0 skipped</span>, <input checked="true" class="filter" data-test-result="failed" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="failed">0 failed</span>, <input checked="true" class="filter" data-test-result="error" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="error">0 errors</span>, <input checked="true" class="filter" data-test-result="xfailed" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="xfailed">0 expected failures</span>, <input checked="true" class="filter" data-test-result="xpassed" disabled="true" hidden="true" name="filter_checkbox" onChange="filterTable(this)" type="checkbox"/><span class="xpassed">0 unexpected passes</span>
  391. <h2>Results</h2>
  392. <table id="results-table">
  393. <thead id="results-table-head">
  394. <tr>
  395. <th class="sortable result initial-sort" col="result">Result</th>
  396. <th class="sortable" col="name">Test</th>
  397. <th class="sortable" col="duration">Duration</th>
  398. <th class="sortable links" col="links">Links</th></tr>
  399. <tr hidden="true" id="not-found-message">
  400. <th colspan="4">No results found. Try to check the filters</th></tr></thead>
  401. <tbody class="passed results-table-row">
  402. <tr>
  403. <td class="col-result">Passed</td>
  404. <td class="col-name">test_saucedemo.py::test_loginOK</td>
  405. <td class="col-duration">6.19</td>
  406. <td class="col-links"></td></tr>
  407. <tr>
  408. <td class="extra" colspan="4">
  409. <div class="log"> -------------------------------Captured log call-------------------------------- <br/>INFO root:test_saucedemo.py:15 Test du Login avec succès<br/></div></td></tr></tbody></table></body></html>