Home | History | Annotate | Download | only in search
      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 }
    983