sebastianbergmann / php-code-coverage

Library that provides collection, processing, and rendering functionality for PHP code coverage information.
BSD 3-Clause "New" or "Revised" License
8.8k stars 373 forks source link

Make colors in HTML report configurable #556

Closed sebastienbarre closed 2 years ago

sebastienbarre commented 6 years ago
Q A
php-code-coverage version 4.0.8
PHP version 7.0.24
Driver Xdebug
Xdebug version (if used) 2.5.5
Installation Method Composer
Usage Method PHPUnit
PHPUnit version (if used) 5.7.23

Hello. Is there an easy way to customize the colors in style.css? My variant of colorblindness make it pretty difficult to differentiate between high coverage (#dff0d8) and low coverage (#f2dede) as they both have very low saturation (8% to 10%). Thank you.

sebastianbergmann commented 6 years ago

The easiest way to do this would be to have a custom style.css that you copy to the target directory, for instance in the test target of your build automation.

sebastienbarre commented 6 years ago

I mostly do coverage manually, e.g. ./Vendor/bin/phpunit --coverage-html coverage Test/Case. Is there a configurable hook there where I could sneak a cp or something?

sebastianbergmann commented 6 years ago

I will look into making the colors configurable.

sebastienbarre commented 6 years ago

Thank you, @sebastianbergmann

sebastianbergmann commented 6 years ago

I just realized that my knowledge about CSS in general and Bootstrap in particular is insufficient to figure out the "right way" to change the colors of all elements affected by success, warning, and danger in style.css. In order to implement this I need someone to tell me how to do this.

kelunik commented 6 years ago

@sebastianbergmann Maybe we can just have better defaults instead of making it configurable? How about going with black (low) → green (high), @sebastienbarre does that work?

matthewtrask commented 6 years ago

I think darker reds and greens would be good? It still holds the same sumbolization but easier to see.

kelunik commented 6 years ago

@matthewtrask Changing the saturation / shade of both might lead to the same issues again for color blind people.

sebastianbergmann commented 6 years ago

I would like to keep the current colors as default.

kelunik commented 6 years ago

In that case I'd introduce a color mode instead of making the colors completely configurable for usability purposes.

sebastianbergmann commented 6 years ago

Of course. All I need is an answer to https://github.com/sebastianbergmann/php-code-coverage/issues/556#issuecomment-344356203.

sebastienbarre commented 6 years ago

The current hues are standard enough (green = ok/success, yellow = warning, red = danger). It's the saturation that is a problem for me, but there are too many variations of color-blindness to make every colorblind person happy, hence my suggestion to make them customizable. PHPStorm's "Color-Deficiency Adjustment" doesn't do anything for me, for example.

@sebastianbergmann can you please clarify? The color is actually defined in one and only one place, in style.css. For insufficient/dangerous coverage (#f2dede) this is:

.table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
 background-color: #f2dede;
}

That's all there is to it. I'd just replace #f2dede with the customized color property when you copy over style.css to the destination directory.

The color should be a string and most people will use an hexadecimal representation with the # symbol included. CSS also supports things like rgb(255, 99, 71) or hsl(9, 100%, 64%) (without the #), hence the string type.

Same goes with medium coverage:

.table tbody td.warning, li.warning, span.warning {
 background-color: #fcf8e3;
}

Now for successful coverage, there are a few paths, the simple one is the same approach:

.table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
 background-color: #dff0d8;
}

where you would replace #dff0d8 with the user color when copying style.css over.

However, there are two more style definitions that "seem" to be using the same hue (green).

.table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests {
 background-color: #c3e3b5;
}
.table tbody tr.covered-by-small-tests, li.covered-by-small-tests {
 background-color: #99cb84;
}

I'm not sure what they are used for (I can guess), but they are essentially darker, more saturated variations of the same hue (green):

