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