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/opaque_browser_frame_view_layout.h"
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_menu_button.h"
11 #include "chrome/browser/ui/views/tab_icon_view.h"
12 #include "chrome/browser/ui/views/tabs/tab.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "components/signin/core/common/profile_management_switches.h"
15 #include "ui/gfx/image/image_skia.h"
16 #include "ui/gfx/image/image_skia_rep.h"
17 #include "ui/gfx/text_constants.h"
18 #include "ui/views/controls/button/image_button.h"
19 #include "ui/views/controls/button/menu_button.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/test/views_test_base.h"
23 #if defined(ENABLE_SUPERVISED_USERS)
24 #include "chrome/browser/ui/views/profiles/supervised_user_avatar_label.h"
31 const int kWidth
= 500;
33 class TestLayoutDelegate
: public OpaqueBrowserFrameViewLayoutDelegate
{
43 : show_avatar_(false),
44 show_caption_buttons_(true),
45 window_state_(STATE_NORMAL
) {
48 ~TestLayoutDelegate() override
{}
50 void SetWindowTitle(const base::string16
& title
) {
51 window_title_
= title
;
54 void SetShouldShowAvatar(bool show_avatar
) {
55 show_avatar_
= show_avatar
;
58 void SetShouldShowCaptionButtons(bool show_caption_buttons
) {
59 show_caption_buttons_
= show_caption_buttons
;
62 void SetWindowState(WindowState state
) {
63 window_state_
= state
;
66 // OpaqueBrowserFrameViewLayoutDelegate overrides:
68 bool ShouldShowWindowIcon() const override
{ return !window_title_
.empty(); }
70 bool ShouldShowWindowTitle() const override
{ return !window_title_
.empty(); }
72 base::string16
GetWindowTitle() const override
{ return window_title_
; }
74 int GetIconSize() const override
{
75 // The value on linux_aura and non-aura windows.
79 bool ShouldLeaveOffsetNearTopBorder() const override
{
80 return !IsMaximized();
83 gfx::Size
GetBrowserViewMinimumSize() const override
{
84 // Taken from a calculation in BrowserViewLayout.
85 return gfx::Size(168, 64);
88 bool ShouldShowCaptionButtons() const override
{
89 return show_caption_buttons_
;
92 bool ShouldShowAvatar() const override
{ return show_avatar_
; }
94 bool IsRegularOrGuestSession() const override
{ return true; }
96 gfx::ImageSkia
GetOTRAvatarIcon() const override
{
97 // The calculations depend on the size of the OTR resource, and chromeos
98 // uses a different sized image, so hard code the size of the current
100 gfx::ImageSkiaRep
rep(gfx::Size(40, 29), 1.0f
);
101 gfx::ImageSkia
image(rep
);
105 bool IsMaximized() const override
{ return window_state_
== STATE_MAXIMIZED
; }
107 bool IsMinimized() const override
{ return window_state_
== STATE_MINIMIZED
; }
109 bool IsFullscreen() const override
{
110 return window_state_
== STATE_FULLSCREEN
;
113 bool IsTabStripVisible() const override
{ return window_title_
.empty(); }
115 int GetTabStripHeight() const override
{
116 return IsTabStripVisible() ? Tab::GetMinimumUnselectedSize().height() : 0;
119 gfx::Size
GetTabstripPreferredSize() const override
{
120 // Measured from Tabstrip::GetPreferredSize().
121 return IsTabStripVisible() ? gfx::Size(78, 29) : gfx::Size(0, 0);
125 base::string16 window_title_
;
127 bool show_caption_buttons_
;
128 WindowState window_state_
;
130 DISALLOW_COPY_AND_ASSIGN(TestLayoutDelegate
);
135 class OpaqueBrowserFrameViewLayoutTest
: public views::ViewsTestBase
{
137 OpaqueBrowserFrameViewLayoutTest() {}
138 ~OpaqueBrowserFrameViewLayoutTest() override
{}
140 void SetUp() override
{
141 views::ViewsTestBase::SetUp();
143 delegate_
.reset(new TestLayoutDelegate
);
144 layout_manager_
= new OpaqueBrowserFrameViewLayout(delegate_
.get());
145 layout_manager_
->set_extra_caption_y(0);
146 layout_manager_
->set_window_caption_spacing(0);
147 widget_
= new Widget
;
148 widget_
->Init(CreateParams(Widget::InitParams::TYPE_POPUP
));
149 root_view_
= widget_
->GetRootView();
150 root_view_
->SetSize(gfx::Size(kWidth
, kWidth
));
151 root_view_
->SetLayoutManager(layout_manager_
);
153 // Add the caption buttons. We use fake images because we're modeling the
154 // Windows assets here, while the linux version uses differently sized
157 // TODO(erg): In a follow up patch, separate these sizes out into virtual
158 // accessors so we can test both the windows and linux behaviours once we
159 // start modifying the code.
160 minimize_button_
= InitWindowCaptionButton(
161 VIEW_ID_MINIMIZE_BUTTON
, gfx::Size(26, 18));
162 maximize_button_
= InitWindowCaptionButton(
163 VIEW_ID_MAXIMIZE_BUTTON
, gfx::Size(25, 18));
164 restore_button_
= InitWindowCaptionButton(
165 VIEW_ID_RESTORE_BUTTON
, gfx::Size(25, 18));
166 close_button_
= InitWindowCaptionButton(
167 VIEW_ID_CLOSE_BUTTON
, gfx::Size(43, 18));
170 void TearDown() override
{
173 views::ViewsTestBase::TearDown();
177 views::ImageButton
* InitWindowCaptionButton(ViewID view_id
,
178 const gfx::Size
& size
) {
179 views::ImageButton
* button
= new views::ImageButton(nullptr);
180 gfx::ImageSkiaRep
rep(size
, 1.0f
);
181 gfx::ImageSkia
image(rep
);
182 button
->SetImage(views::CustomButton::STATE_NORMAL
, &image
);
183 button
->set_id(view_id
);
184 root_view_
->AddChildView(button
);
188 void AddWindowTitleIcons() {
189 tab_icon_view_
= new TabIconView(nullptr, nullptr);
190 tab_icon_view_
->set_is_light(true);
191 tab_icon_view_
->set_id(VIEW_ID_WINDOW_ICON
);
192 root_view_
->AddChildView(tab_icon_view_
);
194 window_title_
= new views::Label(delegate_
->GetWindowTitle());
195 window_title_
->SetVisible(delegate_
->ShouldShowWindowTitle());
196 window_title_
->SetEnabledColor(SK_ColorWHITE
);
197 window_title_
->SetSubpixelRenderingEnabled(false);
198 window_title_
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
199 window_title_
->set_id(VIEW_ID_WINDOW_TITLE
);
200 root_view_
->AddChildView(window_title_
);
203 void AddAvatarButton() {
204 // Disable the New Avatar Menu.
205 switches::DisableNewAvatarMenuForTesting(
206 base::CommandLine::ForCurrentProcess());
208 menu_button_
= new AvatarMenuButton(nullptr, false);
209 menu_button_
->set_id(VIEW_ID_AVATAR_BUTTON
);
210 delegate_
->SetShouldShowAvatar(true);
211 root_view_
->AddChildView(menu_button_
);
214 #if defined(ENABLE_SUPERVISED_USERS)
215 void AddSupervisedUserAvatarLabel() {
216 supervised_user_avatar_label_
= new SupervisedUserAvatarLabel(nullptr);
217 supervised_user_avatar_label_
->set_id(VIEW_ID_SUPERVISED_USER_AVATAR_LABEL
);
218 root_view_
->AddChildView(supervised_user_avatar_label_
);
220 // The avatar label should only be used together with the avatar button.
225 void AddNewAvatarButton() {
226 // Enable the New Avatar Menu.
227 switches::EnableNewAvatarMenuForTesting(
228 base::CommandLine::ForCurrentProcess());
231 new views::MenuButton(nullptr, base::string16(), nullptr, false);
232 new_avatar_button_
->set_id(VIEW_ID_NEW_AVATAR_BUTTON
);
233 root_view_
->AddChildView(new_avatar_button_
);
236 void ExpectBasicWindowBounds() {
237 EXPECT_EQ("428,1 25x18", maximize_button_
->bounds().ToString());
238 EXPECT_EQ("402,1 26x18", minimize_button_
->bounds().ToString());
239 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
240 EXPECT_EQ("453,1 43x18", close_button_
->bounds().ToString());
244 views::View
* root_view_
;
245 OpaqueBrowserFrameViewLayout
* layout_manager_
;
246 scoped_ptr
<TestLayoutDelegate
> delegate_
;
249 views::ImageButton
* minimize_button_
;
250 views::ImageButton
* maximize_button_
;
251 views::ImageButton
* restore_button_
;
252 views::ImageButton
* close_button_
;
254 TabIconView
* tab_icon_view_
;
255 views::Label
* window_title_
;
257 #if defined(ENABLE_SUPERVISED_USERS)
258 SupervisedUserAvatarLabel
* supervised_user_avatar_label_
;
260 AvatarMenuButton
* menu_button_
;
261 views::MenuButton
* new_avatar_button_
;
263 DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayoutTest
);
266 TEST_F(OpaqueBrowserFrameViewLayoutTest
, BasicWindow
) {
267 // Tests the layout of a default chrome window with no avatars, no window
268 // titles, and a tabstrip.
269 root_view_
->Layout();
271 ExpectBasicWindowBounds();
273 // After some visual inspection, it really does look like the tabstrip is
274 // initally positioned out of our view.
275 EXPECT_EQ("-1,13 398x29",
276 layout_manager_
->GetBoundsForTabStrip(
277 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
278 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
280 // A normal window with no window icon still produces icon bounds for
281 // Windows, which has a hidden icon that a user can double click on to close
283 EXPECT_EQ("6,4 17x17", layout_manager_
->IconBounds().ToString());
286 TEST_F(OpaqueBrowserFrameViewLayoutTest
, BasicWindowMaximized
) {
287 // Tests the layout of a default chrome window with no avatars, no window
288 // titles, and a tabstrip, but maximized this time.
289 delegate_
->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED
);
290 root_view_
->Layout();
292 // Note how the bounds start at the exact top of the window while maximized
293 // while they start 1 pixel below when unmaximized.
294 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
295 EXPECT_EQ("403,0 26x18", minimize_button_
->bounds().ToString());
296 EXPECT_EQ("429,0 25x18", restore_button_
->bounds().ToString());
297 EXPECT_EQ("454,0 46x18", close_button_
->bounds().ToString());
299 EXPECT_EQ("-5,-3 392x29",
300 layout_manager_
->GetBoundsForTabStrip(
301 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
302 EXPECT_EQ("262x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
304 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
305 // this rect, extended to the top left corner of the window.
306 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
309 TEST_F(OpaqueBrowserFrameViewLayoutTest
, MaximizedWithYOffset
) {
310 // Tests the layout of a basic chrome window with the caption buttons slightly
311 // offset from the top of the screen (as they are on Linux).
312 layout_manager_
->set_extra_caption_y(2);
313 delegate_
->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED
);
314 root_view_
->Layout();
316 // Note how the bounds start at the exact top of the window, DESPITE the
317 // caption Y offset of 2. This ensures that we obey Fitts' Law (the buttons
318 // are clickable on the top edge of the screen). However, the buttons are 2
319 // pixels taller, so the images appear to be offset by 2 pixels.
320 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
321 EXPECT_EQ("403,0 26x20", minimize_button_
->bounds().ToString());
322 EXPECT_EQ("429,0 25x20", restore_button_
->bounds().ToString());
323 EXPECT_EQ("454,0 46x20", close_button_
->bounds().ToString());
325 EXPECT_EQ("-5,-3 392x29",
326 layout_manager_
->GetBoundsForTabStrip(
327 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
328 EXPECT_EQ("262x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
330 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
331 // this rect, extended to the top left corner of the window.
332 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
335 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowButtonsOnLeft
) {
336 // Tests the layout of a chrome window with caption buttons on the left.
337 std::vector
<views::FrameButton
> leading_buttons
;
338 std::vector
<views::FrameButton
> trailing_buttons
;
339 leading_buttons
.push_back(views::FRAME_BUTTON_CLOSE
);
340 leading_buttons
.push_back(views::FRAME_BUTTON_MINIMIZE
);
341 leading_buttons
.push_back(views::FRAME_BUTTON_MAXIMIZE
);
342 layout_manager_
->SetButtonOrdering(leading_buttons
, trailing_buttons
);
343 root_view_
->Layout();
345 EXPECT_EQ("73,1 25x18", maximize_button_
->bounds().ToString());
346 EXPECT_EQ("47,1 26x18", minimize_button_
->bounds().ToString());
347 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
348 EXPECT_EQ("4,1 43x18", close_button_
->bounds().ToString());
350 EXPECT_EQ("93,13 398x29",
351 layout_manager_
->GetBoundsForTabStrip(
352 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
353 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
355 // If the buttons are on the left, there should be no hidden icon for the user
357 EXPECT_EQ("0,0 0x0", layout_manager_
->IconBounds().ToString());
360 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WithoutCaptionButtons
) {
361 // Tests the layout of a default chrome window with no caption buttons (which
362 // should force the tab strip to be condensed).
363 delegate_
->SetShouldShowCaptionButtons(false);
364 root_view_
->Layout();
366 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
367 EXPECT_EQ("0,0 0x0", minimize_button_
->bounds().ToString());
368 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
369 EXPECT_EQ("0,0 0x0", close_button_
->bounds().ToString());
371 EXPECT_EQ("-5,-3 500x29",
372 layout_manager_
->GetBoundsForTabStrip(
373 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
374 EXPECT_EQ("251x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
376 // A normal window with no window icon still produces icon bounds for
377 // Windows, which has a hidden icon that a user can double click on to close
379 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
382 TEST_F(OpaqueBrowserFrameViewLayoutTest
, MaximizedWithoutCaptionButtons
) {
383 // Tests the layout of a maximized chrome window with no caption buttons.
384 delegate_
->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED
);
385 delegate_
->SetShouldShowCaptionButtons(false);
386 root_view_
->Layout();
388 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
389 EXPECT_EQ("0,0 0x0", minimize_button_
->bounds().ToString());
390 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
391 EXPECT_EQ("0,0 0x0", close_button_
->bounds().ToString());
393 EXPECT_EQ("-5,-3 500x29",
394 layout_manager_
->GetBoundsForTabStrip(
395 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
396 EXPECT_EQ("251x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
398 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
399 // this rect, extended to the top left corner of the window.
400 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
403 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WithWindowTitleAndIcon
) {
404 // Tests the layout of pop up windows.
405 delegate_
->SetWindowTitle(base::ASCIIToUTF16("Window Title"));
406 AddWindowTitleIcons();
407 root_view_
->Layout();
409 // We should have the right hand side should match the BasicWindow case.
410 ExpectBasicWindowBounds();
412 // Check the location of the tab icon and window title.
413 EXPECT_EQ("6,3 17x17", tab_icon_view_
->bounds().ToString());
414 EXPECT_EQ("27,3 370x17", window_title_
->bounds().ToString());
417 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowWithAvatar
) {
418 // Tests a normal tabstrip window with an avatar icon.
420 root_view_
->Layout();
422 ExpectBasicWindowBounds();
424 // Check the location of the avatar
425 EXPECT_EQ("7,11 40x29", menu_button_
->bounds().ToString());
426 EXPECT_EQ("45,13 352x29",
427 layout_manager_
->GetBoundsForTabStrip(
428 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
429 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
432 TEST_F(OpaqueBrowserFrameViewLayoutTest
,
433 WindowWithAvatarWithoutCaptionButtonsOnLeft
) {
434 // Tests the layout of a chrome window with an avatar icon and no caption
435 // buttons. However, the caption buttons *would* be on the left if they
436 // weren't hidden, and therefore, the avatar icon should be on the right.
437 // The lack of caption buttons should force the tab strip to be condensed.
439 std::vector
<views::FrameButton
> leading_buttons
;
440 std::vector
<views::FrameButton
> trailing_buttons
;
441 leading_buttons
.push_back(views::FRAME_BUTTON_CLOSE
);
442 leading_buttons
.push_back(views::FRAME_BUTTON_MINIMIZE
);
443 leading_buttons
.push_back(views::FRAME_BUTTON_MAXIMIZE
);
444 layout_manager_
->SetButtonOrdering(leading_buttons
, trailing_buttons
);
445 delegate_
->SetShouldShowCaptionButtons(false);
446 root_view_
->Layout();
448 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
449 EXPECT_EQ("0,0 0x0", minimize_button_
->bounds().ToString());
450 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
451 EXPECT_EQ("0,0 0x0", close_button_
->bounds().ToString());
453 // Check the location of the avatar
454 EXPECT_EQ("458,0 40x24", menu_button_
->bounds().ToString());
455 EXPECT_EQ("-5,-3 458x29",
456 layout_manager_
->GetBoundsForTabStrip(
457 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
458 EXPECT_EQ("251x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
460 // A normal window with no window icon still produces icon bounds for
461 // Windows, which has a hidden icon that a user can double click on to close
463 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
466 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowWithNewAvatar
) {
467 // Tests a normal tabstrip window with the new style avatar icon.
468 AddNewAvatarButton();
469 root_view_
->Layout();
471 ExpectBasicWindowBounds();
473 // Check the location of the avatar button.
474 EXPECT_EQ("385,1 12x18", new_avatar_button_
->bounds().ToString());
475 // The new tab button is 39px wide and slides completely under the new
476 // avatar button, thus increasing the tabstrip by that amount.
477 EXPECT_EQ("-1,13 420x29",
478 layout_manager_
->GetBoundsForTabStrip(
479 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
480 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
483 #if defined(ENABLE_SUPERVISED_USERS)
484 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowWithAvatarWithButtonsOnLeft
) {
485 // Tests the layout of a chrome window with an avatar icon and caption buttons
486 // on the left. The avatar icon should therefore be on the right.
487 // AddAvatarLabel() also adds the avatar button.
488 AddSupervisedUserAvatarLabel();
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 root_view_
->Layout();
497 EXPECT_EQ("73,1 25x18", maximize_button_
->bounds().ToString());
498 EXPECT_EQ("47,1 26x18", minimize_button_
->bounds().ToString());
499 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
500 EXPECT_EQ("4,1 43x18", close_button_
->bounds().ToString());
502 // Check the location of the avatar
503 EXPECT_EQ("454,11 40x29", menu_button_
->bounds().ToString());
505 // Check the tab strip bounds.
506 gfx::Rect tab_strip_bounds
= layout_manager_
->GetBoundsForTabStrip(
507 delegate_
->GetTabstripPreferredSize(), kWidth
);
508 EXPECT_GT(tab_strip_bounds
.x(), maximize_button_
->bounds().x());
509 EXPECT_GT(maximize_button_
->bounds().right(), tab_strip_bounds
.x());
510 EXPECT_EQ(13, tab_strip_bounds
.y());
511 EXPECT_EQ(29, tab_strip_bounds
.height());
512 EXPECT_GT(supervised_user_avatar_label_
->bounds().x(),
513 tab_strip_bounds
.right());
514 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
516 // Check the relative location of the avatar label to the avatar. The right
517 // end of the avatar label should be slightly to the right of the right end of
519 EXPECT_GT(supervised_user_avatar_label_
->bounds().right(),
520 menu_button_
->bounds().right());
521 EXPECT_GT(menu_button_
->bounds().x(),
522 supervised_user_avatar_label_
->bounds().x());
523 EXPECT_GT(menu_button_
->bounds().bottom(),
524 supervised_user_avatar_label_
->bounds().bottom());
525 EXPECT_GT(supervised_user_avatar_label_
->bounds().y(),
526 menu_button_
->bounds().y());
528 // This means that the menu will pop out facing the left (if it were to face
529 // the right, it would go outside the window frame and be clipped).
530 EXPECT_TRUE(menu_button_
->button_on_right());
532 // If the buttons are on the left, there should be no hidden icon for the user
534 EXPECT_EQ("0,0 0x0", layout_manager_
->IconBounds().ToString());
537 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowWithAvatarLabelAndButtonOnLeft
) {
538 AddSupervisedUserAvatarLabel();
539 root_view_
->Layout();
541 ExpectBasicWindowBounds();
543 // Check the location of the avatar label relative to the avatar button if
544 // both are displayed on the left side.
545 // The label height and width depends on the font size and the text displayed.
546 // This may possibly change, so we don't test it here.
547 EXPECT_EQ(menu_button_
->bounds().x() - 2,
548 supervised_user_avatar_label_
->bounds().x());
549 EXPECT_EQ(menu_button_
->bounds().bottom() - 3 -
550 supervised_user_avatar_label_
->bounds().height(),
551 supervised_user_avatar_label_
->bounds().y());