Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(469)

Unified Diff: ui/views/focus/focus_traversal_unittest.cc

Issue 1894383002: MacViews: Implement Full Keyboard Access. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@SetFocusBehavior
Patch Set: Address review comments. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..c2c66ab2081e531ccceb5a97b94c5c72be8c0a16 100644
--- a/ui/views/focus/focus_traversal_unittest.cc
+++ b/ui/views/focus/focus_traversal_unittest.cc
@@ -2,10 +2,10 @@
// 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 <iterator>
+
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
@@ -23,6 +23,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"
@@ -33,6 +34,12 @@ namespace views {
namespace {
+// Helper function to reverse an iterator.
+template <typename Iterator>
+std::reverse_iterator<Iterator> reverse_iter(Iterator iter) {
+ return std::reverse_iterator<Iterator>(iter);
+}
+
int count = 1;
const int kTopCheckBoxID = count++; // 1
@@ -202,6 +209,23 @@ class FocusTraversalTest : public FocusManagerTest {
}
protected:
+ // Helper function to advance focus multiple times in a loop. |begin| and
+ // |end| are iterators pointing to view-ids and should be in the order in
+ // which views gain focus. |reverse| denotes the direction in which focus
+ // should be advanced.
+ template <typename Iterator>
+ void AdvanceEntireFocusLoop(Iterator begin, Iterator end, bool reverse) {
tapted 2016/05/03 08:08:25 Hm it would be nice to avoid the template<> - I th
karandeepb 2016/05/04 01:56:38 Done.
+ for (int i = 0; i < 3; ++i) {
+ for (auto it = begin; it != end; it++) {
+ GetFocusManager()->AdvanceFocus(reverse);
+ View* focused_view = GetFocusManager()->GetFocusedView();
+ EXPECT_NE(nullptr, focused_view);
+ if (focused_view)
+ EXPECT_EQ(*it, focused_view->id());
+ }
+ }
+ }
+
TabbedPane* style_tab_;
BorderView* search_border_view_;
DummyComboboxModel combobox_model_;
@@ -577,31 +601,81 @@ 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());
- }
- }
+ bool reverse = false;
tapted 2016/05/03 08:08:26 I probably wouldn't worry about this extra variabl
karandeepb 2016/05/04 01:56:38 Done.
+ AdvanceEntireFocusLoop(std::begin(kTraversalIDs), std::end(kTraversalIDs),
+ reverse);
// 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());
- }
- }
+ reverse = true;
+ AdvanceEntireFocusLoop(reverse_iter(std::end(kTraversalIDs)),
+ reverse_iter(std::begin(kTraversalIDs)), reverse);
+}
+
+#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();
+ bool reverse = false;
+ AdvanceEntireFocusLoop(std::begin(kTraversalIDs), std::end(kTraversalIDs),
+ reverse);
+
+ // Let's traverse in reverse order.
+ GetFocusManager()->ClearFocus();
+ reverse = true;
+ AdvanceEntireFocusLoop(reverse_iter(std::end(kTraversalIDs)),
+ reverse_iter(std::begin(kTraversalIDs)), reverse);
+}
+
+// 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[] = {
@@ -619,6 +693,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 +702,17 @@ 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());
- }
- }
+ bool reverse = false;
+ AdvanceEntireFocusLoop(std::begin(kTraversalIDs), std::end(kTraversalIDs),
+ reverse);
// 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());
- }
- }
+ reverse = true;
+ AdvanceEntireFocusLoop(reverse_iter(std::end(kTraversalIDs)),
+ reverse_iter(std::begin(kTraversalIDs)), reverse);
}
TEST_F(FocusTraversalTest, TraversalWithInvisibleViews) {
@@ -666,6 +729,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 +738,17 @@ 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());
- }
- }
+ bool reverse = false;
+ AdvanceEntireFocusLoop(std::begin(kTraversalIDs), std::end(kTraversalIDs),
+ reverse);
// 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());
- }
- }
+ reverse = true;
+ AdvanceEntireFocusLoop(reverse_iter(std::end(kTraversalIDs)),
+ reverse_iter(std::begin(kTraversalIDs)), reverse);
}
TEST_F(FocusTraversalTest, PaneTraversal) {
@@ -710,32 +761,22 @@ 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());
- }
- }
+ bool reverse = false;
+ AdvanceEntireFocusLoop(std::begin(kLeftTraversalIDs),
+ std::end(kLeftTraversalIDs), reverse);
// 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());
- }
- }
+ reverse = true;
+ AdvanceEntireFocusLoop(reverse_iter(std::end(kLeftTraversalIDs)),
+ reverse_iter(std::begin(kLeftTraversalIDs)), reverse);
// Now test the right container, but this time with accessibility mode.
// Make some links not focusable, but mark one of them as
@@ -755,27 +796,15 @@ 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());
- }
- }
+ reverse = false;
+ AdvanceEntireFocusLoop(std::begin(kRightTraversalIDs),
+ std::end(kRightTraversalIDs), reverse);
// 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());
- }
- }
+ reverse = true;
+ AdvanceEntireFocusLoop(reverse_iter(std::end(kRightTraversalIDs)),
+ reverse_iter(std::begin(kRightTraversalIDs)), reverse);
}
class FocusTraversalNonFocusableTest : public FocusManagerTest {

Powered by Google App Engine
This is Rietveld 408576698