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