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.
- pytest_html_plus/compute_filter_counts.py +8 -1
- pytest_html_plus/compute_report_metadata.py +2 -2
- pytest_html_plus/generate_html_report.py +78 -9
- pytest_html_plus/plugin.py +39 -12
- pytest_html_plus/utils.py +1 -1
- {pytest_html_plus-0.4.6.dist-info → pytest_html_plus-0.4.8.dist-info}/METADATA +2 -2
- pytest_html_plus-0.4.8.dist-info/RECORD +16 -0
- pytest_html_plus-0.4.6.dist-info/RECORD +0 -16
- {pytest_html_plus-0.4.6.dist-info → pytest_html_plus-0.4.8.dist-info}/LICENSE +0 -0
- {pytest_html_plus-0.4.6.dist-info → pytest_html_plus-0.4.8.dist-info}/WHEEL +0 -0
- {pytest_html_plus-0.4.6.dist-info → pytest_html_plus-0.4.8.dist-info}/entry_points.txt +0 -0
|
@@ -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"] =
|
|
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", "
|
|
12
|
-
commit = kwargs.get("git_commit", "
|
|
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: #
|
|
188
|
-
.test {{ border: 1px solid #ddd; margin-bottom: 0.5rem; border-radius: 5px; background:
|
|
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 {{
|
|
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
|
-
|
|
638
|
-
|
|
639
|
-
|
|
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'])
|
pytest_html_plus/plugin.py
CHANGED
|
@@ -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
|
|
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 "
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
64
|
-
|
|
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=
|
|
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 "
|
|
166
|
-
git_commit = session.config.getoption("--git-commit") or "
|
|
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="
|
|
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="
|
|
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 "
|
|
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.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|