1 // Copyright 2018 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 <memory>
6 #include <string>
7
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/no_destructor.h"
13 #include "base/path_service.h"
14 #include "base/run_loop.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/threading/thread_restrictions.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/search/instant_service.h"
19 #include "chrome/browser/search/instant_service_factory.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/search/local_ntp_test_utils.h"
22 #include "chrome/common/chrome_paths.h"
23 #include "chrome/test/base/in_process_browser_test.h"
24 #include "components/ntp_tiles/features.h"
25 #include "content/public/browser/render_view_host.h"
26 #include "content/public/browser/render_widget_host.h"
27 #include "content/public/browser/render_widget_host_view.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/test/browser_test.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "third_party/skia/include/core/SkBitmap.h"
32 #include "ui/compositor/compositor_switches.h"
33 #include "ui/gfx/codec/png_codec.h"
34 #include "ui/gfx/geometry/rect.h"
35 #include "ui/gfx/geometry/size.h"
36
37 namespace {
38
39 // Where the captures are stored.
GetTestDataDir()40 const base::FilePath& GetTestDataDir() {
41 static base::NoDestructor<base::FilePath> dir([]() {
42 base::FilePath dir;
43 base::PathService::Get(base::DIR_SOURCE_ROOT, &dir);
44 dir = dir.AppendASCII("components")
45 .AppendASCII("test")
46 .AppendASCII("data")
47 .AppendASCII("ntp")
48 .AppendASCII("render");
49 return dir;
50 }());
51 return *dir;
52 }
53
54 class LocalNTPRenderTest : public InProcessBrowserTest {
55 public:
SetUp()56 void SetUp() override {
57 EnablePixelOutput();
58 InProcessBrowserTest::SetUp();
59 }
60
LoadNewTabPageAndCapture(int viewport_width,int viewport_height,const std::string & filename)61 void LoadNewTabPageAndCapture(int viewport_width,
62 int viewport_height,
63 const std::string& filename) {
64 // Open an NTP and wait until it has fully loaded (tiles may animate, so we
65 // give this some delay).
66 local_ntp_test_utils::NavigateToNTPAndWaitUntilLoaded(browser(),
67 /*delay=*/1000);
68 content::WebContents* active_tab =
69 browser()->tab_strip_model()->GetActiveWebContents();
70 content::RenderFrameSubmissionObserver render_frame_observer(active_tab);
71
72 content::RenderWidgetHost* render_widget_host =
73 active_tab->GetMainFrame()->GetRenderViewHost()->GetWidget();
74 content::RenderWidgetHostView* view = render_widget_host->GetView();
75 ASSERT_TRUE(view && view->IsSurfaceAvailableForCopy());
76
77 // Resize the view to the desired size.
78 view->SetSize(gfx::Size(viewport_width, viewport_height));
79
80 gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size());
81 ASSERT_TRUE(!copy_rect.IsEmpty());
82 const cc::RenderFrameMetadata& last_metadata =
83 render_frame_observer.LastRenderFrameMetadata();
84 ASSERT_TRUE(last_metadata.is_scroll_offset_at_top);
85
86 run_loop_ = std::make_unique<base::RunLoop>();
87 view->CopyFromSurface(copy_rect, copy_rect.size(),
88 base::BindOnce(&LocalNTPRenderTest::OnCapturedBitmap,
89 base::Unretained(this), filename));
90 run_loop_->Run();
91 }
92
93 private:
94 // Will write |bitmap| as a png in the test data directory with |filename|.
OnCapturedBitmap(const std::string & filename,const SkBitmap & bitmap)95 void OnCapturedBitmap(const std::string& filename, const SkBitmap& bitmap) {
96 std::vector<unsigned char> bitmap_data;
97 bool result =
98 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bitmap_data);
99 DCHECK(result);
100 base::ScopedAllowBlockingForTesting allow_blocking;
101 EXPECT_TRUE(
102 base::WriteFile(GetTestDataDir().AppendASCII(filename), bitmap_data));
103 run_loop_->Quit();
104 }
105
106 std::unique_ptr<base::RunLoop> run_loop_;
107 };
108
109 IN_PROC_BROWSER_TEST_F(LocalNTPRenderTest, 1200x800_DefaultMV) {
110 LoadNewTabPageAndCapture(/*viewport_width=*/1200, /*viewport_height=*/800,
111 /*filename=*/"1200x800_DefaultMV.png");
112 }
113
114 IN_PROC_BROWSER_TEST_F(LocalNTPRenderTest, 1200x800_MVWithCustomLinks) {
115 InstantService* instant_service =
116 InstantServiceFactory::GetForProfile(browser()->profile());
117 instant_service->AddCustomLink(GURL("http://192.168.1.1"), "My Router");
118 instant_service->AddCustomLink(GURL("https://www.apple.com"), "Apple");
119 instant_service->AddCustomLink(GURL("https://bobpay.xyz"), "BobPay");
120 instant_service->AddCustomLink(GURL("https://cnn.com"), "CNN");
121 instant_service->AddCustomLink(GURL("https://paymentrequest.show"),
122 "Payment Request Demo Site");
123 instant_service->AddCustomLink(GURL("https://google.com"), "Google");
124 instant_service->AddCustomLink(GURL("https://reddit.com/r/whatever"),
125 "Reddit");
126 instant_service->AddCustomLink(GURL("https://samsung.com"), "Samsung");
127
128 LoadNewTabPageAndCapture(/*viewport_width=*/1200, /*viewport_height=*/800,
129 /*filename=*/"1200x800_MVWithCustomLinks.png");
130 }
131
132 } // namespace
133