1 // Copyright 2017 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 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/json/string_escape.h"
11 #include "base/memory/ref_counted_memory.h"
12 #include "base/optional.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/test/metrics/histogram_tester.h"
16 #include "build/build_config.h"
17 #include "chrome/browser/search/instant_service.h"
18 #include "chrome/browser/search/instant_service_factory.h"
19 #include "chrome/browser/search_provider_logos/logo_service_factory.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/search/instant_test_utils.h"
22 #include "chrome/browser/ui/search/local_ntp_browsertest_base.h"
23 #include "chrome/browser/ui/search/local_ntp_test_utils.h"
24 #include "chrome/common/url_constants.h"
25 #include "chrome/test/base/in_process_browser_test.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "components/keyed_service/content/browser_context_dependency_manager.h"
28 #include "components/search_provider_logos/logo_service.h"
29 #include "content/public/browser/web_contents.h"
30 #include "content/public/test/browser_test.h"
31 #include "content/public/test/browser_test_utils.h"
32 #include "content/public/test/test_navigation_observer.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "url/gurl.h"
35
36 using search_provider_logos::EncodedLogo;
37 using search_provider_logos::EncodedLogoCallback;
38 using search_provider_logos::LogoCallbacks;
39 using search_provider_logos::LogoCallbackReason;
40 using search_provider_logos::LogoObserver;
41 using search_provider_logos::LogoService;
42 using search_provider_logos::LogoType;
43 using testing::_;
44 using testing::DoAll;
45 using testing::Eq;
46 using testing::IsEmpty;
47
48 namespace {
49
50 const char kCachedB64[] = "\161\247\041\171\337\276"; // b64decode("cached++")
51 const char kFreshB64[] = "abc"; // b64decode("YWJj")
52 const int kRealboxTopPx = 56 + 200 + 38; // top margin + height + bottom margin
53
54 #if defined(OS_WIN) || defined(OS_MAC)
55 const char kFreshDarkB64[] = "xyz"; // b64decode("eHl6");
56 #endif
57
58 // A base64 encoding of a tiny but valid gif file.
59 const char kTinyGifData[] =
60 "R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
61
MakeRefPtr(std::string content)62 scoped_refptr<base::RefCountedString> MakeRefPtr(std::string content) {
63 return base::RefCountedString::TakeString(&content);
64 }
65
66 class MockLogoService : public LogoService {
67 public:
68 MOCK_METHOD1(GetLogoPtr, void(LogoCallbacks* callbacks));
69
GetLogo(LogoCallbacks callbacks,bool for_webui_ntp)70 void GetLogo(LogoCallbacks callbacks, bool for_webui_ntp) override {
71 GetLogoPtr(&callbacks);
72 }
GetLogo(LogoObserver * observer)73 void GetLogo(LogoObserver* observer) override { NOTREACHED(); }
74 };
75
ACTION_P2(ReturnCachedLogo,reason,logo)76 ACTION_P2(ReturnCachedLogo, reason, logo) {
77 if (arg0->on_cached_encoded_logo_available) {
78 std::move(arg0->on_cached_encoded_logo_available).Run(reason, logo);
79 }
80 }
81
ACTION_P2(ReturnFreshLogo,reason,logo)82 ACTION_P2(ReturnFreshLogo, reason, logo) {
83 if (arg0->on_fresh_encoded_logo_available) {
84 std::move(arg0->on_fresh_encoded_logo_available).Run(reason, logo);
85 }
86 }
87
88 // A simple class to add a test failure if any console message comes in for
89 // the given WebContents.
90 class FailOnConsoleMessage : public content::WebContentsObserver {
91 public:
FailOnConsoleMessage(content::WebContents * web_contents)92 explicit FailOnConsoleMessage(content::WebContents* web_contents)
93 : WebContentsObserver(web_contents) {}
94 FailOnConsoleMessage(const FailOnConsoleMessage& other) = delete;
95 FailOnConsoleMessage& operator=(const FailOnConsoleMessage& other) = delete;
96 ~FailOnConsoleMessage() override = default;
97
98 private:
99 // content::WebContentsObserver:
OnDidAddMessageToConsole(content::RenderFrameHost * source_frame,blink::mojom::ConsoleMessageLevel log_level,const base::string16 & message,int32_t line_no,const base::string16 & source_id)100 void OnDidAddMessageToConsole(content::RenderFrameHost* source_frame,
101 blink::mojom::ConsoleMessageLevel log_level,
102 const base::string16& message,
103 int32_t line_no,
104 const base::string16& source_id) override {
105 ADD_FAILURE() << "Unexpected console message: " << message;
106 }
107 };
108
109 } // namespace
110
111 class LocalNTPDoodleTest : public InProcessBrowserTest {
112 protected:
LocalNTPDoodleTest()113 LocalNTPDoodleTest() {}
114
logo_service()115 MockLogoService* logo_service() {
116 return static_cast<MockLogoService*>(
117 LogoServiceFactory::GetForProfile(browser()->profile()));
118 }
119
GetDimension(content::WebContents * tab,const std::string & id,const std::string & dimension)120 base::Optional<int> GetDimension(content::WebContents* tab,
121 const std::string& id,
122 const std::string& dimension) {
123 double value = 0.0;
124 if (instant_test_utils::GetDoubleFromJS(
125 tab,
126 base::StringPrintf(
127 "document.getElementById(%s).getBoundingClientRect()[%s]",
128 base::GetQuotedJSONString(id).c_str(),
129 base::GetQuotedJSONString(dimension).c_str()),
130 &value)) {
131 return value;
132 }
133 return base::nullopt;
134 }
135
TeardownWindowOpenTest(content::WebContents * tab)136 void TeardownWindowOpenTest(content::WebContents* tab) {
137 ASSERT_TRUE(content::ExecuteScript(tab, "window.open = windowOpenOld"));
138 }
139
SetupWindowOpenTest(content::WebContents * tab)140 void SetupWindowOpenTest(content::WebContents* tab) {
141 ASSERT_TRUE(content::ExecuteScript(tab,
142 "var windowOpenOld = window.open; "
143 "window.open = (w) => { openedWindow = "
144 "w };"));
145 }
146
GetWindowOpenURL(content::WebContents * tab)147 base::Optional<std::string> GetWindowOpenURL(content::WebContents* tab) {
148 std::string target_url;
149 if (instant_test_utils::GetStringFromJS(tab, "openedWindow", &target_url)) {
150 return target_url;
151 }
152 return base::nullopt;
153 }
154
TeardownNavigatorTest(content::WebContents * tab)155 void TeardownNavigatorTest(content::WebContents* tab) {
156 ASSERT_TRUE(content::ExecuteScript(tab, "window.navigator = navigatorOld"));
157 }
158
SetupBeaconTest(content::WebContents * tab)159 void SetupBeaconTest(content::WebContents* tab) {
160 ASSERT_TRUE(content::ExecuteScript(tab,
161 "var navigatorOld = window.navigator; "
162 "window.navigator = {};"
163 "window.navigator.sendBeacon = "
164 "(url) => { sentbeacon = url };"));
165 }
166
GetBeaconURL(content::WebContents * tab)167 base::Optional<std::string> GetBeaconURL(content::WebContents* tab) {
168 std::string target_url;
169 if (instant_test_utils::GetStringFromJS(tab, "sentbeacon", &target_url)) {
170 return target_url;
171 }
172 return base::nullopt;
173 }
174
ElementExists(content::WebContents * tab,const std::string & id)175 bool ElementExists(content::WebContents* tab, const std::string& id) {
176 return ExecuteBooleanJS(
177 tab, base::StringPrintf("!!document.getElementById(%s)",
178 base::GetQuotedJSONString(id).c_str()));
179 }
180
DialogIsOpen(content::WebContents * tab,const std::string & id)181 bool DialogIsOpen(content::WebContents* tab, const std::string& id) {
182 return ExecuteBooleanJS(
183 tab,
184 base::StringPrintf("!!document.getElementById(%s).hasAttribute('open')",
185 base::GetQuotedJSONString(id).c_str()));
186 }
187
ExecuteBooleanJS(content::WebContents * tab,const std::string & js)188 bool ExecuteBooleanJS(content::WebContents* tab, const std::string& js) {
189 bool value;
190 if (instant_test_utils::GetBoolFromJS(tab, js, &value)) {
191 return value;
192 }
193 return false;
194 }
195
GetComputedStyle(content::WebContents * tab,const std::string & id,const std::string & css_name)196 base::Optional<std::string> GetComputedStyle(content::WebContents* tab,
197 const std::string& id,
198 const std::string& css_name) {
199 std::string css_value;
200 if (instant_test_utils::GetStringFromJS(
201 tab,
202 base::StringPrintf(
203 "getComputedStyle(document.getElementById(%s))[%s]",
204 base::GetQuotedJSONString(id).c_str(),
205 base::GetQuotedJSONString(css_name).c_str()),
206 &css_value)) {
207 return css_value;
208 }
209 return base::nullopt;
210 }
211
GetComputedOpacity(content::WebContents * tab,const std::string & id)212 base::Optional<double> GetComputedOpacity(content::WebContents* tab,
213 const std::string& id) {
214 auto css_value = GetComputedStyle(tab, id, "opacity");
215 double double_value;
216 if ((css_value != base::nullopt) &&
217 base::StringToDouble(*css_value, &double_value)) {
218 return double_value;
219 }
220 return base::nullopt;
221 }
222
GetComputedDisplay(content::WebContents * tab,const std::string & id)223 base::Optional<std::string> GetComputedDisplay(content::WebContents* tab,
224 const std::string& id) {
225 return GetComputedStyle(tab, id, "display");
226 }
227
228 // Gets $(id)[property]. Coerces to string.
GetElementProperty(content::WebContents * tab,const std::string & id,const std::string & property)229 base::Optional<std::string> GetElementProperty(content::WebContents* tab,
230 const std::string& id,
231 const std::string& property) {
232 std::string value;
233 if (instant_test_utils::GetStringFromJS(
234 tab,
235 base::StringPrintf("document.getElementById(%s)[%s] + ''",
236 base::GetQuotedJSONString(id).c_str(),
237 base::GetQuotedJSONString(property).c_str()),
238 &value)) {
239 return value;
240 }
241 return base::nullopt;
242 }
243
WaitForFadeIn(content::WebContents * tab,const std::string & id)244 void WaitForFadeIn(content::WebContents* tab, const std::string& id) {
245 content::WebContentsConsoleObserver console_observer(tab);
246 console_observer.SetPattern("WaitForFadeIn");
247
248 bool result = false;
249 if (!instant_test_utils::GetBoolFromJS(
250 tab,
251 base::StringPrintf(
252 R"js(
253 (function(id, message) {
254 var element = document.getElementById(id);
255 var fn = function() {
256 if (element.classList.contains('show-logo') &&
257 (window.getComputedStyle(element).opacity == 1.0)) {
258 console.log(message);
259 } else {
260 element.addEventListener('transitionend', fn);
261 }
262 };
263 fn();
264 return true;
265 })(%s, 'WaitForFadeIn')
266 )js",
267 base::GetQuotedJSONString(id).c_str()),
268 &result) &&
269 result) {
270 ADD_FAILURE() << "failed to wait for fade-in";
271 return;
272 }
273
274 console_observer.Wait();
275 }
276
WaitForLogoSwap(content::WebContents * tab,const std::string & id)277 void WaitForLogoSwap(content::WebContents* tab, const std::string& id) {
278 content::WebContentsConsoleObserver console_observer(tab);
279 console_observer.SetPattern("WaitForFadeIn");
280
281 bool result = false;
282 if (!instant_test_utils::GetBoolFromJS(
283 tab,
284 base::StringPrintf(
285 R"js(
286 (function(id, message) {
287 var element = document.getElementById(id);
288 var fn = function() {
289 if (element.classList.contains('show-logo') &&
290 (window.getComputedStyle(element).opacity == 1.0)) {
291 console.log(message);
292 }
293 };
294 element.addEventListener('transitionend', fn);
295 return true;
296 })(%s, 'WaitForFadeIn')
297 )js",
298 base::GetQuotedJSONString(id).c_str()),
299 &result) &&
300 result) {
301 ADD_FAILURE() << "failed to wait for fade-in";
302 return;
303 }
304
305 console_observer.Wait();
306 }
307
308 // See enum LogoImpressionType in ntp_user_data_logger.cc.
309 static const int kLogoImpressionStatic = 0;
310 static const int kLogoImpressionCta = 1;
311
312 // See enum LogoClickType in ntp_user_data_logger.cc.
313 static const int kLogoClickCta = 1;
314
315 private:
SetUp()316 void SetUp() override {
317 InProcessBrowserTest::SetUp();
318 }
319
SetUpInProcessBrowserTestFixture()320 void SetUpInProcessBrowserTestFixture() override {
321 create_services_subscription_ =
322 BrowserContextDependencyManager::GetInstance()
323 ->RegisterCreateServicesCallbackForTesting(base::BindRepeating(
324 &LocalNTPDoodleTest::OnWillCreateBrowserContextServices,
325 base::Unretained(this)));
326 }
327
CreateLogoService(content::BrowserContext * context)328 static std::unique_ptr<KeyedService> CreateLogoService(
329 content::BrowserContext* context) {
330 return std::make_unique<MockLogoService>();
331 }
332
OnWillCreateBrowserContextServices(content::BrowserContext * context)333 void OnWillCreateBrowserContextServices(content::BrowserContext* context) {
334 LogoServiceFactory::GetInstance()->SetTestingFactory(
335 context, base::BindRepeating(&LocalNTPDoodleTest::CreateLogoService));
336 }
337
338 std::unique_ptr<
339 BrowserContextDependencyManager::CreateServicesCallbackList::Subscription>
340 create_services_subscription_;
341 };
342
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldBeUnchangedOnLogoFetchCancelled)343 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
344 ShouldBeUnchangedOnLogoFetchCancelled) {
345 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
346 .WillRepeatedly(
347 DoAll(ReturnCachedLogo(LogoCallbackReason::CANCELED, base::nullopt),
348 ReturnFreshLogo(LogoCallbackReason::CANCELED, base::nullopt)));
349
350 // Open a new blank tab, then go to local NTP and listen for console messages.
351 content::WebContents* active_tab =
352 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
353
354 FailOnConsoleMessage console_observer(active_tab);
355 base::HistogramTester histograms;
356 ui_test_utils::NavigateToURL(browser(),
357 GURL(chrome::kChromeSearchLocalNtpUrl));
358
359 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
360 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(1.0));
361 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(0.0));
362
363 histograms.ExpectTotalCount("NewTabPage.LogoShown", 0);
364 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 0);
365 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 0);
366 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 0);
367 }
368
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldBeUnchangedWhenNoCachedOrFreshDoodle)369 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
370 ShouldBeUnchangedWhenNoCachedOrFreshDoodle) {
371 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
372 .WillRepeatedly(DoAll(
373 ReturnCachedLogo(LogoCallbackReason::DETERMINED, base::nullopt),
374 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
375
376 // Open a new blank tab, then go to local NTP and listen for console messages.
377 content::WebContents* active_tab =
378 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
379 FailOnConsoleMessage console_observer(active_tab);
380 base::HistogramTester histograms;
381 ui_test_utils::NavigateToURL(browser(),
382 GURL(chrome::kChromeSearchLocalNtpUrl));
383
384 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
385 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(1.0));
386 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(0.0));
387
388 histograms.ExpectTotalCount("NewTabPage.LogoShown", 0);
389 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 0);
390 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 0);
391 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 0);
392 }
393
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldShowDoodleWhenCached)394 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldShowDoodleWhenCached) {
395 EncodedLogo cached_logo;
396 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
397 cached_logo.metadata.mime_type = "image/png";
398 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
399 cached_logo.metadata.alt_text = "Chromium";
400
401 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
402 .WillRepeatedly(DoAll(
403 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
404 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
405
406 // Open a new blank tab, then go to local NTP and listen for console messages.
407 content::WebContents* active_tab =
408 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
409 FailOnConsoleMessage console_observer(active_tab);
410 base::HistogramTester histograms;
411 ui_test_utils::NavigateToURL(browser(),
412 GURL(chrome::kChromeSearchLocalNtpUrl));
413
414 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
415 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
416 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
417 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
418 Eq<std::string>("inline-block"));
419 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
420 Eq<std::string>("none"));
421 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "title"),
422 Eq<std::string>("Chromium"));
423 // TODO(sfiera): check href by clicking on button.
424
425 histograms.ExpectTotalCount("NewTabPage.LogoShown", 1);
426 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionStatic,
427 1);
428 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 1);
429 histograms.ExpectBucketCount("NewTabPage.LogoShown.FromCache",
430 kLogoImpressionStatic, 1);
431 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 0);
432 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
433 }
434
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldShowInteractiveLogo)435 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldShowInteractiveLogo) {
436 EncodedLogo cached_logo;
437 cached_logo.encoded_image = MakeRefPtr(std::string());
438 cached_logo.metadata.mime_type = "image/png";
439 cached_logo.metadata.type = LogoType::INTERACTIVE;
440 cached_logo.metadata.full_page_url =
441 GURL("https://www.chromium.org/interactive");
442 cached_logo.metadata.alt_text = "alt text";
443 cached_logo.metadata.iframe_width_px = 500;
444 cached_logo.metadata.iframe_height_px = 200;
445
446 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
447 .WillRepeatedly(DoAll(
448 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
449 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
450
451 // Open a new blank tab, then go to local NTP.
452 content::WebContents* active_tab =
453 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
454 base::HistogramTester histograms;
455 ui_test_utils::NavigateToURL(browser(),
456 GURL(chrome::kChromeSearchLocalNtpUrl));
457
458 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
459 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
460 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
461 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
462 Eq<std::string>("none"));
463 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
464 Eq<std::string>("block"));
465
466 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-iframe", "src"),
467 Eq<std::string>("https://www.chromium.org/interactive"));
468 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-iframe", "title"),
469 Eq<std::string>("alt text"));
470 }
471
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldShowInteractiveLogoWithoutImage)472 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
473 ShouldShowInteractiveLogoWithoutImage) {
474 EncodedLogo cached_logo;
475 cached_logo.encoded_image = nullptr;
476 cached_logo.metadata.type = LogoType::INTERACTIVE;
477 cached_logo.metadata.full_page_url =
478 GURL("https://www.chromium.org/interactive");
479 cached_logo.metadata.alt_text = "alt text";
480 cached_logo.metadata.iframe_width_px = 500;
481 cached_logo.metadata.iframe_height_px = 200;
482
483 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
484 .WillRepeatedly(DoAll(
485 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
486 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
487
488 // Open a new blank tab, then go to local NTP.
489 content::WebContents* active_tab =
490 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
491 base::HistogramTester histograms;
492 ui_test_utils::NavigateToURL(browser(),
493 GURL(chrome::kChromeSearchLocalNtpUrl));
494
495 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
496 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
497 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
498 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
499 Eq<std::string>("none"));
500 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
501 Eq<std::string>("block"));
502
503 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-iframe", "src"),
504 Eq<std::string>("https://www.chromium.org/interactive"));
505 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-iframe", "title"),
506 Eq<std::string>("alt text"));
507 }
508
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldFadeSimpleDoodleToDefaultWhenFetched)509 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
510 ShouldFadeSimpleDoodleToDefaultWhenFetched) {
511 EncodedLogo cached_logo;
512 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
513 cached_logo.metadata.mime_type = "image/png";
514 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
515 cached_logo.metadata.alt_text = "Chromium";
516
517 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
518 .WillOnce(
519 DoAll(ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
520 ReturnFreshLogo(LogoCallbackReason::DETERMINED, base::nullopt)))
521 .WillRepeatedly(DoAll(
522 ReturnCachedLogo(LogoCallbackReason::DETERMINED, base::nullopt),
523 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
524
525 // Open a new blank tab, then go to local NTP.
526 content::WebContents* active_tab =
527 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
528 base::HistogramTester histograms;
529 ui_test_utils::NavigateToURL(browser(),
530 GURL(chrome::kChromeSearchLocalNtpUrl));
531
532 WaitForFadeIn(active_tab, "logo-default");
533 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
534 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(1.0));
535 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(0.0));
536
537 histograms.ExpectTotalCount("NewTabPage.LogoShown", 1);
538 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionStatic,
539 1);
540 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 1);
541 histograms.ExpectBucketCount("NewTabPage.LogoShown.FromCache",
542 kLogoImpressionStatic, 1);
543 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 0);
544 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
545 }
546
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldFadeDefaultToSimpleDoodleWhenFetched)547 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
548 ShouldFadeDefaultToSimpleDoodleWhenFetched) {
549 EncodedLogo fresh_logo;
550 fresh_logo.encoded_image = MakeRefPtr(kFreshB64);
551 fresh_logo.metadata.mime_type = "image/png";
552 fresh_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
553 fresh_logo.metadata.alt_text = "Chromium";
554
555 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
556 .WillOnce(
557 DoAll(ReturnCachedLogo(LogoCallbackReason::DETERMINED, base::nullopt),
558 ReturnFreshLogo(LogoCallbackReason::DETERMINED, fresh_logo)))
559 .WillRepeatedly(DoAll(
560 ReturnCachedLogo(LogoCallbackReason::DETERMINED, fresh_logo),
561 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
562
563 // Open a new blank tab, then go to local NTP.
564 content::WebContents* active_tab =
565 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
566 base::HistogramTester histograms;
567 ui_test_utils::NavigateToURL(browser(),
568 GURL(chrome::kChromeSearchLocalNtpUrl));
569
570 WaitForFadeIn(active_tab, "logo-doodle");
571 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
572 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
573 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
574 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
575 Eq<std::string>("inline-block"));
576 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
577 Eq<std::string>("none"));
578 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "title"),
579 Eq<std::string>("Chromium"));
580 // TODO(sfiera): check href by clicking on button.
581
582 histograms.ExpectTotalCount("NewTabPage.LogoShown", 1);
583 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionStatic,
584 1);
585 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 0);
586 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 1);
587 histograms.ExpectBucketCount("NewTabPage.LogoShown.Fresh",
588 kLogoImpressionStatic, 1);
589 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
590 }
591
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldFadeDefaultToInteractiveDoodleWhenFetched)592 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
593 ShouldFadeDefaultToInteractiveDoodleWhenFetched) {
594 EncodedLogo fresh_logo;
595 fresh_logo.encoded_image = MakeRefPtr(std::string());
596 fresh_logo.metadata.mime_type = "image/png";
597 fresh_logo.metadata.type = LogoType::INTERACTIVE;
598 fresh_logo.metadata.full_page_url =
599 GURL("https://www.chromium.org/interactive");
600 fresh_logo.metadata.alt_text = "alt text";
601 fresh_logo.metadata.iframe_width_px = 500;
602 fresh_logo.metadata.iframe_height_px = 200;
603
604 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
605 .WillOnce(
606 DoAll(ReturnCachedLogo(LogoCallbackReason::DETERMINED, base::nullopt),
607 ReturnFreshLogo(LogoCallbackReason::DETERMINED, fresh_logo)))
608 .WillRepeatedly(DoAll(
609 ReturnCachedLogo(LogoCallbackReason::DETERMINED, fresh_logo),
610 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
611
612 // Open a new blank tab, then go to local NTP.
613 content::WebContents* active_tab =
614 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
615 ui_test_utils::NavigateToURL(browser(),
616 GURL(chrome::kChromeSearchLocalNtpUrl));
617
618 WaitForFadeIn(active_tab, "logo-doodle");
619 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
620 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
621 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
622 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
623 Eq<std::string>("none"));
624 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
625 Eq<std::string>("block"));
626 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-iframe", "src"),
627 Eq<std::string>("https://www.chromium.org/interactive"));
628 }
629
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldNotFadeFromInteractiveDoodle)630 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldNotFadeFromInteractiveDoodle) {
631 EncodedLogo cached_logo;
632 cached_logo.encoded_image = MakeRefPtr(std::string());
633 cached_logo.metadata.mime_type = "image/png";
634 cached_logo.metadata.type = LogoType::INTERACTIVE;
635 cached_logo.metadata.full_page_url =
636 GURL("https://www.chromium.org/interactive");
637 cached_logo.metadata.alt_text = "alt text";
638 cached_logo.metadata.iframe_width_px = 500;
639 cached_logo.metadata.iframe_height_px = 200;
640
641 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
642 .WillOnce(
643 DoAll(ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
644 ReturnFreshLogo(LogoCallbackReason::DETERMINED, base::nullopt)))
645 .WillRepeatedly(DoAll(
646 ReturnCachedLogo(LogoCallbackReason::DETERMINED, base::nullopt),
647 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
648
649 // Open a new blank tab, then go to local NTP.
650 content::WebContents* active_tab =
651 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
652 ui_test_utils::NavigateToURL(browser(),
653 GURL(chrome::kChromeSearchLocalNtpUrl));
654
655 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
656 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
657 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
658 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
659 Eq<std::string>("none"));
660 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
661 Eq<std::string>("block"));
662 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-iframe", "src"),
663 Eq<std::string>("https://www.chromium.org/interactive"));
664 }
665
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldFadeSimpleDoodleToSimpleDoodleWhenFetched)666 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
667 ShouldFadeSimpleDoodleToSimpleDoodleWhenFetched) {
668 EncodedLogo cached_logo;
669 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
670 cached_logo.metadata.mime_type = "image/png";
671 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/cached");
672 cached_logo.metadata.alt_text = "cached alt text";
673
674 EncodedLogo fresh_logo;
675 fresh_logo.encoded_image = MakeRefPtr(kFreshB64);
676 fresh_logo.metadata.mime_type = "image/png";
677 fresh_logo.metadata.on_click_url = GURL("https://www.chromium.org/fresh");
678 fresh_logo.metadata.alt_text = "fresh alt text";
679
680 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
681 .WillOnce(
682 DoAll(ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
683 ReturnFreshLogo(LogoCallbackReason::DETERMINED, fresh_logo)))
684 .WillRepeatedly(DoAll(
685 ReturnCachedLogo(LogoCallbackReason::DETERMINED, fresh_logo),
686 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
687
688 // Open a new blank tab, then go to local NTP.
689 content::WebContents* active_tab =
690 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
691 base::HistogramTester histograms;
692 ui_test_utils::NavigateToURL(browser(),
693 GURL(chrome::kChromeSearchLocalNtpUrl));
694
695 WaitForFadeIn(active_tab, "logo-doodle");
696 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
697 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
698 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
699 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
700 Eq<std::string>("inline-block"));
701 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
702 Eq<std::string>("none"));
703 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "src"),
704 Eq<std::string>("data:image/png;base64,YWJj"));
705 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "title"),
706 Eq<std::string>("fresh alt text"));
707 // TODO(sfiera): check href by clicking on button.
708
709 // LogoShown is recorded for both cached and fresh Doodle, but LogoShownTime2
710 // is only recorded once per NTP.
711 histograms.ExpectTotalCount("NewTabPage.LogoShown", 2);
712 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionStatic,
713 2);
714 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 1);
715 histograms.ExpectBucketCount("NewTabPage.LogoShown.FromCache",
716 kLogoImpressionStatic, 1);
717 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 1);
718 histograms.ExpectBucketCount("NewTabPage.LogoShown.Fresh",
719 kLogoImpressionStatic, 1);
720 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
721 }
722
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldUpdateMetadataWhenChanged)723 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldUpdateMetadataWhenChanged) {
724 EncodedLogo cached_logo;
725 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
726 cached_logo.metadata.mime_type = "image/png";
727 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/cached");
728 cached_logo.metadata.alt_text = "cached alt text";
729
730 EncodedLogo fresh_logo;
731 fresh_logo.encoded_image = cached_logo.encoded_image;
732 fresh_logo.metadata.mime_type = cached_logo.metadata.mime_type;
733 fresh_logo.metadata.on_click_url = GURL("https://www.chromium.org/fresh");
734 fresh_logo.metadata.alt_text = "fresh alt text";
735
736 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
737 .WillOnce(
738 DoAll(ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
739 ReturnFreshLogo(LogoCallbackReason::DETERMINED, fresh_logo)))
740 .WillRepeatedly(DoAll(
741 ReturnCachedLogo(LogoCallbackReason::DETERMINED, fresh_logo),
742 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
743
744 // Open a new blank tab, then go to local NTP.
745 content::WebContents* active_tab =
746 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
747 base::HistogramTester histograms;
748 ui_test_utils::NavigateToURL(browser(),
749 GURL(chrome::kChromeSearchLocalNtpUrl));
750
751 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
752 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
753 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
754 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
755 Eq<std::string>("inline-block"));
756 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
757 Eq<std::string>("none"));
758
759 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "title"),
760 Eq<std::string>("fresh alt text"));
761 // TODO(sfiera): check href by clicking on button.
762
763 // Metadata update does not count as a new impression.
764 histograms.ExpectTotalCount("NewTabPage.LogoShown", 1);
765 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionStatic,
766 1);
767 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 1);
768 histograms.ExpectBucketCount("NewTabPage.LogoShown.FromCache",
769 kLogoImpressionStatic, 1);
770 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 0);
771 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
772 }
773
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldAppendShareButtonWhenCached)774 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldAppendShareButtonWhenCached) {
775 EncodedLogo cached_logo;
776 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
777 cached_logo.metadata.mime_type = "image/png";
778 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
779 cached_logo.metadata.alt_text = "Chromium";
780 cached_logo.metadata.short_link = GURL("https://g.co");
781 cached_logo.metadata.share_button_x = 12;
782 cached_logo.metadata.share_button_y = 39;
783 cached_logo.metadata.share_button_opacity = 0.8;
784 cached_logo.metadata.share_button_icon = "sbimg";
785 cached_logo.metadata.share_button_bg = "#ffff00";
786
787 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
788 .WillRepeatedly(DoAll(
789 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
790 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
791
792 // Open a new blank tab, then go to local NTP and listen for console messages.
793 content::WebContents* active_tab =
794 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
795 FailOnConsoleMessage console_observer(active_tab);
796 base::HistogramTester histograms;
797 ui_test_utils::NavigateToURL(browser(),
798 GURL(chrome::kChromeSearchLocalNtpUrl));
799
800 EXPECT_TRUE(ElementExists(active_tab, "ddlsb"));
801 EXPECT_TRUE(ElementExists(active_tab, "ddlsb-img"));
802 EXPECT_THAT(GetComputedStyle(active_tab, "ddlsb", "left"),
803 Eq<std::string>("12px"));
804 EXPECT_THAT(GetComputedStyle(active_tab, "ddlsb", "top"),
805 Eq<std::string>("39px"));
806 EXPECT_THAT(GetComputedStyle(active_tab, "ddlsb", "background-color"),
807 Eq<std::string>("rgba(255, 255, 0, 0.8)"));
808 EXPECT_THAT(GetElementProperty(active_tab, "ddlsb-img", "src"),
809 Eq<std::string>("data:image/png;base64,sbimg"));
810 }
811
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldNotAppendShareButtonWhenCacheEmpty)812 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
813 ShouldNotAppendShareButtonWhenCacheEmpty) {
814 EncodedLogo cached_logo;
815 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
816 cached_logo.metadata.mime_type = "image/png";
817 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
818 cached_logo.metadata.alt_text = "Chromium";
819 cached_logo.metadata.short_link = GURL("https://g.co");
820 cached_logo.metadata.share_button_x = -1;
821 cached_logo.metadata.share_button_y = -1;
822 cached_logo.metadata.share_button_opacity = 0;
823 cached_logo.metadata.share_button_icon = "";
824 cached_logo.metadata.share_button_bg = "";
825
826 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
827 .WillRepeatedly(DoAll(
828 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
829 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
830
831 // Open a new blank tab, then go to local NTP and listen for console messages.
832 content::WebContents* active_tab =
833 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
834 FailOnConsoleMessage console_observer(active_tab);
835 ui_test_utils::NavigateToURL(browser(),
836 GURL(chrome::kChromeSearchLocalNtpUrl));
837
838 EXPECT_FALSE(ElementExists(active_tab, "ddlsb"));
839 EXPECT_FALSE(ElementExists(active_tab, "ddlsb-img"));
840 }
841
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldNotAppendShareButtonWhenCacheIncomplete)842 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
843 ShouldNotAppendShareButtonWhenCacheIncomplete) {
844 EncodedLogo cached_logo;
845 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
846 cached_logo.metadata.mime_type = "image/png";
847 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
848 cached_logo.metadata.alt_text = "Chromium";
849 cached_logo.metadata.short_link = GURL("https://g.co");
850 cached_logo.metadata.share_button_x = 12;
851 cached_logo.metadata.share_button_y = 36;
852 cached_logo.metadata.share_button_opacity = 0.8;
853 cached_logo.metadata.share_button_icon = "";
854 cached_logo.metadata.share_button_bg = "#ffff00";
855
856 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
857 .WillRepeatedly(DoAll(
858 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
859 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
860
861 // Open a new blank tab, then go to local NTP and listen for console messages.
862 content::WebContents* active_tab =
863 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
864 FailOnConsoleMessage console_observer(active_tab);
865 ui_test_utils::NavigateToURL(browser(),
866 GURL(chrome::kChromeSearchLocalNtpUrl));
867
868 EXPECT_FALSE(ElementExists(active_tab, "ddlsb"));
869 EXPECT_FALSE(ElementExists(active_tab, "ddlsb-img"));
870 }
871
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldShowShareDialogWhenShareButtonClicked)872 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
873 ShouldShowShareDialogWhenShareButtonClicked) {
874 EncodedLogo cached_logo;
875 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
876 cached_logo.metadata.mime_type = "image/png";
877 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
878 cached_logo.metadata.alt_text = "Chromium";
879 cached_logo.metadata.short_link = GURL("https://g.co");
880 cached_logo.metadata.share_button_x = 12;
881 cached_logo.metadata.share_button_y = 36;
882 cached_logo.metadata.share_button_opacity = 0.8;
883 cached_logo.metadata.share_button_icon = "sbimg";
884 cached_logo.metadata.share_button_bg = "#ffff00";
885
886 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
887 .WillRepeatedly(DoAll(
888 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
889 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
890
891 // Open a new blank tab, then go to local NTP and listen for console messages.
892 content::WebContents* active_tab =
893 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
894 FailOnConsoleMessage console_observer(active_tab);
895 ui_test_utils::NavigateToURL(browser(),
896 GURL(chrome::kChromeSearchLocalNtpUrl));
897
898 EXPECT_FALSE(DialogIsOpen(active_tab, "ddlsd"));
899 ASSERT_TRUE(content::ExecuteScript(
900 active_tab, "document.getElementById('ddlsb').click();"));
901 EXPECT_TRUE(DialogIsOpen(active_tab, "ddlsd"));
902
903 // Check title
904 std::string title;
905 ASSERT_TRUE(instant_test_utils::GetStringFromJS(
906 active_tab, "document.getElementById('ddlsd-title').innerHTML", &title));
907 EXPECT_THAT(title, Eq<std::string>(cached_logo.metadata.alt_text));
908
909 // Check share link inside textbox
910 std::string link;
911 ASSERT_TRUE(instant_test_utils::GetStringFromJS(
912 active_tab, "document.getElementById('ddlsd-text').value", &link));
913 EXPECT_THAT(link, Eq<std::string>("https://g.co/"));
914
915 ASSERT_TRUE(content::ExecuteScript(
916 active_tab, "document.getElementById('ddlsd-close').click();"));
917 EXPECT_FALSE(DialogIsOpen(active_tab, "ddlsd"));
918 }
919
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldOpenFacebookInShareDialog)920 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldOpenFacebookInShareDialog) {
921 EncodedLogo cached_logo;
922 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
923 cached_logo.metadata.mime_type = "image/png";
924 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
925 cached_logo.metadata.alt_text = "Chromium";
926 cached_logo.metadata.short_link = GURL("https://g.co");
927 cached_logo.metadata.share_button_x = 12;
928 cached_logo.metadata.share_button_y = 36;
929 cached_logo.metadata.share_button_opacity = 0.8;
930 cached_logo.metadata.share_button_icon = "sbimg";
931 cached_logo.metadata.share_button_bg = "#ffff00";
932
933 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
934 .WillRepeatedly(DoAll(
935 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
936 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
937
938 // Open a new blank tab, then go to local NTP and listen for console messages.
939 content::WebContents* active_tab =
940 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
941 ui_test_utils::NavigateToURL(browser(),
942 GURL(chrome::kChromeSearchLocalNtpUrl));
943
944 ASSERT_TRUE(content::ExecuteScript(
945 active_tab, "document.getElementById('ddlsb').click();"));
946 EXPECT_TRUE(DialogIsOpen(active_tab, "ddlsd"));
947 SetupWindowOpenTest(active_tab);
948 ASSERT_TRUE(content::ExecuteScript(
949 active_tab, "document.getElementById('ddlsd-fbb').click();"));
950 EXPECT_THAT(GetWindowOpenURL(active_tab),
951 Eq<std::string>(
952 "https://www.facebook.com/dialog/share?app_id=738026486351791"
953 "&href=https%3A%2F%2Fg.co%2F&hashtag=%23GoogleDoodle"));
954 }
955
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldOpenTwitterInShareDialog)956 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldOpenTwitterInShareDialog) {
957 EncodedLogo cached_logo;
958 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
959 cached_logo.metadata.mime_type = "image/png";
960 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
961 cached_logo.metadata.alt_text = "Chromium";
962 cached_logo.metadata.short_link = GURL("https://g.co");
963 cached_logo.metadata.share_button_x = 12;
964 cached_logo.metadata.share_button_y = 36;
965 cached_logo.metadata.share_button_opacity = 0.8;
966 cached_logo.metadata.share_button_icon = "sbimg";
967 cached_logo.metadata.share_button_bg = "#ffff00";
968
969 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
970 .WillRepeatedly(DoAll(
971 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
972 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
973
974 // Open a new blank tab, then go to local NTP and listen for console messages.
975 content::WebContents* active_tab =
976 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
977 ui_test_utils::NavigateToURL(browser(),
978 GURL(chrome::kChromeSearchLocalNtpUrl));
979
980 ASSERT_TRUE(content::ExecuteScript(
981 active_tab, "document.getElementById('ddlsb').click();"));
982 EXPECT_TRUE(DialogIsOpen(active_tab, "ddlsd"));
983 SetupWindowOpenTest(active_tab);
984 ASSERT_TRUE(content::ExecuteScript(
985 active_tab, "document.getElementById('ddlsd-twb').click();"));
986 EXPECT_THAT(GetWindowOpenURL(active_tab),
987 Eq<std::string>("https://twitter.com/intent/tweet"
988 "?text=Chromium%0Ahttps%3A%2F%2Fg.co%2F"));
989 }
990
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldCopyLinkInShareDialog)991 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldCopyLinkInShareDialog) {
992 EncodedLogo cached_logo;
993 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
994 cached_logo.metadata.mime_type = "image/png";
995 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
996 cached_logo.metadata.alt_text = "Chromium";
997 cached_logo.metadata.short_link = GURL("https://g.co");
998 cached_logo.metadata.share_button_x = 12;
999 cached_logo.metadata.share_button_y = 36;
1000 cached_logo.metadata.share_button_opacity = 0.8;
1001 cached_logo.metadata.share_button_icon = "sbimg";
1002 cached_logo.metadata.share_button_bg = "#ffff00";
1003
1004 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1005 .WillRepeatedly(DoAll(
1006 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1007 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1008
1009 // Open a new blank tab, then go to local NTP and listen for console messages.
1010 content::WebContents* active_tab =
1011 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1012 ui_test_utils::NavigateToURL(browser(),
1013 GURL(chrome::kChromeSearchLocalNtpUrl));
1014
1015 ASSERT_TRUE(content::ExecuteScript(
1016 active_tab, "document.getElementById('ddlsb').click();"));
1017 EXPECT_TRUE(DialogIsOpen(active_tab, "ddlsd"));
1018
1019 ASSERT_TRUE(content::ExecuteScript(
1020 active_tab, "document.getElementById('ddlsd-copy').click();"));
1021 std::string short_link;
1022 ASSERT_TRUE(instant_test_utils::GetStringFromJS(
1023 active_tab, "window.getSelection().toString()", &short_link));
1024 EXPECT_EQ("https://g.co/", short_link);
1025 }
1026
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldLogShareClicksNoEventId)1027 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldLogShareClicksNoEventId) {
1028 EncodedLogo cached_logo;
1029 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
1030 cached_logo.metadata.mime_type = "image/png";
1031 cached_logo.metadata.on_click_url =
1032 GURL("https://www.chrotmium.org/?ct=test");
1033 cached_logo.metadata.alt_text = "Chromium";
1034 cached_logo.metadata.short_link = GURL("https://g.co");
1035 cached_logo.metadata.share_button_x = 12;
1036 cached_logo.metadata.share_button_y = 36;
1037 cached_logo.metadata.share_button_opacity = 0.8;
1038 cached_logo.metadata.share_button_icon = "sbimg";
1039 cached_logo.metadata.share_button_bg = "#ffff00";
1040
1041 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1042 .WillRepeatedly(DoAll(
1043 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1044 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1045
1046 // Open a new blank tab, then go to local NTP and listen for console messages.
1047 content::WebContents* active_tab =
1048 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1049 ui_test_utils::NavigateToURL(browser(),
1050 GURL(chrome::kChromeSearchLocalNtpUrl));
1051
1052 // Replace window.open so we stay in the same tab.
1053 SetupWindowOpenTest(active_tab);
1054 SetupBeaconTest(active_tab);
1055
1056 ASSERT_TRUE(content::ExecuteScript(
1057 active_tab, "document.getElementById('ddlsb').click();"));
1058
1059 ASSERT_TRUE(content::ExecuteScript(
1060 active_tab, "document.getElementById('ddlsd-fbb').click();"));
1061 EXPECT_THAT(
1062 GetBeaconURL(active_tab),
1063 Eq<std::string>("https://www.google.com/gen_204"
1064 "?atyp=i&ct=doodle&cad=sh%2C2%2Cct%3Atest&ntp=1"));
1065
1066 ASSERT_TRUE(content::ExecuteScript(
1067 active_tab, "document.getElementById('ddlsd-twb').click();"));
1068 EXPECT_THAT(
1069 GetBeaconURL(active_tab),
1070 Eq<std::string>("https://www.google.com/gen_204"
1071 "?atyp=i&ct=doodle&cad=sh%2C3%2Cct%3Atest&ntp=1"));
1072
1073 ASSERT_TRUE(content::ExecuteScript(
1074 active_tab, "document.getElementById('ddlsd-emb').click();"));
1075 EXPECT_THAT(
1076 GetBeaconURL(active_tab),
1077 Eq<std::string>("https://www.google.com/gen_204"
1078 "?atyp=i&ct=doodle&cad=sh%2C5%2Cct%3Atest&ntp=1"));
1079
1080 ASSERT_TRUE(content::ExecuteScript(
1081 active_tab, "document.getElementById('ddlsd-copy').click();"));
1082 std::string short_link;
1083 EXPECT_THAT(
1084 GetBeaconURL(active_tab),
1085 Eq<std::string>("https://www.google.com/gen_204"
1086 "?atyp=i&ct=doodle&cad=sh%2C6%2Cct%3Atest&ntp=1"));
1087 }
1088
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldLogShareClicksWithEventId)1089 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldLogShareClicksWithEventId) {
1090 EncodedLogo cached_logo;
1091 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
1092 cached_logo.metadata.mime_type = "image/png";
1093 cached_logo.metadata.on_click_url =
1094 GURL("https://www.chrotmium.org/?ct=test");
1095 cached_logo.metadata.alt_text = "Chromium";
1096 cached_logo.metadata.short_link = GURL("https://g.co");
1097 cached_logo.metadata.share_button_x = 12;
1098 cached_logo.metadata.share_button_y = 36;
1099 cached_logo.metadata.share_button_opacity = 0.8;
1100 cached_logo.metadata.share_button_icon = "sbimg";
1101 cached_logo.metadata.share_button_bg = "#ffff00";
1102
1103 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1104 .WillRepeatedly(DoAll(
1105 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1106 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1107
1108 // Open a new blank tab, then go to local NTP and listen for console messages.
1109 content::WebContents* active_tab =
1110 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1111 ui_test_utils::NavigateToURL(browser(),
1112 GURL(chrome::kChromeSearchLocalNtpUrl));
1113
1114 // Replace window.open so we stay in the same tab.
1115 SetupWindowOpenTest(active_tab);
1116 SetupBeaconTest(active_tab);
1117
1118 ASSERT_TRUE(content::ExecuteScript(active_tab, "doodles.ei = 'test_ei';"));
1119
1120 ASSERT_TRUE(content::ExecuteScript(
1121 active_tab, "document.getElementById('ddlsb').click();"));
1122
1123 ASSERT_TRUE(content::ExecuteScript(
1124 active_tab, "document.getElementById('ddlsd-fbb').click();"));
1125 EXPECT_THAT(
1126 GetBeaconURL(active_tab),
1127 Eq<std::string>("https://www.google.com/gen_204?atyp=i"
1128 "&ct=doodle&cad=sh%2C2%2Cct%3Atest&ntp=1&ei=test_ei"));
1129
1130 ASSERT_TRUE(content::ExecuteScript(
1131 active_tab, "document.getElementById('ddlsd-twb').click();"));
1132 EXPECT_THAT(
1133 GetBeaconURL(active_tab),
1134 Eq<std::string>("https://www.google.com/gen_204?atyp=i"
1135 "&ct=doodle&cad=sh%2C3%2Cct%3Atest&ntp=1&ei=test_ei"));
1136
1137 ASSERT_TRUE(content::ExecuteScript(
1138 active_tab, "document.getElementById('ddlsd-emb').click();"));
1139 EXPECT_THAT(
1140 GetBeaconURL(active_tab),
1141 Eq<std::string>("https://www.google.com/gen_204?atyp=i"
1142 "&ct=doodle&cad=sh%2C5%2Cct%3Atest&ntp=1&ei=test_ei"));
1143
1144 ASSERT_TRUE(content::ExecuteScript(
1145 active_tab, "document.getElementById('ddlsd-copy').click();"));
1146 std::string short_link;
1147 EXPECT_THAT(
1148 GetBeaconURL(active_tab),
1149 Eq<std::string>("https://www.google.com/gen_204?atyp=i"
1150 "&ct=doodle&cad=sh%2C6%2Cct%3Atest&ntp=1&ei=test_ei"));
1151 }
1152
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldAnimateLogoWhenClicked)1153 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldAnimateLogoWhenClicked) {
1154 EncodedLogo cached_logo;
1155 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
1156 cached_logo.metadata.mime_type = "image/png";
1157 cached_logo.metadata.type = LogoType::ANIMATED;
1158 cached_logo.metadata.animated_url = GURL("data:image/png;base64,eHl6");
1159 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
1160 cached_logo.metadata.alt_text = "alt text";
1161
1162 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1163 .WillRepeatedly(DoAll(
1164 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1165 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1166
1167 // Open a new blank tab, then go to local NTP.
1168 content::WebContents* active_tab =
1169 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1170 base::HistogramTester histograms;
1171 ui_test_utils::NavigateToURL(browser(),
1172 GURL(chrome::kChromeSearchLocalNtpUrl));
1173
1174 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
1175 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
1176 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
1177 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
1178 Eq<std::string>("inline-block"));
1179 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
1180 Eq<std::string>("none"));
1181
1182 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "src"),
1183 Eq<std::string>("data:image/png;base64,cached++"));
1184 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "title"),
1185 Eq<std::string>("alt text"));
1186
1187 // Click image, swapping out for animated URL.
1188 ASSERT_TRUE(content::ExecuteScript(
1189 active_tab, "document.getElementById('logo-doodle-button').click();"));
1190
1191 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
1192 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "src"),
1193 Eq(cached_logo.metadata.animated_url.spec()));
1194 // TODO(sfiera): check href by clicking on button.
1195
1196 histograms.ExpectTotalCount("NewTabPage.LogoShown", 1);
1197 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionCta, 1);
1198 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 1);
1199 histograms.ExpectBucketCount("NewTabPage.LogoShown.FromCache",
1200 kLogoImpressionCta, 1);
1201 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 0);
1202 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
1203 histograms.ExpectTotalCount("NewTabPage.LogoClick", 1);
1204 histograms.ExpectBucketCount("NewTabPage.LogoClick", kLogoClickCta, 1);
1205 }
1206
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldAddShareButtonInAnimatedDoodle)1207 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,
1208 ShouldAddShareButtonInAnimatedDoodle) {
1209 EncodedLogo cached_logo;
1210 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
1211 cached_logo.metadata.mime_type = "image/png";
1212 cached_logo.metadata.type = LogoType::ANIMATED;
1213 cached_logo.metadata.animated_url = GURL("data:image/png;base64,eHl6");
1214 cached_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
1215 cached_logo.metadata.alt_text = "alt text";
1216 cached_logo.metadata.short_link = GURL("https://g.co");
1217 cached_logo.metadata.share_button_x = 12;
1218 cached_logo.metadata.share_button_y = 36;
1219 cached_logo.metadata.share_button_opacity = 0.8;
1220 cached_logo.metadata.share_button_icon = "sbimg";
1221 cached_logo.metadata.share_button_bg = "#ffff00";
1222
1223 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1224 .WillRepeatedly(DoAll(
1225 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1226 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1227
1228 // Open a new blank tab, then go to local NTP.
1229 content::WebContents* active_tab =
1230 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1231 base::HistogramTester histograms;
1232 ui_test_utils::NavigateToURL(browser(),
1233 GURL(chrome::kChromeSearchLocalNtpUrl));
1234
1235 // Share button should not be present pre-CTA click
1236 EXPECT_FALSE(ElementExists(active_tab, "ddlsb"));
1237 ASSERT_TRUE(content::ExecuteScript(
1238 active_tab, "document.getElementById('logo-doodle-button').click();"));
1239
1240 // Share button is only added post-CTA click when the animation is playing
1241 EXPECT_TRUE(ElementExists(active_tab, "ddlsb"));
1242 }
1243
WaitForDdllogResponse(content::WebContents * tab,int expected_ddllog_count)1244 std::string WaitForDdllogResponse(content::WebContents* tab,
1245 int expected_ddllog_count) {
1246 std::string response;
1247 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
1248 tab,
1249 base::StringPrintf(R"js(
1250 if (doodles.numDdllogResponsesReceived == %i) {
1251 window.domAutomationController.send(doodles.lastDdllogResponse);
1252 } else {
1253 doodles.onDdllogResponse = function() {
1254 if (doodles.numDdllogResponsesReceived == %i) {
1255 window.domAutomationController.send(doodles.lastDdllogResponse);
1256 doodles.onDdllogResponse = null;
1257 }
1258 }
1259 } )js",
1260 expected_ddllog_count, expected_ddllog_count),
1261 &response));
1262 return response;
1263 }
1264
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldLogForSimpleDoodle)1265 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldLogForSimpleDoodle) {
1266 // Start a test server to provide the ddllog response.
1267 net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
1268 test_server.ServeFilesFromSourceDirectory("chrome/test/data/local_ntp");
1269 ASSERT_TRUE(test_server.Start());
1270 const GURL on_click_url = test_server.GetURL("/simple.html");
1271 const GURL log_url = test_server.GetURL("/ddllog-target_url_params");
1272
1273 EncodedLogo cached_logo;
1274 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
1275 cached_logo.metadata.mime_type = "image/png";
1276 cached_logo.metadata.on_click_url = on_click_url;
1277 cached_logo.metadata.alt_text = "Chromium";
1278 cached_logo.metadata.log_url = log_url;
1279
1280 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1281 .WillRepeatedly(DoAll(
1282 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1283 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1284
1285 // Open a new blank tab, then go to local NTP and listen for console messages.
1286 content::WebContents* active_tab =
1287 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1288 FailOnConsoleMessage console_observer(active_tab);
1289 ui_test_utils::NavigateToURL(browser(),
1290 GURL(chrome::kChromeSearchLocalNtpUrl));
1291
1292 ASSERT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
1293
1294 // Wait for the ddllog request to get resolved.
1295 std::string response = WaitForDdllogResponse(active_tab, 1);
1296 EXPECT_EQ("target_url_params a=b&c=d", response);
1297
1298 content::TestNavigationObserver nav_observer(active_tab);
1299 ASSERT_TRUE(content::ExecuteScript(
1300 active_tab, "document.getElementById('logo-doodle-button').click();"));
1301 nav_observer.Wait();
1302 ASSERT_TRUE(nav_observer.last_navigation_succeeded());
1303
1304 std::string target_url;
1305 ASSERT_TRUE(instant_test_utils::GetStringFromJS(
1306 active_tab, "document.location.href", &target_url));
1307 EXPECT_EQ(on_click_url.spec() + "?a=b&c=d", target_url);
1308 }
1309
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldLogForAnimatedDoodle)1310 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldLogForAnimatedDoodle) {
1311 // Start a test server to provide the ddllog responses.
1312 net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
1313 test_server.ServeFilesFromSourceDirectory("chrome/test/data/local_ntp");
1314 ASSERT_TRUE(test_server.Start());
1315 const GURL on_click_url = test_server.GetURL("/simple.html");
1316 const GURL cta_log_url = test_server.GetURL("/ddllog-interaction_log_url");
1317 const GURL log_url = test_server.GetURL("/ddllog-target_url_params");
1318
1319 EncodedLogo cached_logo;
1320 cached_logo.encoded_image = MakeRefPtr(kCachedB64);
1321 cached_logo.metadata.mime_type = "image/png";
1322 cached_logo.metadata.type = LogoType::ANIMATED;
1323 cached_logo.metadata.animated_url =
1324 GURL(std::string("data:image/gif;base64,") + kTinyGifData);
1325 cached_logo.metadata.on_click_url = on_click_url;
1326 cached_logo.metadata.alt_text = "alt text";
1327 cached_logo.metadata.cta_log_url = cta_log_url;
1328 cached_logo.metadata.log_url = log_url;
1329
1330 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1331 .WillRepeatedly(DoAll(
1332 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1333 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1334
1335 // Open a new blank tab, then go to local NTP and listen for console messages.
1336 content::WebContents* active_tab =
1337 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1338 FailOnConsoleMessage console_observer(active_tab);
1339 ui_test_utils::NavigateToURL(browser(),
1340 GURL(chrome::kChromeSearchLocalNtpUrl));
1341
1342 ASSERT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
1343
1344 // Wait for the first (CTA) ddllog request to get resolved.
1345 std::string cta_response = WaitForDdllogResponse(active_tab, 1);
1346 EXPECT_EQ(
1347 "interaction_log_url https://www.chromium.org/doodle_interaction_log",
1348 cta_response);
1349
1350 // Click image, swapping out for animated URL.
1351 ASSERT_TRUE(content::ExecuteScript(
1352 active_tab, "document.getElementById('logo-doodle-button').click();"));
1353 ASSERT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "src"),
1354 Eq(cached_logo.metadata.animated_url.spec()));
1355
1356 // Wait for the second (non-CTA) ddllog request to get resolved.
1357 std::string anim_response = WaitForDdllogResponse(active_tab, 2);
1358 EXPECT_EQ("target_url_params a=b&c=d", anim_response);
1359
1360 content::TestNavigationObserver nav_observer(active_tab);
1361 ASSERT_TRUE(content::ExecuteScript(
1362 active_tab, "document.getElementById('logo-doodle-button').click();"));
1363 nav_observer.Wait();
1364 ASSERT_TRUE(nav_observer.last_navigation_succeeded());
1365
1366 std::string target_url;
1367 ASSERT_TRUE(instant_test_utils::GetStringFromJS(
1368 active_tab, "document.location.href", &target_url));
1369 EXPECT_EQ(on_click_url.spec() + "?a=b&c=d", target_url);
1370 }
1371
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldNotMoveFakeboxForIframeSizes)1372 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldNotMoveFakeboxForIframeSizes) {
1373 for (int height : {0, 150, 229, 500}) {
1374 EncodedLogo cached_logo;
1375 cached_logo.encoded_image = MakeRefPtr(std::string());
1376 cached_logo.metadata.mime_type = "image/png";
1377 cached_logo.metadata.type = LogoType::INTERACTIVE;
1378 cached_logo.metadata.full_page_url =
1379 GURL("https://www.chromium.org/interactive");
1380 cached_logo.metadata.alt_text = "alt text";
1381 cached_logo.metadata.iframe_width_px = 500;
1382 cached_logo.metadata.iframe_height_px = height;
1383
1384 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1385 .WillRepeatedly(DoAll(
1386 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1387 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1388
1389 // Open a new blank tab, then go to local NTP.
1390 content::WebContents* active_tab =
1391 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1392 base::HistogramTester histograms;
1393 ui_test_utils::NavigateToURL(browser(),
1394 GURL(chrome::kChromeSearchLocalNtpUrl));
1395
1396 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx))
1397 << "iframe_height_px = " << height;
1398 }
1399 }
1400
IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest,ShouldMoveFakeboxWhenIframeResized)1401 IN_PROC_BROWSER_TEST_F(LocalNTPDoodleTest, ShouldMoveFakeboxWhenIframeResized) {
1402 EncodedLogo cached_logo;
1403 cached_logo.encoded_image = MakeRefPtr(std::string());
1404 cached_logo.metadata.mime_type = "image/png";
1405 cached_logo.metadata.type = LogoType::INTERACTIVE;
1406 cached_logo.metadata.full_page_url =
1407 GURL("https://www.chromium.org/interactive");
1408 cached_logo.metadata.alt_text = "alt text";
1409 cached_logo.metadata.iframe_width_px = 400;
1410 cached_logo.metadata.iframe_height_px = 220; // > 200, so smaller margin
1411
1412 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1413 .WillRepeatedly(DoAll(
1414 ReturnCachedLogo(LogoCallbackReason::DETERMINED, cached_logo),
1415 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1416
1417 // Open a new blank tab, then go to local NTP.
1418 content::WebContents* active_tab =
1419 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1420 base::HistogramTester histograms;
1421 ui_test_utils::NavigateToURL(browser(),
1422 GURL(chrome::kChromeSearchLocalNtpUrl));
1423
1424 // Initial dimensions are correct:
1425 EXPECT_THAT(*GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
1426 EXPECT_THAT(*GetDimension(active_tab, "logo-doodle-iframe", "width"),
1427 Eq(400));
1428 EXPECT_THAT(*GetDimension(active_tab, "logo-doodle-iframe", "height"),
1429 Eq(220));
1430
1431 // Trigger resize. The duration parameter is left untested, since that would
1432 // require introducing a potentially-flaky sleep in the test. Additionally,
1433 // this would really be a cross-origin postMessage, from the Doodle iframe,
1434 // origin google.com.
1435 ASSERT_TRUE(content::ExecuteScript(active_tab,
1436 R"js(
1437 window.postMessage({
1438 cmd: "resizeDoodle",
1439 width: "100%",
1440 height: "400px", // 180px more
1441 duration: "0s",
1442 }, "chrome-search://local-ntp");
1443 )js"));
1444
1445 // Fakebox is now 180px lower, with the iframe larger, as requested.
1446 EXPECT_THAT(*GetDimension(active_tab, "realbox", "top"),
1447 Eq(kRealboxTopPx + 180));
1448 EXPECT_THAT(*GetDimension(active_tab, "logo-doodle-iframe", "width"),
1449 Eq(*GetDimension(active_tab, "logo", "width")));
1450 EXPECT_THAT(*GetDimension(active_tab, "logo-doodle-iframe", "height"),
1451 Eq(400));
1452
1453 ASSERT_TRUE(content::ExecuteScript(active_tab,
1454 R"js(
1455 window.postMessage({
1456 cmd: "resizeDoodle",
1457 width: "400px",
1458 height: "220px",
1459 duration: "0s",
1460 }, "chrome-search://local-ntp");
1461 )js"));
1462
1463 // Back to the original dimensions now.
1464 EXPECT_THAT(*GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
1465 EXPECT_THAT(*GetDimension(active_tab, "logo-doodle-iframe", "width"),
1466 Eq(400));
1467 EXPECT_THAT(*GetDimension(active_tab, "logo-doodle-iframe", "height"),
1468 Eq(220));
1469 }
1470
1471 // TODO(crbug/980638): Update/Remove when Linux and/or ChromeOS support dark
1472 // mode.
1473 #if defined(OS_WIN) || defined(OS_MAC)
1474
1475 // Tests that dark mode styling is properly applied to the local NTP Doodle.
1476 class LocalNTPDarkModeDoodleTest : public LocalNTPDoodleTest,
1477 public DarkModeTestBase {
1478 public:
1479 LocalNTPDarkModeDoodleTest() {}
1480
1481 private:
1482 void SetUpOnMainThread() override {
1483 LocalNTPDoodleTest::SetUpOnMainThread();
1484
1485 theme()->AddColorSchemeNativeThemeObserver(
1486 ui::NativeTheme::GetInstanceForWeb());
1487 }
1488 };
1489
1490 IN_PROC_BROWSER_TEST_F(LocalNTPDarkModeDoodleTest,
1491 ShouldFadeDefaultToSimpleDoodleWhenFetched) {
1492 InstantService* instant_service =
1493 InstantServiceFactory::GetForProfile(browser()->profile());
1494 theme()->SetDarkMode(true);
1495 instant_service->SetNativeThemeForTesting(theme());
1496 theme()->NotifyObservers();
1497
1498 EncodedLogo fresh_logo;
1499 fresh_logo.encoded_image = MakeRefPtr(kFreshB64);
1500 fresh_logo.dark_encoded_image = MakeRefPtr(kFreshDarkB64);
1501 fresh_logo.metadata.mime_type = "image/png";
1502 fresh_logo.metadata.dark_mime_type = "image/png";
1503 fresh_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
1504 fresh_logo.metadata.alt_text = "Chromium";
1505 fresh_logo.metadata.dark_background_color = "#ABCDEF";
1506
1507 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1508 .WillOnce(
1509 DoAll(ReturnCachedLogo(LogoCallbackReason::DETERMINED, base::nullopt),
1510 ReturnFreshLogo(LogoCallbackReason::DETERMINED, fresh_logo)))
1511 .WillRepeatedly(DoAll(
1512 ReturnCachedLogo(LogoCallbackReason::DETERMINED, fresh_logo),
1513 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1514
1515 // Open a new blank tab, then go to local NTP.
1516 content::WebContents* active_tab =
1517 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1518 base::HistogramTester histograms;
1519 ui_test_utils::NavigateToURL(browser(),
1520 GURL(chrome::kChromeSearchLocalNtpUrl));
1521
1522 WaitForFadeIn(active_tab, "logo-doodle");
1523 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
1524 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
1525 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
1526 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
1527 Eq<std::string>("inline-block"));
1528 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-wrapper"),
1529 Eq<std::string>("inline-block"));
1530 EXPECT_THAT(
1531 GetComputedStyle(active_tab, "logo-doodle-wrapper", "background-color"),
1532 Eq<std::string>("rgb(171, 205, 239)"));
1533 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
1534 Eq<std::string>("none"));
1535 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "title"),
1536 Eq<std::string>("Chromium"));
1537 // TODO(sfiera): check href by clicking on button.
1538
1539 histograms.ExpectTotalCount("NewTabPage.LogoShown", 1);
1540 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionStatic,
1541 1);
1542 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 0);
1543 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 1);
1544 histograms.ExpectBucketCount("NewTabPage.LogoShown.Fresh",
1545 kLogoImpressionStatic, 1);
1546 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
1547 }
1548
IN_PROC_BROWSER_TEST_F(LocalNTPDarkModeDoodleTest,DoodleUpdatesOnDarkModeChanged)1549 IN_PROC_BROWSER_TEST_F(LocalNTPDarkModeDoodleTest,
1550 DoodleUpdatesOnDarkModeChanged) {
1551 InstantService* instant_service =
1552 InstantServiceFactory::GetForProfile(browser()->profile());
1553 theme()->SetDarkMode(false);
1554 instant_service->SetNativeThemeForTesting(theme());
1555 theme()->NotifyObservers();
1556
1557 EncodedLogo fresh_logo;
1558 fresh_logo.encoded_image = MakeRefPtr(kFreshB64);
1559 fresh_logo.dark_encoded_image = MakeRefPtr(kFreshDarkB64);
1560 fresh_logo.metadata.mime_type = "image/png";
1561 fresh_logo.metadata.dark_mime_type = "image/png";
1562 fresh_logo.metadata.on_click_url = GURL("https://www.chromium.org/");
1563 fresh_logo.metadata.alt_text = "Chromium";
1564 fresh_logo.metadata.dark_background_color = "#ABCDEF";
1565
1566 EXPECT_CALL(*logo_service(), GetLogoPtr(_))
1567 .WillOnce(
1568 DoAll(ReturnCachedLogo(LogoCallbackReason::DETERMINED, base::nullopt),
1569 ReturnFreshLogo(LogoCallbackReason::DETERMINED, fresh_logo)))
1570 .WillRepeatedly(DoAll(
1571 ReturnCachedLogo(LogoCallbackReason::DETERMINED, fresh_logo),
1572 ReturnFreshLogo(LogoCallbackReason::REVALIDATED, base::nullopt)));
1573
1574 // Open a new blank tab, then go to local NTP.
1575 content::WebContents* active_tab =
1576 local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
1577 base::HistogramTester histograms;
1578 ui_test_utils::NavigateToURL(browser(),
1579 GURL(chrome::kChromeSearchLocalNtpUrl));
1580
1581 WaitForFadeIn(active_tab, "logo-doodle");
1582 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
1583 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
1584 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
1585 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
1586 Eq<std::string>("inline-block"));
1587 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-wrapper"),
1588 Eq<std::string>("inline-block"));
1589 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
1590 Eq<std::string>("none"));
1591 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "title"),
1592 Eq<std::string>("Chromium"));
1593 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "src"),
1594 Eq<std::string>("data:image/png;base64,YWJj"));
1595 // TODO(sfiera): check href by clicking on button.
1596
1597 histograms.ExpectTotalCount("NewTabPage.LogoShown", 1);
1598 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionStatic,
1599 1);
1600 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 0);
1601 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 1);
1602 histograms.ExpectBucketCount("NewTabPage.LogoShown.Fresh",
1603 kLogoImpressionStatic, 1);
1604 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
1605
1606 content::DOMMessageQueue msg_queue(active_tab);
1607 theme()->SetDarkMode(true);
1608 theme()->NotifyObservers();
1609
1610 local_ntp_test_utils::WaitUntilTilesLoaded(active_tab, &msg_queue,
1611 /*delay=*/1000);
1612
1613 WaitForLogoSwap(active_tab, "logo-doodle");
1614 EXPECT_TRUE(GetIsDarkModeApplied(active_tab));
1615 EXPECT_THAT(GetDimension(active_tab, "realbox", "top"), Eq(kRealboxTopPx));
1616 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-default"), Eq(0.0));
1617 EXPECT_THAT(GetComputedOpacity(active_tab, "logo-doodle"), Eq(1.0));
1618 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-container"),
1619 Eq<std::string>("inline-block"));
1620 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-wrapper"),
1621 Eq<std::string>("inline-block"));
1622 EXPECT_THAT(
1623 GetComputedStyle(active_tab, "logo-doodle-wrapper", "background-color"),
1624 Eq<std::string>("rgb(171, 205, 239)"));
1625 EXPECT_THAT(GetComputedDisplay(active_tab, "logo-doodle-iframe"),
1626 Eq<std::string>("none"));
1627 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "title"),
1628 Eq<std::string>("Chromium"));
1629 EXPECT_THAT(GetElementProperty(active_tab, "logo-doodle-image", "src"),
1630 Eq<std::string>("data:image/png;base64,eHl6"));
1631 // TODO(sfiera): check href by clicking on button.
1632
1633 histograms.ExpectTotalCount("NewTabPage.LogoShown", 2);
1634 histograms.ExpectBucketCount("NewTabPage.LogoShown", kLogoImpressionStatic,
1635 2);
1636 histograms.ExpectTotalCount("NewTabPage.LogoShown.FromCache", 0);
1637 histograms.ExpectTotalCount("NewTabPage.LogoShown.Fresh", 2);
1638 histograms.ExpectBucketCount("NewTabPage.LogoShown.Fresh",
1639 kLogoImpressionStatic, 2);
1640 histograms.ExpectTotalCount("NewTabPage.LogoShownTime2", 1);
1641 }
1642
1643 #endif
1644