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 "ui/views/controls/single_split_view.h" 18#include "ui/views/controls/webview/webview.h" 19 20namespace { 21 22// Tab strip bounds depend on the window frame sizes. 23gfx::Point ExpectedTabStripOrigin(BrowserView* browser_view) { 24 gfx::Rect tabstrip_bounds( 25 browser_view->frame()->GetBoundsForTabStrip(browser_view->tabstrip())); 26 gfx::Point tabstrip_origin(tabstrip_bounds.origin()); 27 views::View::ConvertPointToTarget(browser_view->parent(), 28 browser_view, 29 &tabstrip_origin); 30 return tabstrip_origin; 31} 32 33} // namespace 34 35typedef TestWithBrowserView BrowserViewTest; 36 37// Test basic construction and initialization. 38TEST_F(BrowserViewTest, BrowserView) { 39 // The window is owned by the native widget, not the test class. 40 EXPECT_FALSE(window()); 41 42 EXPECT_TRUE(browser_view()->browser()); 43 44 // Test initial state. 45 EXPECT_TRUE(browser_view()->IsTabStripVisible()); 46 EXPECT_FALSE(browser_view()->IsOffTheRecord()); 47 EXPECT_FALSE(browser_view()->IsGuestSession()); 48 EXPECT_FALSE(browser_view()->ShouldShowAvatar()); 49 EXPECT_TRUE(browser_view()->IsBrowserTypeNormal()); 50 EXPECT_FALSE(browser_view()->IsFullscreen()); 51 EXPECT_FALSE(browser_view()->IsBookmarkBarVisible()); 52 EXPECT_FALSE(browser_view()->IsBookmarkBarAnimating()); 53} 54 55// Test layout of the top-of-window UI. 56TEST_F(BrowserViewTest, BrowserViewLayout) { 57 BookmarkBarView::DisableAnimationsForTesting(true); 58 59 // |browser_view_| owns the Browser, not the test class. 60 Browser* browser = browser_view()->browser(); 61 TopContainerView* top_container = browser_view()->top_container(); 62 TabStrip* tabstrip = browser_view()->tabstrip(); 63 ToolbarView* toolbar = browser_view()->toolbar(); 64 views::View* contents_container = 65 browser_view()->GetContentsContainerForTest(); 66 views::WebView* contents_web_view = 67 browser_view()->GetContentsWebViewForTest(); 68 views::WebView* devtools_web_view = 69 browser_view()->GetDevToolsWebViewForTest(); 70 71 // Start with a single tab open to a normal page. 72 AddTab(browser, GURL("about:blank")); 73 74 // Verify the view hierarchy. 75 EXPECT_EQ(top_container, browser_view()->tabstrip()->parent()); 76 EXPECT_EQ(top_container, browser_view()->toolbar()->parent()); 77 EXPECT_EQ(top_container, browser_view()->GetBookmarkBarView()->parent()); 78 EXPECT_EQ(browser_view(), browser_view()->infobar_container()->parent()); 79 80 // Find bar host is at the front of the view hierarchy, followed by the top 81 // container. 82 EXPECT_EQ(browser_view()->child_count() - 1, 83 browser_view()->GetIndexOf(browser_view()->find_bar_host_view())); 84 EXPECT_EQ(browser_view()->child_count() - 2, 85 browser_view()->GetIndexOf(top_container)); 86 87 // Verify basic layout. 88 EXPECT_EQ(0, top_container->x()); 89 EXPECT_EQ(0, top_container->y()); 90 EXPECT_EQ(browser_view()->width(), top_container->width()); 91 // Tabstrip layout varies based on window frame sizes. 92 gfx::Point expected_tabstrip_origin = ExpectedTabStripOrigin(browser_view()); 93 EXPECT_EQ(expected_tabstrip_origin.x(), tabstrip->x()); 94 EXPECT_EQ(expected_tabstrip_origin.y(), tabstrip->y()); 95 EXPECT_EQ(0, toolbar->x()); 96 EXPECT_EQ( 97 tabstrip->bounds().bottom() - 98 BrowserViewLayout::kToolbarTabStripVerticalOverlap, 99 toolbar->y()); 100 EXPECT_EQ(0, contents_container->x()); 101 EXPECT_EQ(toolbar->bounds().bottom(), contents_container->y()); 102 EXPECT_EQ(top_container->bounds().bottom(), contents_container->y()); 103 EXPECT_EQ(0, devtools_web_view->x()); 104 EXPECT_EQ(0, devtools_web_view->y()); 105 EXPECT_EQ(0, contents_web_view->x()); 106 EXPECT_EQ(0, contents_web_view->y()); 107 108 // Verify bookmark bar visibility. 109 BookmarkBarView* bookmark_bar = browser_view()->GetBookmarkBarView(); 110 EXPECT_FALSE(bookmark_bar->visible()); 111 EXPECT_FALSE(bookmark_bar->IsDetached()); 112 chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR); 113 EXPECT_TRUE(bookmark_bar->visible()); 114 EXPECT_FALSE(bookmark_bar->IsDetached()); 115 chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR); 116 EXPECT_FALSE(bookmark_bar->visible()); 117 EXPECT_FALSE(bookmark_bar->IsDetached()); 118 119 // Bookmark bar is reparented to BrowserView on NTP. 120 NavigateAndCommitActiveTabWithTitle(browser, 121 GURL(chrome::kChromeUINewTabURL), 122 base::string16()); 123 EXPECT_TRUE(bookmark_bar->visible()); 124 EXPECT_TRUE(bookmark_bar->IsDetached()); 125 EXPECT_EQ(browser_view(), bookmark_bar->parent()); 126 // Find bar host is still at the front of the view hierarchy, followed by 127 // the top container. 128 EXPECT_EQ(browser_view()->child_count() - 1, 129 browser_view()->GetIndexOf(browser_view()->find_bar_host_view())); 130 EXPECT_EQ(browser_view()->child_count() - 2, 131 browser_view()->GetIndexOf(top_container)); 132 133 // Bookmark bar layout on NTP. 134 EXPECT_EQ(0, bookmark_bar->x()); 135 EXPECT_EQ( 136 tabstrip->bounds().bottom() + 137 toolbar->height() - 138 BrowserViewLayout::kToolbarTabStripVerticalOverlap - 139 views::NonClientFrameView::kClientEdgeThickness, 140 bookmark_bar->y()); 141 EXPECT_EQ(toolbar->bounds().bottom(), contents_container->y()); 142 // Contents view has a "top margin" pushing it below the bookmark bar. 143 EXPECT_EQ(bookmark_bar->height() - 144 views::NonClientFrameView::kClientEdgeThickness, 145 devtools_web_view->y()); 146 EXPECT_EQ(bookmark_bar->height() - 147 views::NonClientFrameView::kClientEdgeThickness, 148 contents_web_view->y()); 149 150 // Bookmark bar is parented back to top container on normal page. 151 NavigateAndCommitActiveTabWithTitle(browser, 152 GURL("about:blank"), 153 base::string16()); 154 EXPECT_FALSE(bookmark_bar->visible()); 155 EXPECT_FALSE(bookmark_bar->IsDetached()); 156 EXPECT_EQ(top_container, bookmark_bar->parent()); 157 // Top container is still second from front. 158 EXPECT_EQ(browser_view()->child_count() - 2, 159 browser_view()->GetIndexOf(top_container)); 160 161 BookmarkBarView::DisableAnimationsForTesting(false); 162} 163 164class BrowserViewHostedAppTest : public TestWithBrowserView { 165 public: 166 BrowserViewHostedAppTest() 167 : TestWithBrowserView(Browser::TYPE_POPUP, 168 chrome::HOST_DESKTOP_TYPE_NATIVE, 169 true) { 170 } 171 virtual ~BrowserViewHostedAppTest() { 172 } 173 174 private: 175 DISALLOW_COPY_AND_ASSIGN(BrowserViewHostedAppTest); 176}; 177 178// Test basic layout for hosted apps. 179TEST_F(BrowserViewHostedAppTest, Layout) { 180 // Add a tab because the browser starts out without any tabs at all. 181 AddTab(browser(), GURL("about:blank")); 182 183 views::View* contents_container = 184 browser_view()->GetContentsContainerForTest(); 185 186 // The tabstrip, toolbar and bookmark bar should not be visible for hosted 187 // apps. 188 EXPECT_FALSE(browser_view()->tabstrip()->visible()); 189 EXPECT_FALSE(browser_view()->toolbar()->visible()); 190 EXPECT_FALSE(browser_view()->IsBookmarkBarVisible()); 191 192 gfx::Point header_offset; 193 views::View::ConvertPointToTarget( 194 browser_view(), 195 browser_view()->frame()->non_client_view()->frame_view(), 196 &header_offset); 197 198 // The position of the bottom of the header (the bar with the window 199 // controls) in the coordinates of BrowserView. 200 int bottom_of_header = browser_view()->frame()->GetTopInset() - 201 header_offset.y(); 202 203 // The web contents should be flush with the bottom of the header. 204 EXPECT_EQ(bottom_of_header, contents_container->y()); 205 206 // The find bar should overlap the 1px header/web-contents separator at the 207 // bottom of the header. 208 EXPECT_EQ(browser_view()->frame()->GetTopInset() - 1, 209 browser_view()->GetFindBarBoundingBox().y()); 210} 211