| Index: ui/views/focus/focus_traversal_unittest.cc
|
| diff --git a/ui/views/focus/focus_traversal_unittest.cc b/ui/views/focus/focus_traversal_unittest.cc
|
| index 039c2b647a314143a24aa04c40e3c1365edc3d5f..4bc43614590abbd2df4adab2da15a1d6d29e3d5a 100644
|
| --- a/ui/views/focus/focus_traversal_unittest.cc
|
| +++ b/ui/views/focus/focus_traversal_unittest.cc
|
| @@ -2,8 +2,6 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "ui/views/focus/focus_manager.h"
|
| -
|
| #include <stddef.h>
|
|
|
| #include "base/macros.h"
|
| @@ -23,6 +21,7 @@
|
| #include "ui/views/controls/scroll_view.h"
|
| #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
|
| #include "ui/views/controls/textfield/textfield.h"
|
| +#include "ui/views/focus/focus_manager.h"
|
| #include "ui/views/test/focus_manager_test.h"
|
| #include "ui/views/widget/root_view.h"
|
| #include "ui/views/widget/widget.h"
|
| @@ -202,6 +201,24 @@ class FocusTraversalTest : public FocusManagerTest {
|
| }
|
|
|
| protected:
|
| + // Helper function to advance focus multiple times in a loop. |traversal_ids|
|
| + // is an array of view ids of length |N|. |reverse| denotes the direction in
|
| + // which focus should be advanced.
|
| + template <size_t N>
|
| + void AdvanceEntireFocusLoop(const int (&traversal_ids)[N], bool reverse) {
|
| + for (size_t i = 0; i < 3; ++i) {
|
| + for (size_t j = 0; j < N; j++) {
|
| + SCOPED_TRACE(testing::Message() << "reverse:" << reverse << " i:" << i
|
| + << " j:" << j);
|
| + GetFocusManager()->AdvanceFocus(reverse);
|
| + View* focused_view = GetFocusManager()->GetFocusedView();
|
| + EXPECT_NE(nullptr, focused_view);
|
| + if (focused_view)
|
| + EXPECT_EQ(traversal_ids[reverse ? N - j - 1 : j], focused_view->id());
|
| + }
|
| + }
|
| + }
|
| +
|
| TabbedPane* style_tab_;
|
| BorderView* search_border_view_;
|
| DummyComboboxModel combobox_model_;
|
| @@ -577,32 +594,74 @@ TEST_F(FocusTraversalTest, NormalTraversal) {
|
| kSearchTextfieldID, kSearchButtonID, kHelpLinkID,
|
| kThumbnailContainerID, kThumbnailStarID, kThumbnailSuperStarID };
|
|
|
| + SCOPED_TRACE("NormalTraversal");
|
| +
|
| // Let's traverse the whole focus hierarchy (several times, to make sure it
|
| // loops OK).
|
| GetFocusManager()->ClearFocus();
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (size_t j = 0; j < arraysize(kTraversalIDs); j++) {
|
| - GetFocusManager()->AdvanceFocus(false);
|
| - View* focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kTraversalIDs, false);
|
|
|
| // Let's traverse in reverse order.
|
| GetFocusManager()->ClearFocus();
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) {
|
| - GetFocusManager()->AdvanceFocus(true);
|
| - View* focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kTraversalIDs, true);
|
| +}
|
| +
|
| +#if defined(OS_MACOSX)
|
| +// Test focus traversal with full keyboard access off on Mac.
|
| +TEST_F(FocusTraversalTest, NormalTraversalMac) {
|
| + GetFocusManager()->SetKeyboardAccessible(false);
|
| +
|
| + // Now only views with FocusBehavior of ALWAYS will be focusable.
|
| + const int kTraversalIDs[] = {kAppleTextfieldID, kOrangeTextfieldID,
|
| + kBananaTextfieldID, kKiwiTextfieldID,
|
| + kStyleTextEditID, kSearchTextfieldID,
|
| + kThumbnailContainerID};
|
| +
|
| + SCOPED_TRACE("NormalTraversalMac");
|
| +
|
| + // Let's traverse the whole focus hierarchy (several times, to make sure it
|
| + // loops OK).
|
| + GetFocusManager()->ClearFocus();
|
| + AdvanceEntireFocusLoop(kTraversalIDs, false);
|
| +
|
| + // Let's traverse in reverse order.
|
| + GetFocusManager()->ClearFocus();
|
| + AdvanceEntireFocusLoop(kTraversalIDs, true);
|
| }
|
|
|
| +// Test toggling full keyboard access correctly changes the focused view on Mac.
|
| +TEST_F(FocusTraversalTest, FullKeyboardToggle) {
|
| + // Give focus to kTopCheckBoxID .
|
| + FindViewByID(kTopCheckBoxID)->RequestFocus();
|
| + EXPECT_EQ(kTopCheckBoxID, GetFocusManager()->GetFocusedView()->id());
|
| +
|
| + // Turn off full keyboard access. Focus should move to next view with ALWAYS
|
| + // focus behavior.
|
| + GetFocusManager()->SetKeyboardAccessible(false);
|
| + EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id());
|
| +
|
| + // Turning on full keyboard access should not change the focused view.
|
| + GetFocusManager()->SetKeyboardAccessible(true);
|
| + EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id());
|
| +
|
| + // Give focus to kSearchButtonID.
|
| + FindViewByID(kSearchButtonID)->RequestFocus();
|
| + EXPECT_EQ(kSearchButtonID, GetFocusManager()->GetFocusedView()->id());
|
| +
|
| + // Turn off full keyboard access. Focus should move to next view with ALWAYS
|
| + // focus behavior.
|
| + GetFocusManager()->SetKeyboardAccessible(false);
|
| + EXPECT_EQ(kThumbnailContainerID, GetFocusManager()->GetFocusedView()->id());
|
| +
|
| + // See focus advances correctly in both directions.
|
| + GetFocusManager()->AdvanceFocus(false);
|
| + EXPECT_EQ(kAppleTextfieldID, GetFocusManager()->GetFocusedView()->id());
|
| +
|
| + GetFocusManager()->AdvanceFocus(true);
|
| + EXPECT_EQ(kThumbnailContainerID, GetFocusManager()->GetFocusedView()->id());
|
| +}
|
| +#endif // OS_MACOSX
|
| +
|
| TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
|
| const int kDisabledIDs[] = {
|
| kBananaTextfieldID, kFruitCheckBoxID, kComboboxID, kAsparagusButtonID,
|
| @@ -619,6 +678,8 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
|
| kSearchButtonID, kThumbnailContainerID, kThumbnailStarID,
|
| kThumbnailSuperStarID };
|
|
|
| + SCOPED_TRACE("TraversalWithNonEnabledViews");
|
| +
|
| // Let's disable some views.
|
| for (size_t i = 0; i < arraysize(kDisabledIDs); i++) {
|
| View* v = FindViewByID(kDisabledIDs[i]);
|
| @@ -626,30 +687,13 @@ TEST_F(FocusTraversalTest, TraversalWithNonEnabledViews) {
|
| v->SetEnabled(false);
|
| }
|
|
|
| - View* focused_view;
|
| // Let's do one traversal (several times, to make sure it loops ok).
|
| GetFocusManager()->ClearFocus();
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (size_t j = 0; j < arraysize(kTraversalIDs); j++) {
|
| - GetFocusManager()->AdvanceFocus(false);
|
| - focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kTraversalIDs, false);
|
|
|
| // Same thing in reverse.
|
| GetFocusManager()->ClearFocus();
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) {
|
| - GetFocusManager()->AdvanceFocus(true);
|
| - focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kTraversalIDs, true);
|
| }
|
|
|
| TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) {
|
| @@ -666,6 +710,7 @@ TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) {
|
| kItalicCheckBoxID, kUnderlinedCheckBoxID, kStyleHelpLinkID,
|
| kStyleTextEditID, kSearchTextfieldID, kSearchButtonID, kHelpLinkID };
|
|
|
| + SCOPED_TRACE("TraversalWithInvisibleViews");
|
|
|
| // Let's make some views invisible.
|
| for (size_t i = 0; i < arraysize(kInvisibleIDs); i++) {
|
| @@ -674,30 +719,13 @@ TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) {
|
| v->SetVisible(false);
|
| }
|
|
|
| - View* focused_view;
|
| // Let's do one traversal (several times, to make sure it loops ok).
|
| GetFocusManager()->ClearFocus();
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (size_t j = 0; j < arraysize(kTraversalIDs); j++) {
|
| - GetFocusManager()->AdvanceFocus(false);
|
| - focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kTraversalIDs, false);
|
|
|
| // Same thing in reverse.
|
| GetFocusManager()->ClearFocus();
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (int j = arraysize(kTraversalIDs) - 1; j >= 0; --j) {
|
| - GetFocusManager()->AdvanceFocus(true);
|
| - focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kTraversalIDs, true);
|
| }
|
|
|
| TEST_F(FocusTraversalTest, PaneTraversal) {
|
| @@ -710,32 +738,18 @@ TEST_F(FocusTraversalTest, PaneTraversal) {
|
| kOrangeTextfieldID, kBananaTextfieldID, kKiwiTextfieldID,
|
| kFruitButtonID, kFruitCheckBoxID, kComboboxID };
|
|
|
| + SCOPED_TRACE("PaneTraversal");
|
| +
|
| FocusSearch focus_search_left(left_container_, true, false);
|
| left_container_->EnablePaneFocus(&focus_search_left);
|
| FindViewByID(kComboboxID)->RequestFocus();
|
|
|
| // Traverse the focus hierarchy within the pane several times.
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (size_t j = 0; j < arraysize(kLeftTraversalIDs); j++) {
|
| - GetFocusManager()->AdvanceFocus(false);
|
| - View* focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kLeftTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kLeftTraversalIDs, false);
|
|
|
| // Traverse in reverse order.
|
| FindViewByID(kAppleTextfieldID)->RequestFocus();
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (int j = arraysize(kLeftTraversalIDs) - 1; j >= 0; --j) {
|
| - GetFocusManager()->AdvanceFocus(true);
|
| - View* focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kLeftTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kLeftTraversalIDs, true);
|
|
|
| // Now test the right container, but this time with accessibility mode.
|
| // Make some links not focusable, but mark one of them as
|
| @@ -755,27 +769,11 @@ TEST_F(FocusTraversalTest, PaneTraversal) {
|
| FindViewByID(kAsterixLinkID)->RequestFocus();
|
|
|
| // Traverse the focus hierarchy within the pane several times.
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (size_t j = 0; j < arraysize(kRightTraversalIDs); j++) {
|
| - GetFocusManager()->AdvanceFocus(false);
|
| - View* focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kRightTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kRightTraversalIDs, false);
|
|
|
| // Traverse in reverse order.
|
| FindViewByID(kBroccoliButtonID)->RequestFocus();
|
| - for (int i = 0; i < 3; ++i) {
|
| - for (int j = arraysize(kRightTraversalIDs) - 1; j >= 0; --j) {
|
| - GetFocusManager()->AdvanceFocus(true);
|
| - View* focused_view = GetFocusManager()->GetFocusedView();
|
| - EXPECT_TRUE(focused_view != NULL);
|
| - if (focused_view)
|
| - EXPECT_EQ(kRightTraversalIDs[j], focused_view->id());
|
| - }
|
| - }
|
| + AdvanceEntireFocusLoop(kRightTraversalIDs, true);
|
| }
|
|
|
| class FocusTraversalNonFocusableTest : public FocusManagerTest {
|
|
|