1 // Copyright 2013 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 <sstream>
6
7 #include "base/command_line.h"
8 #include "base/metrics/histogram_base.h"
9 #include "base/metrics/histogram_samples.h"
10 #include "base/metrics/statistics_recorder.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/run_loop.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/time/time.h"
18 #include "chrome/browser/autocomplete/autocomplete_controller.h"
19 #include "chrome/browser/autocomplete/autocomplete_match.h"
20 #include "chrome/browser/autocomplete/autocomplete_provider.h"
21 #include "chrome/browser/autocomplete/autocomplete_result.h"
22 #include "chrome/browser/autocomplete/search_provider.h"
23 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
24 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/extensions/extension_browsertest.h"
26 #include "chrome/browser/extensions/extension_service.h"
27 #include "chrome/browser/favicon/favicon_tab_helper.h"
28 #include "chrome/browser/history/history_db_task.h"
29 #include "chrome/browser/history/history_service.h"
30 #include "chrome/browser/history/history_service_factory.h"
31 #include "chrome/browser/history/history_types.h"
32 #include "chrome/browser/history/top_sites.h"
33 #include "chrome/browser/profiles/profile.h"
34 #include "chrome/browser/search/instant_service.h"
35 #include "chrome/browser/search/instant_service_factory.h"
36 #include "chrome/browser/search/search.h"
37 #include "chrome/browser/search_engines/template_url_service.h"
38 #include "chrome/browser/search_engines/template_url_service_factory.h"
39 #include "chrome/browser/task_manager/task_manager.h"
40 #include "chrome/browser/task_manager/task_manager_browsertest_util.h"
41 #include "chrome/browser/themes/theme_service.h"
42 #include "chrome/browser/themes/theme_service_factory.h"
43 #include "chrome/browser/ui/browser_list.h"
44 #include "chrome/browser/ui/browser_tabstrip.h"
45 #include "chrome/browser/ui/omnibox/omnibox_view.h"
46 #include "chrome/browser/ui/search/instant_tab.h"
47 #include "chrome/browser/ui/search/instant_test_utils.h"
48 #include "chrome/browser/ui/search/search_tab_helper.h"
49 #include "chrome/browser/ui/tabs/tab_strip_model.h"
50 #include "chrome/browser/ui/webui/theme_source.h"
51 #include "chrome/common/chrome_switches.h"
52 #include "chrome/common/instant_types.h"
53 #include "chrome/common/pref_names.h"
54 #include "chrome/common/url_constants.h"
55 #include "chrome/test/base/in_process_browser_test.h"
56 #include "chrome/test/base/interactive_test_utils.h"
57 #include "chrome/test/base/ui_test_utils.h"
58 #include "components/bookmarks/browser/bookmark_utils.h"
59 #include "components/bookmarks/test/bookmark_test_helpers.h"
60 #include "components/google/core/browser/google_url_tracker.h"
61 #include "components/history/core/common/thumbnail_score.h"
62 #include "components/sessions/serialized_navigation_entry.h"
63 #include "content/public/browser/navigation_controller.h"
64 #include "content/public/browser/navigation_entry.h"
65 #include "content/public/browser/notification_service.h"
66 #include "content/public/browser/render_process_host.h"
67 #include "content/public/browser/render_view_host.h"
68 #include "content/public/browser/site_instance.h"
69 #include "content/public/browser/url_data_source.h"
70 #include "content/public/browser/web_contents.h"
71 #include "content/public/common/bindings_policy.h"
72 #include "content/public/test/browser_test_utils.h"
73 #include "content/public/test/test_utils.h"
74 #include "grit/generated_resources.h"
75 #include "net/base/network_change_notifier.h"
76 #include "net/http/http_status_code.h"
77 #include "net/url_request/test_url_fetcher_factory.h"
78 #include "net/url_request/url_fetcher_impl.h"
79 #include "net/url_request/url_request_status.h"
80 #include "testing/gmock/include/gmock/gmock.h"
81 #include "third_party/skia/include/core/SkBitmap.h"
82 #include "ui/base/l10n/l10n_util.h"
83
84 using base::ASCIIToUTF16;
85 using testing::HasSubstr;
86
87 namespace {
88
89 // Task used to make sure history has finished processing a request. Intended
90 // for use with BlockUntilHistoryProcessesPendingRequests.
91 class QuittingHistoryDBTask : public history::HistoryDBTask {
92 public:
QuittingHistoryDBTask()93 QuittingHistoryDBTask() {}
94
RunOnDBThread(history::HistoryBackend * backend,history::HistoryDatabase * db)95 virtual bool RunOnDBThread(history::HistoryBackend* backend,
96 history::HistoryDatabase* db) OVERRIDE {
97 return true;
98 }
99
DoneRunOnMainThread()100 virtual void DoneRunOnMainThread() OVERRIDE {
101 base::MessageLoop::current()->Quit();
102 }
103
104 private:
~QuittingHistoryDBTask()105 virtual ~QuittingHistoryDBTask() {}
106
107 DISALLOW_COPY_AND_ASSIGN(QuittingHistoryDBTask);
108 };
109
110 class FakeNetworkChangeNotifier : public net::NetworkChangeNotifier {
111 public:
FakeNetworkChangeNotifier()112 FakeNetworkChangeNotifier() : connection_type_(CONNECTION_NONE) {}
113
GetCurrentConnectionType() const114 virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
115 return connection_type_;
116 }
117
SetConnectionType(ConnectionType type)118 void SetConnectionType(ConnectionType type) {
119 connection_type_ = type;
120 NotifyObserversOfNetworkChange(type);
121 base::RunLoop().RunUntilIdle();
122 }
123
~FakeNetworkChangeNotifier()124 virtual ~FakeNetworkChangeNotifier() {}
125
126 private:
127 ConnectionType connection_type_;
128 DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifier);
129 };
130 } // namespace
131
132 class InstantExtendedTest : public InProcessBrowserTest,
133 public InstantTestBase {
134 public:
InstantExtendedTest()135 InstantExtendedTest()
136 : on_most_visited_change_calls_(0),
137 most_visited_items_count_(0),
138 first_most_visited_item_id_(0),
139 on_native_suggestions_calls_(0),
140 on_change_calls_(0),
141 submit_count_(0),
142 on_esc_key_press_event_calls_(0),
143 on_focus_changed_calls_(0),
144 is_focused_(false),
145 on_toggle_voice_search_calls_(0) {
146 }
147 protected:
SetUpInProcessBrowserTestFixture()148 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
149 chrome::EnableQueryExtractionForTesting();
150 ASSERT_TRUE(https_test_server().Start());
151 GURL instant_url = https_test_server().GetURL(
152 "files/instant_extended.html?strk=1&");
153 GURL ntp_url = https_test_server().GetURL(
154 "files/instant_extended_ntp.html?strk=1&");
155 InstantTestBase::Init(instant_url, ntp_url, false);
156 }
157
GetHistogramCount(const char * name)158 int64 GetHistogramCount(const char* name) {
159 base::HistogramBase* histogram =
160 base::StatisticsRecorder::FindHistogram(name);
161 if (!histogram) {
162 // If no histogram is found, it's possible that no values have been
163 // recorded yet. Assume that the value is zero.
164 return 0;
165 }
166 return histogram->SnapshotSamples()->TotalCount();
167 }
168
UpdateSearchState(content::WebContents * contents)169 bool UpdateSearchState(content::WebContents* contents) WARN_UNUSED_RESULT {
170 return GetIntFromJS(contents, "onMostVisitedChangedCalls",
171 &on_most_visited_change_calls_) &&
172 GetIntFromJS(contents, "mostVisitedItemsCount",
173 &most_visited_items_count_) &&
174 GetIntFromJS(contents, "firstMostVisitedItemId",
175 &first_most_visited_item_id_) &&
176 GetIntFromJS(contents, "onNativeSuggestionsCalls",
177 &on_native_suggestions_calls_) &&
178 GetIntFromJS(contents, "onChangeCalls",
179 &on_change_calls_) &&
180 GetIntFromJS(contents, "submitCount",
181 &submit_count_) &&
182 GetStringFromJS(contents, "apiHandle.value",
183 &query_value_) &&
184 GetIntFromJS(contents, "onEscKeyPressedCalls",
185 &on_esc_key_press_event_calls_) &&
186 GetIntFromJS(contents, "onFocusChangedCalls",
187 &on_focus_changed_calls_) &&
188 GetBoolFromJS(contents, "isFocused",
189 &is_focused_) &&
190 GetIntFromJS(contents, "onToggleVoiceSearchCalls",
191 &on_toggle_voice_search_calls_) &&
192 GetStringFromJS(contents, "prefetchQuery", &prefetch_query_value_);
193
194 }
195
GetDefaultSearchProviderTemplateURL()196 TemplateURL* GetDefaultSearchProviderTemplateURL() {
197 TemplateURLService* template_url_service =
198 TemplateURLServiceFactory::GetForProfile(browser()->profile());
199 if (template_url_service)
200 return template_url_service->GetDefaultSearchProvider();
201 return NULL;
202 }
203
AddSearchToHistory(base::string16 term,int visit_count)204 bool AddSearchToHistory(base::string16 term, int visit_count) {
205 TemplateURL* template_url = GetDefaultSearchProviderTemplateURL();
206 if (!template_url)
207 return false;
208
209 HistoryService* history = HistoryServiceFactory::GetForProfile(
210 browser()->profile(), Profile::EXPLICIT_ACCESS);
211 GURL search(template_url->url_ref().ReplaceSearchTerms(
212 TemplateURLRef::SearchTermsArgs(term),
213 TemplateURLServiceFactory::GetForProfile(
214 browser()->profile())->search_terms_data()));
215 history->AddPageWithDetails(
216 search, base::string16(), visit_count, visit_count,
217 base::Time::Now(), false, history::SOURCE_BROWSED);
218 history->SetKeywordSearchTermsForURL(
219 search, template_url->id(), term);
220 return true;
221 }
222
BlockUntilHistoryProcessesPendingRequests()223 void BlockUntilHistoryProcessesPendingRequests() {
224 HistoryService* history = HistoryServiceFactory::GetForProfile(
225 browser()->profile(), Profile::EXPLICIT_ACCESS);
226 DCHECK(history);
227 DCHECK(base::MessageLoop::current());
228
229 CancelableRequestConsumer consumer;
230 history->ScheduleDBTask(new QuittingHistoryDBTask(), &consumer);
231 base::MessageLoop::current()->Run();
232 }
233
CountSearchProviderSuggestions()234 int CountSearchProviderSuggestions() {
235 return omnibox()->model()->autocomplete_controller()->search_provider()->
236 matches().size();
237 }
238
239 int on_most_visited_change_calls_;
240 int most_visited_items_count_;
241 int first_most_visited_item_id_;
242 int on_native_suggestions_calls_;
243 int on_change_calls_;
244 int submit_count_;
245 int on_esc_key_press_event_calls_;
246 std::string query_value_;
247 int on_focus_changed_calls_;
248 bool is_focused_;
249 int on_toggle_voice_search_calls_;
250 std::string prefetch_query_value_;
251 };
252
253 class InstantExtendedPrefetchTest : public InstantExtendedTest {
254 public:
InstantExtendedPrefetchTest()255 InstantExtendedPrefetchTest()
256 : factory_(new net::URLFetcherImplFactory()),
257 fake_factory_(new net::FakeURLFetcherFactory(factory_.get())) {
258 }
259
SetUpInProcessBrowserTestFixture()260 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
261 chrome::EnableQueryExtractionForTesting();
262 ASSERT_TRUE(https_test_server().Start());
263 GURL instant_url = https_test_server().GetURL(
264 "files/instant_extended.html?strk=1&");
265 GURL ntp_url = https_test_server().GetURL(
266 "files/instant_extended_ntp.html?strk=1&");
267 InstantTestBase::Init(instant_url, ntp_url, true);
268 }
269
SetUpCommandLine(CommandLine * command_line)270 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
271 command_line->AppendSwitchASCII(
272 switches::kForceFieldTrials,
273 "EmbeddedSearch/Group11 prefetch_results_srp:1/");
274 }
275
fake_factory()276 net::FakeURLFetcherFactory* fake_factory() { return fake_factory_.get(); }
277
278 private:
279 // Used to instantiate FakeURLFetcherFactory.
280 scoped_ptr<net::URLFetcherImplFactory> factory_;
281
282 // Used to mock default search provider suggest response.
283 scoped_ptr<net::FakeURLFetcherFactory> fake_factory_;
284
285 DISALLOW_COPY_AND_ASSIGN(InstantExtendedPrefetchTest);
286 };
287
288 class InstantExtendedNetworkTest : public InstantExtendedTest {
289 protected:
SetUpOnMainThread()290 virtual void SetUpOnMainThread() OVERRIDE {
291 disable_for_test_.reset(new net::NetworkChangeNotifier::DisableForTest);
292 fake_network_change_notifier_.reset(new FakeNetworkChangeNotifier);
293 InstantExtendedTest::SetUpOnMainThread();
294 }
295
CleanUpOnMainThread()296 virtual void CleanUpOnMainThread() OVERRIDE {
297 InstantExtendedTest::CleanUpOnMainThread();
298 fake_network_change_notifier_.reset();
299 disable_for_test_.reset();
300 }
301
SetConnectionType(net::NetworkChangeNotifier::ConnectionType type)302 void SetConnectionType(net::NetworkChangeNotifier::ConnectionType type) {
303 fake_network_change_notifier_->SetConnectionType(type);
304 }
305
306 private:
307 scoped_ptr<net::NetworkChangeNotifier::DisableForTest> disable_for_test_;
308 scoped_ptr<FakeNetworkChangeNotifier> fake_network_change_notifier_;
309 };
310
311 // Test class used to verify chrome-search: scheme and access policy from the
312 // Instant overlay. This is a subclass of |ExtensionBrowserTest| because it
313 // loads a theme that provides a background image.
314 class InstantPolicyTest : public ExtensionBrowserTest, public InstantTestBase {
315 public:
InstantPolicyTest()316 InstantPolicyTest() {}
317
318 protected:
SetUpInProcessBrowserTestFixture()319 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
320 ASSERT_TRUE(https_test_server().Start());
321 GURL instant_url = https_test_server().GetURL(
322 "files/instant_extended.html?strk=1&");
323 GURL ntp_url = https_test_server().GetURL(
324 "files/instant_extended_ntp.html?strk=1&");
325 InstantTestBase::Init(instant_url, ntp_url, false);
326 }
327
InstallThemeSource()328 void InstallThemeSource() {
329 ThemeSource* theme = new ThemeSource(profile());
330 content::URLDataSource::Add(profile(), theme);
331 }
332
InstallThemeAndVerify(const std::string & theme_dir,const std::string & theme_name)333 void InstallThemeAndVerify(const std::string& theme_dir,
334 const std::string& theme_name) {
335 const extensions::Extension* theme =
336 ThemeServiceFactory::GetThemeForProfile(
337 ExtensionBrowserTest::browser()->profile());
338 // If there is already a theme installed, the current theme should be
339 // disabled and the new one installed + enabled.
340 int expected_change = theme ? 0 : 1;
341
342 const base::FilePath theme_path = test_data_dir_.AppendASCII(theme_dir);
343 ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(
344 theme_path, expected_change, ExtensionBrowserTest::browser()));
345 const extensions::Extension* new_theme =
346 ThemeServiceFactory::GetThemeForProfile(
347 ExtensionBrowserTest::browser()->profile());
348 ASSERT_NE(static_cast<extensions::Extension*>(NULL), new_theme);
349 ASSERT_EQ(new_theme->name(), theme_name);
350 }
351
352 private:
353 DISALLOW_COPY_AND_ASSIGN(InstantPolicyTest);
354 };
355
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,SearchReusesInstantTab)356 IN_PROC_BROWSER_TEST_F(InstantExtendedTest, SearchReusesInstantTab) {
357 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
358 FocusOmnibox();
359
360 content::WindowedNotificationObserver observer(
361 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
362 content::NotificationService::AllSources());
363 SetOmniboxText("flowers");
364 PressEnterAndWaitForFrameLoad();
365 observer.Wait();
366
367 // Just did a regular search.
368 content::WebContents* active_tab =
369 browser()->tab_strip_model()->GetActiveWebContents();
370 ASSERT_THAT(active_tab->GetURL().spec(), HasSubstr("q=flowers"));
371 ASSERT_TRUE(UpdateSearchState(active_tab));
372 ASSERT_EQ(0, submit_count_);
373
374 SetOmniboxText("puppies");
375 PressEnterAndWaitForNavigation();
376
377 // Should have reused the tab and sent an onsubmit message.
378 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
379 ASSERT_THAT(active_tab->GetURL().spec(), HasSubstr("q=puppies"));
380 ASSERT_TRUE(UpdateSearchState(active_tab));
381 EXPECT_EQ(1, submit_count_);
382 }
383
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,SearchDoesntReuseInstantTabWithoutSupport)384 IN_PROC_BROWSER_TEST_F(InstantExtendedTest,
385 SearchDoesntReuseInstantTabWithoutSupport) {
386 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
387 FocusOmnibox();
388
389 // Don't wait for the navigation to complete.
390 SetOmniboxText("flowers");
391 browser()->window()->GetLocationBar()->AcceptInput();
392
393 SetOmniboxText("puppies");
394 browser()->window()->GetLocationBar()->AcceptInput();
395
396 // Should not have reused the tab.
397 ASSERT_THAT(
398 browser()->tab_strip_model()->GetActiveWebContents()->GetURL().spec(),
399 HasSubstr("q=puppies"));
400 }
401
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,TypedSearchURLDoesntReuseInstantTab)402 IN_PROC_BROWSER_TEST_F(InstantExtendedTest,
403 TypedSearchURLDoesntReuseInstantTab) {
404 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
405 FocusOmnibox();
406
407 // Create an observer to wait for the instant tab to support Instant.
408 content::WindowedNotificationObserver observer_1(
409 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
410 content::NotificationService::AllSources());
411 SetOmniboxText("flowers");
412 PressEnterAndWaitForFrameLoad();
413 observer_1.Wait();
414
415 // Just did a regular search.
416 content::WebContents* active_tab =
417 browser()->tab_strip_model()->GetActiveWebContents();
418 ASSERT_THAT(active_tab->GetURL().spec(), HasSubstr("q=flowers"));
419 ASSERT_TRUE(UpdateSearchState(active_tab));
420 ASSERT_EQ(0, submit_count_);
421
422 // Typed in a search URL "by hand".
423 content::WindowedNotificationObserver observer_2(
424 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
425 content::NotificationService::AllSources());
426 SetOmniboxText(instant_url().Resolve("#q=puppies").spec());
427 PressEnterAndWaitForNavigation();
428 observer_2.Wait();
429
430 // Should not have reused the tab.
431 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
432 ASSERT_THAT(active_tab->GetURL().spec(), HasSubstr("q=puppies"));
433 }
434
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,OmniboxMarginSetForSearchURLs)435 IN_PROC_BROWSER_TEST_F(InstantExtendedTest, OmniboxMarginSetForSearchURLs) {
436 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
437 FocusOmnibox();
438
439 // Create an observer to wait for the instant tab to support Instant.
440 content::WindowedNotificationObserver observer(
441 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
442 content::NotificationService::AllSources());
443
444 SetOmniboxText("flowers");
445 browser()->window()->GetLocationBar()->AcceptInput();
446 observer.Wait();
447
448 const std::string& url =
449 browser()->tab_strip_model()->GetActiveWebContents()->GetURL().spec();
450 // Make sure we actually used search_url, not instant_url.
451 ASSERT_THAT(url, HasSubstr("&is_search"));
452 EXPECT_THAT(url, HasSubstr("&es_sm="));
453 }
454
455 // Test to verify that switching tabs should not dispatch onmostvisitedchanged
456 // events.
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,NoMostVisitedChangedOnTabSwitch)457 IN_PROC_BROWSER_TEST_F(InstantExtendedTest, NoMostVisitedChangedOnTabSwitch) {
458 // Initialize Instant.
459 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
460
461 // Open new tab.
462 ui_test_utils::NavigateToURLWithDisposition(
463 browser(),
464 GURL(chrome::kChromeUINewTabURL),
465 NEW_FOREGROUND_TAB,
466 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB |
467 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
468 EXPECT_EQ(2, browser()->tab_strip_model()->count());
469
470 // Make sure new tab received the onmostvisitedchanged event once.
471 content::WebContents* active_tab =
472 browser()->tab_strip_model()->GetActiveWebContents();
473 EXPECT_TRUE(UpdateSearchState(active_tab));
474 EXPECT_EQ(1, on_most_visited_change_calls_);
475
476 // Activate the previous tab.
477 browser()->tab_strip_model()->ActivateTabAt(0, false);
478
479 // Switch back to new tab.
480 browser()->tab_strip_model()->ActivateTabAt(1, false);
481
482 // Confirm that new tab got no onmostvisitedchanged event.
483 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
484 EXPECT_TRUE(UpdateSearchState(active_tab));
485 EXPECT_EQ(1, on_most_visited_change_calls_);
486 }
487
IN_PROC_BROWSER_TEST_F(InstantPolicyTest,ThemeBackgroundAccess)488 IN_PROC_BROWSER_TEST_F(InstantPolicyTest, ThemeBackgroundAccess) {
489 InstallThemeSource();
490 ASSERT_NO_FATAL_FAILURE(InstallThemeAndVerify("theme", "camo theme"));
491 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
492
493 // The "Instant" New Tab should have access to chrome-search: scheme but not
494 // chrome: scheme.
495 ui_test_utils::NavigateToURLWithDisposition(
496 browser(),
497 GURL(chrome::kChromeUINewTabURL),
498 NEW_FOREGROUND_TAB,
499 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB |
500 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
501
502 content::RenderViewHost* rvh =
503 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost();
504
505 const std::string chrome_url("chrome://theme/IDR_THEME_NTP_BACKGROUND");
506 const std::string search_url(
507 "chrome-search://theme/IDR_THEME_NTP_BACKGROUND");
508 bool loaded = false;
509 ASSERT_TRUE(LoadImage(rvh, chrome_url, &loaded));
510 EXPECT_FALSE(loaded) << chrome_url;
511 ASSERT_TRUE(LoadImage(rvh, search_url, &loaded));
512 EXPECT_TRUE(loaded) << search_url;
513 }
514
515 // Flaky on all bots. http://crbug.com/335297.
IN_PROC_BROWSER_TEST_F(InstantPolicyTest,DISABLED_NoThemeBackgroundChangeEventOnTabSwitch)516 IN_PROC_BROWSER_TEST_F(InstantPolicyTest,
517 DISABLED_NoThemeBackgroundChangeEventOnTabSwitch) {
518 InstallThemeSource();
519 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
520
521 // Install a theme.
522 ASSERT_NO_FATAL_FAILURE(InstallThemeAndVerify("theme", "camo theme"));
523 EXPECT_EQ(1, browser()->tab_strip_model()->count());
524
525 // Open new tab.
526 ui_test_utils::NavigateToURLWithDisposition(
527 browser(),
528 GURL(chrome::kChromeUINewTabURL),
529 NEW_FOREGROUND_TAB,
530 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB |
531 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
532 EXPECT_EQ(2, browser()->tab_strip_model()->count());
533
534 content::WebContents* active_tab =
535 browser()->tab_strip_model()->GetActiveWebContents();
536 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
537 int on_theme_changed_calls = 0;
538 EXPECT_TRUE(GetIntFromJS(active_tab, "onThemeChangedCalls",
539 &on_theme_changed_calls));
540 EXPECT_EQ(1, on_theme_changed_calls);
541
542 // Activate the previous tab.
543 browser()->tab_strip_model()->ActivateTabAt(0, false);
544 ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
545
546 // Switch back to new tab.
547 browser()->tab_strip_model()->ActivateTabAt(1, false);
548 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
549
550 // Confirm that new tab got no onthemechanged event while switching tabs.
551 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
552 on_theme_changed_calls = 0;
553 EXPECT_TRUE(GetIntFromJS(active_tab, "onThemeChangedCalls",
554 &on_theme_changed_calls));
555 EXPECT_EQ(1, on_theme_changed_calls);
556 }
557
558 // Flaky on all bots. http://crbug.com/335297, http://crbug.com/265971.
IN_PROC_BROWSER_TEST_F(InstantPolicyTest,DISABLED_SendThemeBackgroundChangedEvent)559 IN_PROC_BROWSER_TEST_F(InstantPolicyTest,
560 DISABLED_SendThemeBackgroundChangedEvent) {
561 InstallThemeSource();
562 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
563
564 // Install a theme.
565 ASSERT_NO_FATAL_FAILURE(InstallThemeAndVerify("theme", "camo theme"));
566
567 // Open new tab.
568 ui_test_utils::NavigateToURLWithDisposition(
569 browser(),
570 GURL(chrome::kChromeUINewTabURL),
571 NEW_FOREGROUND_TAB,
572 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB |
573 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
574 EXPECT_EQ(2, browser()->tab_strip_model()->count());
575
576 // Make sure new tab received an onthemechanged event.
577 content::WebContents* active_tab =
578 browser()->tab_strip_model()->GetActiveWebContents();
579 ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
580 int on_theme_changed_calls = 0;
581 EXPECT_TRUE(GetIntFromJS(active_tab, "onThemeChangedCalls",
582 &on_theme_changed_calls));
583 EXPECT_EQ(1, on_theme_changed_calls);
584
585 // Install a new theme.
586 ASSERT_NO_FATAL_FAILURE(InstallThemeAndVerify("theme2", "snowflake theme"));
587
588 // Confirm that new tab is notified about the theme changed event.
589 on_theme_changed_calls = 0;
590 EXPECT_TRUE(GetIntFromJS(active_tab, "onThemeChangedCalls",
591 &on_theme_changed_calls));
592 EXPECT_EQ(2, on_theme_changed_calls);
593 }
594
595 // Flaky on Mac and Linux Tests bots.
596 #if defined(OS_MACOSX) || defined(OS_LINUX)
597 #define MAYBE_UpdateSearchQueryOnBackNavigation DISABLED_UpdateSearchQueryOnBackNavigation
598 #else
599 #define MAYBE_UpdateSearchQueryOnBackNavigation UpdateSearchQueryOnBackNavigation
600 #endif
601 // Test to verify that the omnibox search query is updated on browser
602 // back button press event.
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,MAYBE_UpdateSearchQueryOnBackNavigation)603 IN_PROC_BROWSER_TEST_F(InstantExtendedTest,
604 MAYBE_UpdateSearchQueryOnBackNavigation) {
605 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
606
607 // Focus omnibox and confirm overlay isn't shown.
608 FocusOmnibox();
609
610 // Create an observer to wait for the instant tab to support Instant.
611 content::WindowedNotificationObserver observer(
612 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
613 content::NotificationService::AllSources());
614
615 SetOmniboxText("flowers");
616 // Commit the search by pressing 'Enter'.
617 PressEnterAndWaitForNavigation();
618 observer.Wait();
619
620 EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText());
621
622 // Typing in the new search query in omnibox.
623 SetOmniboxText("cattles");
624 // Commit the search by pressing 'Enter'.
625 PressEnterAndWaitForNavigation();
626 // 'Enter' commits the query as it was typed. This creates a navigation entry
627 // in the history.
628 EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText());
629
630 content::WebContents* active_tab =
631 browser()->tab_strip_model()->GetActiveWebContents();
632 EXPECT_TRUE(active_tab->GetController().CanGoBack());
633 content::WindowedNotificationObserver load_stop_observer(
634 content::NOTIFICATION_LOAD_STOP,
635 content::Source<content::NavigationController>(
636 &active_tab->GetController()));
637 active_tab->GetController().GoBack();
638 load_stop_observer.Wait();
639
640 EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText());
641 // Commit the search by pressing 'Enter'.
642 FocusOmnibox();
643 PressEnterAndWaitForNavigation();
644 EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText());
645 }
646
647 // Flaky: crbug.com/253092.
648 // Test to verify that the omnibox search query is updated on browser
649 // forward button press events.
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,DISABLED_UpdateSearchQueryOnForwardNavigation)650 IN_PROC_BROWSER_TEST_F(InstantExtendedTest,
651 DISABLED_UpdateSearchQueryOnForwardNavigation) {
652 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
653
654 // Focus omnibox and confirm overlay isn't shown.
655 FocusOmnibox();
656
657 // Create an observer to wait for the instant tab to support Instant.
658 content::WindowedNotificationObserver observer(
659 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
660 content::NotificationService::AllSources());
661
662 SetOmniboxText("flowers");
663 // Commit the search by pressing 'Enter'.
664 PressEnterAndWaitForNavigation();
665 observer.Wait();
666
667 EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText());
668
669 // Typing in the new search query in omnibox.
670 SetOmniboxText("cattles");
671 // Commit the search by pressing 'Enter'.
672 PressEnterAndWaitForNavigation();
673 // 'Enter' commits the query as it was typed. This creates a navigation entry
674 // in the history.
675 EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText());
676
677 content::WebContents* active_tab =
678 browser()->tab_strip_model()->GetActiveWebContents();
679 EXPECT_TRUE(active_tab->GetController().CanGoBack());
680 content::WindowedNotificationObserver load_stop_observer(
681 content::NOTIFICATION_LOAD_STOP,
682 content::Source<content::NavigationController>(
683 &active_tab->GetController()));
684 active_tab->GetController().GoBack();
685 load_stop_observer.Wait();
686
687 EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText());
688
689 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
690 EXPECT_TRUE(active_tab->GetController().CanGoForward());
691 content::WindowedNotificationObserver load_stop_observer_2(
692 content::NOTIFICATION_LOAD_STOP,
693 content::Source<content::NavigationController>(
694 &active_tab->GetController()));
695 active_tab->GetController().GoForward();
696 load_stop_observer_2.Wait();
697
698 // Commit the search by pressing 'Enter'.
699 FocusOmnibox();
700 EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText());
701 PressEnterAndWaitForNavigation();
702 EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText());
703 }
704
705 // Flaky on all bots since re-enabled in r208032, crbug.com/253092
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,DISABLED_NavigateBackToNTP)706 IN_PROC_BROWSER_TEST_F(InstantExtendedTest, DISABLED_NavigateBackToNTP) {
707 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
708 FocusOmnibox();
709
710 // Open a new tab page.
711 ui_test_utils::NavigateToURLWithDisposition(
712 browser(),
713 GURL(chrome::kChromeUINewTabURL),
714 NEW_FOREGROUND_TAB,
715 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB |
716 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
717 EXPECT_EQ(2, browser()->tab_strip_model()->count());
718
719 content::WindowedNotificationObserver observer(
720 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
721 content::NotificationService::AllSources());
722 SetOmniboxText("flowers");
723 PressEnterAndWaitForNavigation();
724 observer.Wait();
725
726 EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText());
727
728 // Typing in the new search query in omnibox.
729 // Commit the search by pressing 'Enter'.
730 SetOmniboxText("cattles");
731 PressEnterAndWaitForNavigation();
732
733 // 'Enter' commits the query as it was typed. This creates a navigation entry
734 // in the history.
735 EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText());
736
737 // Navigate back to "flowers" search result page.
738 content::WebContents* active_tab =
739 browser()->tab_strip_model()->GetActiveWebContents();
740 EXPECT_TRUE(active_tab->GetController().CanGoBack());
741 content::WindowedNotificationObserver load_stop_observer(
742 content::NOTIFICATION_LOAD_STOP,
743 content::Source<content::NavigationController>(
744 &active_tab->GetController()));
745 active_tab->GetController().GoBack();
746 load_stop_observer.Wait();
747
748 EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText());
749
750 // Navigate back to NTP.
751 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
752 EXPECT_TRUE(active_tab->GetController().CanGoBack());
753 content::WindowedNotificationObserver load_stop_observer_2(
754 content::NOTIFICATION_LOAD_STOP,
755 content::Source<content::NavigationController>(
756 &active_tab->GetController()));
757 active_tab->GetController().GoBack();
758 load_stop_observer_2.Wait();
759
760 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
761 EXPECT_TRUE(chrome::IsInstantNTP(active_tab));
762 }
763
764 // Flaky: crbug.com/267119
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,DISABLED_DispatchMVChangeEventWhileNavigatingBackToNTP)765 IN_PROC_BROWSER_TEST_F(InstantExtendedTest,
766 DISABLED_DispatchMVChangeEventWhileNavigatingBackToNTP) {
767 // Setup Instant.
768 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
769 FocusOmnibox();
770
771 // Open new tab.
772 ui_test_utils::NavigateToURLWithDisposition(
773 browser(),
774 GURL(chrome::kChromeUINewTabURL),
775 NEW_FOREGROUND_TAB,
776 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB |
777 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
778
779 content::WebContents* active_tab =
780 browser()->tab_strip_model()->GetActiveWebContents();
781 EXPECT_TRUE(UpdateSearchState(active_tab));
782 EXPECT_EQ(1, on_most_visited_change_calls_);
783
784 content::WindowedNotificationObserver observer(
785 content::NOTIFICATION_LOAD_STOP,
786 content::NotificationService::AllSources());
787 // Set the text and press enter to navigate from NTP.
788 SetOmniboxText("Pen");
789 PressEnterAndWaitForNavigation();
790 EXPECT_EQ(ASCIIToUTF16("Pen"), omnibox()->GetText());
791 observer.Wait();
792
793 // Navigate back to NTP.
794 content::WindowedNotificationObserver back_observer(
795 content::NOTIFICATION_LOAD_STOP,
796 content::NotificationService::AllSources());
797 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
798 EXPECT_TRUE(active_tab->GetController().CanGoBack());
799 active_tab->GetController().GoBack();
800 back_observer.Wait();
801
802 // Verify that onmostvisitedchange event is dispatched when we navigate from
803 // SRP to NTP.
804 active_tab = browser()->tab_strip_model()->GetActiveWebContents();
805 EXPECT_TRUE(UpdateSearchState(active_tab));
806 EXPECT_EQ(1, on_most_visited_change_calls_);
807 }
808
IN_PROC_BROWSER_TEST_F(InstantExtendedPrefetchTest,SetPrefetchQuery)809 IN_PROC_BROWSER_TEST_F(InstantExtendedPrefetchTest, SetPrefetchQuery) {
810 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
811 FocusOmnibox();
812
813 content::WindowedNotificationObserver new_tab_observer(
814 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
815 content::NotificationService::AllSources());
816 ui_test_utils::NavigateToURLWithDisposition(
817 browser(),
818 GURL(chrome::kChromeUINewTabURL),
819 CURRENT_TAB,
820 ui_test_utils::BROWSER_TEST_NONE);
821 new_tab_observer.Wait();
822
823 omnibox()->model()->autocomplete_controller()->search_provider()->
824 kMinimumTimeBetweenSuggestQueriesMs = 0;
825
826 // Set the fake response for search query.
827 fake_factory()->SetFakeResponse(instant_url().Resolve("#q=flowers"),
828 "",
829 net::HTTP_OK,
830 net::URLRequestStatus::SUCCESS);
831
832 // Navigate to a search results page.
833 content::WindowedNotificationObserver observer(
834 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
835 content::NotificationService::AllSources());
836 SetOmniboxText("flowers");
837 PressEnterAndWaitForNavigation();
838 observer.Wait();
839
840 // Set the fake response for suggest request. Response has prefetch details.
841 // Ensure that the page received the prefetch query.
842 fake_factory()->SetFakeResponse(
843 instant_url().Resolve("#q=pupp"),
844 "[\"pupp\",[\"puppy\", \"puppies\"],[],[],"
845 "{\"google:clientdata\":{\"phi\": 0},"
846 "\"google:suggesttype\":[\"QUERY\", \"QUERY\"],"
847 "\"google:suggestrelevance\":[1400, 9]}]",
848 net::HTTP_OK,
849 net::URLRequestStatus::SUCCESS);
850
851 SetOmniboxText("pupp");
852 while (!omnibox()->model()->autocomplete_controller()->done()) {
853 content::WindowedNotificationObserver ready_observer(
854 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
855 content::Source<AutocompleteController>(
856 omnibox()->model()->autocomplete_controller()));
857 ready_observer.Wait();
858 }
859
860 ASSERT_EQ(3, CountSearchProviderSuggestions());
861 content::WebContents* active_tab =
862 browser()->tab_strip_model()->GetActiveWebContents();
863 ASSERT_TRUE(UpdateSearchState(active_tab));
864 ASSERT_TRUE(SearchProvider::ShouldPrefetch(*(
865 omnibox()->model()->result().default_match())));
866 ASSERT_EQ("puppy", prefetch_query_value_);
867 }
868
IN_PROC_BROWSER_TEST_F(InstantExtendedPrefetchTest,ClearPrefetchedResults)869 IN_PROC_BROWSER_TEST_F(InstantExtendedPrefetchTest, ClearPrefetchedResults) {
870 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
871 FocusOmnibox();
872
873 content::WindowedNotificationObserver new_tab_observer(
874 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
875 content::NotificationService::AllSources());
876 ui_test_utils::NavigateToURLWithDisposition(
877 browser(),
878 GURL(chrome::kChromeUINewTabURL),
879 CURRENT_TAB,
880 ui_test_utils::BROWSER_TEST_NONE);
881 new_tab_observer.Wait();
882
883 omnibox()->model()->autocomplete_controller()->search_provider()->
884 kMinimumTimeBetweenSuggestQueriesMs = 0;
885
886 // Set the fake response for search query.
887 fake_factory()->SetFakeResponse(instant_url().Resolve("#q=flowers"),
888 "",
889 net::HTTP_OK,
890 net::URLRequestStatus::SUCCESS);
891
892 // Navigate to a search results page.
893 content::WindowedNotificationObserver observer(
894 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
895 content::NotificationService::AllSources());
896 SetOmniboxText("flowers");
897 PressEnterAndWaitForNavigation();
898 observer.Wait();
899
900 // Set the fake response for suggest request. Response has no prefetch
901 // details. Ensure that the page received a blank query to clear the
902 // prefetched results.
903 fake_factory()->SetFakeResponse(
904 instant_url().Resolve("#q=dogs"),
905 "[\"dogs\",[\"https://dogs.com\"],[],[],"
906 "{\"google:suggesttype\":[\"NAVIGATION\"],"
907 "\"google:suggestrelevance\":[2]}]",
908 net::HTTP_OK,
909 net::URLRequestStatus::SUCCESS);
910
911 SetOmniboxText("dogs");
912 while (!omnibox()->model()->autocomplete_controller()->done()) {
913 content::WindowedNotificationObserver ready_observer(
914 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
915 content::Source<AutocompleteController>(
916 omnibox()->model()->autocomplete_controller()));
917 ready_observer.Wait();
918 }
919
920 ASSERT_EQ(2, CountSearchProviderSuggestions());
921 ASSERT_FALSE(SearchProvider::ShouldPrefetch(*(
922 omnibox()->model()->result().default_match())));
923 content::WebContents* active_tab =
924 browser()->tab_strip_model()->GetActiveWebContents();
925 ASSERT_TRUE(UpdateSearchState(active_tab));
926 ASSERT_EQ("", prefetch_query_value_);
927 }
928
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,ShowURL)929 IN_PROC_BROWSER_TEST_F(InstantExtendedTest, ShowURL) {
930 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
931 FocusOmnibox();
932
933 // Create an observer to wait for the instant tab to support Instant.
934 content::WindowedNotificationObserver observer(
935 chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
936 content::NotificationService::AllSources());
937
938 // Do a search and commit it. The omnibox should show the search terms.
939 SetOmniboxText("foo");
940 EXPECT_EQ(ASCIIToUTF16("foo"), omnibox()->GetText());
941 browser()->window()->GetLocationBar()->AcceptInput();
942 observer.Wait();
943 EXPECT_FALSE(omnibox()->model()->user_input_in_progress());
944 EXPECT_TRUE(browser()->toolbar_model()->WouldPerformSearchTermReplacement(
945 false));
946 EXPECT_EQ(ASCIIToUTF16("foo"), omnibox()->GetText());
947
948 // Calling ShowURL() should disable search term replacement and show the URL.
949 omnibox()->ShowURL();
950 EXPECT_FALSE(browser()->toolbar_model()->WouldPerformSearchTermReplacement(
951 false));
952 // Don't bother looking for a specific URL; ensuring we're no longer showing
953 // the search terms is sufficient.
954 EXPECT_NE(ASCIIToUTF16("foo"), omnibox()->GetText());
955 }
956
957 // Check that clicking on a result sends the correct referrer.
IN_PROC_BROWSER_TEST_F(InstantExtendedTest,Referrer)958 IN_PROC_BROWSER_TEST_F(InstantExtendedTest, Referrer) {
959 ASSERT_TRUE(test_server()->Start());
960 GURL result_url =
961 test_server()->GetURL("files/referrer_policy/referrer-policy-log.html");
962 ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
963 FocusOmnibox();
964
965 // Type a query and press enter to get results.
966 SetOmniboxText("query");
967 PressEnterAndWaitForFrameLoad();
968
969 // Simulate going to a result.
970 content::WebContents* contents =
971 browser()->tab_strip_model()->GetActiveWebContents();
972 std::ostringstream stream;
973 stream << "var link = document.createElement('a');";
974 stream << "link.href = \"" << result_url.spec() << "\";";
975 stream << "document.body.appendChild(link);";
976 stream << "link.click();";
977 EXPECT_TRUE(content::ExecuteScript(contents, stream.str()));
978
979 content::WaitForLoadStop(contents);
980 std::string expected_title =
981 "Referrer is " + instant_url().GetWithEmptyPath().spec();
982 EXPECT_EQ(ASCIIToUTF16(expected_title), contents->GetTitle());
983 }
984