1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/files/file_util.h"
6 #include "base/path_service.h"
7 #include "base/test/scoped_feature_list.h"
8 #include "build/build_config.h"
9 #include "cc/test/pixel_comparator.h"
10 #include "content/public/browser/render_widget_host_view.h"
11 #include "content/public/common/content_paths.h"
12 #include "content/public/test/browser_test.h"
13 #include "content/public/test/browser_test_utils.h"
14 #include "content/public/test/content_browser_test.h"
15 #include "content/public/test/content_browser_test_utils.h"
16 #include "content/public/test/test_utils.h"
17 #include "content/shell/browser/shell.h"
18 #include "ui/base/ui_base_features.h"
19
20 #if defined(OS_ANDROID)
21 #include "base/android/build_info.h"
22 #endif
23
24 // TODO(crbug.com/958242): Move the baselines to skia gold for easier
25 // rebaselining when all platforms are supported.
26
27 // To rebaseline this test on all platforms:
28 // 1. Run a CQ+1 dry run.
29 // 2. Click the failing bots for android, windows, mac, and linux.
30 // 3. Find the failing interactive_ui_browsertests step.
31 // 4. Click the "Deterministic failure" link for the failing test case.
32 // 5. Copy the "Actual pixels" data url and paste into browser.
33 // 6. Save the image into your chromium checkout in content/test/data/forms/.
34
35 namespace content {
36
37 class FormControlsBrowserTest : public ContentBrowserTest {
38 public:
FormControlsBrowserTest()39 FormControlsBrowserTest() {
40 feature_list_.InitWithFeatures({features::kFormControlsRefresh}, {});
41 }
42
SetUp()43 void SetUp() override {
44 EnablePixelOutput(/*force_device_scale_factor=*/1.f);
45 ContentBrowserTest::SetUp();
46 }
47
SetUpCommandLine(base::CommandLine * command_line)48 void SetUpCommandLine(base::CommandLine* command_line) override {
49 ContentBrowserTest::SetUpCommandLine(command_line);
50
51 // The --disable-lcd-text flag helps text render more similarly on
52 // different bots and platform.
53 command_line->AppendSwitch(switches::kDisableLCDText);
54 }
55
RunTest(const std::string & screenshot_filename,const std::string & body_html,int screenshot_width,int screenshot_height)56 void RunTest(const std::string& screenshot_filename,
57 const std::string& body_html,
58 int screenshot_width,
59 int screenshot_height) {
60 base::ScopedAllowBlockingForTesting allow_blocking;
61
62 ASSERT_TRUE(features::IsFormControlsRefreshEnabled());
63
64 std::string platform_suffix;
65 #if defined(OS_MAC)
66 platform_suffix = "_mac";
67 #elif defined(OS_WIN)
68 platform_suffix = "_win";
69 #elif defined(OS_CHROMEOS)
70 platform_suffix = "_chromeos";
71 #elif defined(OS_ANDROID)
72 int sdk_int = base::android::BuildInfo::GetInstance()->sdk_int();
73 if (sdk_int == base::android::SDK_VERSION_KITKAT) {
74 platform_suffix = "_android_kitkat";
75 } else {
76 platform_suffix = "_android";
77 }
78 #endif
79
80 base::FilePath dir_test_data;
81 ASSERT_TRUE(base::PathService::Get(DIR_TEST_DATA, &dir_test_data));
82 base::FilePath golden_filepath =
83 dir_test_data.AppendASCII("forms").AppendASCII(screenshot_filename +
84 ".png");
85
86 base::FilePath golden_filepath_platform =
87 golden_filepath.InsertBeforeExtensionASCII(platform_suffix);
88 if (base::PathExists(golden_filepath_platform)) {
89 golden_filepath = golden_filepath_platform;
90 }
91
92 ASSERT_TRUE(NavigateToURL(
93 shell()->web_contents(),
94 GURL("data:text/html,<!DOCTYPE html><body>" + body_html + "</body>")));
95
96 #if defined(OS_MAC)
97 // This fuzzy pixel comparator handles several mac behaviors:
98 // - Different font rendering after 10.14
99 // - 10.12 subpixel rendering differences: crbug.com/1037971
100 // - Slight differences in radio and checkbox rendering in 10.15
101 cc::FuzzyPixelComparator comparator(
102 /* discard_alpha */ true,
103 /* error_pixels_percentage_limit */ 9.f,
104 /* small_error_pixels_percentage_limit */ 0.f,
105 /* avg_abs_error_limit */ 20.f,
106 /* max_abs_error_limit */ 79.f,
107 /* small_error_threshold */ 0);
108 #elif defined(OS_ANDROID)
109 // Different versions of android may have slight differences in rendering.
110 // Some versions have more significant differences than others, which are
111 // tracked separately in separate baseline image files. The less significant
112 // differences are accommodated for with this fuzzy pixel comparator.
113 cc::FuzzyPixelComparator comparator(
114 /* discard_alpha */ true,
115 /* error_pixels_percentage_limit */ 6.f,
116 /* small_error_pixels_percentage_limit */ 0.f,
117 /* avg_abs_error_limit */ 2.f,
118 /* max_abs_error_limit */ 3.f,
119 /* small_error_threshold */ 0);
120 #else
121 cc::ExactPixelComparator comparator(/* disard_alpha */ true);
122 #endif
123 EXPECT_TRUE(CompareWebContentsOutputToReference(
124 shell()->web_contents(), golden_filepath,
125 gfx::Size(screenshot_width, screenshot_height), comparator));
126 }
127
128 private:
129 base::test::ScopedFeatureList feature_list_;
130 };
131
IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest,Checkbox)132 IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest, Checkbox) {
133 RunTest("form_controls_browsertest_checkbox",
134 "<input type=checkbox>"
135 "<input type=checkbox checked>"
136 "<input type=checkbox disabled>"
137 "<input type=checkbox checked disabled>"
138 "<input type=checkbox id=\"indeterminate\">"
139 "<script>"
140 " document.getElementById('indeterminate').indeterminate = true"
141 "</script>",
142 /* screenshot_width */ 130,
143 /* screenshot_height */ 40);
144 }
145
IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest,Radio)146 IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest, Radio) {
147 RunTest("form_controls_browsertest_radio",
148 "<input type=radio>"
149 "<input type=radio checked>"
150 "<input type=radio disabled>"
151 "<input type=radio checked disabled>"
152 "<input type=radio id=\"indeterminate\">"
153 "<script>"
154 " document.getElementById('indeterminate').indeterminate = true"
155 "</script>",
156 /* screenshot_width */ 140,
157 /* screenshot_height */ 40);
158 }
159
160 // TODO(jarhar): Add tests for other elements from
161 // https://concrete-hardboard.glitch.me
162
163 } // namespace content
164