lighthouse-ci icon indicating copy to clipboard operation
lighthouse-ci copied to clipboard

Documentation: How to test a site in dark mode

Open ptmkenny opened this issue 10 months ago • 12 comments

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.

ptmkenny avatar Apr 05 '24 07:04 ptmkenny

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 avatar Apr 05 '24 14:04 Elte156

@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.

ptmkenny avatar Apr 05 '24 14:04 ptmkenny

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"): image

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\"}"
      }
    }
  }
}

Elte156 avatar Apr 05 '24 16:04 Elte156

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.

ptmkenny avatar Apr 06 '24 09:04 ptmkenny

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 avatar Apr 06 '24 12:04 Elte156

@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"?

ptmkenny avatar Apr 06 '24 13:04 ptmkenny

It seems Chrome has a flag for forcing dark mode:

--enable-features=WebContentsForceDark

Is there a way to use this flag with lighthouse-ci?

ptmkenny avatar Apr 06 '24 13:04 ptmkenny

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 avatar Apr 06 '24 17:04 Elte156

@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.

ptmkenny avatar Apr 11 '24 03:04 ptmkenny

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?

ptmkenny avatar Apr 11 '24 14:04 ptmkenny

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.

hamirmahal avatar Jun 29 '24 08:06 hamirmahal

  • 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

dcsaszar avatar Aug 03 '24 09:08 dcsaszar