Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / ash / frame / caption_buttons / frame_size_button_unittest.cc
blob3c950c1f71ec53536b0fc075893be5c1489d1dce
1 // Copyright 2014 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 "ash/frame/caption_buttons/frame_size_button.h"
7 #include "ash/frame/caption_buttons/frame_caption_button.h"
8 #include "ash/frame/caption_buttons/frame_caption_button_container_view.h"
9 #include "ash/shell.h"
10 #include "ash/test/ash_test_base.h"
11 #include "ash/wm/window_state.h"
12 #include "base/i18n/rtl.h"
13 #include "grit/ash_resources.h"
14 #include "ui/aura/window.h"
15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/events/gesture_detection/gesture_configuration.h"
17 #include "ui/events/test/event_generator.h"
18 #include "ui/gfx/display.h"
19 #include "ui/gfx/screen.h"
20 #include "ui/views/widget/widget.h"
21 #include "ui/views/widget/widget_delegate.h"
23 namespace ash {
24 namespace test {
26 namespace {
28 class TestWidgetDelegate : public views::WidgetDelegateView {
29 public:
30 TestWidgetDelegate() {}
31 ~TestWidgetDelegate() override {}
33 // Overridden from views::WidgetDelegate:
34 views::View* GetContentsView() override { return this; }
35 bool CanResize() const override { return true; }
36 bool CanMaximize() const override { return true; }
37 bool CanMinimize() const override { return true; }
39 ash::FrameCaptionButtonContainerView* caption_button_container() {
40 return caption_button_container_;
43 private:
44 // Overridden from views::View:
45 void Layout() override {
46 caption_button_container_->Layout();
48 // Right align the caption button container.
49 gfx::Size preferred_size = caption_button_container_->GetPreferredSize();
50 caption_button_container_->SetBounds(width() - preferred_size.width(), 0,
51 preferred_size.width(), preferred_size.height());
54 void ViewHierarchyChanged(
55 const ViewHierarchyChangedDetails& details) override {
56 if (details.is_add && details.child == this) {
57 caption_button_container_ =
58 new FrameCaptionButtonContainerView(GetWidget());
60 // Set arbitrary images for the container's buttons so that the buttons
61 // have non-empty sizes.
62 for (int icon = 0; icon < CAPTION_BUTTON_ICON_COUNT; ++icon) {
63 caption_button_container_->SetButtonImages(
64 static_cast<CaptionButtonIcon>(icon),
65 IDR_AURA_WINDOW_CONTROL_ICON_CLOSE,
66 IDR_AURA_WINDOW_CONTROL_BACKGROUND_H,
67 IDR_AURA_WINDOW_CONTROL_BACKGROUND_P);
70 AddChildView(caption_button_container_);
74 // Not owned.
75 ash::FrameCaptionButtonContainerView* caption_button_container_;
77 DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
80 } // namespace
82 class FrameSizeButtonTest : public AshTestBase {
83 public:
84 FrameSizeButtonTest() {}
85 ~FrameSizeButtonTest() override {}
87 // Returns the center point of |view| in screen coordinates.
88 gfx::Point CenterPointInScreen(views::View* view) {
89 return view->GetBoundsInScreen().CenterPoint();
92 // Returns true if the window has |state_type|.
93 bool HasStateType(wm::WindowStateType state_type) const {
94 return window_state()->GetStateType() == state_type;
97 // Returns true if all three buttons are in the normal state.
98 bool AllButtonsInNormalState() const {
99 return minimize_button_->state() == views::Button::STATE_NORMAL &&
100 size_button_->state() == views::Button::STATE_NORMAL &&
101 close_button_->state() == views::Button::STATE_NORMAL;
104 // Creates a widget with |delegate|. The returned widget takes ownership of
105 // |delegate|.
106 views::Widget* CreateWidget(views::WidgetDelegate* delegate) {
107 views::Widget* widget = new views::Widget;
108 views::Widget::InitParams params(
109 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
110 params.context = CurrentContext();
111 params.delegate = delegate;
112 params.bounds = gfx::Rect(10, 10, 100, 100);
113 widget->Init(params);
114 widget->Show();
115 return widget;
118 // AshTestBase overrides:
119 void SetUp() override {
120 AshTestBase::SetUp();
122 TestWidgetDelegate* delegate = new TestWidgetDelegate();
123 window_state_ = ash::wm::GetWindowState(
124 CreateWidget(delegate)->GetNativeWindow());
126 FrameCaptionButtonContainerView::TestApi test(
127 delegate->caption_button_container());
129 minimize_button_ = test.minimize_button();
130 size_button_ = test.size_button();
131 static_cast<FrameSizeButton*>(
132 size_button_)->set_delay_to_set_buttons_to_snap_mode(0);
133 close_button_ = test.close_button();
136 ash::wm::WindowState* window_state() { return window_state_; }
137 const ash::wm::WindowState* window_state() const { return window_state_; }
139 FrameCaptionButton* minimize_button() { return minimize_button_; }
140 FrameCaptionButton* size_button() { return size_button_; }
141 FrameCaptionButton* close_button() { return close_button_; }
143 private:
144 // Not owned.
145 ash::wm::WindowState* window_state_;
146 FrameCaptionButton* minimize_button_;
147 FrameCaptionButton* size_button_;
148 FrameCaptionButton* close_button_;
150 DISALLOW_COPY_AND_ASSIGN(FrameSizeButtonTest);
153 // Tests that pressing the left mouse button or tapping down on the size button
154 // puts the button into the pressed state.
155 TEST_F(FrameSizeButtonTest, PressedState) {
156 ui::test::EventGenerator& generator = GetEventGenerator();
157 generator.MoveMouseTo(CenterPointInScreen(size_button()));
158 generator.PressLeftButton();
159 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
160 generator.ReleaseLeftButton();
161 RunAllPendingInMessageLoop();
162 EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state());
164 generator.MoveMouseTo(CenterPointInScreen(size_button()));
165 generator.PressTouchId(3);
166 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
167 generator.ReleaseTouchId(3);
168 RunAllPendingInMessageLoop();
169 EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state());
172 // Tests that clicking on the size button toggles between the maximized and
173 // normal state.
174 TEST_F(FrameSizeButtonTest, ClickSizeButtonTogglesMaximize) {
175 EXPECT_FALSE(window_state()->IsMaximized());
177 ui::test::EventGenerator& generator = GetEventGenerator();
178 generator.MoveMouseTo(CenterPointInScreen(size_button()));
179 generator.ClickLeftButton();
180 RunAllPendingInMessageLoop();
181 EXPECT_TRUE(window_state()->IsMaximized());
183 generator.MoveMouseTo(CenterPointInScreen(size_button()));
184 generator.ClickLeftButton();
185 RunAllPendingInMessageLoop();
186 EXPECT_FALSE(window_state()->IsMaximized());
188 generator.GestureTapAt(CenterPointInScreen(size_button()));
189 RunAllPendingInMessageLoop();
190 EXPECT_TRUE(window_state()->IsMaximized());
192 generator.GestureTapAt(CenterPointInScreen(size_button()));
193 RunAllPendingInMessageLoop();
194 EXPECT_FALSE(window_state()->IsMaximized());
197 // Test that clicking + dragging to a button adjacent to the size button snaps
198 // the window left or right.
199 TEST_F(FrameSizeButtonTest, ButtonDrag) {
200 EXPECT_TRUE(window_state()->IsNormalStateType());
202 // 1) Test by dragging the mouse.
203 // Snap right.
204 ui::test::EventGenerator& generator = GetEventGenerator();
205 generator.MoveMouseTo(CenterPointInScreen(size_button()));
206 generator.PressLeftButton();
207 generator.MoveMouseTo(CenterPointInScreen(close_button()));
208 generator.ReleaseLeftButton();
209 RunAllPendingInMessageLoop();
210 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
212 // Snap left.
213 generator.MoveMouseTo(CenterPointInScreen(size_button()));
214 generator.PressLeftButton();
215 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
216 generator.ReleaseLeftButton();
217 RunAllPendingInMessageLoop();
218 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
220 // 2) Test with scroll gestures.
221 // Snap right.
222 generator.GestureScrollSequence(
223 CenterPointInScreen(size_button()),
224 CenterPointInScreen(close_button()),
225 base::TimeDelta::FromMilliseconds(100),
227 RunAllPendingInMessageLoop();
228 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
230 // Snap left.
231 generator.GestureScrollSequence(
232 CenterPointInScreen(size_button()),
233 CenterPointInScreen(minimize_button()),
234 base::TimeDelta::FromMilliseconds(100),
236 RunAllPendingInMessageLoop();
237 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
239 // 3) Test with tap gestures.
240 const float touch_default_radius =
241 ui::GestureConfiguration::GetInstance()->default_radius();
242 ui::GestureConfiguration::GetInstance()->set_default_radius(0);
243 // Snap right.
244 generator.MoveMouseTo(CenterPointInScreen(size_button()));
245 generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(close_button()));
246 RunAllPendingInMessageLoop();
247 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
248 // Snap left.
249 generator.MoveMouseTo(CenterPointInScreen(size_button()));
250 generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(minimize_button()));
251 RunAllPendingInMessageLoop();
252 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
253 ui::GestureConfiguration::GetInstance()->set_default_radius(
254 touch_default_radius);
257 // Test that clicking, dragging, and overshooting the minimize button a bit
258 // horizontally still snaps the window left.
259 TEST_F(FrameSizeButtonTest, SnapLeftOvershootMinimize) {
260 EXPECT_TRUE(window_state()->IsNormalStateType());
262 ui::test::EventGenerator& generator = GetEventGenerator();
263 generator.MoveMouseTo(CenterPointInScreen(size_button()));
265 generator.PressLeftButton();
266 // Move to the minimize button.
267 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
268 // Overshoot the minimize button.
269 generator.MoveMouseBy(-minimize_button()->width(), 0);
270 generator.ReleaseLeftButton();
271 RunAllPendingInMessageLoop();
272 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
275 // Test that right clicking the size button has no effect.
276 TEST_F(FrameSizeButtonTest, RightMouseButton) {
277 EXPECT_TRUE(window_state()->IsNormalStateType());
279 ui::test::EventGenerator& generator = GetEventGenerator();
280 generator.MoveMouseTo(CenterPointInScreen(size_button()));
281 generator.PressRightButton();
282 generator.ReleaseRightButton();
283 RunAllPendingInMessageLoop();
284 EXPECT_TRUE(window_state()->IsNormalStateType());
287 // Test that upon releasing the mouse button after having pressed the size
288 // button
289 // - The state of all the caption buttons is reset.
290 // - The icon displayed by all of the caption buttons is reset.
291 TEST_F(FrameSizeButtonTest, ResetButtonsAfterClick) {
292 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
293 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
294 EXPECT_TRUE(AllButtonsInNormalState());
296 // Pressing the size button should result in the size button being pressed and
297 // the minimize and close button icons changing.
298 ui::test::EventGenerator& generator = GetEventGenerator();
299 generator.MoveMouseTo(CenterPointInScreen(size_button()));
300 generator.PressLeftButton();
301 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
302 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
303 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
304 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
305 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
307 // Dragging the mouse over the minimize button should hover the minimize
308 // button and the minimize and close button icons should stay changed.
309 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
310 EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
311 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
312 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
313 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
314 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
316 // Release the mouse, snapping the window left.
317 generator.ReleaseLeftButton();
318 RunAllPendingInMessageLoop();
319 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
321 // None of the buttons should stay pressed and the buttons should have their
322 // regular icons.
323 EXPECT_TRUE(AllButtonsInNormalState());
324 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
325 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
327 // Repeat test but release button where it does not affect the window's state
328 // because the code path is different.
329 generator.MoveMouseTo(CenterPointInScreen(size_button()));
330 generator.PressLeftButton();
331 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
332 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
333 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
334 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
335 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
337 const gfx::Rect& kWorkAreaBoundsInScreen =
338 ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
339 generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left());
341 // None of the buttons should be pressed because we are really far away from
342 // any of the caption buttons. The minimize and close button icons should
343 // be changed because the mouse is pressed.
344 EXPECT_TRUE(AllButtonsInNormalState());
345 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
346 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
348 // Release the mouse. The window should stay snapped left.
349 generator.ReleaseLeftButton();
350 RunAllPendingInMessageLoop();
351 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
353 // The buttons should stay unpressed and the buttons should now have their
354 // regular icons.
355 EXPECT_TRUE(AllButtonsInNormalState());
356 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
357 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
360 // Test that the size button is pressed whenever the snap left/right buttons
361 // are hovered.
362 TEST_F(FrameSizeButtonTest, SizeButtonPressedWhenSnapButtonHovered) {
363 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
364 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
365 EXPECT_TRUE(AllButtonsInNormalState());
367 // Pressing the size button should result in the size button being pressed and
368 // the minimize and close button icons changing.
369 ui::test::EventGenerator& generator = GetEventGenerator();
370 generator.MoveMouseTo(CenterPointInScreen(size_button()));
371 generator.PressLeftButton();
372 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
373 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
374 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
375 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
376 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
378 // Dragging the mouse over the minimize button (snap left button) should hover
379 // the minimize button and keep the size button pressed.
380 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
381 EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
382 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
383 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
385 // Moving the mouse far away from the caption buttons and then moving it over
386 // the close button (snap right button) should hover the close button and
387 // keep the size button pressed.
388 const gfx::Rect& kWorkAreaBoundsInScreen =
389 ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
390 generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left());
391 EXPECT_TRUE(AllButtonsInNormalState());
392 generator.MoveMouseTo(CenterPointInScreen(close_button()));
393 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
394 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
395 EXPECT_EQ(views::Button::STATE_HOVERED, close_button()->state());
398 class FrameSizeButtonTestRTL : public FrameSizeButtonTest {
399 public:
400 FrameSizeButtonTestRTL() {}
401 ~FrameSizeButtonTestRTL() override {}
403 void SetUp() override {
404 original_locale_ = l10n_util::GetApplicationLocale(std::string());
405 base::i18n::SetICUDefaultLocale("he");
407 FrameSizeButtonTest::SetUp();
410 void TearDown() override {
411 FrameSizeButtonTest::TearDown();
412 base::i18n::SetICUDefaultLocale(original_locale_);
415 private:
416 std::string original_locale_;
418 DISALLOW_COPY_AND_ASSIGN(FrameSizeButtonTestRTL);
421 // Test that clicking + dragging to a button adjacent to the size button presses
422 // the correct button and snaps the window to the correct side.
423 TEST_F(FrameSizeButtonTestRTL, ButtonDrag) {
424 // In RTL the close button should be left of the size button and the minimize
425 // button should be right of the size button.
426 ASSERT_LT(close_button()->GetBoundsInScreen().x(),
427 size_button()->GetBoundsInScreen().x());
428 ASSERT_LT(size_button()->GetBoundsInScreen().x(),
429 minimize_button()->GetBoundsInScreen().x());
431 // Test initial state.
432 EXPECT_TRUE(window_state()->IsNormalStateType());
433 EXPECT_TRUE(AllButtonsInNormalState());
434 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
435 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
437 // Pressing the size button should swap the icons of the minimize and close
438 // buttons to icons for snapping right and for snapping left respectively.
439 ui::test::EventGenerator& generator = GetEventGenerator();
440 generator.MoveMouseTo(CenterPointInScreen(size_button()));
441 generator.PressLeftButton();
442 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
443 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
444 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
445 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, minimize_button()->icon());
446 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, close_button()->icon());
448 // Dragging over to the minimize button should press it.
449 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
450 EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
451 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
452 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
454 // Releasing should snap the window right.
455 generator.ReleaseLeftButton();
456 RunAllPendingInMessageLoop();
457 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
459 // None of the buttons should stay pressed and the buttons should have their
460 // regular icons.
461 EXPECT_TRUE(AllButtonsInNormalState());
462 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
463 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
466 } // namespace test
467 } // namespace ash