lighthouse-ci
lighthouse-ci copied to clipboard
Documentation: How to test a site in dark mode
Is your feature request related to a problem? Please describe.
The accessibility assessment checks contrast ratios. Websites often provide a light theme and a dark theme, and it is common to for the site to automatically set the theme based on the browser/OS preference.
Describe the solution you'd like
It would be great to have an easy way to run "dark mode" tests against sites that let the browser/OS select the theme.
Describe alternatives you've considered
I read through the documentation but it seems quite complicated to set up, and searching for "dark mode" yielded no results.
it is common to for the site to automatically set the theme based on the browser/OS preference
@ptmkenny can you provide an example site that does this? I'm curious what triggers are available for a site to automatically adjust to dark mode.
@Elte156 Sure, https://bulma.io/.
You will see whatever your browser/OS preference is, but you can change it by opening a new tab in Chrome, go to settings -> appearance -> light/dark and refreshing the page.
Looking into this myself, I found Puppeteer has Page.emulateMediaFeatures():
await page.emulateMediaFeatures([
{name: 'prefers-color-scheme', value: 'dark'},
]);
But I don't know a convenient way to make use of this with lighthouse.
Thank you. @ptmkenny These are the triggers I was looking for:
- https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-Prefers-Color-Scheme
When I visit bulma.io, the light/dark mode tests didn't work for me (maybe because this color scheme detection is experimental at the moment).
What I did notice were these request headers (didn't include header Sec-CH-Prefers-Color-Scheme: "dark"
):
So perhaps try this in your lighthouse config and see if it does what you expect:
{
"ci": {
"collect": {
"settings": {
"extraHeaders": "{\"Sec-CH-Prefers-Color-Scheme\": \"dark\"}"
}
}
}
}
Thanks for this information.
I tried your suggested config but it doesn't seem to work:
lhci --config .dark.json collect --url https://www.bulma.io
In this case, on my local machine (macOS, OS set to dark mode), for the three test runs:
- The first is in dark mode.
- The second and third are in light mode.
If I change the config to be light
instead of dark
, the result is the same (dark, then light and light again).
If I run without the config, then the result is the same (dark - light - light).
On GHA, I always seem to get light mode, even with the config.
Then it seems that bulma.io doesn't respond to that special CH
header.
When you run it locally on your Mac, what does the UserAgent
request header read when you load bulma.io? I suspect that's the other way how the OS/browser tells the website which theme mode to load.
@Elte156 It must be something that the OS/Chrome is doing itself because, in addition to changing from Light to Dark and back in the browser, I noticed I can also change between Light and Dark in macOS, and the Bulma website (and my personal website, which is based on Bulma) both automatically switch between light and dark mode.
I checked the headers when in light mode and in dark mode and they don't change; they are exactly the same, but dark or light mode is returned depending on the browser or OS preference.
Bulma is a CSS-only framework, so this is not due to JS.
So the question is how to put lighthouse's browser/OS into "dark mode"?
It seems Chrome has a flag for forcing dark mode:
--enable-features=WebContentsForceDark
Is there a way to use this flag with lighthouse-ci?
I was able to see this work when I change my macOS appearance from light to dark and it's instantaneous (no page reload needed). Pretty cool.
There is a way to feed the chrome instance options. Take a look here at all the flags available: https://bit.ly/chrome-flags
Try this and see if it works:
{
"ci": {
"collect": {
"settings": {
"chromeFlags": "--force-dark-mode"
}
}
}
}
@Elte156 Unfortunately, that did not work. It seems there is something special about the dark mode behavior, but I can't find good documentation for it so I asked Stack Overflow. I'll update when I find a reliable way to do this.
Ok, I think the issue is this.
The way to force Chrome to enable dark mode is to use --enable-features=WebContentsForceDark
. So, for example, I can launch Chrome and see my site in dark mode with this command on macOS.
open -a Google\ Chrome --args --enable-features=WebContentsForceDark
However, when I access chrome://version/
and check the Command Line parameters, this is the result:
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --enable-features=WebContentsForceDark --flag-switches-begin --flag-switches-end
So --enable-features=WebContentsForceDark
is not a "flag" in the sense that it goes between --flag-switches-begin
and --flag-switches-end
. Maybe this is why it's failing when I use chromeFlags
?
I was just about to create an issue for this.
Do you have your CI setup to run Lighthouse once with your web-app's default theme, and then again with a night theme active? I'm curious to see how the configuration files for that would look.
- The first is in dark mode.
- The second and third are in light mode.
Looks like this is caused by #1067. As a workaround, you could try:
collect:
headful: true
settings:
chromeFlags: --headless=new --enable-features=WebContentsForceDark