Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / frame / browser_view_unittest.cc
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 "chrome/browser/ui/views/frame/browser_view.h"
6
7 #include "chrome/app/chrome_command_ids.h"
8 #include "chrome/browser/ui/browser_commands.h"
9 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
10 #include "chrome/browser/ui/views/frame/browser_view_layout.h"
11 #include "chrome/browser/ui/views/frame/test_with_browser_view.h"
12 #include "chrome/browser/ui/views/frame/top_container_view.h"
13 #include "chrome/browser/ui/views/infobars/infobar_container_view.h"
14 #include "chrome/browser/ui/views/tabs/tab_strip.h"
15 #include "chrome/browser/ui/views/toolbar/toolbar_view.h"
16 #include "chrome/common/url_constants.h"
17 #include "grit/generated_resources.h"
18 #include "grit/theme_resources.h"
19 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/views/controls/single_split_view.h"
21 #include "ui/views/controls/webview/webview.h"
22
23 namespace {
24
25 // Tab strip bounds depend on the window frame sizes.
26 gfx::Point ExpectedTabStripOrigin(BrowserView* browser_view) {
27   gfx::Rect tabstrip_bounds(
28       browser_view->frame()->GetBoundsForTabStrip(browser_view->tabstrip()));
29   gfx::Point tabstrip_origin(tabstrip_bounds.origin());
30   views::View::ConvertPointToTarget(browser_view->parent(),
31                                     browser_view,
32                                     &tabstrip_origin);
33   return tabstrip_origin;
34 }
35
36 }  // namespace
37
38 typedef TestWithBrowserView BrowserViewTest;
39
40 // Test basic construction and initialization.
41 TEST_F(BrowserViewTest, BrowserView) {
42   // The window is owned by the native widget, not the test class.
43   EXPECT_FALSE(window());
44
45   EXPECT_TRUE(browser_view()->browser());
46
47   // Test initial state.
48   EXPECT_TRUE(browser_view()->IsTabStripVisible());
49   EXPECT_FALSE(browser_view()->IsOffTheRecord());
50   EXPECT_EQ(IDR_OTR_ICON, browser_view()->GetOTRIconResourceID());
51   EXPECT_FALSE(browser_view()->IsGuestSession());
52   EXPECT_FALSE(browser_view()->ShouldShowAvatar());
53   EXPECT_TRUE(browser_view()->IsBrowserTypeNormal());
54   EXPECT_FALSE(browser_view()->IsFullscreen());
55   EXPECT_FALSE(browser_view()->IsBookmarkBarVisible());
56   EXPECT_FALSE(browser_view()->IsBookmarkBarAnimating());
57 }
58
59 // Test layout of the top-of-window UI.
60 TEST_F(BrowserViewTest, BrowserViewLayout) {
61   BookmarkBarView::DisableAnimationsForTesting(true);
62
63   // |browser_view_| owns the Browser, not the test class.
64   Browser* browser = browser_view()->browser();
65   TopContainerView* top_container = browser_view()->top_container();
66   TabStrip* tabstrip = browser_view()->tabstrip();
67   ToolbarView* toolbar = browser_view()->toolbar();
68   views::View* contents_container =
69       browser_view()->GetContentsContainerForTest();
70   views::WebView* contents_web_view =
71       browser_view()->GetContentsWebViewForTest();
72   views::WebView* devtools_web_view =
73       browser_view()->GetDevToolsWebViewForTest();
74
75   // Start with a single tab open to a normal page.
76   AddTab(browser, GURL("about:blank"));
77
78   // Verify the view hierarchy.
79   EXPECT_EQ(top_container, browser_view()->tabstrip()->parent());
80   EXPECT_EQ(top_container, browser_view()->toolbar()->parent());
81   EXPECT_EQ(top_container, browser_view()->GetBookmarkBarView()->parent());
82   EXPECT_EQ(browser_view(), browser_view()->infobar_container()->parent());
83
84   // Find bar host is at the front of the view hierarchy, followed by the top
85   // container.
86   EXPECT_EQ(browser_view()->child_count() - 1,
87             browser_view()->GetIndexOf(browser_view()->find_bar_host_view()));
88   EXPECT_EQ(browser_view()->child_count() - 2,
89             browser_view()->GetIndexOf(top_container));
90
91   // Verify basic layout.
92   EXPECT_EQ(0, top_container->x());
93   EXPECT_EQ(0, top_container->y());
94   EXPECT_EQ(browser_view()->width(), top_container->width());
95   // Tabstrip layout varies based on window frame sizes.
96   gfx::Point expected_tabstrip_origin = ExpectedTabStripOrigin(browser_view());
97   EXPECT_EQ(expected_tabstrip_origin.x(), tabstrip->x());
98   EXPECT_EQ(expected_tabstrip_origin.y(), tabstrip->y());
99   EXPECT_EQ(0, toolbar->x());
100   EXPECT_EQ(
101       tabstrip->bounds().bottom() -
102           BrowserViewLayout::kToolbarTabStripVerticalOverlap,
103       toolbar->y());
104   EXPECT_EQ(0, contents_container->x());
105   EXPECT_EQ(toolbar->bounds().bottom(), contents_container->y());
106   EXPECT_EQ(top_container->bounds().bottom(), contents_container->y());
107   EXPECT_EQ(0, devtools_web_view->x());
108   EXPECT_EQ(0, devtools_web_view->y());
109   EXPECT_EQ(0, contents_web_view->x());
110   EXPECT_EQ(0, contents_web_view->y());
111
112   // Verify bookmark bar visibility.
113   BookmarkBarView* bookmark_bar = browser_view()->GetBookmarkBarView();
114   EXPECT_FALSE(bookmark_bar->visible());
115   EXPECT_FALSE(bookmark_bar->IsDetached());
116   chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR);
117   EXPECT_TRUE(bookmark_bar->visible());
118   EXPECT_FALSE(bookmark_bar->IsDetached());
119   chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR);
120   EXPECT_FALSE(bookmark_bar->visible());
121   EXPECT_FALSE(bookmark_bar->IsDetached());
122
123   // Bookmark bar is reparented to BrowserView on NTP.
124   NavigateAndCommitActiveTabWithTitle(browser,
125                                       GURL(chrome::kChromeUINewTabURL),
126                                       base::string16());
127   EXPECT_TRUE(bookmark_bar->visible());
128   EXPECT_TRUE(bookmark_bar->IsDetached());
129   EXPECT_EQ(browser_view(), bookmark_bar->parent());
130   // Find bar host is still at the front of the view hierarchy, followed by
131   // the top container.
132   EXPECT_EQ(browser_view()->child_count() - 1,
133             browser_view()->GetIndexOf(browser_view()->find_bar_host_view()));
134   EXPECT_EQ(browser_view()->child_count() - 2,
135             browser_view()->GetIndexOf(top_container));
136
137   // Bookmark bar layout on NTP.
138   EXPECT_EQ(0, bookmark_bar->x());
139   EXPECT_EQ(
140       tabstrip->bounds().bottom() +
141           toolbar->height() -
142           BrowserViewLayout::kToolbarTabStripVerticalOverlap -
143           views::NonClientFrameView::kClientEdgeThickness,
144       bookmark_bar->y());
145   EXPECT_EQ(toolbar->bounds().bottom(), contents_container->y());
146   // Contents view has a "top margin" pushing it below the bookmark bar.
147   EXPECT_EQ(bookmark_bar->height() -
148                 views::NonClientFrameView::kClientEdgeThickness,
149             devtools_web_view->y());
150   EXPECT_EQ(bookmark_bar->height() -
151                 views::NonClientFrameView::kClientEdgeThickness,
152             contents_web_view->y());
153
154   // Bookmark bar is parented back to top container on normal page.
155   NavigateAndCommitActiveTabWithTitle(browser,
156                                       GURL("about:blank"),
157                                       base::string16());
158   EXPECT_FALSE(bookmark_bar->visible());
159   EXPECT_FALSE(bookmark_bar->IsDetached());
160   EXPECT_EQ(top_container, bookmark_bar->parent());
161   // Top container is still second from front.
162   EXPECT_EQ(browser_view()->child_count() - 2,
163             browser_view()->GetIndexOf(top_container));
164
165   BookmarkBarView::DisableAnimationsForTesting(false);
166 }
167
168 class BrowserViewHostedAppTest : public TestWithBrowserView {
169  public:
170   BrowserViewHostedAppTest()
171       : TestWithBrowserView(Browser::TYPE_POPUP,
172                             chrome::HOST_DESKTOP_TYPE_NATIVE,
173                             true) {
174   }
175   virtual ~BrowserViewHostedAppTest() {
176   }
177
178  private:
179   DISALLOW_COPY_AND_ASSIGN(BrowserViewHostedAppTest);
180 };
181
182 // Test basic layout for hosted apps.
183 TEST_F(BrowserViewHostedAppTest, Layout) {
184   // Add a tab because the browser starts out without any tabs at all.
185   AddTab(browser(), GURL("about:blank"));
186
187   views::View* contents_container =
188       browser_view()->GetContentsContainerForTest();
189
190   // The tabstrip, toolbar and bookmark bar should not be visible for hosted
191   // apps.
192   EXPECT_FALSE(browser_view()->tabstrip()->visible());
193   EXPECT_FALSE(browser_view()->toolbar()->visible());
194   EXPECT_FALSE(browser_view()->IsBookmarkBarVisible());
195
196   gfx::Point header_offset;
197   views::View::ConvertPointToTarget(
198       browser_view(),
199       browser_view()->frame()->non_client_view()->frame_view(),
200       &header_offset);
201
202   // The position of the bottom of the header (the bar with the window
203   // controls) in the coordinates of BrowserView.
204   int bottom_of_header = browser_view()->frame()->GetTopInset() -
205       header_offset.y();
206
207   // The web contents should be flush with the bottom of the header.
208   EXPECT_EQ(bottom_of_header, contents_container->y());
209
210   // The find bar should overlap the 1px header/web-contents separator at the
211   // bottom of the header.
212   EXPECT_EQ(browser_view()->frame()->GetTopInset() - 1,
213             browser_view()->GetFindBarBoundingBox().y());
214 }
215
216 #if defined(OS_WIN)
217
218 // This class provides functionality to test the incognito window/normal window
219 // switcher button which is added to Windows 8 metro Chrome.
220 // We create the BrowserView ourselves in the
221 // BrowserWithTestWindowTest::CreateBrowserWindow function override and add the
222 // switcher button to the view. We also provide an incognito profile to ensure
223 // that the switcher button is visible.
224 class BrowserViewIncognitoSwitcherTest : public TestWithBrowserView {
225  public:
226   // Subclass of BrowserView, which overrides the GetRestoreBounds/IsMaximized
227   // functions to return dummy values. This is needed because we create the
228   // BrowserView instance ourselves and initialize it with the created Browser
229   // instance. These functions get called before the underlying Widget is
230   // initialized which causes a crash while dereferencing a null native_widget_
231   // pointer in the Widget class.
232   class TestBrowserView : public BrowserView {
233    public:
234     virtual ~TestBrowserView() {}
235
236     virtual gfx::Rect GetRestoredBounds() const OVERRIDE {
237       return gfx::Rect();
238     }
239     virtual bool IsMaximized() const OVERRIDE {
240       return false;
241     }
242   };
243
244   BrowserViewIncognitoSwitcherTest()
245       : browser_view_(NULL) {}
246
247   virtual void SetUp() OVERRIDE {
248     TestWithBrowserView::SetUp();
249     browser_view_->Init(browser());
250     (new BrowserFrame(browser_view_))->InitBrowserFrame();
251     browser_view_->SetBounds(gfx::Rect(10, 10, 500, 500));
252     browser_view_->Show();
253   }
254
255   virtual void TearDown() OVERRIDE {
256     // ok to release the window_ pointer because BrowserViewTest::TearDown
257     // deletes the BrowserView instance created.
258     release_browser_window();
259     BrowserViewTest::TearDown();
260     browser_view_ = NULL;
261   }
262
263   virtual BrowserWindow* CreateBrowserWindow() OVERRIDE {
264     // We need an incognito profile for the window switcher button to be
265     // visible.
266     // This profile instance is owned by the TestingProfile instance within the
267     // BrowserWithTestWindowTest class.
268     TestingProfile::Builder builder;
269     builder.SetIncognito();
270     GetProfile()->SetOffTheRecordProfile(builder.Build());
271
272     browser_view_ = new TestBrowserView();
273
274     views::ImageButton* switcher_button = new views::ImageButton(NULL);
275     // The button in the incognito window has the hot-cold images inverted
276     // with respect to the regular browser window.
277     switcher_button->SetImage(
278         views::ImageButton::STATE_NORMAL,
279         ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
280             IDR_INCOGNITO_SWITCH_OFF));
281     switcher_button->SetImage(
282         views::ImageButton::STATE_HOVERED,
283         ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
284             IDR_INCOGNITO_SWITCH_ON));
285     switcher_button->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
286                                         views::ImageButton::ALIGN_MIDDLE);
287
288     browser_view_->SetWindowSwitcherButton(switcher_button);
289     return browser_view_;
290   }
291
292  private:
293   BrowserView* browser_view_;
294
295   DISALLOW_COPY_AND_ASSIGN(BrowserViewIncognitoSwitcherTest);
296 };
297
298 // Test whether the windows incognito/normal browser window switcher button
299 // is the event handler for a point within its bounds. The event handler for
300 // a point in the View class is dependent on the order in which children are
301 // added to it. This test ensures that we don't regress in the window switcher
302 // functionality when additional children are added to the BrowserView class.
303 TEST_F(BrowserViewIncognitoSwitcherTest,
304        BrowserViewIncognitoSwitcherEventHandlerTest) {
305   // |browser_view_| owns the Browser, not the test class.
306   EXPECT_TRUE(browser_view()->browser());
307   // Test initial state.
308   EXPECT_TRUE(browser_view()->IsTabStripVisible());
309   // Validate whether the window switcher button is the target for the position
310   // passed in.
311   gfx::Point switcher_point(browser_view()->window_switcher_button()->x() + 2,
312                             browser_view()->window_switcher_button()->y());
313   EXPECT_EQ(browser_view()->GetEventHandlerForPoint(switcher_point),
314             browser_view()->window_switcher_button());
315 }
316 #endif