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