pytest-html-plus 0.4.6__py3-none-any.whl → 0.4.8__py3-none-any.whl

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.
@@ -12,6 +12,8 @@ def compute_filter_count(results):
12
12
 
13
13
  if status == "failed" and not flaky:
14
14
  filters["failed"] += 1
15
+ if status == "error":
16
+ filters["error"] += 1
15
17
  if flaky:
16
18
  filters["flaky"] += 1
17
19
  if status == "skipped":
@@ -24,7 +26,12 @@ def compute_filter_count(results):
24
26
 
25
27
  total = len(results)
26
28
  filters["total"] = total
27
- filters["passed"] = total - filters["failed"] - filters["skipped"] # estimate
29
+ filters["passed"] = (
30
+ total
31
+ - filters["failed"]
32
+ - filters["skipped"]
33
+ - filters["error"]
34
+ )
28
35
 
29
36
  filters["marker_counts"] = dict(marker_counts)
30
37
  return dict(filters)
@@ -8,8 +8,8 @@ from pytest_html_plus.utils import is_main_worker, get_env_marker, get_report_ti
8
8
  def write_plus_metadata_if_main_worker(config, report_path, output_path="plus_metadata.json", **kwargs):
9
9
  if not is_main_worker():
10
10
  return
11
- branch = kwargs.get("git_branch", "NA")
12
- commit = kwargs.get("git_commit", "NA")
11
+ branch = kwargs.get("git_branch", "Pass --git-branch to populate git metadata")
12
+ commit = kwargs.get("git_commit", "Pass --git-commit to populate git metadata")
13
13
  metadata = {
14
14
  "report_title": get_report_title(output_path=report_path),
15
15
  "environment": get_env_marker(config),
@@ -184,13 +184,17 @@ class JSONReporter:
184
184
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
185
185
  <style>
186
186
 
187
- body {{ font-family: Arial, sans-serif; padding: 1rem; background: #f9f9f9; }}
188
- .test {{ border: 1px solid #ddd; margin-bottom: 0.5rem; border-radius: 5px; background: white; }}
187
+ body {{ font-family: Arial, sans-serif; padding: 1rem; background: #f2f4f7; }}
188
+ .test {{ border: 1px solid #ddd; margin-bottom: 0.5rem; border-radius: 5px; background: #ffffff; }}
189
189
  .header {{ padding: 0.5rem; cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }}
190
190
  .header.passed {{ background: #e6f4ea; color: #2f7a33; }}
191
191
  .header.failed {{ background: #fdecea; color: #a83232; }}
192
192
  .header.skipped {{ background: #fff8e1; color: #b36b00; }}
193
- .header.error {{ background: #f0f0f0; color: #f0f0f0; }}
193
+ .header.error {{
194
+ background: #fdecea; /* light red / pink */
195
+ color: #b71c1c; /* deep red */
196
+ border-left: 4px solid #d32f2f;
197
+ }}
194
198
  .details {{ padding: 0.5rem 1rem; display: none; border-top: 1px solid #ddd; }}
195
199
  .toggle::before {{ content: "▶"; display: inline-block; margin-right: 0.5rem; transition: transform 0.3s ease; }}
196
200
  .header.expanded .toggle::before {{ transform: rotate(90deg); }}
@@ -289,6 +293,13 @@ class JSONReporter:
289
293
  width: 100%;
290
294
  border-collapse: collapse;
291
295
  }}
296
+
297
+ .muted-hint code {{
298
+ background: #f1f5f9;
299
+ padding: 2px 4px;
300
+ border-radius: 4px;
301
+ font-size: 0.9em;
302
+ }}
292
303
 
293
304
  .report-metadata th, .report-metadata td {{
294
305
  text-align: left;
@@ -364,12 +375,14 @@ class JSONReporter:
364
375
  const flakyCheckbox = document.getElementById('flakyOnlyCheckbox');
365
376
  const testsContainer = document.getElementById('tests-container');
366
377
  const testElements = Array.from(testsContainer.querySelectorAll('.test'));
378
+ const errorCheckbox = document.getElementById('errorOnlyCheckbox');
367
379
 
368
380
  if (longestCheckbox.checked) {{
369
381
  failedCheckbox.checked = false;
370
382
  skippedCheckbox.checked = false;
371
383
  untrackedCheckbox.checked = false;
372
384
  flakyCheckbox.checked = false;
385
+ errorCheckbox.checked = false;
373
386
  // Re-enable all tests before sorting
374
387
  testElements.forEach(el => el.style.display = 'block');
375
388
 
@@ -395,11 +408,13 @@ class JSONReporter:
395
408
  const skippedCheckbox = document.getElementById('skippedOnlyCheckbox');
396
409
  const failedCheckbox = document.getElementById('failedOnlyCheckbox');
397
410
  const flakyCheckbox = document.getElementById('flakyOnlyCheckbox');
411
+ const errorCheckbox = document.getElementById('errorOnlyCheckbox');
398
412
 
399
413
  if (checkbox.checked) {{
400
414
  longestCheckbox.checked = false;
401
415
  skippedCheckbox.checked = false;
402
416
  failedCheckbox.checked = false;
417
+ errorCheckbox.checked = false;
403
418
  flakyCheckbox.checked = false
404
419
  testCards.forEach(card => {{
405
420
  const hasLink = card.querySelector('a[href]');
@@ -422,11 +437,13 @@ class JSONReporter:
422
437
  const untrackedCheckbox = document.getElementById('untrackedOnlyCheckbox');
423
438
  const skippedCheckbox = document.getElementById('skippedOnlyCheckbox');
424
439
  const failedCheckbox = document.getElementById('failedOnlyCheckbox');
440
+ const errorCheckbox = document.getElementById('errorOnlyCheckbox');
425
441
  const testElements = document.querySelectorAll('.test');
426
442
  if (checkbox.checked) {{
427
443
  longestCheckbox.checked = false;
428
444
  skippedCheckbox.checked = false;
429
445
  failedCheckbox.checked = false;
446
+ errorCheckbox.checked = false;
430
447
  untrackedCheckbox.checked = false;
431
448
  testElements.forEach(el => {{
432
449
  const isFlaky = el.querySelector('.is-flaky') !== null;
@@ -444,12 +461,14 @@ class JSONReporter:
444
461
  const untrackedCheckbox = document.getElementById('untrackedOnlyCheckbox');
445
462
  const skippedCheckbox = document.getElementById('skippedOnlyCheckbox');
446
463
  const flakyCheckbox = document.getElementById('flakyOnlyCheckbox');
464
+ const errorCheckbox = document.getElementById('errorOnlyCheckbox');
447
465
  const testElements = document.querySelectorAll('.test');
448
466
  if (failedCheckbox.checked) {{
449
467
  longestCheckbox.checked = false;
450
468
  untrackedCheckbox.checked = false;
451
469
  skippedCheckbox.checked = false;
452
470
  flakyCheckbox.checked = false;
471
+ errorCheckbox.checked = false;
453
472
  testElements.forEach(el => {{
454
473
  const header = el.querySelector('.header');
455
474
  const isFailed = header.classList.contains('failed');
@@ -466,6 +485,7 @@ class JSONReporter:
466
485
  const failedCheckbox = document.getElementById('failedOnlyCheckbox');
467
486
  const untrackedCheckbox = document.getElementById('untrackedOnlyCheckbox');
468
487
  const flakyCheckbox = document.getElementById('flakyOnlyCheckbox');
488
+ const errorCheckbox = document.getElementById('errorOnlyCheckbox');
469
489
  const testElements = document.querySelectorAll('.test');
470
490
 
471
491
  if (skippedCheckbox.checked) {{
@@ -473,6 +493,7 @@ class JSONReporter:
473
493
  failedCheckbox.checked = false;
474
494
  untrackedCheckbox.checked = false;
475
495
  flakyCheckbox.checked = false;
496
+ errorCheckbox.checked = false;
476
497
  testElements.forEach(el => {{
477
498
  const header = el.querySelector('.header');
478
499
  const isSkipped = header.classList.contains('skipped');
@@ -485,6 +506,32 @@ class JSONReporter:
485
506
  filterByMarkers(); // Reapply marker filter
486
507
  }}
487
508
 
509
+ function toggleErrorOnly(errorCheckbox) {{
510
+ const longestCheckbox = document.getElementById('longestOnlyCheckbox');
511
+ const failedCheckbox = document.getElementById('failedOnlyCheckbox');
512
+ const untrackedCheckbox = document.getElementById('untrackedOnlyCheckbox');
513
+ const flakyCheckbox = document.getElementById('flakyOnlyCheckbox');
514
+ const skippedCheckbox = document.getElementById('skippedOnlyCheckbox');
515
+ const testElements = document.querySelectorAll('.test');
516
+
517
+ if (errorCheckbox.checked) {{
518
+ longestCheckbox.checked = false;
519
+ failedCheckbox.checked = false;
520
+ untrackedCheckbox.checked = false;
521
+ flakyCheckbox.checked = false;
522
+ skippedCheckbox.checked = false;
523
+ testElements.forEach(el => {{
524
+ const header = el.querySelector('.header');
525
+ const isError = header.classList.contains('error');
526
+ el.style.display = isError ? 'block' : 'none';
527
+ }});
528
+ }} else {{
529
+ testElements.forEach(el => el.style.display = 'block');
530
+ }}
531
+
532
+ filterByMarkers();
533
+ }}
534
+
488
535
  function initializeUniversalSearch() {{
489
536
  const searchInput = document.getElementById('universal-search');
490
537
  if (!searchInput) return;
@@ -506,19 +553,22 @@ class JSONReporter:
506
553
  const selected = Array.from(document.querySelectorAll('.marker-filter input[type="checkbox"]:checked')).map(cb => cb.value);
507
554
  const failedOnly = document.getElementById('failedOnlyCheckbox').checked;
508
555
  const skippedOnly = document.getElementById('skippedOnlyCheckbox').checked;
556
+ const errorOnly = document.getElementById('errorOnlyCheckbox').checked;
509
557
 
510
558
  document.querySelectorAll('.test').forEach(el => {{
511
559
  const header = el.querySelector('.header');
512
560
  const markers = el.getAttribute('data-markers').split(',');
513
561
  const isFailed = header.classList.contains('failed');
514
562
  const isSkipped = header.classList.contains('skipped');
563
+ const isError = header.classList.contains('error');
515
564
 
516
565
  const showAllMarkers = selected.length === 0;
517
566
  const matchesMarker = showAllMarkers || selected.some(m => markers.includes(m));
518
567
  const matchesFailed = !failedOnly || isFailed;
519
568
  const matchesSkipped = !skippedOnly || isSkipped;
569
+ const matchesError = !errorOnly || isError;
520
570
 
521
- el.style.display = (matchesMarker && matchesFailed && matchesSkipped) ? 'block' : 'none';
571
+ el.style.display = (matchesMarker && matchesFailed && matchesSkipped && matchesError) ? 'block' : 'none';
522
572
  }});
523
573
  }}
524
574
 
@@ -529,9 +579,11 @@ class JSONReporter:
529
579
  const skippedCheckbox = document.getElementById('skippedOnlyCheckbox');
530
580
  const untrackedCheckbox = document.getElementById('untrackedOnlyCheckbox');
531
581
  const flakyCheckbox = document.getElementById('flakyOnlyCheckbox');
582
+ const errorCheckbox = document.getElementById('errorOnlyCheckbox');
532
583
  failedCheckbox.checked = true;
533
584
  toggleFailedOnly(failedCheckbox);
534
585
  failedCheckbox.addEventListener('change', () => toggleFailedOnly(failedCheckbox));
586
+ errorCheckbox.addEventListener('change', () => toggleErrorOnly(errorCheckbox));
535
587
  longestCheckbox.addEventListener('change', () => toggleFilter(longestCheckbox));
536
588
  skippedCheckbox.addEventListener('change', () => toggleSkippedOnly(skippedCheckbox));
537
589
  untrackedCheckbox.addEventListener('change', () => toggleUntrackedOnly(untrackedCheckbox));
@@ -542,8 +594,8 @@ class JSONReporter:
542
594
  </script>
543
595
  </head>
544
596
  <body>
545
- <div class="report-metadata">
546
- <h2 onclick="this.nextElementSibling.classList.toggle('hidden')" style="cursor: pointer; font-size: 12px;">
597
+ <div class="report-metadata" style="background: #f2f4f7;">
598
+ <h2 onclick="this.nextElementSibling.classList.toggle('hidden')" style="cursor: pointer; font-size: 12px; ">
547
599
  Execution Metadata (click to toggle)
548
600
  {self.generate_copy_button(self.metadata, "metadata")}
549
601
  </h2>
@@ -562,6 +614,10 @@ class JSONReporter:
562
614
  <input type="checkbox" id="failedOnlyCheckbox" />
563
615
  Show only failed tests (<span>{self.filters.get("failed", 0)}</span>)
564
616
  </label>
617
+ <label>
618
+ <input type="checkbox" id="errorOnlyCheckbox" />
619
+ Show only error tests (<span>{self.filters.get("error", 0)}</span>)
620
+ </label>
565
621
  <label>
566
622
  <input type="checkbox" id="skippedOnlyCheckbox" />
567
623
  Show only skipped tests (<span>{self.filters.get("skipped", 0)}</span>)
@@ -634,9 +690,21 @@ class JSONReporter:
634
690
 
635
691
  # Add checkboxes for all markers
636
692
  marker_counts = self.filters.get("marker_counts", {})
637
- for marker in sorted(marker_counts):
638
- count = marker_counts[marker]
639
- html += f'<label><input type="checkbox" value="{marker}" /> {marker} ({count})</label> '
693
+ if not marker_counts:
694
+ html += (
695
+ '<span class="muted-hint">'
696
+ 'Use <code>pytest.mark.*</code> to enable marker filters'
697
+ '</span>'
698
+ )
699
+ else:
700
+ for marker in sorted(marker_counts):
701
+ count = marker_counts[marker]
702
+ html += (
703
+ f'<label>'
704
+ f'<input type="checkbox" value="{marker}" /> '
705
+ f'{marker} ({count})'
706
+ f'</label> '
707
+ )
640
708
 
641
709
  html += '<div id="tests-container">'
642
710
 
@@ -645,6 +713,7 @@ class JSONReporter:
645
713
  status_class = (
646
714
  'passed' if test['status'] == 'passed' else
647
715
  'failed' if test['status'] == 'failed' else
716
+ 'error' if test['status'] == 'error' else
648
717
  'skipped'
649
718
  )
650
719
  screenshot_path = self.find_screenshot_and_copy(test['test'])
@@ -48,21 +48,33 @@ def pytest_runtest_makereport(item, call):
48
48
  error = extract_error_block(error=full_error)
49
49
  trace = extract_trace_block(str(report.longrepr))
50
50
 
51
- if report.when == "call" or (report.when == "setup" and report.skipped):
51
+ if (
52
+ report.when == "call"
53
+ or (report.when == "setup" and report.skipped)
54
+ or (report.when in ("setup", "teardown") and report.failed)
55
+ ):
52
56
  config = item.config
53
57
  capture_option = config.getoption("--capture-screenshots")
54
58
 
55
59
  caplog_text = None
56
- if "caplog" in item.funcargs:
57
- caplog = item.funcargs["caplog"]
58
- caplog_text = "\n".join(caplog.messages) if caplog.messages else None
60
+ if report.when in ("call", "setup"):
61
+ if "caplog" in item.funcargs:
62
+ caplog = item.funcargs["caplog"]
63
+ try:
64
+ caplog_text = "\n".join(caplog.messages) if caplog.messages else None
65
+ except KeyError:
66
+ caplog_text = None
59
67
 
60
68
  screenshot_path = config.getoption("--screenshots") or "screenshots"
61
69
 
62
70
  should_capture_screenshot = (
63
- capture_option == "all" or
64
- (capture_option == "failed" and report.outcome == "failed")
65
- )
71
+ report.when in ("setup", "call") and
72
+ (
73
+ capture_option == "all" or
74
+ (capture_option == "failed" and report.outcome == "failed")
75
+ )
76
+ )
77
+
66
78
 
67
79
  if should_capture_screenshot:
68
80
  driver = resolve_driver(item)
@@ -75,10 +87,13 @@ def pytest_runtest_makereport(item, call):
75
87
  reporter = config._json_reporter
76
88
  worker_id = os.getenv("PYTEST_XDIST_WORKER") or "main"
77
89
  test_name = "".join(c if c.isalnum() else "_" for c in item.name)
90
+ status = report.outcome
91
+ if report.when in ("setup", "teardown") and report.failed:
92
+ status = "error"
78
93
  reporter.log_result(
79
94
  test_name=test_name,
80
95
  nodeid=item.nodeid,
81
- status=report.outcome,
96
+ status=status,
82
97
  duration=report.duration,
83
98
  error=error,
84
99
  trace=trace if report.failed else None,
@@ -162,8 +177,8 @@ def pytest_sessionfinish(session, exitstatus):
162
177
 
163
178
  def pytest_sessionstart(session):
164
179
  html_output = session.config.getoption("--html-output") or "report_output"
165
- git_branch = session.config.getoption("--git-branch") or "NA"
166
- git_commit = session.config.getoption("--git-commit") or "NA"
180
+ git_branch = session.config.getoption("--git-branch") or "Pass --git-branch to populate git metadata"
181
+ git_commit = session.config.getoption("--git-commit") or "Pass --git-commit to populate git metadata"
167
182
  configure_logging()
168
183
  session.config.addinivalue_line(
169
184
  "markers", "link(url): Add a link to external test case or documentation."
@@ -227,13 +242,25 @@ def pytest_addoption(parser):
227
242
  parser.addoption(
228
243
  "--git-branch",
229
244
  action="store",
230
- default="NA",
245
+ default="Pass --git-branch to populate git metadata",
231
246
  help="Helps show branch information on the report"
232
247
  )
233
248
  parser.addoption(
234
249
  "--git-commit",
235
250
  action="store",
236
- default="NA",
251
+ default="Pass --git-commit to populate git metadata",
252
+ help="Helps show commitId information on the report"
253
+ )
254
+ parser.addoption(
255
+ "--env",
256
+ action="store",
257
+ default="Pass --env or --environment <name> to populate environment",
258
+ help="Helps show commitId information on the report"
259
+ )
260
+ parser.addoption(
261
+ "--environment",
262
+ action="store",
263
+ default="Pass --env or --environment <name> to populate environment",
237
264
  help="Helps show commitId information on the report"
238
265
  )
239
266
 
pytest_html_plus/utils.py CHANGED
@@ -7,7 +7,7 @@ def get_env_marker(config):
7
7
  for arg in ("--env", "--environment"):
8
8
  if config.getoption(arg.lstrip("-").replace("-", "_"), default=None):
9
9
  return config.getoption(arg.lstrip("-").replace("-", "_"))
10
- return "NA"
10
+ return "Pass --env <name> to populate environment"
11
11
 
12
12
  def get_report_title(output_path):
13
13
  report_path = output_path
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pytest-html-plus
3
- Version: 0.4.6
4
- Summary: Generate Actionable, automatic screenshots, unified Pytest HTML report in less than 3 seconds — no hooks, merge plugins, no config, xdist-ready.
3
+ Version: 0.4.8
4
+ Summary: Generate Actionable, automatic screenshots, unified Mobile friendly Pytest HTML report in less than 3 seconds — no hooks, merge plugins, no config, xdist-ready.
5
5
  License: MIT
6
6
  Keywords: pytest,pytest-html-plus,pytest-plugin,html-test-report,beautiful-test-report,shareable-test-results,test-report,test-results,unit-test-report,functional-test-report,test-summary,reporting,python-testing,automated-testing,test-runner,report-generator,continuous-integration,ci-cd,github-actions,jenkins,pytest-html,pytest-report
7
7
  Author: reporterplus
@@ -0,0 +1,16 @@
1
+ pytest_html_plus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ pytest_html_plus/compute_filter_counts.py,sha256=FznjPos-bgYSi8bERG_WbaZWMQDIAfoYP4QTRbe8vHw,963
3
+ pytest_html_plus/compute_report_metadata.py,sha256=OR3MLLg2yZD2H4KRdogv7EiB2zKE4fHFafNfSK4NU2U,863
4
+ pytest_html_plus/extract_link.py,sha256=1XtqkbZkrl1YgPGtFc3Ss1XFWm4LNLuO3Hi407HNChk,340
5
+ pytest_html_plus/generate_html_report.py,sha256=Q-2jbFyUYfwKwncMWrKybytLLnPptOzb5zdq_CwqSEI,37152
6
+ pytest_html_plus/json_merge.py,sha256=EQu23n8z4a0FxvFOlvYoDlX1jrZYjWwsCL-6oxfDREw,1868
7
+ pytest_html_plus/json_to_xml_converter.py,sha256=5E6BGMw4FaJhoYDUZQ6dF8NWqAeXrcuSrlySy81IrVE,3468
8
+ pytest_html_plus/plugin.py,sha256=NbvC4SvJ6AxO1g5-l_i-e2hRmobHd5FrIHg2DqRxvlM,12529
9
+ pytest_html_plus/resolver_driver.py,sha256=hehokRO5EuG4Ti8MyaSBW4xaHduUK3Ot2jbw1YpIsnk,1287
10
+ pytest_html_plus/send_email_report.py,sha256=qDnAPy1Jc4favOvXg6MT0ttNmSsG3MXGQX1Hu7wN1Go,2622
11
+ pytest_html_plus/utils.py,sha256=Qa34fOmZ6uWlIGG6hyoLWG1LIX1O9HFCtjWOtn03gSs,2244
12
+ pytest_html_plus-0.4.8.dist-info/LICENSE,sha256=8flU0ghLnuKK8qZv9pJ1xhXiKQdUncg0OvqMwYhGWzY,1090
13
+ pytest_html_plus-0.4.8.dist-info/METADATA,sha256=w7klAQr0fMiLB7LO7H0mxpfGAHD1mfwgcsyDm_a1V68,8520
14
+ pytest_html_plus-0.4.8.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
15
+ pytest_html_plus-0.4.8.dist-info/entry_points.txt,sha256=eSbV9G_n_XnR4wemMxKHSSuPMcBSoHbE1WuC2IQp4Zk,53
16
+ pytest_html_plus-0.4.8.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- pytest_html_plus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- pytest_html_plus/compute_filter_counts.py,sha256=A1rLdY9XWiIunpIs3VlmJsQ5JkKcWbVdj9r1Xg_4g6o,872
3
- pytest_html_plus/compute_report_metadata.py,sha256=k35kCSCAc8Fj9zgzzM49kh0h1NV2Ope9Lr8JHG_1jlU,783
4
- pytest_html_plus/extract_link.py,sha256=1XtqkbZkrl1YgPGtFc3Ss1XFWm4LNLuO3Hi407HNChk,340
5
- pytest_html_plus/generate_html_report.py,sha256=JmoU8mRgW-5b_u2p7_535B2aRTtGNoXypwzVreiuvCk,34255
6
- pytest_html_plus/json_merge.py,sha256=EQu23n8z4a0FxvFOlvYoDlX1jrZYjWwsCL-6oxfDREw,1868
7
- pytest_html_plus/json_to_xml_converter.py,sha256=5E6BGMw4FaJhoYDUZQ6dF8NWqAeXrcuSrlySy81IrVE,3468
8
- pytest_html_plus/plugin.py,sha256=sxCai3u018MRIhwYYsTjFv65Ss7OZOYM_xREU7XNn9E,11526
9
- pytest_html_plus/resolver_driver.py,sha256=hehokRO5EuG4Ti8MyaSBW4xaHduUK3Ot2jbw1YpIsnk,1287
10
- pytest_html_plus/send_email_report.py,sha256=qDnAPy1Jc4favOvXg6MT0ttNmSsG3MXGQX1Hu7wN1Go,2622
11
- pytest_html_plus/utils.py,sha256=DkGzQDFG_SUQHo97_lBnqTyeNxlo3NlFBZ2X_ooZRdM,2205
12
- pytest_html_plus-0.4.6.dist-info/LICENSE,sha256=8flU0ghLnuKK8qZv9pJ1xhXiKQdUncg0OvqMwYhGWzY,1090
13
- pytest_html_plus-0.4.6.dist-info/METADATA,sha256=G3lBbjk4omUV07pZcbcrkrFHrAA0hMycmU6N_hTvMYc,8504
14
- pytest_html_plus-0.4.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
15
- pytest_html_plus-0.4.6.dist-info/entry_points.txt,sha256=eSbV9G_n_XnR4wemMxKHSSuPMcBSoHbE1WuC2IQp4Zk,53
16
- pytest_html_plus-0.4.6.dist-info/RECORD,,