You can either make them configurable as well, which leaves the burden of creating the variations to the user (should it be the case, I would just use the same color for all 3 to make my life easier, but that's just me). Or you can do the math for them, by taking the base color meant to replace #dff0d8, computing the hue, and creating the two other colors by plugging that hue and using the saturation and brightness listed above (mexitek/phpColor to the rescue). However, you would potentially face the same issues, since these two colors could be problematic for some colorblind people.

Hope this helps

saschanowak commented 6 years ago

I would suggest to refactor the css to use css variables (https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables). The browser support is quit good today (https://caniuse.com/#feat=css-variables).

The implementation could look like this:

.table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
 background-color: #dff0d8;
 background-color: var(--color-success, #dff0d8); // IE11 should ignore this line and use the fallback 
}

Then we need to define a place where the user can configure the colors and render inline css:

<style>
:root {
  --color-success: #c3e3b5;
}
</style>

I can give it a try if someone could give me a hint where to configure the colors.

sebastienbarre commented 6 years ago

That's another way for sure, but I'd rather be able configure the colors with the rest of my settings, in my phpunit.xml (something like coverageColorDanger="#223344"), and this would support IE11.

If you need the user to provide their own stylesheet for css variables... then you might as well not bother with css variables, since you can override all styles directly in that user-specified stylesheet, right?

saschanowak commented 6 years ago

@sebastienbarre sorry as it seems my explanation was not detailed enough. As you suggested the user would configure the coverageColorDanger="#223344" in the phpunit.xml. If this configuration is present then the renderer would add

<style>
:root {
  --color-danger: #223344;
}
</style>

to the template as for example cssVariables and then we can render {{{cssVariables}}} in this file before the style.css include: https://github.com/sebastianbergmann/php-code-coverage/blob/master/src/Report/Html/Renderer/Template/dashboard.html.dist#L9

sebastianbergmann commented 6 years ago

Re: https://github.com/sebastianbergmann/php-code-coverage/issues/556#issuecomment-344374651

My bad, apparently I did not look into the existing style.css. Otherwise I would have seen that what I need is already (almost) there.

adrian7 commented 6 years ago

IMHO, this is out of scope of phpunit. However I do understand the importance of having custom styling to make things easier to browse or read.

It's fairly easy to just copy your own style.css to the css or .css folder once phpunit/coverage analysis has run.

I did this by wrapping phpunit command in a bash script:

#!/usr/bin/env bash

#Run phpunit
./vendor/bin/phpunit

#Copy custom stylesheet
cp ./tests/code-coverage-daylight.css ./tests/logs/.css/style.css
cp ./tests/code-coverage-daylight.css ./tests/logs/css/style.css

I configured the "coverage-html" to tests/logs in phpunit.xml , then I just run ./myphpunit - the bash script above (you may need to chmod +x first tho.)

BTW here is the styling I use: https://gist.github.com/adrian7/cde0f8844b979a02b3212483ca226e4b

sebastienbarre commented 6 years ago

Hello @sebastianbergmann, was wondering if configurable colors for colorblind people is still on the table, or if you need some help? Thanks.

legoktm commented 6 years ago

Hi, the current colors are a problem for me as well, with my colorblindness they're just not distinguishable. I'd recommend using a yellow and blue to represent covered/not covered - I've seen that contrast used well in the uBlock software, as well as Wikipedia (MediaWiki), and should be accessible to nearly everyone I think. Here's a quick screenshot of MediaWiki's code coverage report using the same colors that MediaWiki diffs use:

screenshot-2018-5-28 code coverage for srv jenkins-workspace workspace mediawiki-core-code-coverage src includes collation

Yellow: #feeec8 (might need to tweak so it doesn't conflict with the warning color) Blue: #d8ecff

If I submitted a patch to add an optional flag to use more accessible colors instead of the defaults, would that be acceptable?

sebastianbergmann commented 6 years ago

I do not want to change the default colors, at least not to something completely different than blue.

What should be done, IMO, is make it easier to use a custom CSS.

Using a custom CSS is already possible, it just needs to be copied manually (or automatically, as a step in your build script) to the right place.

legoktm commented 6 years ago

I do not want to change the default colors, at least not to something completely different than blue.

Makes sense, I was thinking something like phpunit --coverage-html coverage --accessible-colors, that requires the user to opt-in to the more accessible colors.

What should be done, IMO, is make it easier to use a custom CSS.

Using a custom CSS is already possible, it just needs to be copied manually (or automatically, as a step in your build script) to the right place.

It would be nice if PHPUnit came with a standard accessible option, since I suspect any accessible stylesheet will just get copied around to many projects anyways.

But since that would at least let me fix this problem for my projects, I'm happy to help work towards that :) Were you thinking of something like phpunit --coverage-html coverage --custom-css=~/foobar/phpunit.css, and then having PHPUnit append that custom CSS to the existing styles.css?

adrian7 commented 6 years ago

FYI I am working on a project to allow replacing coverage html styles (also can generate badges and possibly replace templates later): https://github.com/adrian7/candybar/

Pull requests are welcome. Thanks.

sebastianbergmann commented 6 years ago

As of 5626697ba169fc6bd56d38d83b478682f279bf7b, there is now an empty .css/custom.css file that is included by all generated HTML files (after .css/style.css is included).

This should make what I described in https://github.com/sebastianbergmann/php-code-coverage/issues/556#issuecomment-392423453 a little easier.

sebastienbarre commented 6 years ago

As stated when I opened this issue, I run ./Vendor/bin/phpunit --coverage-html from the command-line, with different parameters, depending on which piece of code I'm testing. I don't use a build script. Some people in our team use other IDEs which interacts/calls phpunit. In either cases, this means building yet another script on top of that so that a custom CSS is copied over (and I'm not even sure all PHP IDEs would allow that level of customization).

All of this would be solved in one fell swoop if there were 3 options you could set in phpunit.xml for: success, warning, danger. Then the generator would put these colors inline in the HTML, as regular, good-old inline CSS, after the inclusion of style.css (but before the link to the new, aforementioned custom.css). I'm still open to create that PR, but back in November (!) it seemed you wanted to do it yourself...

@legoktm thanks for the color scheme, unfortunately there are just way too many levels of color-blindness to attempt to fix them all.

CJDennis commented 6 years ago

I see you've already implemented a solution, but what I would suggest is adding another class to the elements. I.e. "success" would change to "success custom-colour" or similar. That way, your default colours remain the same, but user's CSS rules using the ".success.custom-colour" class are more specific so they take precedence.

keomaborges commented 4 years ago

Suggestion of CSS script for a simple dark-mode. Works for me.

body {
    background-color: black;
    color: darkgrey;
}
table {
    color: darkgrey !important;
}
a {
    color: deepskyblue;
}
ol {
    background-color: dimgrey !important;
}
span {
    color: darkgrey !important;
}
.breadcrumb-item {
    color: white !important;
}
.danger {
    background-color: #5f0202 !important;
}
.success {
    background-color: #013c01 !important;
}
.warning {
    background-color: #7b5916 !important;
}
daniel-farina commented 4 years ago

@adrian7
The script idea is good solution. In my case in a Laravel project I made a script that gets the style from the test folder:

tests/coverage-style.css

body {
    padding: 0px;
    background-color: rgba(0, 0, 0, 0.90);
}
*{

    color: #cbcbcb !important;
}

.table-bordered td, .table-bordered th {
    border: 1px solid #424242;
}

.table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
    background-color: rgba(0, 60, 8, 0.96);
}

.table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
    background-color: #430107;
    color:white;
}

.table tbody td.warning, li.warning, span.warning {
    background-color: #514800;
}

.breadcrumb {
    background-color: #001827;
    border-radius: .25rem;
}

.octicon
{
    filter: invert(0.8)
}

.progress {
    background-color: rgb(66, 66, 66);

}

phpunit.bash looks like this:

#!/usr/bin/env bash
#Run phpunit
./vendor/bin/phpunit
#Copy custom stylesheet
cp ./tests/coverage-style.css ./report/_css/custom.css

Make it executable

chmod +x phpunit.bash

then run it, it will copy your custom css stylesheet to your report directory

./phpunit.bash

In my case my phpunit.xml is configured to save the report inside a folder called report

    <logging>
        <log type="coverage-html" target="./report" lowUpperBound="50" highLowerBound="80" />
    </logging>

This is the final result: image

@sebastianbergmann Thank you for adding the custom.css file. Quite handy.

e-belair commented 4 years ago

It should be great to customize the color for Text report as It's hard to view the report in console: image

Do I have to open a new issue for that?

sebastianbergmann commented 4 years ago

The colors of the text report are controlled by your terminal / shell.

e-belair commented 4 years ago

Ha ok, sorry I believed it was the color const inside the Text class

sebastienbarre commented 2 years ago

Five years to come to this. It only needed 3 options one could have simply set in phpunit.xml to specify the hexadecimal colors for success, warning, and danger respectively, but nope. Five years.

sebastianbergmann commented 2 years ago

I am not happy with this situation either. I will try my best to find a solution. This will not make into a release before PHPUnit 10, though.

sebastianbergmann commented 2 years ago

The php-code-coverage side of things has been implemented in 1f6a9a5a0ec9228296b11f8e93a1d2a7a78236b1.

hemberger commented 2 years ago

Accessibility options can be very tedious, and often have unsatisfying solutions. It must be especially difficult to budget time for this when you are almost solely responsible for the entire phpunit ecosystem, but I am grateful that you haven't given up on this issue.

Personally, I would have rather had a more convenient option to specify our own custom.css file than the limited set of configurable colors that have been added. I suppose it'll be good enough for most colorblind folks (like me), but I'm also photosensitive and have to use a custom.css regardless to add my own dark mode.

The reason I created #901 was because it's sometimes tricky to add the custom.css file when working inside Docker containers, and it seemed like a very straightforward thing for php-code-coverage to be able to do. I don't think this is mutually exclusive with the basic configurable colors that you have added, so maybe we can knock out both at once?

Lacking any native support, I will probably have to resort to a browser-based CSS tool, such as Stylish, but that's obviously not a very satisfying solution, and doesn't help anyone else trying to solve the same problem.

For anyone interested, here's the CSS I came up with for a colorblind-friendly dark mode (using https://github.com/sebastianbergmann/php-code-coverage/issues/556#issuecomment-596880366 as a starting point). It's not perfect, but there's an art to these things that I have not mastered!

:root {
    --text-color: #c7c7c7;
}
body {
    background-color: #22272e;
    color: var(--text-color);
}
a {
    color: deepskyblue;
}

/* Header (breadcrumb) */
.breadcrumb {
    background-color: dimgrey !important;
}
.breadcrumb-item, .breadcrumb-item::before {
    color: white !important;
}

/* Code colors */
span.default, span.keyword {
    color: var(--text-color) !important;
}
span.comment {
    color: #727272 !important;
    font-style: italic;
}

/* Coverage colors */
.danger {
    background-color: #260000 !important;
}
.success, .covered-by-large-tests {
    background-color: #013c01 !important;
    color: var(--text-color);
}
.warning {
    background-color: #7b5916 !important;
}

/* Table */
table {
    color: var(--text-color) !important;
}
.table-bordered td, .table-bordered th {
    border: 1px solid black;
}
.progress {
    background-color: black;
}

/* Tooltip */
.popover {
    --tooltip-bg-color: #0d0d0d;
}
.popover-header {
    border-bottom: 0px var(--tooltip-bg-color) !important;
}
.popover, .popover-header {
    background-color: var(--tooltip-bg-color);
}
.arrow::after {
    border-top-color: var(--tooltip-bg-color) !important;
    border-bottom-color: var(--tooltip-bg-color) !important;
}

image

sebastienbarre commented 2 years ago

@sebastianbergmann Thanks, I appreciate.

For fellow colorblind people landing here, my understanding based on the code that was just added is that you will be able to configure a good subset of colors by using the new options.

Since they are passed to the constructor the same way highLowerBound is, my assumption at this point is that you will be able to pass them from phpunit.xml through the <report> element, as shown in the documentation here:

<report>
    <clover outputFile="clover.xml"/>
    <cobertura outputFile="cobertura.xml"/>
    <crap4j outputFile="crap4j.xml" threshold="50"/>
    <html outputDirectory="html-coverage" lowUpperBound="50" highLowerBound="90"/>
    <php outputFile="coverage.php"/>
    <text outputFile="coverage.txt" showUncoveredFiles="false" showOnlySummary="true"/>
    <xml outputDirectory="xml-coverage"/>
</report>

where

    <html outputDirectory="html-coverage" lowUpperBound="50" highLowerBound="90"/>

is likely where these options will be accepted (pending official documentation).

Thanks

sebastianbergmann commented 1 year ago

Personally, I would have rather had a more convenient option to specify our own custom.css file than the limited set of configurable colors that have been added.

At the same time, back when support for configuring the colors was added, support for specifying a custom CSS file was added. Did you not know about that or is that not good enough? Thank you for your feedback!

sebastianbergmann commented 1 year ago

For fellow colorblind people landing here, my understanding based on the code that was just added is that you will be able to configure a good subset of colors by using the new options.

The relevant options are now documented here.

hemberger commented 1 year ago

Personally, I would have rather had a more convenient option to specify our own custom.css file than the limited set of configurable colors that have been added.

At the same time, back when support for configuring the colors was added, support for specifying a custom CSS file was added. Did you not know about that or is that not good enough? Thank you for your feedback!

I believe my comment was made before the customCssFile option was added (or at least before I noticed it!). I have been using customCssFile since the release of PHPUnit 10, and am finding it extremely helpful. Thank you for implementing it!