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