browser_view_interactive_uitest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 2012 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 "chrome/browser/ui/views/frame/browser_view.h"
6
7#include "chrome/app/chrome_command_ids.h"
8#include "chrome/browser/autocomplete/autocomplete_controller.h"
9#include "chrome/browser/search/search.h"
10#include "chrome/browser/ui/browser_commands.h"
11#include "chrome/browser/ui/immersive_fullscreen_configuration.h"
12#include "chrome/browser/ui/omnibox/omnibox_view.h"
13#include "chrome/browser/ui/search/instant_test_utils.h"
14#include "chrome/browser/ui/tabs/tab_strip_model.h"
15#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
16#include "chrome/browser/ui/views/frame/contents_container.h"
17#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
18#include "chrome/browser/ui/views/frame/overlay_container.h"
19#include "chrome/browser/ui/views/frame/top_container_view.h"
20#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
21#include "chrome/browser/ui/views/tabs/tab.h"
22#include "chrome/browser/ui/views/toolbar_view.h"
23#include "chrome/common/instant_types.h"
24#include "chrome/common/url_constants.h"
25#include "chrome/test/base/in_process_browser_test.h"
26#include "chrome/test/base/ui_test_utils.h"
27#include "ui/views/controls/webview/webview.h"
28#include "ui/views/focus/focus_manager.h"
29#include "ui/views/window/non_client_view.h"
30
31#if defined(OS_CHROMEOS)
32#include "chrome/common/chrome_notification_types.h"
33#include "content/public/browser/notification_service.h"
34#include "ui/compositor/layer.h"
35#include "ui/compositor/scoped_animation_duration_scale_mode.h"
36#endif
37
38using views::FocusManager;
39
40namespace {
41
42// Returns the bounds of |view| in widget coordinates.
43gfx::Rect GetRectInWidget(views::View* view) {
44  return view->ConvertRectToWidget(view->GetLocalBounds());
45}
46
47}
48
49typedef InProcessBrowserTest BrowserViewTest;
50
51// Active window and focus testing is not reliable on Windows crbug.com/79493
52// TODO(linux_aura) http://crbug.com/163931
53#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
54#define MAYBE_FullscreenClearsFocus DISABLED_FullscreenClearsFocus
55#else
56#define MAYBE_FullscreenClearsFocus FullscreenClearsFocus
57#endif
58IN_PROC_BROWSER_TEST_F(BrowserViewTest, MAYBE_FullscreenClearsFocus) {
59  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
60  LocationBarView* location_bar_view = browser_view->GetLocationBarView();
61  FocusManager* focus_manager = browser_view->GetFocusManager();
62
63  // Focus starts in the location bar or one of its children.
64  EXPECT_TRUE(location_bar_view->Contains(focus_manager->GetFocusedView()));
65
66  chrome::ToggleFullscreenMode(browser());
67  EXPECT_TRUE(browser_view->IsFullscreen());
68
69  // Focus is released from the location bar.
70  EXPECT_FALSE(location_bar_view->Contains(focus_manager->GetFocusedView()));
71}
72
73//////////////////////////////////////////////////////////////////////////////
74
75#if defined(HTML_INSTANT_EXTENDED_POPUP)
76class BrowserViewInstantExtendedTest : public InProcessBrowserTest,
77                                       public InstantTestBase {
78 public:
79  BrowserViewInstantExtendedTest() {}
80  virtual ~BrowserViewInstantExtendedTest() {}
81
82  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
83    chrome::EnableInstantExtendedAPIForTesting();
84    ASSERT_TRUE(https_test_server().Start());
85    GURL instant_url = https_test_server().GetURL(
86        "files/instant_extended.html?strk=1&");
87    InstantTestBase::Init(instant_url);
88  }
89
90 private:
91  DISALLOW_COPY_AND_ASSIGN(BrowserViewInstantExtendedTest);
92};
93
94IN_PROC_BROWSER_TEST_F(BrowserViewInstantExtendedTest,
95                       InstantExtendedForOverlay) {
96  BookmarkBarView::DisableAnimationsForTesting(true);
97
98  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
99  ContentsContainer* contents_container =
100      browser_view->GetContentsContainerForTest();
101  OverlayContainer* overlay_container =
102      browser_view->GetOverlayContainerForTest();
103
104  // Start up instant.
105  ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
106
107  // Enable attached bookmark bar.
108  BookmarkBarView* bookmark_bar = browser_view->GetBookmarkBarView();
109  chrome::ExecuteCommand(browser(), IDC_SHOW_BOOKMARK_BAR);
110  EXPECT_TRUE(bookmark_bar->visible());
111  EXPECT_FALSE(bookmark_bar->IsDetached());
112
113  // Overlay container is invisible but at front of view hierarchy.
114  EXPECT_FALSE(overlay_container->visible());
115  EXPECT_EQ(browser_view->child_count() - 1,
116            browser_view->GetIndexOf(overlay_container));
117
118  ////////////////////////////////////////////////////////////////////////////
119  // Test suggestions on a normal web page, which are in an overlay.
120
121  // Focus omnibox, which constructs an overlay web contents.
122  FocusOmniboxAndWaitForInstantOverlayAndNTPSupport();
123  // Typing in the omnibox should show suggestions in an overlay view.
124  SetOmniboxTextAndWaitForOverlayToShow("santa");
125  EXPECT_TRUE(instant()->model()->mode().is_search_suggestions());
126
127  views::WebView* overlay = overlay_container->GetOverlayWebViewForTest();
128  content::WebContents* overlay_contents = overlay->web_contents();
129
130  // Overlay container is still at front, but is now visible and has an overlay.
131  EXPECT_EQ(browser_view->child_count() - 1,
132            browser_view->GetIndexOf(overlay_container));
133  EXPECT_TRUE(overlay_container->visible());
134  EXPECT_EQ(overlay_container, overlay->parent());
135
136  // Content area is still immediately below the visible attached bookmark bar.
137  EXPECT_TRUE(bookmark_bar->visible());
138  EXPECT_EQ(GetRectInWidget(bookmark_bar).bottom(),
139            GetRectInWidget(browser_view->GetContentsWebViewForTest()).y());
140
141  // Overlay web view (with suggestions) aligns with the bottom of the toolbar.
142  gfx::Rect overlay_rect_in_widget = GetRectInWidget(
143      overlay_container->GetOverlayWebViewForTest());
144  EXPECT_EQ(GetRectInWidget(browser_view->toolbar()).bottom(),
145                            overlay_rect_in_widget.y());
146
147  // Commit the search by pressing Enter.
148  browser_view->GetLocationBar()->AcceptInput();
149
150  // Overlay is reparented to and becomes active in ContentsContainer with the
151  // same web contents, which is the active contents in browser, while overlay
152  // container is childless and invisible.
153  EXPECT_EQ(contents_container, overlay->parent());
154  EXPECT_EQ(overlay, contents_container->GetActiveWebViewForTest());
155  EXPECT_EQ(overlay_contents, overlay->web_contents());
156  EXPECT_EQ(overlay_contents,
157            browser()->tab_strip_model()->GetActiveWebContents());
158  EXPECT_EQ(1, contents_container->child_count());
159  EXPECT_EQ(0, overlay_container->child_count());
160  EXPECT_FALSE(overlay_container->visible());
161
162  BookmarkBarView::DisableAnimationsForTesting(false);
163}
164
165//////////////////////////////////////////////////////////////////////////////
166
167// Immersive fullscreen is currently enabled only on Chrome OS.
168#if defined(OS_CHROMEOS)
169
170class BrowserViewImmersiveInstantExtendedTest : public InProcessBrowserTest,
171                                                public InstantTestBase {
172 public:
173  BrowserViewImmersiveInstantExtendedTest() {}
174  virtual ~BrowserViewImmersiveInstantExtendedTest() {}
175
176  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
177    ImmersiveFullscreenConfiguration::EnableImmersiveFullscreenForTest();
178    chrome::EnableInstantExtendedAPIForTesting();
179    ASSERT_TRUE(https_test_server().Start());
180    GURL instant_url = https_test_server().GetURL(
181        "files/instant_extended.html?strk=1&");
182    InstantTestBase::Init(instant_url);
183  }
184
185 private:
186  DISALLOW_COPY_AND_ASSIGN(BrowserViewImmersiveInstantExtendedTest);
187};
188
189IN_PROC_BROWSER_TEST_F(BrowserViewImmersiveInstantExtendedTest,
190                       ImmersiveInstantExtended) {
191  ui::ScopedAnimationDurationScaleMode zero_duration_mode(
192      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
193  BookmarkBarView::DisableAnimationsForTesting(true);
194
195  // Cache some pointers we'll need below.
196  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
197  ToolbarView* toolbar = browser_view->toolbar();
198
199  // Start up both instant and immersive fullscreen.
200  ASSERT_NO_FATAL_FAILURE(SetupInstant(browser()));
201  ASSERT_TRUE(ImmersiveFullscreenConfiguration::UseImmersiveFullscreen());
202  chrome::ToggleFullscreenMode(browser());
203  ASSERT_TRUE(browser_view->IsFullscreen());
204  ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled());
205
206  ////////////////////////////////////////////////////////////////////////////
207  // Test suggestions on a normal web page, which are in an overlay.
208
209  // Focus omnibox, which constructs an overlay web contents.
210  FocusOmniboxAndWaitForInstantOverlayAndNTPSupport();
211  EXPECT_TRUE(instant()->model()->mode().is_default());
212  // The above testing code doesn't trigger the views location bar focus path,
213  // so force it to happen explicitly.
214  browser_view->SetFocusToLocationBar(false);
215  EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed());
216  // Content area is immediately below the tab indicators.
217  views::WebView* contents_web_view =
218      browser_view->GetContentsWebViewForTest();
219  EXPECT_EQ(GetRectInWidget(browser_view).y() + Tab::GetImmersiveHeight(),
220            GetRectInWidget(contents_web_view).y());
221
222  // Typing in the omnibox should show suggestions in an overlay view.
223  SetOmniboxTextAndWaitForOverlayToShow("santa");
224  EXPECT_TRUE(instant()->model()->mode().is_search_suggestions());
225  // Content area is still immediately below the tab indicators.
226  EXPECT_EQ(GetRectInWidget(browser_view).y() + Tab::GetImmersiveHeight(),
227            GetRectInWidget(contents_web_view).y());
228  // Overlay web view (with suggestions) aligns with the bottom of the omnibox.
229  OverlayContainer* overlay_container =
230      browser_view->GetOverlayContainerForTest();
231  gfx::Rect overlay_rect_in_widget = GetRectInWidget(
232      overlay_container->GetOverlayWebViewForTest());
233  EXPECT_EQ(GetRectInWidget(toolbar).bottom(), overlay_rect_in_widget.y());
234
235  // Overlay container layer is on top of top container layer, so that it
236  // paints over the bookmark bar and bottom of toolbar.
237  ui::Layer* top_container_layer = browser_view->top_container()->layer();
238  if (top_container_layer != NULL) {
239    ui::Layer* overlay_container_layer = overlay_container->layer();
240    EXPECT_TRUE(overlay_container_layer != NULL);
241    if (overlay_container_layer && overlay_container_layer->parent()) {
242      const std::vector<ui::Layer*>& children =
243          overlay_container_layer->parent()->children();
244      size_t top_index =
245          std::find(children.begin(), children.end(), top_container_layer) -
246              children.begin();
247      size_t overlay_index =
248          std::find(children.begin(), children.end(), overlay_container_layer) -
249              children.begin();
250      EXPECT_TRUE(overlay_index > top_index);
251    }
252  }
253
254  ////////////////////////////////////////////////////////////////////////////
255  // Test suggestions on the NTP, which are not in an overlay.
256
257  // Navigate to the Instant NTP, and wait for it to be recognized.
258  content::WindowedNotificationObserver instant_tab_observer(
259      chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED,
260      content::NotificationService::AllSources());
261  ui_test_utils::NavigateToURLWithDisposition(browser(),
262                                              GURL(chrome::kChromeUINewTabURL),
263                                              CURRENT_TAB,
264                                              ui_test_utils::BROWSER_TEST_NONE);
265  instant_tab_observer.Wait();
266
267  // Type in the omnibox, which should generate suggestions in the main page
268  // contents.
269  SetOmniboxText("claus");
270  // The autocomplete controller isn't done until all the providers are done.
271  // Though we don't care about the SearchProvider when we send autocomplete
272  // results to the page, we do need to cause it to be "done" to make this test
273  // work. Setting the suggestion calls SearchProvider::FinalizeInstantQuery(),
274  // thus causing it to be done.
275  omnibox()->model()->SetInstantSuggestion(
276      InstantSuggestion(ASCIIToUTF16("query"),
277                        INSTANT_COMPLETE_NOW,
278                        INSTANT_SUGGESTION_SEARCH,
279                        ASCIIToUTF16("query"),
280                        kNoMatchIndex));
281  while (!omnibox()->model()->autocomplete_controller()->done()) {
282    content::WindowedNotificationObserver autocomplete_observer(
283        chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
284        content::NotificationService::AllSources());
285    autocomplete_observer.Wait();
286  }
287  // Ensure JavaScript has finished running by executing a blank script.
288  EXPECT_TRUE(ExecuteScript(std::string()));
289  // We're still revealed, since focus is in the omnibox.
290  EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed());
291  // The active web contents are aligned with the toolbar.
292  gfx::Rect web_view_rect_in_widget = GetRectInWidget(
293      browser_view->GetContentsContainerForTest()->GetActiveWebViewForTest());
294  EXPECT_EQ(GetRectInWidget(toolbar).bottom(), web_view_rect_in_widget.y());
295
296  BookmarkBarView::DisableAnimationsForTesting(false);
297}
298
299#endif  // defined(OS_CHROMEOS)
300#endif  // defined(HTML_INSTANT_EXTENDED_POPUP)
301