Skip to content

Commit 8320b74

Browse files
committed
style(html): tweak the styling for the new stmt/branch stats #2085
1 parent 7e08183 commit 8320b74

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1261
-816
lines changed

CHANGES.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ upgrading your version of coverage.py.
2323
Unreleased
2424
----------
2525

26+
- The HTML report now shows separate coverage totals for statements and
27+
branches, as well as the usual combined coverage percentage. Thanks to Ryuta
28+
for the `discussion <issue 2081_>`_ and the `implementation <pull 2085_>`_.
29+
2630
- Fix: ``except*`` clauses were not handled properly under the "sysmon"
2731
measurement core, causing KeyError exceptions as described in `issue 2086`_.
2832
This is now fixed.
@@ -33,7 +37,9 @@ Unreleased
3337
- A small tweak to the HTML report: file paths now use thin spaces around
3438
slashes to make them easier to read.
3539

40+
.. _issue 2081: https://github.com/coveragepy/coveragepy/issues/2081
3641
.. _issue 2083: https://github.com/coveragepy/coveragepy/issues/2083
42+
.. _pull 2085: https://github.com/coveragepy/coveragepy/pull/2085
3743
.. _issue 2086: https://github.com/coveragepy/coveragepy/issues/2086
3844

3945

coverage/htmlfiles/coverage_html.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ coverage.wire_up_filter = function () {
194194
for (let column = 0; column < totals.length; column++) {
195195
// Accumulate dynamic totals
196196
cell = row.cells[column] // nosemgrep: eslint.detect-object-injection
197-
if (cell.classList.contains("name")) {
197+
if (cell.matches(".name, .spacer")) {
198198
continue;
199199
}
200200
if (ratio_columns[column] && cell.dataset.ratio) {
@@ -225,7 +225,7 @@ coverage.wire_up_filter = function () {
225225
for (let column = 0; column < totals.length; column++) {
226226
// Get footer cell element.
227227
const cell = footer.cells[column]; // nosemgrep: eslint.detect-object-injection
228-
if (cell.classList.contains("name")) {
228+
if (cell.matches(".name, .spacer")) {
229229
continue;
230230
}
231231

coverage/htmlfiles/index.html

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,74 +83,86 @@ <h2>
8383
{# The title="" attr doesn't work in Safari. #}
8484
{% if has_arcs %}
8585
<tr class="tablehead grouphead">
86-
<th>&nbsp;</th>
86+
<th class="spacer">&nbsp;</th>
8787
{% if region_noun %}
88-
<th>&nbsp;</th>
88+
<th class="spacer">&nbsp;</th>
8989
{% endif %}
90-
<th colspan="4" class="group-label">Statements</th>
91-
<th colspan="3" class="group-label">Branches</th>
92-
<th colspan="1" class="group-label">Overall</th>
90+
<th class="spacer">&nbsp;</th>
91+
<th class="left" colspan="{% if has_arcs %}4{% else %}3{% endif %}">Statements</th>
92+
<th class="spacer">&nbsp;</th>
93+
<th class="left" colspan="3">Branches</th>
94+
<th class="spacer">&nbsp;</th>
95+
<th>Total</th>
9396
</tr>
9497
{% endif %}
9598
<tr class="tablehead" title="Click to sort">
96-
<th id="file" class="name left" aria-sort="none" data-shortcut="f">File<span class="arrows"></span></th>
99+
<th id="file" class="name" aria-sort="none" data-shortcut="f">File<span class="arrows"></span></th>
97100
{% if region_noun %}
98-
<th id="region" class="name left" aria-sort="none" data-default-sort-order="ascending" data-shortcut="n">{{ region_noun }}<span class="arrows"></span></th>
101+
<th id="region" class="name" aria-sort="none" data-default-sort-order="ascending" data-shortcut="n">{{ region_noun }}<span class="arrows"></span></th>
99102
{% endif %}
103+
<th class="spacer">&nbsp;</th>
100104
{% if has_arcs %}
101105
<th id="statements_coverage" aria-sort="none" data-default-sort-order="descending">coverage<span class="arrows"></span></th>
102106
{% endif %}
103107
<th id="statements" aria-sort="none" data-default-sort-order="descending" data-shortcut="s">statements<span class="arrows"></span></th>
104108
<th id="missing" aria-sort="none" data-default-sort-order="descending" data-shortcut="m">missing<span class="arrows"></span></th>
105109
<th id="excluded" aria-sort="none" data-default-sort-order="descending" data-shortcut="x">excluded<span class="arrows"></span></th>
106110
{% if has_arcs %}
111+
<th class="spacer">&nbsp;</th>
107112
<th id="branches_coverage" aria-sort="none" data-default-sort-order="descending">coverage<span class="arrows"></span></th>
108113
<th id="branches" aria-sort="none" data-default-sort-order="descending" data-shortcut="b">branches<span class="arrows"></span></th>
109114
<th id="partial" aria-sort="none" data-default-sort-order="descending" data-shortcut="p">partial<span class="arrows"></span></th>
110115
{% endif %}
111-
<th id="coverage" class="right" aria-sort="none" data-shortcut="c">coverage<span class="arrows"></span></th>
116+
<th class="spacer">&nbsp;</th>
117+
<th id="coverage" aria-sort="none" data-shortcut="c">coverage<span class="arrows"></span></th>
112118
</tr>
113119
</thead>
114120
<tbody>
115121
{% for region in regions %}
116122
<tr class="region">
117-
<td class="name left"><a href="{{region.url}}">{{region.file|escape|pretty_file}}</a></td>
123+
<td class="name"><a href="{{region.url}}">{{region.file|escape|pretty_file}}</a></td>
118124
{% if region_noun %}
119-
<td class="name left"><a href="{{region.url}}">{{region.description}}</a></td>
125+
<td class="name"><a href="{{region.url}}">{{region.description}}</a></td>
120126
{% endif %}
127+
<td class="spacer">&nbsp;</td>
121128
{% if has_arcs %}
122129
<td data-ratio="{{region.nums.ratio_statements|pair}}">{{region.nums.pc_statements_str}}%</td>
123130
{% endif %}
124131
<td>{{region.nums.n_statements}}</td>
125132
<td>{{region.nums.n_missing}}</td>
126133
<td>{{region.nums.n_excluded}}</td>
127134
{% if has_arcs %}
135+
<td class="spacer">&nbsp;</td>
128136
<td data-ratio="{{region.nums.ratio_branches|pair}}">{{region.nums.pc_branches_str}}%</td>
129137
<td>{{region.nums.n_branches}}</td>
130138
<td>{{region.nums.n_partial_branches}}</td>
131139
{% endif %}
132-
<td class="right" data-ratio="{{region.nums.ratio_covered|pair}}">{{region.nums.pc_covered_str}}%</td>
140+
<td class="spacer">&nbsp;</td>
141+
<td data-ratio="{{region.nums.ratio_covered|pair}}">{{region.nums.pc_covered_str}}%</td>
133142
</tr>
134143
{% endfor %}
135144
</tbody>
136145
<tfoot>
137146
<tr class="total">
138-
<td class="name left">Total</td>
147+
<td class="name">Total</td>
139148
{% if region_noun %}
140-
<td class="name left">&nbsp;</td>
149+
<td class="name">&nbsp;</td>
141150
{% endif %}
151+
<td class="spacer">&nbsp;</td>
142152
{% if has_arcs %}
143153
<td data-ratio="{{totals.ratio_statements|pair}}">{{totals.pc_statements_str}}%</td>
144154
{% endif %}
145155
<td>{{totals.n_statements}}</td>
146156
<td>{{totals.n_missing}}</td>
147157
<td>{{totals.n_excluded}}</td>
148158
{% if has_arcs %}
159+
<td class="spacer">&nbsp;</td>
149160
<td data-ratio="{{totals.ratio_branches|pair}}">{{totals.pc_branches_str}}%</td>
150161
<td>{{totals.n_branches}}</td>
151162
<td>{{totals.n_partial_branches}}</td>
152163
{% endif %}
153-
<td class="right" data-ratio="{{totals.ratio_covered|pair}}">{{totals.pc_covered_str}}%</td>
164+
<td class="spacer">&nbsp;</td>
165+
<td data-ratio="{{totals.ratio_covered|pair}}">{{totals.pc_covered_str}}%</td>
154166
</tr>
155167
</tfoot>
156168
</table>

coverage/htmlfiles/style.css

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,19 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
328328

329329
#index table.index { margin-left: -.5em; }
330330

331-
#index td, #index th { text-align: right; padding: .25em .5em; border-bottom: 1px solid #eee; }
331+
#index td, #index th { text-align: right; vertical-align: baseline; padding: .25em .5em; border-bottom: 1px solid #eee; }
332332

333333
@media (prefers-color-scheme: dark) { #index td, #index th { border-color: #333; } }
334334

335335
#index td.name, #index th.name { text-align: left; width: auto; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; min-width: 15em; }
336336

337-
#index th { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-style: italic; color: #333; cursor: pointer; }
337+
#index td.left, #index th.left { text-align: left; }
338+
339+
#index td.spacer, #index th.spacer { border: none; padding: 0; }
340+
341+
#index td.spacer:hover, #index th.spacer:hover { background: inherit; }
342+
343+
#index th { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-style: italic; color: #333; border-color: #ccc; cursor: pointer; }
338344

339345
@media (prefers-color-scheme: dark) { #index th { color: #ddd; } }
340346

@@ -352,17 +358,15 @@ kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em
352358

353359
#index th[aria-sort="descending"] .arrows::after { content: " ▼"; }
354360

355-
#index tr.grouphead th { cursor: default; font-style: normal; text-align: left; }
356-
357-
#index tr.grouphead .group-label { font-weight: bold; }
361+
#index tr.grouphead th { cursor: default; font-style: normal; border-color: #999; }
358362

359363
#index td.name { font-size: 1.15em; }
360364

361365
#index td.name a { text-decoration: none; color: inherit; }
362366

363367
#index td.name .no-noun { font-style: italic; }
364368

365-
#index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-top: 1px solid #ccc; border-bottom: none; }
369+
#index tr.total td, #index tr.total_dynamic td { font-weight: bold; border-bottom: none; }
366370

367371
#index tr.region:hover { background: #eee; }
368372

coverage/htmlfiles/style.scss

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ $border-indicator-width: .2em;
733733
}
734734
td, th {
735735
text-align: right;
736+
vertical-align: baseline;
736737
padding: .25em .5em;
737738
border-bottom: 1px solid $light-gray2;
738739
@include border-color-dark($dark-gray2);
@@ -742,12 +743,23 @@ $border-indicator-width: .2em;
742743
font-family: $font-normal;
743744
min-width: 15em;
744745
}
746+
&.left {
747+
text-align: left;
748+
}
749+
&.spacer {
750+
border: none;
751+
padding: 0;
752+
&:hover {
753+
background: inherit;
754+
}
755+
}
745756
}
746757
th {
747758
font-family: $font-normal;
748759
font-style: italic;
749760
color: $light-gray6;
750761
@include color-dark($dark-gray6);
762+
border-color: #ccc;
751763
cursor: pointer;
752764
&:hover {
753765
background: $light-gray2;
@@ -777,10 +789,7 @@ $border-indicator-width: .2em;
777789
th {
778790
cursor: default;
779791
font-style: normal;
780-
text-align: left;
781-
}
782-
.group-label {
783-
font-weight: bold;
792+
border-color: #999;
784793
}
785794
}
786795
td.name {
@@ -797,7 +806,6 @@ $border-indicator-width: .2em;
797806
tr.total td,
798807
tr.total_dynamic td {
799808
font-weight: bold;
800-
border-top: 1px solid #ccc;
801809
border-bottom: none;
802810
}
803811
tr.region:hover {

tests/gold/html/a/class_index.html

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
55
<title>Coverage report</title>
66
<link rel="icon" sizes="32x32" href="favicon_32_cb_58284776.png">
7-
<link rel="stylesheet" href="style_cb_15de8441.css" type="text/css">
8-
<script src="coverage_html_cb_d1619a95.js" defer></script>
7+
<link rel="stylesheet" href="style_cb_8432e98f.css" type="text/css">
8+
<script src="coverage_html_cb_bcae5fc4.js" defer></script>
99
</head>
1010
<body class="indexfile">
1111
<header>
@@ -54,41 +54,47 @@ <h2>
5454
<a class="button current">Classes</a>
5555
</h2>
5656
<p class="text">
57-
<a class="nav" href="https://coverage.readthedocs.io/en/7.11.3a0.dev1">coverage.py v7.11.3a0.dev1</a>,
58-
created at 2025-11-10 15:34 +0900
57+
<a class="nav" href="https://coverage.readthedocs.io/en/7.11.4a0.dev1">coverage.py v7.11.4a0.dev1</a>,
58+
created at 2025-11-16 16:02 -0500
5959
</p>
6060
</div>
6161
</header>
6262
<main id="index">
6363
<table class="index" data-sortable>
6464
<thead>
6565
<tr class="tablehead" title="Click to sort">
66-
<th id="file" class="name left" aria-sort="none" data-shortcut="f">File<span class="arrows"></span></th>
67-
<th id="region" class="name left" aria-sort="none" data-default-sort-order="ascending" data-shortcut="n">class<span class="arrows"></span></th>
66+
<th id="file" class="name" aria-sort="none" data-shortcut="f">File<span class="arrows"></span></th>
67+
<th id="region" class="name" aria-sort="none" data-default-sort-order="ascending" data-shortcut="n">class<span class="arrows"></span></th>
68+
<th class="spacer">&nbsp;</th>
6869
<th id="statements" aria-sort="none" data-default-sort-order="descending" data-shortcut="s">statements<span class="arrows"></span></th>
6970
<th id="missing" aria-sort="none" data-default-sort-order="descending" data-shortcut="m">missing<span class="arrows"></span></th>
7071
<th id="excluded" aria-sort="none" data-default-sort-order="descending" data-shortcut="x">excluded<span class="arrows"></span></th>
71-
<th id="coverage" class="right" aria-sort="none" data-shortcut="c">coverage<span class="arrows"></span></th>
72+
<th class="spacer">&nbsp;</th>
73+
<th id="coverage" aria-sort="none" data-shortcut="c">coverage<span class="arrows"></span></th>
7274
</tr>
7375
</thead>
7476
<tbody>
7577
<tr class="region">
76-
<td class="name left"><a href="a_py.html">a.py</a></td>
77-
<td class="name left"><a href="a_py.html"><data value=''><span class='no-noun'>(no class)</span></data></a></td>
78+
<td class="name"><a href="a_py.html">a.py</a></td>
79+
<td class="name"><a href="a_py.html"><data value=''><span class='no-noun'>(no class)</span></data></a></td>
80+
<td class="spacer">&nbsp;</td>
7881
<td>3</td>
7982
<td>1</td>
8083
<td>0</td>
81-
<td class="right" data-ratio="2 3">67%</td>
84+
<td class="spacer">&nbsp;</td>
85+
<td data-ratio="2 3">67%</td>
8286
</tr>
8387
</tbody>
8488
<tfoot>
8589
<tr class="total">
86-
<td class="name left">Total</td>
87-
<td class="name left">&nbsp;</td>
90+
<td class="name">Total</td>
91+
<td class="name">&nbsp;</td>
92+
<td class="spacer">&nbsp;</td>
8893
<td>3</td>
8994
<td>1</td>
9095
<td>0</td>
91-
<td class="right" data-ratio="2 3">67%</td>
96+
<td class="spacer">&nbsp;</td>
97+
<td data-ratio="2 3">67%</td>
9298
</tr>
9399
</tfoot>
94100
</table>
@@ -99,8 +105,8 @@ <h2>
99105
<footer>
100106
<div class="content">
101107
<p>
102-
<a class="nav" href="https://coverage.readthedocs.io/en/7.11.3a0.dev1">coverage.py v7.11.3a0.dev1</a>,
103-
created at 2025-11-10 15:34 +0900
108+
<a class="nav" href="https://coverage.readthedocs.io/en/7.11.4a0.dev1">coverage.py v7.11.4a0.dev1</a>,
109+
created at 2025-11-16 16:02 -0500
104110
</p>
105111
</div>
106112
<aside class="hidden">

tests/gold/html/a/function_index.html

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
55
<title>Coverage report</title>
66
<link rel="icon" sizes="32x32" href="favicon_32_cb_58284776.png">
7-
<link rel="stylesheet" href="style_cb_15de8441.css" type="text/css">
8-
<script src="coverage_html_cb_d1619a95.js" defer></script>
7+
<link rel="stylesheet" href="style_cb_8432e98f.css" type="text/css">
8+
<script src="coverage_html_cb_bcae5fc4.js" defer></script>
99
</head>
1010
<body class="indexfile">
1111
<header>
@@ -54,41 +54,47 @@ <h2>
5454
<a class="button" href="class_index.html">Classes</a>
5555
</h2>
5656
<p class="text">
57-
<a class="nav" href="https://coverage.readthedocs.io/en/7.11.3a0.dev1">coverage.py v7.11.3a0.dev1</a>,
58-
created at 2025-11-10 15:34 +0900
57+
<a class="nav" href="https://coverage.readthedocs.io/en/7.11.4a0.dev1">coverage.py v7.11.4a0.dev1</a>,
58+
created at 2025-11-16 16:02 -0500
5959
</p>
6060
</div>
6161
</header>
6262
<main id="index">
6363
<table class="index" data-sortable>
6464
<thead>
6565
<tr class="tablehead" title="Click to sort">
66-
<th id="file" class="name left" aria-sort="none" data-shortcut="f">File<span class="arrows"></span></th>
67-
<th id="region" class="name left" aria-sort="none" data-default-sort-order="ascending" data-shortcut="n">function<span class="arrows"></span></th>
66+
<th id="file" class="name" aria-sort="none" data-shortcut="f">File<span class="arrows"></span></th>
67+
<th id="region" class="name" aria-sort="none" data-default-sort-order="ascending" data-shortcut="n">function<span class="arrows"></span></th>
68+
<th class="spacer">&nbsp;</th>
6869
<th id="statements" aria-sort="none" data-default-sort-order="descending" data-shortcut="s">statements<span class="arrows"></span></th>
6970
<th id="missing" aria-sort="none" data-default-sort-order="descending" data-shortcut="m">missing<span class="arrows"></span></th>
7071
<th id="excluded" aria-sort="none" data-default-sort-order="descending" data-shortcut="x">excluded<span class="arrows"></span></th>
71-
<th id="coverage" class="right" aria-sort="none" data-shortcut="c">coverage<span class="arrows"></span></th>
72+
<th class="spacer">&nbsp;</th>
73+
<th id="coverage" aria-sort="none" data-shortcut="c">coverage<span class="arrows"></span></th>
7274
</tr>
7375
</thead>
7476
<tbody>
7577
<tr class="region">
76-
<td class="name left"><a href="a_py.html">a.py</a></td>
77-
<td class="name left"><a href="a_py.html"><data value=''><span class='no-noun'>(no function)</span></data></a></td>
78+
<td class="name"><a href="a_py.html">a.py</a></td>
79+
<td class="name"><a href="a_py.html"><data value=''><span class='no-noun'>(no function)</span></data></a></td>
80+
<td class="spacer">&nbsp;</td>
7881
<td>3</td>
7982
<td>1</td>
8083
<td>0</td>
81-
<td class="right" data-ratio="2 3">67%</td>
84+
<td class="spacer">&nbsp;</td>
85+
<td data-ratio="2 3">67%</td>
8286
</tr>
8387
</tbody>
8488
<tfoot>
8589
<tr class="total">
86-
<td class="name left">Total</td>
87-
<td class="name left">&nbsp;</td>
90+
<td class="name">Total</td>
91+
<td class="name">&nbsp;</td>
92+
<td class="spacer">&nbsp;</td>
8893
<td>3</td>
8994
<td>1</td>
9095
<td>0</td>
91-
<td class="right" data-ratio="2 3">67%</td>
96+
<td class="spacer">&nbsp;</td>
97+
<td data-ratio="2 3">67%</td>
9298
</tr>
9399
</tfoot>
94100
</table>
@@ -99,8 +105,8 @@ <h2>
99105
<footer>
100106
<div class="content">
101107
<p>
102-
<a class="nav" href="https://coverage.readthedocs.io/en/7.11.3a0.dev1">coverage.py v7.11.3a0.dev1</a>,
103-
created at 2025-11-10 15:34 +0900
108+
<a class="nav" href="https://coverage.readthedocs.io/en/7.11.4a0.dev1">coverage.py v7.11.4a0.dev1</a>,
109+
created at 2025-11-16 16:02 -0500
104110
</p>
105111
</div>
106112
<aside class="hidden">

0 commit comments

Comments
 (0)