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