| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package org.chromium.android_webview.test; |
| |
| import androidx.test.filters.SmallTest; |
| |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import org.chromium.android_webview.AwContents; |
| import org.chromium.android_webview.AwSettings; |
| import org.chromium.android_webview.settings.ForceDarkBehavior; |
| import org.chromium.android_webview.settings.ForceDarkMode; |
| |
| /** |
| * Tests dark-mode related data are correctly passed to blink. |
| */ |
| @RunWith(AwJUnit4ClassRunner.class) |
| public class DarkModeTest { |
| @Rule |
| public AwActivityTestRule mRule = new AwActivityTestRule(); |
| |
| private TestAwContentsClient mContentsClient = new TestAwContentsClient(); |
| private AwContents mContents; |
| private AwSettings mSettings; |
| |
| @Before |
| public void setUp() { |
| mContents = createAwContentsJsEnabled(); |
| mSettings = mContents.getSettings(); |
| } |
| |
| @Test |
| @SmallTest |
| public void testDarkModeOff() throws Throwable { |
| mRule.loadUrlSync(mContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); |
| |
| // Disable dark mode and check that prefers-color-scheme is not set to dark. |
| mSettings.setForceDarkMode(ForceDarkMode.FORCE_DARK_OFF); |
| assertNotDarkScheme(mContents); |
| } |
| |
| @Test |
| @SmallTest |
| public void testUAOnlyDarkening() throws Throwable { |
| // If WebView uses UA only darkening strategy prefer-color-scheme should always been set to |
| // 'light' to avoid double darkening regardless whether web-page supports dark theme. |
| mSettings.setForceDarkMode(ForceDarkMode.FORCE_DARK_ON); |
| mSettings.setForceDarkBehavior(ForceDarkBehavior.FORCE_DARK_ONLY); |
| |
| // Load web-page which does not support dark theme and |
| // check prefers-color-scheme is not set to dark |
| mRule.loadUrlSync(mContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); |
| assertNotDarkScheme(mContents); |
| |
| // Load web page which supports dark theme and |
| // check prefers-color-scheme is still not set to dark |
| final String supportsDarkScheme = |
| "<html><head><meta name=\"color-scheme\" content=\"dark light\"></head>" |
| + "<body></body></html>"; |
| mRule.loadHtmlSync( |
| mContents, mContentsClient.getOnPageFinishedHelper(), supportsDarkScheme); |
| assertNotDarkScheme(mContents); |
| } |
| |
| @Test |
| @SmallTest |
| public void testWebThemeOnlyDarkening() throws Throwable { |
| // If WebView uses web theme only darkening strategy |
| // prefer-color-scheme should been set to dark. |
| mRule.loadUrlSync(mContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); |
| mSettings.setForceDarkMode(ForceDarkMode.FORCE_DARK_ON); |
| mSettings.setForceDarkBehavior(ForceDarkBehavior.MEDIA_QUERY_ONLY); |
| |
| assertDarkScheme(mContents); |
| } |
| |
| @Test |
| @SmallTest |
| public void testPreferWebThemeDarkening() throws Throwable { |
| // If WebView prefers web theme darkening over UA darkening prefer-color-scheme is set |
| // according to whether web page supports dark-theme |
| mRule.loadUrlSync(mContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); |
| mSettings.setForceDarkMode(ForceDarkMode.FORCE_DARK_ON); |
| mSettings.setForceDarkBehavior(ForceDarkBehavior.PREFER_MEDIA_QUERY_OVER_FORCE_DARK); |
| |
| // If web page does not support dark theme prefer-color-scheme should be set to 'light' |
| assertNotDarkScheme(mContents); |
| |
| final String supportsDarkScheme = |
| "<html><head><meta name=\"color-scheme\" content=\"dark light\"></head>" |
| + "<body></body></html>"; |
| mRule.loadHtmlSync( |
| mContents, mContentsClient.getOnPageFinishedHelper(), supportsDarkScheme); |
| |
| // If web page supports dark theme, prefer-color-scheme is set to dark. |
| assertDarkScheme(mContents); |
| } |
| |
| @Test |
| @SmallTest |
| public void testDarkThemePerWebView() throws Throwable { |
| // WebView allows to set dark mode preferences per WebView, check that their settings |
| // do not interfere with each other. |
| |
| mRule.loadUrlSync(mContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); |
| mSettings.setForceDarkMode(ForceDarkMode.FORCE_DARK_ON); |
| mSettings.setForceDarkBehavior(ForceDarkBehavior.MEDIA_QUERY_ONLY); |
| |
| AwContents otherContents = createAwContentsJsEnabled(); |
| AwSettings otherSettings = otherContents.getSettings(); |
| mRule.loadUrlSync(otherContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); |
| otherSettings.setForceDarkMode(ForceDarkMode.FORCE_DARK_ON); |
| otherSettings.setForceDarkBehavior(ForceDarkBehavior.FORCE_DARK_ONLY); |
| |
| assertDarkScheme(mContents); |
| assertNotDarkScheme(otherContents); |
| } |
| |
| @Test |
| @SmallTest |
| public void testColorSchemeUpdatedInPreferWebThemeMode() throws Throwable { |
| // Test that preferred-color-scheme is updated respectively in |
| // prefer-web-theme-over-ua-darkening-mode, and force dark is |
| // correctly applied when web theme is not available. |
| |
| mSettings.setForceDarkMode(ForceDarkMode.FORCE_DARK_ON); |
| mSettings.setForceDarkBehavior(ForceDarkBehavior.PREFER_MEDIA_QUERY_OVER_FORCE_DARK); |
| |
| // Load a web-page without dark theme support and check that preferred-color-scheme is set |
| // to no-preferences |
| mRule.loadUrlSync(mContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); |
| assertNotDarkScheme(mContents); |
| |
| // Load a web-page with dark theme support in them same WebView and check that |
| // preferred-color-scheme is set to dark, so media query is applied |
| final String supportsDarkScheme = |
| "<html><head><meta name=\"color-scheme\" content=\"dark light\"></head>" |
| + "<body></body></html>"; |
| mRule.loadHtmlSync( |
| mContents, mContentsClient.getOnPageFinishedHelper(), supportsDarkScheme); |
| assertDarkScheme(mContents); |
| |
| // Load a web-page with no dark theme support in them same WebView and check that |
| // preferred-color-scheme is set back to no-preferences |
| mRule.loadUrlSync(mContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); |
| assertNotDarkScheme(mContents); |
| } |
| |
| private boolean prefersDarkTheme(AwContents contents) throws Exception { |
| final String colorSchemeSelector = |
| "window.matchMedia('(prefers-color-scheme: dark)').matches"; |
| String result = mRule.executeJavaScriptAndWaitForResult( |
| contents, mContentsClient, colorSchemeSelector); |
| |
| return "true".equals(result); |
| } |
| |
| private void assertNotDarkScheme(AwContents contents) throws Exception { |
| Assert.assertFalse(prefersDarkTheme(contents)); |
| } |
| |
| private void assertDarkScheme(AwContents contents) throws Exception { |
| Assert.assertTrue(prefersDarkTheme(contents)); |
| } |
| |
| private AwContents createAwContentsJsEnabled() { |
| AwTestContainerView view = mRule.createAwTestContainerViewOnMainSync(mContentsClient); |
| AwContents contents = view.getAwContents(); |
| AwActivityTestRule.enableJavaScriptOnUiThread(contents); |
| return contents; |
| } |
| } |