instant_browsertest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2011 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 "base/command_line.h"
6#include "base/stringprintf.h"
7#include "base/utf_string_conversions.h"
8#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
9#include "chrome/browser/browser_list.h"
10#include "chrome/browser/browser_window.h"
11#include "chrome/browser/instant/instant_controller.h"
12#include "chrome/browser/instant/instant_loader.h"
13#include "chrome/browser/instant/instant_loader_manager.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/search_engines/template_url.h"
16#include "chrome/browser/search_engines/template_url_model.h"
17#include "chrome/browser/ui/browser.h"
18#include "chrome/browser/ui/omnibox/location_bar.h"
19#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
20#include "chrome/common/url_constants.h"
21#include "chrome/test/in_process_browser_test.h"
22#include "chrome/test/ui_test_utils.h"
23#include "content/browser/renderer_host/render_view_host.h"
24#include "content/browser/renderer_host/render_widget_host_view.h"
25#include "content/browser/tab_contents/tab_contents.h"
26
27#define EXPECT_STR_EQ(ascii, utf16) \
28  EXPECT_EQ(ASCIIToWide(ascii), UTF16ToWide(utf16))
29
30class InstantTest : public InProcessBrowserTest {
31 public:
32  InstantTest()
33      : location_bar_(NULL),
34        preview_(NULL) {
35    set_show_window(true);
36    EnableDOMAutomation();
37  }
38
39  void EnableInstant() {
40    InstantController::Enable(browser()->profile());
41  }
42
43  void SetupInstantProvider(const std::string& page) {
44    TemplateURLModel* model = browser()->profile()->GetTemplateURLModel();
45    ASSERT_TRUE(model);
46
47    if (!model->loaded()) {
48      model->Load();
49      ui_test_utils::WaitForNotification(
50          NotificationType::TEMPLATE_URL_MODEL_LOADED);
51    }
52
53    ASSERT_TRUE(model->loaded());
54
55    // TemplateURLModel takes ownership of this.
56    TemplateURL* template_url = new TemplateURL();
57
58    std::string url = StringPrintf(
59        "http://%s:%d/files/instant/%s?q={searchTerms}",
60        test_server()->host_port_pair().host().c_str(),
61        test_server()->host_port_pair().port(),
62        page.c_str());
63    template_url->SetURL(url, 0, 0);
64    template_url->SetInstantURL(url, 0, 0);
65    template_url->set_keyword(ASCIIToUTF16("foo"));
66    template_url->set_short_name(ASCIIToUTF16("foo"));
67
68    model->Add(template_url);
69    model->SetDefaultSearchProvider(template_url);
70  }
71
72  void FindLocationBar() {
73    if (location_bar_)
74      return;
75    location_bar_ = browser()->window()->GetLocationBar();
76    ASSERT_TRUE(location_bar_);
77  }
78
79  TabContentsWrapper* GetPendingPreviewContents() {
80    return browser()->instant()->GetPendingPreviewContents();
81  }
82
83  // Type a character to get instant to trigger.
84  void SetupLocationBar() {
85    FindLocationBar();
86    // "a" triggers the "about:" provider.  "b" begins the "bing.com" keyword.
87    // "c" might someday trigger a "chrome:" provider.
88    location_bar_->location_entry()->SetUserText(ASCIIToUTF16("d"));
89  }
90
91  // Waits for preview to be shown.
92  void WaitForPreviewToNavigate(bool use_current) {
93    InstantController* instant = browser()->instant();
94    ASSERT_TRUE(instant);
95    TabContentsWrapper* tab = use_current ?
96        instant->GetPreviewContents() : GetPendingPreviewContents();
97    ASSERT_TRUE(tab);
98    preview_ = tab->tab_contents();
99    ASSERT_TRUE(preview_);
100    ui_test_utils::WaitForNavigation(&preview_->controller());
101  }
102
103  // Wait for instant to load and ensure it is in the state we expect.
104  void SetupPreview() {
105    // Wait for the preview to navigate.
106    WaitForPreviewToNavigate(true);
107
108    ASSERT_TRUE(browser()->instant()->IsShowingInstant());
109    ASSERT_FALSE(browser()->instant()->is_displayable());
110    ASSERT_TRUE(browser()->instant()->is_active());
111
112    // When the page loads, the initial searchBox values are set and only a
113    // resize will have been sent.
114    ASSERT_EQ("true 0 0 0 1 d false d false 1 1",
115              GetSearchStateAsString(preview_));
116  }
117
118  void SetLocationBarText(const std::string& text) {
119    ASSERT_NO_FATAL_FAILURE(FindLocationBar());
120    location_bar_->location_entry()->SetUserText(UTF8ToUTF16(text));
121    ui_test_utils::WaitForNotification(
122        NotificationType::INSTANT_CONTROLLER_SHOWN);
123  }
124
125  const string16& GetSuggestion() const {
126    return browser()->instant()->loader_manager_->
127        current_loader()->complete_suggested_text_;
128  }
129
130  void SendKey(ui::KeyboardCode key) {
131    ASSERT_TRUE(ui_test_utils::SendKeyPressSync(
132        browser(), key, false, false, false, false));
133  }
134
135  void SetSuggestionsJavascriptArgument(TabContents* tab_contents,
136                                        const std::string& argument) {
137    std::string script = StringPrintf(
138        "window.setSuggestionsArgument = %s;", argument.c_str());
139    ASSERT_TRUE(ui_test_utils::ExecuteJavaScript(
140        tab_contents->render_view_host(),
141        std::wstring(),
142        UTF8ToWide(script)));
143  }
144
145  bool GetStringFromJavascript(TabContents* tab_contents,
146                               const std::string& function,
147                               std::string* result) {
148    std::string script = StringPrintf(
149        "window.domAutomationController.send(%s)", function.c_str());
150    return ui_test_utils::ExecuteJavaScriptAndExtractString(
151        tab_contents->render_view_host(),
152        std::wstring(), UTF8ToWide(script), result);
153  }
154
155  bool GetIntFromJavascript(TabContents* tab_contents,
156                            const std::string& function,
157                            int* result) {
158    std::string script = StringPrintf(
159        "window.domAutomationController.send(%s)", function.c_str());
160    return ui_test_utils::ExecuteJavaScriptAndExtractInt(
161        tab_contents->render_view_host(),
162        std::wstring(), UTF8ToWide(script), result);
163  }
164
165  bool GetBoolFromJavascript(TabContents* tab_contents,
166                             const std::string& function,
167                             bool* result) {
168    std::string script = StringPrintf(
169        "window.domAutomationController.send(%s)", function.c_str());
170    return ui_test_utils::ExecuteJavaScriptAndExtractBool(
171        tab_contents->render_view_host(),
172        std::wstring(), UTF8ToWide(script), result);
173  }
174
175  // Returns the state of the search box as a string. This consists of the
176  // following:
177  // window.chrome.sv
178  // window.onsubmitcalls
179  // window.oncancelcalls
180  // window.onchangecalls
181  // window.onresizecalls
182  // window.beforeLoadSearchBox.value
183  // window.beforeLoadSearchBox.verbatim
184  // window.chrome.searchBox.value
185  // window.chrome.searchBox.verbatim
186  // window.chrome.searchBox.selectionStart
187  // window.chrome.searchBox.selectionEnd
188  // If determining any of the values fails, the value is 'fail'.
189  std::string GetSearchStateAsString(TabContents* tab_contents) {
190    bool sv = false;
191    int onsubmitcalls = 0;
192    int oncancelcalls = 0;
193    int onchangecalls = 0;
194    int onresizecalls = 0;
195    int selection_start = 0;
196    int selection_end = 0;
197    std::string before_load_value;
198    bool before_load_verbatim = false;
199    std::string value;
200    bool verbatim = false;
201
202    if (!GetBoolFromJavascript(tab_contents, "window.chrome.sv", &sv) ||
203        !GetIntFromJavascript(tab_contents, "window.onsubmitcalls",
204                              &onsubmitcalls) ||
205        !GetIntFromJavascript(tab_contents, "window.oncancelcalls",
206                              &oncancelcalls) ||
207        !GetIntFromJavascript(tab_contents, "window.onchangecalls",
208                              &onchangecalls) ||
209        !GetIntFromJavascript(tab_contents, "window.onresizecalls",
210                              &onresizecalls) ||
211        !GetStringFromJavascript(
212            tab_contents, "window.beforeLoadSearchBox.value",
213            &before_load_value) ||
214        !GetBoolFromJavascript(
215            tab_contents, "window.beforeLoadSearchBox.verbatim",
216            &before_load_verbatim) ||
217        !GetStringFromJavascript(tab_contents, "window.chrome.searchBox.value",
218                                 &value) ||
219        !GetBoolFromJavascript(tab_contents, "window.chrome.searchBox.verbatim",
220                               &verbatim) ||
221        !GetIntFromJavascript(tab_contents,
222                              "window.chrome.searchBox.selectionStart",
223                              &selection_start) ||
224        !GetIntFromJavascript(tab_contents,
225                              "window.chrome.searchBox.selectionEnd",
226                              &selection_end)) {
227      return "fail";
228    }
229
230    return StringPrintf("%s %d %d %d %d %s %s %s %s %d %d",
231                        sv ? "true" : "false",
232                        onsubmitcalls,
233                        oncancelcalls,
234                        onchangecalls,
235                        onresizecalls,
236                        before_load_value.c_str(),
237                        before_load_verbatim ? "true" : "false",
238                        value.c_str(),
239                        verbatim ? "true" : "false",
240                        selection_start,
241                        selection_end);
242  }
243
244  void CheckStringValueFromJavascript(
245      const std::string& expected,
246      const std::string& function,
247      TabContents* tab_contents) {
248    std::string result;
249    ASSERT_TRUE(GetStringFromJavascript(tab_contents, function, &result));
250    ASSERT_EQ(expected, result);
251  }
252
253  void CheckBoolValueFromJavascript(
254      bool expected,
255      const std::string& function,
256      TabContents* tab_contents) {
257    bool result;
258    ASSERT_TRUE(GetBoolFromJavascript(tab_contents, function, &result));
259    ASSERT_EQ(expected, result);
260  }
261
262  void CheckIntValueFromJavascript(
263      int expected,
264      const std::string& function,
265      TabContents* tab_contents) {
266    int result;
267    ASSERT_TRUE(GetIntFromJavascript(tab_contents, function, &result));
268    ASSERT_EQ(expected, result);
269  }
270
271  // Sends a message to the renderer and waits for the response to come back to
272  // the browser.
273  void WaitForMessageToBeProcessedByRenderer(TabContentsWrapper* tab) {
274    ASSERT_NO_FATAL_FAILURE(
275        CheckBoolValueFromJavascript(true, "true", tab->tab_contents()));
276  }
277
278 protected:
279  LocationBar* location_bar_;
280  TabContents* preview_;
281};
282
283// TODO(tonyg): Add the following tests:
284// - Test that the search box API is not populated for pages other than the
285//   default search provider.
286// - Test resize events.
287
288// Verify that the onchange event is dispatched upon typing in the box.
289IN_PROC_BROWSER_TEST_F(InstantTest, OnChangeEvent) {
290  ASSERT_TRUE(test_server()->Start());
291  EnableInstant();
292  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
293  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
294  ASSERT_NO_FATAL_FAILURE(SetupPreview());
295
296  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
297
298  ASSERT_EQ(ASCIIToUTF16("defghi"), location_bar_->location_entry()->GetText());
299
300  // Make sure the url that will get committed when we press enter matches that
301  // of the default search provider.
302  const TemplateURL* default_turl =
303      browser()->profile()->GetTemplateURLModel()->GetDefaultSearchProvider();
304  ASSERT_TRUE(default_turl);
305  ASSERT_TRUE(default_turl->url());
306  EXPECT_EQ(default_turl->url()->ReplaceSearchTerms(
307                *default_turl, ASCIIToUTF16("defghi"), 0, string16()),
308            browser()->instant()->GetCurrentURL().spec());
309
310  // Check that the value is reflected and onchange is called.
311  EXPECT_EQ("true 0 0 1 2 d false def false 3 3",
312            GetSearchStateAsString(preview_));
313}
314
315IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsArrayOfStrings) {
316  ASSERT_TRUE(test_server()->Start());
317  EnableInstant();
318  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
319  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
320  ASSERT_NO_FATAL_FAILURE(SetupPreview());
321
322  SetSuggestionsJavascriptArgument(preview_, "['defgh', 'unused']");
323  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
324  EXPECT_STR_EQ("defgh", GetSuggestion());
325}
326
327IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsEmptyArray) {
328  ASSERT_TRUE(test_server()->Start());
329  EnableInstant();
330  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
331  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
332  ASSERT_NO_FATAL_FAILURE(SetupPreview());
333
334  SetSuggestionsJavascriptArgument(preview_, "[]");
335  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
336  EXPECT_STR_EQ("", GetSuggestion());
337}
338
339IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsValidJson) {
340  ASSERT_TRUE(test_server()->Start());
341  EnableInstant();
342  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
343  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
344  ASSERT_NO_FATAL_FAILURE(SetupPreview());
345
346  SetSuggestionsJavascriptArgument(
347      preview_,
348      "{suggestions:[{value:'defghij'},{value:'unused'}]}");
349  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
350  EXPECT_STR_EQ("defghij", GetSuggestion());
351}
352
353IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsInvalidSuggestions) {
354  ASSERT_TRUE(test_server()->Start());
355  EnableInstant();
356  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
357  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
358  ASSERT_NO_FATAL_FAILURE(SetupPreview());
359
360  SetSuggestionsJavascriptArgument(
361      preview_,
362      "{suggestions:{value:'defghi'}}");
363  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
364  EXPECT_STR_EQ("", GetSuggestion());
365}
366
367IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsEmptyJson) {
368  ASSERT_TRUE(test_server()->Start());
369  EnableInstant();
370  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
371  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
372  ASSERT_NO_FATAL_FAILURE(SetupPreview());
373
374  SetSuggestionsJavascriptArgument(preview_, "{}");
375  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
376  EXPECT_STR_EQ("", GetSuggestion());
377}
378
379IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsEmptySuggestions) {
380  ASSERT_TRUE(test_server()->Start());
381  EnableInstant();
382  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
383  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
384  ASSERT_NO_FATAL_FAILURE(SetupPreview());
385
386  SetSuggestionsJavascriptArgument(preview_, "{suggestions:[]}");
387  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
388  EXPECT_STR_EQ("", GetSuggestion());
389}
390
391IN_PROC_BROWSER_TEST_F(InstantTest, SetSuggestionsEmptySuggestion) {
392  ASSERT_TRUE(test_server()->Start());
393  EnableInstant();
394  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
395  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
396  ASSERT_NO_FATAL_FAILURE(SetupPreview());
397
398  SetSuggestionsJavascriptArgument(preview_, "{suggestions:[{}]}");
399  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
400  EXPECT_STR_EQ("", GetSuggestion());
401}
402
403// Verify instant preview is shown correctly for a non-search query.
404IN_PROC_BROWSER_TEST_F(InstantTest, ShowPreviewNonSearch) {
405  ASSERT_TRUE(test_server()->Start());
406  EnableInstant();
407  GURL url(test_server()->GetURL("files/instant/empty.html"));
408  ASSERT_NO_FATAL_FAILURE(SetLocationBarText(url.spec()));
409  // The preview should be active and showing.
410  ASSERT_TRUE(browser()->instant()->is_active());
411  ASSERT_TRUE(browser()->instant()->is_displayable());
412  ASSERT_TRUE(browser()->instant()->IsCurrent());
413  ASSERT_TRUE(browser()->instant()->GetPreviewContents());
414  RenderWidgetHostView* rwhv =
415      browser()->instant()->GetPreviewContents()->tab_contents()->
416      GetRenderWidgetHostView();
417  ASSERT_TRUE(rwhv);
418  ASSERT_TRUE(rwhv->IsShowing());
419}
420
421// Transition from non-search to search and make sure everything is shown
422// correctly.
423IN_PROC_BROWSER_TEST_F(InstantTest, NonSearchToSearch) {
424  ASSERT_TRUE(test_server()->Start());
425  EnableInstant();
426  GURL url(test_server()->GetURL("files/instant/empty.html"));
427  ASSERT_NO_FATAL_FAILURE(SetLocationBarText(url.spec()));
428  // The preview should be active and showing.
429  ASSERT_TRUE(browser()->instant()->is_active());
430  ASSERT_TRUE(browser()->instant()->is_displayable());
431  TabContentsWrapper* initial_tab = browser()->instant()->GetPreviewContents();
432  ASSERT_TRUE(initial_tab);
433  RenderWidgetHostView* rwhv =
434      initial_tab->tab_contents()->GetRenderWidgetHostView();
435  ASSERT_TRUE(rwhv);
436  ASSERT_TRUE(rwhv->IsShowing());
437
438  // Now type in some search text.
439  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
440  location_bar_->location_entry()->SetUserText(ASCIIToUTF16("def"));
441
442  // Wait for the preview to navigate.
443  ASSERT_NO_FATAL_FAILURE(WaitForPreviewToNavigate(false));
444
445  // The controller is still determining if the provider really supports
446  // instant. As a result the tabcontents should not have changed.
447  TabContentsWrapper* current_tab = browser()->instant()->GetPreviewContents();
448  ASSERT_EQ(current_tab, initial_tab);
449  // The preview should still be showing.
450  rwhv = current_tab->tab_contents()->GetRenderWidgetHostView();
451  ASSERT_TRUE(rwhv);
452  ASSERT_TRUE(rwhv->IsShowing());
453
454  // Use MightSupportInstant as the controller is still determining if the
455  // page supports instant and hasn't actually commited yet.
456  EXPECT_TRUE(browser()->instant()->MightSupportInstant());
457
458  // Instant should still be active.
459  EXPECT_TRUE(browser()->instant()->is_active());
460  EXPECT_TRUE(browser()->instant()->is_displayable());
461
462  // Because we're waiting on the page, instant isn't current.
463  ASSERT_FALSE(browser()->instant()->IsCurrent());
464
465  // Bounce a message to the renderer so that we know the instant has gotten a
466  // response back from the renderer as to whether the page supports instant.
467  ASSERT_NO_FATAL_FAILURE(
468      WaitForMessageToBeProcessedByRenderer(GetPendingPreviewContents()));
469
470  // Reset the user text so that the page is told the text changed. We should be
471  // able to nuke this once 66104 is fixed.
472  location_bar_->location_entry()->SetUserText(ASCIIToUTF16("defg"));
473
474  // Wait for the renderer to process it.
475  ASSERT_NO_FATAL_FAILURE(
476      WaitForMessageToBeProcessedByRenderer(GetPendingPreviewContents()));
477
478  // We should have gotten a response back from the renderer that resulted in
479  // committing.
480  ASSERT_FALSE(GetPendingPreviewContents());
481  ASSERT_TRUE(browser()->instant()->is_active());
482  ASSERT_TRUE(browser()->instant()->is_displayable());
483  TabContentsWrapper* new_tab = browser()->instant()->GetPreviewContents();
484  ASSERT_TRUE(new_tab);
485  ASSERT_NE(new_tab, initial_tab);
486  RenderWidgetHostView* new_rwhv =
487      new_tab->tab_contents()->GetRenderWidgetHostView();
488  ASSERT_TRUE(new_rwhv);
489  ASSERT_NE(new_rwhv, rwhv);
490  ASSERT_TRUE(new_rwhv->IsShowing());
491}
492
493// Makes sure that if the server doesn't support the instant API we don't show
494// anything.
495#if defined(OS_MACOSX) || defined(OS_LINUX)
496// Showing as flaky on Mac and Linux.
497// http://crbug.com/70860
498#define MAYBE_SearchServerDoesntSupportInstant \
499    DISABLED_SearchServerDoesntSupportInstant
500#else
501#define MAYBE_SearchServerDoesntSupportInstant \
502    SearchServerDoesntSupportInstant
503#endif
504IN_PROC_BROWSER_TEST_F(InstantTest, MAYBE_SearchServerDoesntSupportInstant) {
505  ASSERT_TRUE(test_server()->Start());
506  EnableInstant();
507  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("empty.html"));
508  ASSERT_NO_FATAL_FAILURE(FindLocationBar());
509  location_bar_->location_entry()->SetUserText(ASCIIToUTF16("d"));
510  ASSERT_TRUE(browser()->instant());
511  // Because we typed in a search string we should think we're showing instant
512  // results.
513  EXPECT_TRUE(browser()->instant()->IsShowingInstant());
514  // But because we're waiting to determine if the page really supports instant
515  // we shouldn't be showing the preview.
516  EXPECT_FALSE(browser()->instant()->is_displayable());
517  // But instant should still be active.
518  EXPECT_TRUE(browser()->instant()->is_active());
519
520  // When the response comes back that the page doesn't support instant the tab
521  // should be closed.
522  ui_test_utils::WaitForNotification(NotificationType::TAB_CLOSED);
523  EXPECT_FALSE(browser()->instant()->IsShowingInstant());
524  EXPECT_FALSE(browser()->instant()->is_displayable());
525  EXPECT_TRUE(browser()->instant()->is_active());
526  EXPECT_FALSE(browser()->instant()->IsCurrent());
527}
528
529// Verifies transitioning from loading a non-search string to a search string
530// with the provider not supporting instant works (meaning we don't display
531// anything).
532#if defined(OS_MACOSX)
533// Showing as flaky on Mac
534// http://crbug.com/70810
535#define MAYBE_NonSearchToSearchDoesntSupportInstant \
536    DISABLED_NonSearchToSearchDoesntSupportInstant
537#else
538#define MAYBE_NonSearchToSearchDoesntSupportInstant \
539    NonSearchToSearchDoesntSupportInstant
540#endif
541IN_PROC_BROWSER_TEST_F(InstantTest,
542                       MAYBE_NonSearchToSearchDoesntSupportInstant) {
543  ASSERT_TRUE(test_server()->Start());
544  EnableInstant();
545  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("empty.html"));
546  GURL url(test_server()->GetURL("files/instant/empty.html"));
547  ASSERT_NO_FATAL_FAILURE(SetLocationBarText(url.spec()));
548  // The preview should be active and showing.
549  ASSERT_TRUE(browser()->instant()->is_displayable());
550  ASSERT_TRUE(browser()->instant()->is_active());
551  TabContentsWrapper* initial_tab = browser()->instant()->GetPreviewContents();
552  ASSERT_TRUE(initial_tab);
553  RenderWidgetHostView* rwhv =
554      initial_tab->tab_contents()->GetRenderWidgetHostView();
555  ASSERT_TRUE(rwhv);
556  ASSERT_TRUE(rwhv->IsShowing());
557
558  // Now type in some search text.
559  location_bar_->location_entry()->SetUserText(ASCIIToUTF16("d"));
560
561  // Instant should still be live.
562  ASSERT_TRUE(browser()->instant()->is_displayable());
563  ASSERT_TRUE(browser()->instant()->is_active());
564  // Because we typed in a search string we should think we're showing instant
565  // results.
566  EXPECT_TRUE(browser()->instant()->MightSupportInstant());
567  // Instant should not be current (it's still loading).
568  EXPECT_FALSE(browser()->instant()->IsCurrent());
569
570  // When the response comes back that the page doesn't support instant the tab
571  // should be closed.
572  ui_test_utils::WaitForNotification(NotificationType::TAB_CLOSED);
573  EXPECT_FALSE(browser()->instant()->IsShowingInstant());
574  EXPECT_FALSE(browser()->instant()->is_displayable());
575  // But because the omnibox is still open, instant should be active.
576  ASSERT_TRUE(browser()->instant()->is_active());
577}
578
579// Verifies the page was told a non-zero height.
580IN_PROC_BROWSER_TEST_F(InstantTest, ValidHeight) {
581  ASSERT_TRUE(test_server()->Start());
582  EnableInstant();
583  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
584  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
585  ASSERT_NO_FATAL_FAILURE(SetupPreview());
586
587  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
588
589  int height;
590
591  // searchBox height is not yet set during initial load.
592  ASSERT_TRUE(GetIntFromJavascript(preview_,
593      "window.beforeLoadSearchBox.height",
594      &height));
595  EXPECT_EQ(0, height);
596
597  // searchBox height is available by the time the page loads.
598  ASSERT_TRUE(GetIntFromJavascript(preview_,
599      "window.chrome.searchBox.height",
600      &height));
601  EXPECT_GT(height, 0);
602}
603
604// Verifies that if the server returns a 403 we don't show the preview and
605// query the host again.
606IN_PROC_BROWSER_TEST_F(InstantTest, HideOn403) {
607  ASSERT_TRUE(test_server()->Start());
608  EnableInstant();
609  GURL url(test_server()->GetURL("files/instant/403.html"));
610  ASSERT_NO_FATAL_FAILURE(FindLocationBar());
611  location_bar_->location_entry()->SetUserText(UTF8ToUTF16(url.spec()));
612  // The preview shouldn't be showing, but it should be loading.
613  ASSERT_TRUE(browser()->instant()->GetPreviewContents());
614  ASSERT_TRUE(browser()->instant()->is_active());
615  ASSERT_FALSE(browser()->instant()->is_displayable());
616
617  // When instant sees the 403, it should close the tab.
618  ui_test_utils::WaitForNotification(NotificationType::TAB_CLOSED);
619  ASSERT_FALSE(browser()->instant()->GetPreviewContents());
620  ASSERT_TRUE(browser()->instant()->is_active());
621  ASSERT_FALSE(browser()->instant()->is_displayable());
622
623  // Try loading another url on the server. Instant shouldn't create a new tab
624  // as the server returned 403.
625  GURL url2(test_server()->GetURL("files/instant/empty.html"));
626  location_bar_->location_entry()->SetUserText(UTF8ToUTF16(url2.spec()));
627  ASSERT_FALSE(browser()->instant()->GetPreviewContents());
628  ASSERT_TRUE(browser()->instant()->is_active());
629  ASSERT_FALSE(browser()->instant()->is_displayable());
630}
631
632// Verify that the onsubmit event is dispatched upon pressing enter.
633IN_PROC_BROWSER_TEST_F(InstantTest, OnSubmitEvent) {
634  ASSERT_TRUE(test_server()->Start());
635  EnableInstant();
636  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
637
638  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
639  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
640  ASSERT_NO_FATAL_FAILURE(SetupPreview());
641
642  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
643  ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN));
644
645  // Check that the preview contents have been committed.
646  ASSERT_FALSE(browser()->instant()->GetPreviewContents());
647  ASSERT_FALSE(browser()->instant()->is_active());
648  TabContents* contents = browser()->GetSelectedTabContents();
649  ASSERT_TRUE(contents);
650
651  // Check that the value is reflected and onsubmit is called.
652  EXPECT_EQ("true 1 0 1 2 d false defghi true 3 3",
653            GetSearchStateAsString(preview_));
654}
655
656// Verify that the oncancel event is dispatched upon losing focus.
657IN_PROC_BROWSER_TEST_F(InstantTest, OnCancelEvent) {
658  ASSERT_TRUE(test_server()->Start());
659  EnableInstant();
660  ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
661
662  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
663  ASSERT_NO_FATAL_FAILURE(SetupLocationBar());
664  ASSERT_NO_FATAL_FAILURE(SetupPreview());
665
666  ASSERT_NO_FATAL_FAILURE(SetLocationBarText("def"));
667  ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(),
668                                                     VIEW_ID_TAB_CONTAINER));
669
670  // Check that the preview contents have been committed.
671  ASSERT_FALSE(browser()->instant()->GetPreviewContents());
672  ASSERT_FALSE(browser()->instant()->is_active());
673  TabContents* contents = browser()->GetSelectedTabContents();
674  ASSERT_TRUE(contents);
675
676  // Check that the value is reflected and oncancel is called.
677  EXPECT_EQ("true 0 1 1 2 d false def false 3 3",
678            GetSearchStateAsString(preview_));
679}
680
681// Make sure about:crash is shown.
682IN_PROC_BROWSER_TEST_F(InstantTest, ShowAboutCrash) {
683  ASSERT_TRUE(test_server()->Start());
684  EnableInstant();
685
686  ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
687
688  ASSERT_NO_FATAL_FAILURE(SetLocationBarText(chrome::kAboutCrashURL));
689
690  // If we get here it means the preview was shown. If we time out, it means the
691  // preview was never shown.
692}
693