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