browser_view_unittest.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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_view.h"
16#include "chrome/common/url_constants.h"
17#include "grit/theme_resources.h"
18#include "ui/views/controls/single_split_view.h"
19#include "ui/views/controls/webview/webview.h"
20
21#if defined(OS_WIN)
22#include "chrome/browser/ui/views/frame/browser_frame_win.h"
23#endif
24
25namespace {
26
27// Tab strip bounds depend on the window frame sizes.
28gfx::Point ExpectedTabStripOrigin(BrowserView* browser_view) {
29  gfx::Rect tabstrip_bounds(
30      browser_view->frame()->GetBoundsForTabStrip(browser_view->tabstrip()));
31  gfx::Point tabstrip_origin(tabstrip_bounds.origin());
32  views::View::ConvertPointToTarget(browser_view->parent(),
33                                    browser_view,
34                                    &tabstrip_origin);
35  return tabstrip_origin;
36}
37
38}  // namespace
39
40typedef TestWithBrowserView BrowserViewTest;
41
42// Test basic construction and initialization.
43TEST_F(BrowserViewTest, BrowserView) {
44  // The window is owned by the native widget, not the test class.
45  EXPECT_FALSE(window());
46
47  EXPECT_TRUE(browser_view()->browser());
48
49  // Test initial state.
50  EXPECT_TRUE(browser_view()->IsTabStripVisible());
51  EXPECT_FALSE(browser_view()->IsOffTheRecord());
52  EXPECT_EQ(IDR_OTR_ICON, browser_view()->GetOTRIconResourceID());
53  EXPECT_FALSE(browser_view()->IsGuestSession());
54  EXPECT_FALSE(browser_view()->ShouldShowAvatar());
55  EXPECT_TRUE(browser_view()->IsBrowserTypeNormal());
56  EXPECT_FALSE(browser_view()->IsFullscreen());
57  EXPECT_FALSE(browser_view()->IsBookmarkBarVisible());
58  EXPECT_FALSE(browser_view()->IsBookmarkBarAnimating());
59}
60
61// Test layout of the top-of-window UI.
62TEST_F(BrowserViewTest, BrowserViewLayout) {
63  BookmarkBarView::DisableAnimationsForTesting(true);
64
65  // |browser_view_| owns the Browser, not the test class.
66  Browser* browser = browser_view()->browser();
67  TopContainerView* top_container = browser_view()->top_container();
68  TabStrip* tabstrip = browser_view()->tabstrip();
69  ToolbarView* toolbar = browser_view()->toolbar();
70  views::SingleSplitView* contents_split =
71      browser_view()->GetContentsSplitForTest();
72  views::WebView* contents_web_view =
73      browser_view()->GetContentsWebViewForTest();
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_split->x());
105  EXPECT_EQ(toolbar->bounds().bottom(), contents_split->y());
106  EXPECT_EQ(0, contents_web_view->x());
107  EXPECT_EQ(0, contents_web_view->y());
108
109  // Verify bookmark bar visibility.
110  BookmarkBarView* bookmark_bar = browser_view()->GetBookmarkBarView();
111  EXPECT_FALSE(bookmark_bar->visible());
112  EXPECT_FALSE(bookmark_bar->IsDetached());
113  chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR);
114  EXPECT_TRUE(bookmark_bar->visible());
115  EXPECT_FALSE(bookmark_bar->IsDetached());
116  chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR);
117  EXPECT_FALSE(bookmark_bar->visible());
118  EXPECT_FALSE(bookmark_bar->IsDetached());
119
120  // Bookmark bar is reparented to BrowserView on NTP.
121  NavigateAndCommitActiveTabWithTitle(browser,
122                                      GURL(chrome::kChromeUINewTabURL),
123                                      string16());
124  EXPECT_TRUE(bookmark_bar->visible());
125  EXPECT_TRUE(bookmark_bar->IsDetached());
126  EXPECT_EQ(browser_view(), bookmark_bar->parent());
127  // Find bar host is still at the front of the view hierarchy, followed by
128  // the top container.
129  EXPECT_EQ(browser_view()->child_count() - 1,
130            browser_view()->GetIndexOf(browser_view()->find_bar_host_view()));
131  EXPECT_EQ(browser_view()->child_count() - 2,
132            browser_view()->GetIndexOf(top_container));
133
134  // Bookmark bar layout on NTP.
135  EXPECT_EQ(0, bookmark_bar->x());
136  EXPECT_EQ(
137      tabstrip->bounds().bottom() +
138          toolbar->height() -
139          BrowserViewLayout::kToolbarTabStripVerticalOverlap -
140          views::NonClientFrameView::kClientEdgeThickness,
141      bookmark_bar->y());
142  EXPECT_EQ(toolbar->bounds().bottom(), contents_split->y());
143  // Contents view has a "top margin" pushing it below the bookmark bar.
144  EXPECT_EQ(bookmark_bar->height() -
145                views::NonClientFrameView::kClientEdgeThickness,
146            contents_web_view->y());
147
148  // Bookmark bar is parented back to top container on normal page.
149  NavigateAndCommitActiveTabWithTitle(browser,
150                                      GURL("about:blank"),
151                                      string16());
152  EXPECT_FALSE(bookmark_bar->visible());
153  EXPECT_FALSE(bookmark_bar->IsDetached());
154  EXPECT_EQ(top_container, bookmark_bar->parent());
155  // Top container is still second from front.
156  EXPECT_EQ(browser_view()->child_count() - 2,
157            browser_view()->GetIndexOf(top_container));
158
159  BookmarkBarView::DisableAnimationsForTesting(false);
160}
161
162#if defined(OS_WIN) && !defined(USE_AURA)
163
164// This class provides functionality to test the incognito window/normal window
165// switcher button which is added to Windows 8 metro Chrome.
166// We create the BrowserView ourselves in the
167// BrowserWithTestWindowTest::CreateBrowserWindow function override and add the
168// switcher button to the view. We also provide an incognito profile to ensure
169// that the switcher button is visible.
170class BrowserViewIncognitoSwitcherTest : public TestWithBrowserView {
171 public:
172  // Subclass of BrowserView, which overrides the GetRestoreBounds/IsMaximized
173  // functions to return dummy values. This is needed because we create the
174  // BrowserView instance ourselves and initialize it with the created Browser
175  // instance. These functions get called before the underlying Widget is
176  // initialized which causes a crash while dereferencing a null native_widget_
177  // pointer in the Widget class.
178  class TestBrowserView : public BrowserView {
179   public:
180    virtual ~TestBrowserView() {}
181
182    virtual gfx::Rect GetRestoredBounds() const OVERRIDE {
183      return gfx::Rect();
184    }
185    virtual bool IsMaximized() const OVERRIDE {
186      return false;
187    }
188  };
189
190  BrowserViewIncognitoSwitcherTest()
191      : browser_view_(NULL) {}
192
193  virtual void SetUp() OVERRIDE {
194    TestWithBrowserView::SetUp();
195    browser_view_->Init(browser());
196    (new BrowserFrame(browser_view_))->InitBrowserFrame();
197    browser_view_->SetBounds(gfx::Rect(10, 10, 500, 500));
198    browser_view_->Show();
199  }
200
201  virtual void TearDown() OVERRIDE {
202    // ok to release the window_ pointer because BrowserViewTest::TearDown
203    // deletes the BrowserView instance created.
204    release_browser_window();
205    BrowserViewTest::TearDown();
206    browser_view_ = NULL;
207  }
208
209  virtual BrowserWindow* CreateBrowserWindow() OVERRIDE {
210    // We need an incognito profile for the window switcher button to be
211    // visible.
212    // This profile instance is owned by the TestingProfile instance within the
213    // BrowserWithTestWindowTest class.
214    TestingProfile::Builder builder;
215    builder.SetIncognito();
216    GetProfile()->SetOffTheRecordProfile(builder.Build());
217
218    browser_view_ = new TestBrowserView();
219    browser_view_->SetWindowSwitcherButton(
220        MakeWindowSwitcherButton(NULL, false));
221    return browser_view_;
222  }
223
224 private:
225  BrowserView* browser_view_;
226
227  DISALLOW_COPY_AND_ASSIGN(BrowserViewIncognitoSwitcherTest);
228};
229
230// Test whether the windows incognito/normal browser window switcher button
231// is the event handler for a point within its bounds. The event handler for
232// a point in the View class is dependent on the order in which children are
233// added to it. This test ensures that we don't regress in the window switcher
234// functionality when additional children are added to the BrowserView class.
235TEST_F(BrowserViewIncognitoSwitcherTest,
236       BrowserViewIncognitoSwitcherEventHandlerTest) {
237  // |browser_view_| owns the Browser, not the test class.
238  EXPECT_FALSE(browser());
239  EXPECT_TRUE(browser_view()->browser());
240  // Test initial state.
241  EXPECT_TRUE(browser_view()->IsTabStripVisible());
242  // Validate whether the window switcher button is the target for the position
243  // passed in.
244  gfx::Point switcher_point(browser_view()->window_switcher_button()->x() + 2,
245                            browser_view()->window_switcher_button()->y());
246  EXPECT_EQ(browser_view()->GetEventHandlerForPoint(switcher_point),
247            browser_view()->window_switcher_button());
248}
249#endif
250