blob: 051421cab48c4304b89d907f22b3e67bbb783d49 [file] [log] [blame]
// Copyright 2019 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.
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "cc/test/pixel_comparator.h"
#include "cc/test/pixel_test_utils.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/common/content_paths.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/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display_switches.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/skbitmap_operations.h"
// To rebaseline this test on android:
// 1. Run a CQ+1 dry run
// 2. Click the failing android bot
// 3. Find the failing content_browsertests step
// 4. Click the "Deterministic failure" link for the failing test case
// 5. Copy the "Actual pixels" data url and paste into browser
// 6. Save the image into your chromium checkout in content/test/data/forms/
namespace content {
class FormControlsBrowserTest : public ContentBrowserTest {
public:
FormControlsBrowserTest() = default;
void SetUp() override {
EnablePixelOutput();
ContentBrowserTest::SetUp();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
ContentBrowserTest::SetUpCommandLine(command_line);
// The --force-device-scale-factor flag helps make the pixel output of
// different android trybots more similar.
command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1.0");
feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
feature_list_->InitWithFeatures({features::kFormControlsRefresh}, {});
}
void TearDown() override { feature_list_.reset(); }
void AsyncSnapshotCallback(const gfx::Image& image) {
got_snapshot_ = true;
snapshot_ = image;
}
void RunFormControlsTest(const std::string& expected_filename,
const std::string& body_html,
int screenshot_width,
int screenshot_height) {
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(features::IsFormControlsRefreshEnabled());
std::string url =
"data:text/html,<!DOCTYPE html>"
"<head>"
// The <meta name=viewport> tag helps make the pixel output of
// different android trybots more similar.
" <meta name=\"viewport\" content=\"width=640, initial-scale=1, "
" maximum-scale=1, minimum-scale=1\">"
"</head>"
"<body>" +
body_html + "</body>";
ASSERT_TRUE(NavigateToURL(shell(), GURL(url)));
RenderWidgetHostImpl* const rwh =
RenderWidgetHostImpl::From(shell()
->web_contents()
->GetRenderWidgetHostView()
->GetRenderWidgetHost());
CHECK(rwh);
rwh->GetSnapshotFromBrowser(
base::BindOnce(&FormControlsBrowserTest::AsyncSnapshotCallback,
base::Unretained(this)),
/* from_surface */ true);
while (!got_snapshot_)
base::RunLoop().RunUntilIdle();
SkBitmap bitmap = SkBitmapOperations::CreateTiledBitmap(
*snapshot_.ToSkBitmap(), /* src_x */ 0, /* src_y */ 0, screenshot_width,
screenshot_height);
base::FilePath dir_test_data;
ASSERT_TRUE(base::PathService::Get(DIR_TEST_DATA, &dir_test_data));
std::string filename_with_extension = expected_filename;
#if defined(OS_ANDROID)
filename_with_extension += "_android";
#endif
filename_with_extension += ".png";
base::FilePath expected_path =
dir_test_data.AppendASCII("forms").AppendASCII(filename_with_extension);
SkBitmap expected_bitmap;
ASSERT_TRUE(cc::ReadPNGFile(expected_path, &expected_bitmap));
EXPECT_TRUE(cc::MatchesBitmap(
bitmap, expected_bitmap,
#if defined(OS_MACOSX)
// The Mac 10.12 trybot has more significant subpixel rendering
// differences which we accommodate for here with a large avg/max
// per-pixel error limit.
// TODO(crbug.com/1037971): Remove this special case for mac once this
// bug is resolved.
cc::FuzzyPixelComparator(/* discard_alpha */ true,
/* error_pixels_percentage_limit */ 7.f,
/* small_error_pixels_percentage_limit */ 0.f,
/* avg_abs_error_limit */ 16.f,
/* max_abs_error_limit */ 79.f,
/* small_error_threshold */ 0)));
#else
// We use a fuzzy comparator to accommodate for slight
// differences between the kitkat and marshmallow trybots that aren't
// visible to the human eye. We use a very low error limit because the
// pixels that are different are very similar shades of color.
cc::FuzzyPixelComparator(/* discard_alpha */ true,
/* error_pixels_percentage_limit */ 6.f,
/* small_error_pixels_percentage_limit */ 0.f,
/* avg_abs_error_limit */ 4.f,
/* max_abs_error_limit */ 4.f,
/* small_error_threshold */ 0)));
#endif
}
bool got_snapshot_ = false;
gfx::Image snapshot_;
std::unique_ptr<base::test::ScopedFeatureList> feature_list_;
};
IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest, Checkbox) {
RunFormControlsTest(
"form_controls_browsertest_checkbox",
"<input type=checkbox>"
"<input type=checkbox checked>"
"<input type=checkbox disabled>"
"<input type=checkbox checked disabled>"
"<input type=checkbox id=\"indeterminate\">"
"<script>"
" document.getElementById('indeterminate').indeterminate = true"
"</script>",
/* screenshot_width */ 130,
/* screenshot_height */ 40);
}
IN_PROC_BROWSER_TEST_F(FormControlsBrowserTest, Radio) {
RunFormControlsTest(
"form_controls_browsertest_radio",
"<input type=radio>"
"<input type=radio checked>"
"<input type=radio disabled>"
"<input type=radio checked disabled>"
"<input type=radio id=\"indeterminate\">"
"<script>"
" document.getElementById('indeterminate').indeterminate = true"
"</script>",
/* screenshot_width */ 140,
/* screenshot_height */ 40);
}
// TODO(jarhar): Add tests for other elements from
// https://concrete-hardboard.glitch.me
} // namespace content