Delete chrome.mediaGalleriesPrivate because the functionality unique to it has since...
[chromium-blink-merge.git] / ash / frame / caption_buttons / frame_size_button_unittest.cc
blobf02d68251ed92915a6a3cfabe64c0c960fb31808
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_ICON_CLOSE_I,
67 IDR_AURA_WINDOW_CONTROL_BACKGROUND_H,
68 IDR_AURA_WINDOW_CONTROL_BACKGROUND_P);
71 AddChildView(caption_button_container_);
75 // Not owned.
76 ash::FrameCaptionButtonContainerView* caption_button_container_;
78 DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
81 } // namespace
83 class FrameSizeButtonTest : public AshTestBase {
84 public:
85 FrameSizeButtonTest() {}
86 ~FrameSizeButtonTest() override {}
88 // Returns the center point of |view| in screen coordinates.
89 gfx::Point CenterPointInScreen(views::View* view) {
90 return view->GetBoundsInScreen().CenterPoint();
93 // Returns true if the window has |state_type|.
94 bool HasStateType(wm::WindowStateType state_type) const {
95 return window_state()->GetStateType() == state_type;
98 // Returns true if all three buttons are in the normal state.
99 bool AllButtonsInNormalState() const {
100 return minimize_button_->state() == views::Button::STATE_NORMAL &&
101 size_button_->state() == views::Button::STATE_NORMAL &&
102 close_button_->state() == views::Button::STATE_NORMAL;
105 // Creates a widget with |delegate|. The returned widget takes ownership of
106 // |delegate|.
107 views::Widget* CreateWidget(views::WidgetDelegate* delegate) {
108 views::Widget* widget = new views::Widget;
109 views::Widget::InitParams params(
110 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
111 params.context = CurrentContext();
112 params.delegate = delegate;
113 params.bounds = gfx::Rect(10, 10, 100, 100);
114 widget->Init(params);
115 widget->Show();
116 return widget;
119 // AshTestBase overrides:
120 void SetUp() override {
121 AshTestBase::SetUp();
123 TestWidgetDelegate* delegate = new TestWidgetDelegate();
124 window_state_ = ash::wm::GetWindowState(
125 CreateWidget(delegate)->GetNativeWindow());
127 FrameCaptionButtonContainerView::TestApi test(
128 delegate->caption_button_container());
130 minimize_button_ = test.minimize_button();
131 size_button_ = test.size_button();
132 static_cast<FrameSizeButton*>(
133 size_button_)->set_delay_to_set_buttons_to_snap_mode(0);
134 close_button_ = test.close_button();
137 ash::wm::WindowState* window_state() { return window_state_; }
138 const ash::wm::WindowState* window_state() const { return window_state_; }
140 FrameCaptionButton* minimize_button() { return minimize_button_; }
141 FrameCaptionButton* size_button() { return size_button_; }
142 FrameCaptionButton* close_button() { return close_button_; }
144 private:
145 // Not owned.
146 ash::wm::WindowState* window_state_;
147 FrameCaptionButton* minimize_button_;
148 FrameCaptionButton* size_button_;
149 FrameCaptionButton* close_button_;
151 DISALLOW_COPY_AND_ASSIGN(FrameSizeButtonTest);
154 // Tests that pressing the left mouse button or tapping down on the size button
155 // puts the button into the pressed state.
156 TEST_F(FrameSizeButtonTest, PressedState) {
157 ui::test::EventGenerator& generator = GetEventGenerator();
158 generator.MoveMouseTo(CenterPointInScreen(size_button()));
159 generator.PressLeftButton();
160 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
161 generator.ReleaseLeftButton();
162 RunAllPendingInMessageLoop();
163 EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state());
165 generator.MoveMouseTo(CenterPointInScreen(size_button()));
166 generator.PressTouchId(3);
167 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
168 generator.ReleaseTouchId(3);
169 RunAllPendingInMessageLoop();
170 EXPECT_EQ(views::Button::STATE_NORMAL, size_button()->state());
173 // Tests that clicking on the size button toggles between the maximized and
174 // normal state.
175 TEST_F(FrameSizeButtonTest, ClickSizeButtonTogglesMaximize) {
176 EXPECT_FALSE(window_state()->IsMaximized());
178 ui::test::EventGenerator& generator = GetEventGenerator();
179 generator.MoveMouseTo(CenterPointInScreen(size_button()));
180 generator.ClickLeftButton();
181 RunAllPendingInMessageLoop();
182 EXPECT_TRUE(window_state()->IsMaximized());
184 generator.MoveMouseTo(CenterPointInScreen(size_button()));
185 generator.ClickLeftButton();
186 RunAllPendingInMessageLoop();
187 EXPECT_FALSE(window_state()->IsMaximized());
189 generator.GestureTapAt(CenterPointInScreen(size_button()));
190 RunAllPendingInMessageLoop();
191 EXPECT_TRUE(window_state()->IsMaximized());
193 generator.GestureTapAt(CenterPointInScreen(size_button()));
194 RunAllPendingInMessageLoop();
195 EXPECT_FALSE(window_state()->IsMaximized());
198 // Test that clicking + dragging to a button adjacent to the size button snaps
199 // the window left or right.
200 TEST_F(FrameSizeButtonTest, ButtonDrag) {
201 EXPECT_TRUE(window_state()->IsNormalStateType());
203 // 1) Test by dragging the mouse.
204 // Snap right.
205 ui::test::EventGenerator& generator = GetEventGenerator();
206 generator.MoveMouseTo(CenterPointInScreen(size_button()));
207 generator.PressLeftButton();
208 generator.MoveMouseTo(CenterPointInScreen(close_button()));
209 generator.ReleaseLeftButton();
210 RunAllPendingInMessageLoop();
211 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
213 // Snap left.
214 generator.MoveMouseTo(CenterPointInScreen(size_button()));
215 generator.PressLeftButton();
216 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
217 generator.ReleaseLeftButton();
218 RunAllPendingInMessageLoop();
219 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
221 // 2) Test with scroll gestures.
222 // Snap right.
223 generator.GestureScrollSequence(
224 CenterPointInScreen(size_button()),
225 CenterPointInScreen(close_button()),
226 base::TimeDelta::FromMilliseconds(100),
228 RunAllPendingInMessageLoop();
229 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
231 // Snap left.
232 generator.GestureScrollSequence(
233 CenterPointInScreen(size_button()),
234 CenterPointInScreen(minimize_button()),
235 base::TimeDelta::FromMilliseconds(100),
237 RunAllPendingInMessageLoop();
238 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
240 // 3) Test with tap gestures.
241 const float touch_default_radius =
242 ui::GestureConfiguration::GetInstance()->default_radius();
243 ui::GestureConfiguration::GetInstance()->set_default_radius(0);
244 // Snap right.
245 generator.MoveMouseTo(CenterPointInScreen(size_button()));
246 generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(close_button()));
247 RunAllPendingInMessageLoop();
248 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
249 // Snap left.
250 generator.MoveMouseTo(CenterPointInScreen(size_button()));
251 generator.PressMoveAndReleaseTouchTo(CenterPointInScreen(minimize_button()));
252 RunAllPendingInMessageLoop();
253 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
254 ui::GestureConfiguration::GetInstance()->set_default_radius(
255 touch_default_radius);
258 // Test that clicking, dragging, and overshooting the minimize button a bit
259 // horizontally still snaps the window left.
260 TEST_F(FrameSizeButtonTest, SnapLeftOvershootMinimize) {
261 EXPECT_TRUE(window_state()->IsNormalStateType());
263 ui::test::EventGenerator& generator = GetEventGenerator();
264 generator.MoveMouseTo(CenterPointInScreen(size_button()));
266 generator.PressLeftButton();
267 // Move to the minimize button.
268 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
269 // Overshoot the minimize button.
270 generator.MoveMouseBy(-minimize_button()->width(), 0);
271 generator.ReleaseLeftButton();
272 RunAllPendingInMessageLoop();
273 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
276 // Test that right clicking the size button has no effect.
277 TEST_F(FrameSizeButtonTest, RightMouseButton) {
278 EXPECT_TRUE(window_state()->IsNormalStateType());
280 ui::test::EventGenerator& generator = GetEventGenerator();
281 generator.MoveMouseTo(CenterPointInScreen(size_button()));
282 generator.PressRightButton();
283 generator.ReleaseRightButton();
284 RunAllPendingInMessageLoop();
285 EXPECT_TRUE(window_state()->IsNormalStateType());
288 // Test that upon releasing the mouse button after having pressed the size
289 // button
290 // - The state of all the caption buttons is reset.
291 // - The icon displayed by all of the caption buttons is reset.
292 TEST_F(FrameSizeButtonTest, ResetButtonsAfterClick) {
293 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
294 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
295 EXPECT_TRUE(AllButtonsInNormalState());
297 // Pressing the size button should result in the size button being pressed and
298 // the minimize and close button icons changing.
299 ui::test::EventGenerator& generator = GetEventGenerator();
300 generator.MoveMouseTo(CenterPointInScreen(size_button()));
301 generator.PressLeftButton();
302 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
303 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
304 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
305 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
306 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
308 // Dragging the mouse over the minimize button should hover the minimize
309 // button and the minimize and close button icons should stay changed.
310 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
311 EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
312 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
313 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
314 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
315 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
317 // Release the mouse, snapping the window left.
318 generator.ReleaseLeftButton();
319 RunAllPendingInMessageLoop();
320 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
322 // None of the buttons should stay pressed and the buttons should have their
323 // regular icons.
324 EXPECT_TRUE(AllButtonsInNormalState());
325 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
326 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
328 // Repeat test but release button where it does not affect the window's state
329 // because the code path is different.
330 generator.MoveMouseTo(CenterPointInScreen(size_button()));
331 generator.PressLeftButton();
332 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
333 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
334 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
335 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
336 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
338 const gfx::Rect& kWorkAreaBoundsInScreen =
339 ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
340 generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left());
342 // None of the buttons should be pressed because we are really far away from
343 // any of the caption buttons. The minimize and close button icons should
344 // be changed because the mouse is pressed.
345 EXPECT_TRUE(AllButtonsInNormalState());
346 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
347 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
349 // Release the mouse. The window should stay snapped left.
350 generator.ReleaseLeftButton();
351 RunAllPendingInMessageLoop();
352 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED));
354 // The buttons should stay unpressed and the buttons should now have their
355 // regular icons.
356 EXPECT_TRUE(AllButtonsInNormalState());
357 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
358 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
361 // Test that the size button is pressed whenever the snap left/right buttons
362 // are hovered.
363 TEST_F(FrameSizeButtonTest, SizeButtonPressedWhenSnapButtonHovered) {
364 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
365 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
366 EXPECT_TRUE(AllButtonsInNormalState());
368 // Pressing the size button should result in the size button being pressed and
369 // the minimize and close button icons changing.
370 ui::test::EventGenerator& generator = GetEventGenerator();
371 generator.MoveMouseTo(CenterPointInScreen(size_button()));
372 generator.PressLeftButton();
373 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
374 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
375 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
376 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, minimize_button()->icon());
377 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, close_button()->icon());
379 // Dragging the mouse over the minimize button (snap left button) should hover
380 // the minimize button and keep the size button pressed.
381 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
382 EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
383 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
384 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
386 // Moving the mouse far away from the caption buttons and then moving it over
387 // the close button (snap right button) should hover the close button and
388 // keep the size button pressed.
389 const gfx::Rect& kWorkAreaBoundsInScreen =
390 ash::Shell::GetScreen()->GetPrimaryDisplay().work_area();
391 generator.MoveMouseTo(kWorkAreaBoundsInScreen.bottom_left());
392 EXPECT_TRUE(AllButtonsInNormalState());
393 generator.MoveMouseTo(CenterPointInScreen(close_button()));
394 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
395 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
396 EXPECT_EQ(views::Button::STATE_HOVERED, close_button()->state());
399 class FrameSizeButtonTestRTL : public FrameSizeButtonTest {
400 public:
401 FrameSizeButtonTestRTL() {}
402 ~FrameSizeButtonTestRTL() override {}
404 void SetUp() override {
405 original_locale_ = l10n_util::GetApplicationLocale(std::string());
406 base::i18n::SetICUDefaultLocale("he");
408 FrameSizeButtonTest::SetUp();
411 void TearDown() override {
412 FrameSizeButtonTest::TearDown();
413 base::i18n::SetICUDefaultLocale(original_locale_);
416 private:
417 std::string original_locale_;
419 DISALLOW_COPY_AND_ASSIGN(FrameSizeButtonTestRTL);
422 // Test that clicking + dragging to a button adjacent to the size button presses
423 // the correct button and snaps the window to the correct side.
424 TEST_F(FrameSizeButtonTestRTL, ButtonDrag) {
425 // In RTL the close button should be left of the size button and the minimize
426 // button should be right of the size button.
427 ASSERT_LT(close_button()->GetBoundsInScreen().x(),
428 size_button()->GetBoundsInScreen().x());
429 ASSERT_LT(size_button()->GetBoundsInScreen().x(),
430 minimize_button()->GetBoundsInScreen().x());
432 // Test initial state.
433 EXPECT_TRUE(window_state()->IsNormalStateType());
434 EXPECT_TRUE(AllButtonsInNormalState());
435 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
436 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
438 // Pressing the size button should swap the icons of the minimize and close
439 // buttons to icons for snapping right and for snapping left respectively.
440 ui::test::EventGenerator& generator = GetEventGenerator();
441 generator.MoveMouseTo(CenterPointInScreen(size_button()));
442 generator.PressLeftButton();
443 EXPECT_EQ(views::Button::STATE_NORMAL, minimize_button()->state());
444 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
445 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
446 EXPECT_EQ(CAPTION_BUTTON_ICON_RIGHT_SNAPPED, minimize_button()->icon());
447 EXPECT_EQ(CAPTION_BUTTON_ICON_LEFT_SNAPPED, close_button()->icon());
449 // Dragging over to the minimize button should press it.
450 generator.MoveMouseTo(CenterPointInScreen(minimize_button()));
451 EXPECT_EQ(views::Button::STATE_HOVERED, minimize_button()->state());
452 EXPECT_EQ(views::Button::STATE_PRESSED, size_button()->state());
453 EXPECT_EQ(views::Button::STATE_NORMAL, close_button()->state());
455 // Releasing should snap the window right.
456 generator.ReleaseLeftButton();
457 RunAllPendingInMessageLoop();
458 EXPECT_TRUE(HasStateType(wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED));
460 // None of the buttons should stay pressed and the buttons should have their
461 // regular icons.
462 EXPECT_TRUE(AllButtonsInNormalState());
463 EXPECT_EQ(CAPTION_BUTTON_ICON_MINIMIZE, minimize_button()->icon());
464 EXPECT_EQ(CAPTION_BUTTON_ICON_CLOSE, close_button()->icon());
467 } // namespace test
468 } // namespace ash