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