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.
5 #include "chrome/browser/ui/views/frame/browser_view.h"
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"
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(),
33 return tabstrip_origin
;
38 typedef TestWithBrowserView BrowserViewTest
;
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());
45 EXPECT_TRUE(browser_view()->browser());
47 // Test initial state.
48 EXPECT_TRUE(browser_view()->IsTabStripVisible());
49 EXPECT_FALSE(browser_view()->IsOffTheRecord());
50 EXPECT_FALSE(browser_view()->IsGuestSession());
51 EXPECT_FALSE(browser_view()->ShouldShowAvatar());
52 EXPECT_TRUE(browser_view()->IsBrowserTypeNormal());
53 EXPECT_FALSE(browser_view()->IsFullscreen());
54 EXPECT_FALSE(browser_view()->IsBookmarkBarVisible());
55 EXPECT_FALSE(browser_view()->IsBookmarkBarAnimating());
58 // Test layout of the top-of-window UI.
59 TEST_F(BrowserViewTest
, BrowserViewLayout
) {
60 BookmarkBarView::DisableAnimationsForTesting(true);
62 // |browser_view_| owns the Browser, not the test class.
63 Browser
* browser
= browser_view()->browser();
64 TopContainerView
* top_container
= browser_view()->top_container();
65 TabStrip
* tabstrip
= browser_view()->tabstrip();
66 ToolbarView
* toolbar
= browser_view()->toolbar();
67 views::View
* contents_container
=
68 browser_view()->GetContentsContainerForTest();
69 views::WebView
* contents_web_view
=
70 browser_view()->GetContentsWebViewForTest();
71 views::WebView
* devtools_web_view
=
72 browser_view()->GetDevToolsWebViewForTest();
74 // Start with a single tab open to a normal page.
75 AddTab(browser
, GURL("about:blank"));
77 // Verify the view hierarchy.
78 EXPECT_EQ(top_container
, browser_view()->tabstrip()->parent());
79 EXPECT_EQ(top_container
, browser_view()->toolbar()->parent());
80 EXPECT_EQ(top_container
, browser_view()->GetBookmarkBarView()->parent());
81 EXPECT_EQ(browser_view(), browser_view()->infobar_container()->parent());
83 // Find bar host is at the front of the view hierarchy, followed by the top
85 EXPECT_EQ(browser_view()->child_count() - 1,
86 browser_view()->GetIndexOf(browser_view()->find_bar_host_view()));
87 EXPECT_EQ(browser_view()->child_count() - 2,
88 browser_view()->GetIndexOf(top_container
));
90 // Verify basic layout.
91 EXPECT_EQ(0, top_container
->x());
92 EXPECT_EQ(0, top_container
->y());
93 EXPECT_EQ(browser_view()->width(), top_container
->width());
94 // Tabstrip layout varies based on window frame sizes.
95 gfx::Point expected_tabstrip_origin
= ExpectedTabStripOrigin(browser_view());
96 EXPECT_EQ(expected_tabstrip_origin
.x(), tabstrip
->x());
97 EXPECT_EQ(expected_tabstrip_origin
.y(), tabstrip
->y());
98 EXPECT_EQ(0, toolbar
->x());
100 tabstrip
->bounds().bottom() -
101 BrowserViewLayout::kToolbarTabStripVerticalOverlap
,
103 EXPECT_EQ(0, contents_container
->x());
104 EXPECT_EQ(toolbar
->bounds().bottom(), contents_container
->y());
105 EXPECT_EQ(top_container
->bounds().bottom(), contents_container
->y());
106 EXPECT_EQ(0, devtools_web_view
->x());
107 EXPECT_EQ(0, devtools_web_view
->y());
108 EXPECT_EQ(0, contents_web_view
->x());
109 EXPECT_EQ(0, contents_web_view
->y());
111 // Verify bookmark bar visibility.
112 BookmarkBarView
* bookmark_bar
= browser_view()->GetBookmarkBarView();
113 EXPECT_FALSE(bookmark_bar
->visible());
114 EXPECT_FALSE(bookmark_bar
->IsDetached());
115 chrome::ExecuteCommand(browser
, IDC_SHOW_BOOKMARK_BAR
);
116 EXPECT_TRUE(bookmark_bar
->visible());
117 EXPECT_FALSE(bookmark_bar
->IsDetached());
118 chrome::ExecuteCommand(browser
, IDC_SHOW_BOOKMARK_BAR
);
119 EXPECT_FALSE(bookmark_bar
->visible());
120 EXPECT_FALSE(bookmark_bar
->IsDetached());
122 // Bookmark bar is reparented to BrowserView on NTP.
123 NavigateAndCommitActiveTabWithTitle(browser
,
124 GURL(chrome::kChromeUINewTabURL
),
126 EXPECT_TRUE(bookmark_bar
->visible());
127 EXPECT_TRUE(bookmark_bar
->IsDetached());
128 EXPECT_EQ(browser_view(), bookmark_bar
->parent());
129 // Find bar host is still at the front of the view hierarchy, followed by
130 // the top container.
131 EXPECT_EQ(browser_view()->child_count() - 1,
132 browser_view()->GetIndexOf(browser_view()->find_bar_host_view()));
133 EXPECT_EQ(browser_view()->child_count() - 2,
134 browser_view()->GetIndexOf(top_container
));
136 // Bookmark bar layout on NTP.
137 EXPECT_EQ(0, bookmark_bar
->x());
139 tabstrip
->bounds().bottom() +
141 BrowserViewLayout::kToolbarTabStripVerticalOverlap
-
142 views::NonClientFrameView::kClientEdgeThickness
,
144 EXPECT_EQ(toolbar
->bounds().bottom(), contents_container
->y());
145 // Contents view has a "top margin" pushing it below the bookmark bar.
146 EXPECT_EQ(bookmark_bar
->height() -
147 views::NonClientFrameView::kClientEdgeThickness
,
148 devtools_web_view
->y());
149 EXPECT_EQ(bookmark_bar
->height() -
150 views::NonClientFrameView::kClientEdgeThickness
,
151 contents_web_view
->y());
153 // Bookmark bar is parented back to top container on normal page.
154 NavigateAndCommitActiveTabWithTitle(browser
,
157 EXPECT_FALSE(bookmark_bar
->visible());
158 EXPECT_FALSE(bookmark_bar
->IsDetached());
159 EXPECT_EQ(top_container
, bookmark_bar
->parent());
160 // Top container is still second from front.
161 EXPECT_EQ(browser_view()->child_count() - 2,
162 browser_view()->GetIndexOf(top_container
));
164 BookmarkBarView::DisableAnimationsForTesting(false);
167 class BrowserViewHostedAppTest
: public TestWithBrowserView
{
169 BrowserViewHostedAppTest()
170 : TestWithBrowserView(Browser::TYPE_POPUP
,
171 chrome::HOST_DESKTOP_TYPE_NATIVE
,
174 virtual ~BrowserViewHostedAppTest() {
178 DISALLOW_COPY_AND_ASSIGN(BrowserViewHostedAppTest
);
181 // Test basic layout for hosted apps.
182 TEST_F(BrowserViewHostedAppTest
, Layout
) {
183 // Add a tab because the browser starts out without any tabs at all.
184 AddTab(browser(), GURL("about:blank"));
186 views::View
* contents_container
=
187 browser_view()->GetContentsContainerForTest();
189 // The tabstrip, toolbar and bookmark bar should not be visible for hosted
191 EXPECT_FALSE(browser_view()->tabstrip()->visible());
192 EXPECT_FALSE(browser_view()->toolbar()->visible());
193 EXPECT_FALSE(browser_view()->IsBookmarkBarVisible());
195 gfx::Point header_offset
;
196 views::View::ConvertPointToTarget(
198 browser_view()->frame()->non_client_view()->frame_view(),
201 // The position of the bottom of the header (the bar with the window
202 // controls) in the coordinates of BrowserView.
203 int bottom_of_header
= browser_view()->frame()->GetTopInset() -
206 // The web contents should be flush with the bottom of the header.
207 EXPECT_EQ(bottom_of_header
, contents_container
->y());
209 // The find bar should overlap the 1px header/web-contents separator at the
210 // bottom of the header.
211 EXPECT_EQ(browser_view()->frame()->GetTopInset() - 1,
212 browser_view()->GetFindBarBoundingBox().y());