opaque_browser_frame_view_layout_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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/opaque_browser_frame_view_layout.h"
6
7#include "base/basictypes.h"
8#include "base/command_line.h"
9#include "base/strings/utf_string_conversions.h"
10#include "chrome/browser/ui/views/profiles/avatar_label.h"
11#include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
12#include "chrome/browser/ui/views/tab_icon_view.h"
13#include "chrome/browser/ui/views/tabs/tab.h"
14#include "chrome/common/chrome_switches.h"
15#include "components/signin/core/common/profile_management_switches.h"
16#include "ui/gfx/image/image_skia.h"
17#include "ui/gfx/image/image_skia_rep.h"
18#include "ui/gfx/text_constants.h"
19#include "ui/views/controls/button/image_button.h"
20#include "ui/views/controls/button/menu_button.h"
21#include "ui/views/controls/label.h"
22#include "ui/views/test/views_test_base.h"
23
24using views::Widget;
25
26namespace {
27
28const int kWidth = 500;
29
30class TestLayoutDelegate : public OpaqueBrowserFrameViewLayoutDelegate {
31 public:
32  enum WindowState {
33    STATE_NORMAL,
34    STATE_MAXIMIZED,
35    STATE_MINIMIZED,
36    STATE_FULLSCREEN
37  };
38
39  TestLayoutDelegate()
40      : show_avatar_(false),
41        show_caption_buttons_(true),
42        window_state_(STATE_NORMAL) {
43  }
44
45  virtual ~TestLayoutDelegate() {}
46
47  void SetWindowTitle(const base::string16& title) {
48    window_title_ = title;
49  }
50
51  void SetShouldShowAvatar(bool show_avatar) {
52    show_avatar_ = show_avatar;
53  }
54
55  void SetShouldShowCaptionButtons(bool show_caption_buttons) {
56    show_caption_buttons_ = show_caption_buttons;
57  }
58
59  void SetWindowState(WindowState state) {
60    window_state_ = state;
61  }
62
63  // OpaqueBrowserFrameViewLayoutDelegate overrides:
64
65  virtual bool ShouldShowWindowIcon() const OVERRIDE {
66    return !window_title_.empty();
67  }
68
69  virtual bool ShouldShowWindowTitle() const OVERRIDE {
70    return !window_title_.empty();
71  }
72
73  virtual base::string16 GetWindowTitle() const OVERRIDE {
74    return window_title_;
75  }
76
77  virtual int GetIconSize() const OVERRIDE {
78    // The value on linux_aura and non-aura windows.
79    return 17;
80  }
81
82  virtual bool ShouldLeaveOffsetNearTopBorder() const OVERRIDE {
83    return !IsMaximized();
84  }
85
86  virtual gfx::Size GetBrowserViewMinimumSize() const OVERRIDE {
87    // Taken from a calculation in BrowserViewLayout.
88    return gfx::Size(168, 64);
89  }
90
91  virtual bool ShouldShowCaptionButtons() const OVERRIDE {
92    return show_caption_buttons_;
93  }
94
95  virtual bool ShouldShowAvatar() const OVERRIDE {
96    return show_avatar_;
97  }
98
99  virtual bool IsRegularOrGuestSession() const OVERRIDE {
100    return true;
101  }
102
103  virtual gfx::ImageSkia GetOTRAvatarIcon() const OVERRIDE {
104    // The calculations depend on the size of the OTR resource, and chromeos
105    // uses a different sized image, so hard code the size of the current
106    // windows/linux one.
107    gfx::ImageSkiaRep rep(gfx::Size(40, 29), 1.0f);
108    gfx::ImageSkia image(rep);
109    return image;
110  }
111
112  virtual bool IsMaximized() const OVERRIDE {
113    return window_state_ == STATE_MAXIMIZED;
114  }
115
116  virtual bool IsMinimized() const OVERRIDE {
117    return window_state_ == STATE_MINIMIZED;
118  }
119
120  virtual bool IsFullscreen() const OVERRIDE {
121    return window_state_ == STATE_FULLSCREEN;
122  }
123
124  virtual bool IsTabStripVisible() const OVERRIDE {
125    return window_title_.empty();
126  }
127
128  virtual int GetTabStripHeight() const OVERRIDE {
129    return IsTabStripVisible() ? Tab::GetMinimumUnselectedSize().height() : 0;
130  }
131
132  virtual gfx::Size GetTabstripPreferredSize() const OVERRIDE {
133    // Measured from Tabstrip::GetPreferredSize().
134    return IsTabStripVisible() ? gfx::Size(78, 29) : gfx::Size(0, 0);
135  }
136
137 private:
138  base::string16 window_title_;
139  bool show_avatar_;
140  bool show_caption_buttons_;
141  WindowState window_state_;
142
143  DISALLOW_COPY_AND_ASSIGN(TestLayoutDelegate);
144};
145
146}  // namespace
147
148class OpaqueBrowserFrameViewLayoutTest : public views::ViewsTestBase {
149 public:
150  OpaqueBrowserFrameViewLayoutTest() {}
151  virtual ~OpaqueBrowserFrameViewLayoutTest() {}
152
153  virtual void SetUp() OVERRIDE {
154    views::ViewsTestBase::SetUp();
155
156    delegate_.reset(new TestLayoutDelegate);
157    layout_manager_ = new OpaqueBrowserFrameViewLayout(delegate_.get());
158    layout_manager_->set_extra_caption_y(0);
159    layout_manager_->set_window_caption_spacing(0);
160    widget_ = new Widget;
161    widget_->Init(CreateParams(Widget::InitParams::TYPE_POPUP));
162    root_view_ = widget_->GetRootView();
163    root_view_->SetSize(gfx::Size(kWidth, kWidth));
164    root_view_->SetLayoutManager(layout_manager_);
165
166    // Add the caption buttons. We use fake images because we're modeling the
167    // Windows assets here, while the linux version uses differently sized
168    // assets.
169    //
170    // TODO(erg): In a follow up patch, separate these sizes out into virtual
171    // accessors so we can test both the windows and linux behaviours once we
172    // start modifying the code.
173    minimize_button_ = InitWindowCaptionButton(
174        VIEW_ID_MINIMIZE_BUTTON, gfx::Size(26, 18));
175    maximize_button_ = InitWindowCaptionButton(
176        VIEW_ID_MAXIMIZE_BUTTON, gfx::Size(25, 18));
177    restore_button_ = InitWindowCaptionButton(
178        VIEW_ID_RESTORE_BUTTON, gfx::Size(25, 18));
179    close_button_ = InitWindowCaptionButton(
180        VIEW_ID_CLOSE_BUTTON, gfx::Size(43, 18));
181  }
182
183  virtual void TearDown() OVERRIDE {
184    widget_->CloseNow();
185
186    views::ViewsTestBase::TearDown();
187  }
188
189 protected:
190  views::ImageButton* InitWindowCaptionButton(ViewID view_id,
191                                              const gfx::Size& size) {
192    views::ImageButton* button = new views::ImageButton(NULL);
193    gfx::ImageSkiaRep rep(size, 1.0f);
194    gfx::ImageSkia image(rep);
195    button->SetImage(views::CustomButton::STATE_NORMAL, &image);
196    button->set_id(view_id);
197    root_view_->AddChildView(button);
198    return button;
199  }
200
201  void AddWindowTitleIcons() {
202    tab_icon_view_ = new TabIconView(NULL, NULL);
203    tab_icon_view_->set_is_light(true);
204    tab_icon_view_->set_id(VIEW_ID_WINDOW_ICON);
205    root_view_->AddChildView(tab_icon_view_);
206
207    window_title_ = new views::Label(delegate_->GetWindowTitle());
208    window_title_->SetVisible(delegate_->ShouldShowWindowTitle());
209    window_title_->SetEnabledColor(SK_ColorWHITE);
210    window_title_->SetSubpixelRenderingEnabled(false);
211    window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
212    window_title_->set_id(VIEW_ID_WINDOW_TITLE);
213    root_view_->AddChildView(window_title_);
214  }
215
216  void AddAvatarButton() {
217    menu_button_ = new AvatarMenuButton(NULL, false);
218    menu_button_->set_id(VIEW_ID_AVATAR_BUTTON);
219    delegate_->SetShouldShowAvatar(true);
220    root_view_->AddChildView(menu_button_);
221  }
222
223  void AddAvatarLabel() {
224    avatar_label_ = new AvatarLabel(NULL);
225    avatar_label_->set_id(VIEW_ID_AVATAR_LABEL);
226    root_view_->AddChildView(avatar_label_);
227
228    // The avatar label should only be used together with the avatar button.
229    AddAvatarButton();
230  }
231
232  void AddNewAvatarButton() {
233   new_avatar_button_ =
234       new views::MenuButton(NULL, base::string16(), NULL, false);
235   new_avatar_button_->set_id(VIEW_ID_NEW_AVATAR_BUTTON);
236   root_view_->AddChildView(new_avatar_button_);
237  }
238
239  void ExpectBasicWindowBounds() {
240    EXPECT_EQ("428,1 25x18", maximize_button_->bounds().ToString());
241    EXPECT_EQ("402,1 26x18", minimize_button_->bounds().ToString());
242    EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
243    EXPECT_EQ("453,1 43x18", close_button_->bounds().ToString());
244  }
245
246  Widget* widget_;
247  views::View* root_view_;
248  OpaqueBrowserFrameViewLayout* layout_manager_;
249  scoped_ptr<TestLayoutDelegate> delegate_;
250
251  // Widgets:
252  views::ImageButton* minimize_button_;
253  views::ImageButton* maximize_button_;
254  views::ImageButton* restore_button_;
255  views::ImageButton* close_button_;
256
257  TabIconView* tab_icon_view_;
258  views::Label* window_title_;
259
260  AvatarLabel* avatar_label_;
261  AvatarMenuButton* menu_button_;
262  views::MenuButton* new_avatar_button_;
263
264  DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayoutTest);
265};
266
267TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindow) {
268  // Tests the layout of a default chrome window with no avatars, no window
269  // titles, and a tabstrip.
270  root_view_->Layout();
271
272  ExpectBasicWindowBounds();
273
274  // After some visual inspection, it really does look like the tabstrip is
275  // initally positioned out of our view.
276  EXPECT_EQ("-1,13 398x29",
277            layout_manager_->GetBoundsForTabStrip(
278                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
279  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
280
281  // A normal window with no window icon still produces icon bounds for
282  // Windows, which has a hidden icon that a user can double click on to close
283  // the window.
284  EXPECT_EQ("6,4 17x17", layout_manager_->IconBounds().ToString());
285}
286
287TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindowMaximized) {
288  // Tests the layout of a default chrome window with no avatars, no window
289  // titles, and a tabstrip, but maximized this time.
290  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
291  root_view_->Layout();
292
293  // Note how the bounds start at the exact top of the window while maximized
294  // while they start 1 pixel below when unmaximized.
295  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
296  EXPECT_EQ("403,0 26x18", minimize_button_->bounds().ToString());
297  EXPECT_EQ("429,0 25x18", restore_button_->bounds().ToString());
298  EXPECT_EQ("454,0 46x18", close_button_->bounds().ToString());
299
300  EXPECT_EQ("-5,-3 392x29",
301            layout_manager_->GetBoundsForTabStrip(
302                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
303  EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString());
304
305  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
306  // this rect, extended to the top left corner of the window.
307  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
308}
309
310TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithYOffset) {
311  // Tests the layout of a basic chrome window with the caption buttons slightly
312  // offset from the top of the screen (as they are on Linux).
313  layout_manager_->set_extra_caption_y(2);
314  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
315  root_view_->Layout();
316
317  // Note how the bounds start at the exact top of the window, DESPITE the
318  // caption Y offset of 2. This ensures that we obey Fitts' Law (the buttons
319  // are clickable on the top edge of the screen). However, the buttons are 2
320  // pixels taller, so the images appear to be offset by 2 pixels.
321  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
322  EXPECT_EQ("403,0 26x20", minimize_button_->bounds().ToString());
323  EXPECT_EQ("429,0 25x20", restore_button_->bounds().ToString());
324  EXPECT_EQ("454,0 46x20", close_button_->bounds().ToString());
325
326  EXPECT_EQ("-5,-3 392x29",
327            layout_manager_->GetBoundsForTabStrip(
328                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
329  EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString());
330
331  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
332  // this rect, extended to the top left corner of the window.
333  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
334}
335
336TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowButtonsOnLeft) {
337  // Tests the layout of a chrome window with caption buttons on the left.
338  std::vector<views::FrameButton> leading_buttons;
339  std::vector<views::FrameButton> trailing_buttons;
340  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
341  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
342  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
343  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
344  root_view_->Layout();
345
346  EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString());
347  EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString());
348  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
349  EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString());
350
351  EXPECT_EQ("93,13 398x29",
352            layout_manager_->GetBoundsForTabStrip(
353                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
354  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
355
356  // If the buttons are on the left, there should be no hidden icon for the user
357  // to double click.
358  EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString());
359}
360
361TEST_F(OpaqueBrowserFrameViewLayoutTest, WithoutCaptionButtons) {
362  // Tests the layout of a default chrome window with no caption buttons (which
363  // should force the tab strip to be condensed).
364  delegate_->SetShouldShowCaptionButtons(false);
365  root_view_->Layout();
366
367  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
368  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
369  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
370  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
371
372  EXPECT_EQ("-5,-3 500x29",
373            layout_manager_->GetBoundsForTabStrip(
374                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
375  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
376
377  // A normal window with no window icon still produces icon bounds for
378  // Windows, which has a hidden icon that a user can double click on to close
379  // the window.
380  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
381}
382
383TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithoutCaptionButtons) {
384  // Tests the layout of a maximized chrome window with no caption buttons.
385  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
386  delegate_->SetShouldShowCaptionButtons(false);
387  root_view_->Layout();
388
389  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
390  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
391  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
392  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
393
394  EXPECT_EQ("-5,-3 500x29",
395            layout_manager_->GetBoundsForTabStrip(
396                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
397  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
398
399  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
400  // this rect, extended to the top left corner of the window.
401  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
402}
403
404TEST_F(OpaqueBrowserFrameViewLayoutTest, WithWindowTitleAndIcon) {
405  // Tests the layout of pop up windows.
406  delegate_->SetWindowTitle(base::ASCIIToUTF16("Window Title"));
407  AddWindowTitleIcons();
408  root_view_->Layout();
409
410  // We should have the right hand side should match the BasicWindow case.
411  ExpectBasicWindowBounds();
412
413  // Check the location of the tab icon and window title.
414  EXPECT_EQ("6,3 17x17", tab_icon_view_->bounds().ToString());
415  EXPECT_EQ("27,3 370x17", window_title_->bounds().ToString());
416}
417
418TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatar) {
419  // Tests a normal tabstrip window with an avatar icon.
420  AddAvatarButton();
421  root_view_->Layout();
422
423  ExpectBasicWindowBounds();
424
425  // Check the location of the avatar
426  EXPECT_EQ("7,11 40x29", menu_button_->bounds().ToString());
427  EXPECT_EQ("45,13 352x29",
428            layout_manager_->GetBoundsForTabStrip(
429                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
430  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
431}
432
433TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatarWithButtonsOnLeft) {
434  // Tests the layout of a chrome window with an avatar icon and caption buttons
435  // on the left. The avatar icon should therefore be on the right.
436  // AddAvatarLabel() also adds the avatar button.
437  AddAvatarLabel();
438  std::vector<views::FrameButton> leading_buttons;
439  std::vector<views::FrameButton> trailing_buttons;
440  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
441  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
442  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
443  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
444  root_view_->Layout();
445
446  EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString());
447  EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString());
448  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
449  EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString());
450
451  // Check the location of the avatar
452  EXPECT_EQ("454,11 40x29", menu_button_->bounds().ToString());
453
454  // Check the tab strip bounds.
455  gfx::Rect tab_strip_bounds = layout_manager_->GetBoundsForTabStrip(
456      delegate_->GetTabstripPreferredSize(), kWidth);
457  EXPECT_GT(tab_strip_bounds.x(), maximize_button_->bounds().x());
458  EXPECT_GT(maximize_button_->bounds().right(), tab_strip_bounds.x());
459  EXPECT_EQ(13, tab_strip_bounds.y());
460  EXPECT_EQ(29, tab_strip_bounds.height());
461  EXPECT_GT(avatar_label_->bounds().x(), tab_strip_bounds.right());
462  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
463
464  // Check the relative location of the avatar label to the avatar. The right
465  // end of the avatar label should be slightly to the right of the right end of
466  // the avatar icon.
467  EXPECT_GT(avatar_label_->bounds().right(), menu_button_->bounds().right());
468  EXPECT_GT(menu_button_->bounds().x(), avatar_label_->bounds().x());
469  EXPECT_GT(menu_button_->bounds().bottom(),
470            avatar_label_->bounds().bottom());
471  EXPECT_GT(avatar_label_->bounds().y(), menu_button_->bounds().y());
472
473  // This means that the menu will pop out facing the left (if it were to face
474  // the right, it would go outside the window frame and be clipped).
475  EXPECT_TRUE(menu_button_->button_on_right());
476
477  // If the buttons are on the left, there should be no hidden icon for the user
478  // to double click.
479  EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString());
480}
481
482TEST_F(OpaqueBrowserFrameViewLayoutTest,
483       WindowWithAvatarWithoutCaptionButtonsOnLeft) {
484  // Tests the layout of a chrome window with an avatar icon and no caption
485  // buttons. However, the caption buttons *would* be on the left if they
486  // weren't hidden, and therefore, the avatar icon should be on the right.
487  // The lack of caption buttons should force the tab strip to be condensed.
488  AddAvatarButton();
489  std::vector<views::FrameButton> leading_buttons;
490  std::vector<views::FrameButton> trailing_buttons;
491  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
492  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
493  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
494  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
495  delegate_->SetShouldShowCaptionButtons(false);
496  root_view_->Layout();
497
498  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
499  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
500  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
501  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
502
503  // Check the location of the avatar
504  EXPECT_EQ("458,0 40x24", menu_button_->bounds().ToString());
505  EXPECT_EQ("-5,-3 458x29",
506            layout_manager_->GetBoundsForTabStrip(
507                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
508  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
509
510  // A normal window with no window icon still produces icon bounds for
511  // Windows, which has a hidden icon that a user can double click on to close
512  // the window.
513  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
514}
515
516TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithNewAvatar) {
517  switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
518
519  // Tests a normal tabstrip window with the new style avatar icon.
520  AddNewAvatarButton();
521  root_view_->Layout();
522
523  ExpectBasicWindowBounds();
524
525  // Check the location of the caption button
526  EXPECT_EQ("385,1 12x20", new_avatar_button_->bounds().ToString());
527  // The basic window bounds are (-1, 13 398x29). There should not be an icon
528  // avatar in the left, and the new avatar button has an offset of 5 to its
529  // next control.
530  EXPECT_EQ("-1,13 381x29",
531            layout_manager_->GetBoundsForTabStrip(
532                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
533  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
534}
535
536TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatarLabelAndButtonOnLeft) {
537  AddAvatarLabel();
538  root_view_->Layout();
539
540  ExpectBasicWindowBounds();
541
542  // Check the location of the avatar label relative to the avatar button if
543  // both are displayed on the left side.
544  // The label height and width depends on the font size and the text displayed.
545  // This may possibly change, so we don't test it here.
546  EXPECT_EQ(menu_button_->bounds().x() - 2, avatar_label_->bounds().x());
547  EXPECT_EQ(
548      menu_button_->bounds().bottom() - 3 - avatar_label_->bounds().height(),
549      avatar_label_->bounds().y());
550}
551