blob: cf5a6a4c2b1cb5a6b0517f68ca1d41539faf9d2f [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdlib.h>
#include "base/strings/utf_string_conversions.h"
#include "content/browser/devtools/protocol/devtools_protocol_test_support.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
namespace content {
namespace {
std::string_view MaybeStripFontationsSuffix(const std::string& font_name) {
std::string_view view = font_name;
std::size_t pos = view.rfind(" (Fontations)");
if (pos != std::string_view::npos) {
view.remove_suffix(view.size() - pos);
}
return view;
}
} // namespace
class FontPreferencesBrowserTest : public DevToolsProtocolTest {
public:
FontPreferencesBrowserTest() = default;
~FontPreferencesBrowserTest() override = default;
protected:
std::string GetFirstPlatformFontForBody() {
base::Value::Dict params1;
params1.Set("depth", 0);
const base::Value::Dict* result =
SendCommand("DOM.getDocument", std::move(params1));
std::optional<int> body_node_id =
result->FindIntByDottedPath("root.nodeId");
DCHECK(body_node_id);
base::Value::Dict params2;
params2.Set("nodeId", *body_node_id);
params2.Set("selector", "body");
result = SendCommand("DOM.querySelector", std::move(params2));
DCHECK(result);
body_node_id = result->FindInt("nodeId");
DCHECK(body_node_id);
base::Value::Dict params3;
params3.Set("nodeId", *body_node_id);
const base::Value::Dict* font_info =
SendCommand("CSS.getPlatformFontsForNode", std::move(params3));
DCHECK(font_info);
const base::Value::List* font_list = font_info->FindList("fonts");
DCHECK(font_list);
DCHECK(font_list->size() > 0);
const base::Value& first_font_info = font_list->front();
const std::string* first_font_name =
first_font_info.GetDict().FindString("familyName");
DCHECK(first_font_name);
return *first_font_name;
}
// Verify that text rendered with CSS font-family set to generic_family uses
// the corresponding value from WebPreferences:
// - generic_family: A CSS font-family to test e.g. "serif".
// - default_preferences: the default WebPreferences.
// - default_preferences_font_family_map: the font family map corresponding to
// the generic_family e.g. default_preferences.serif_font_family_map.
void TestGenericFamilyPreference(
const std::string& generic_family,
blink::web_pref::WebPreferences& default_preferences,
blink::web_pref::ScriptFontFamilyMap&
default_preferences_font_family_map) {
// The test works by setting the tested preference to a system font
// different from the default value, and verifying that this change is
// taken into account for text rendering.
const std::u16string default_system_font =
default_preferences_font_family_map[blink::web_pref::kCommonScript];
#if BUILDFLAG(IS_WIN)
const std::string non_default_system_font = "Lucida Console";
#elif BUILDFLAG(IS_MAC)
const std::string non_default_system_font = "Monaco";
#elif BUILDFLAG(IS_IOS)
const std::string non_default_system_font = "Verdana";
#elif BUILDFLAG(IS_FUCHSIA)
// Fuchsia platforms don't seem to have many pre-installed fonts besides the
// default Roboto families. Let's instead choose the default monospace
// family or, if 'monospace' is tested, the default sans-serif family.
const char* default_system_font_sans_serif = "Roboto";
const char* default_system_font_monospace = "Roboto Mono";
const std::string non_default_system_font =
generic_family == "monospace" ? default_system_font_sans_serif
: default_system_font_monospace;
#else
const std::string non_default_system_font = "Ahem";
#endif
// Set the font-family of the body to the specified generic family.
WebContents* web_contents = shell()->web_contents();
EXPECT_TRUE(ExecJs(web_contents, "document.body.style.fontFamily = '" +
generic_family + "'"));
// Verify that by default, the non-default system font above is not used.
web_contents->SetWebPreferences(default_preferences);
EXPECT_TRUE(ExecJs(web_contents, "document.body.offsetTop"));
EXPECT_NE(MaybeStripFontationsSuffix(GetFirstPlatformFontForBody()),
non_default_system_font);
// Set the preference to that non-default system font and try again.
default_preferences_font_family_map[blink::web_pref::kCommonScript] =
base::ASCIIToUTF16(non_default_system_font);
web_contents->SetWebPreferences(default_preferences);
EXPECT_TRUE(ExecJs(web_contents, "document.body.offsetTop"));
EXPECT_EQ(MaybeStripFontationsSuffix(GetFirstPlatformFontForBody()),
non_default_system_font);
// Restore the preference to its default value.
default_preferences_font_family_map[blink::web_pref::kCommonScript] =
default_system_font;
}
};
IN_PROC_BROWSER_TEST_F(FontPreferencesBrowserTest, GenericFamilies) {
ASSERT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(NavigateToURL(shell(), GURL("data:text/html,BODY_TEXT")));
Attach();
ASSERT_TRUE(SendCommand("DOM.enable", base::Value::Dict(), true));
ASSERT_TRUE(SendCommand("CSS.enable", base::Value::Dict(), true));
blink::web_pref::WebPreferences default_preferences =
shell()->web_contents()->GetOrCreateWebPreferences();
TestGenericFamilyPreference("initial", default_preferences,
default_preferences.standard_font_family_map);
TestGenericFamilyPreference("serif", default_preferences,
default_preferences.serif_font_family_map);
TestGenericFamilyPreference("sans-serif", default_preferences,
default_preferences.sans_serif_font_family_map);
TestGenericFamilyPreference("cursive", default_preferences,
default_preferences.cursive_font_family_map);
TestGenericFamilyPreference("fantasy", default_preferences,
default_preferences.fantasy_font_family_map);
TestGenericFamilyPreference("monospace", default_preferences,
default_preferences.fixed_font_family_map);
TestGenericFamilyPreference("math", default_preferences,
default_preferences.math_font_family_map);
}
} // namespace content