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