blob: 3de09b6a0e769f958701901be0b8d777dc4924fe [file] [log] [blame]
// 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;
}
}