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

Side by Side Diff: content/browser/accessibility/browser_accessibility_win_unittest.cc

Issue 1195223006: Reports the position of the caret and current selection in content editables. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added unit tests. Created 5 years, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/scoped_ptr.h" 5 #include "base/memory/scoped_ptr.h"
6 #include "base/strings/utf_string_conversions.h" 6 #include "base/strings/utf_string_conversions.h"
7 #include "base/win/scoped_bstr.h" 7 #include "base/win/scoped_bstr.h"
8 #include "base/win/scoped_comptr.h" 8 #include "base/win/scoped_comptr.h"
9 #include "base/win/scoped_variant.h" 9 #include "base/win/scoped_variant.h"
10 #include "content/browser/accessibility/browser_accessibility_manager.h" 10 #include "content/browser/accessibility/browser_accessibility_manager.h"
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 EXPECT_NE(nullptr, static_cast<BSTR>(attributes)); 805 EXPECT_NE(nullptr, static_cast<BSTR>(attributes));
806 std::wstring attributes_str(attributes, attributes.Length()); 806 std::wstring attributes_str(attributes, attributes.Length());
807 EXPECT_EQ(L"checkable:true;", attributes_str); 807 EXPECT_EQ(L"checkable:true;", attributes_str);
808 808
809 manager.reset(); 809 manager.reset();
810 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); 810 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
811 } 811 }
812 812
813 /** 813 /**
814 * Ensures that ui::AX_ATTR_TEXT_SEL_START/END attributes are correctly used to 814 * Ensures that ui::AX_ATTR_TEXT_SEL_START/END attributes are correctly used to
815 * determine caret position and text selection in various types of editable 815 * determine caret position and text selection in simple form fields.
816 * elements.
817 */ 816 */
818 TEST_F(BrowserAccessibilityTest, TestCaretAndTextSelection) { 817 TEST_F(BrowserAccessibilityTest, TestCaretAndSelectionInSimpleFields) {
819 ui::AXNodeData root; 818 ui::AXNodeData root;
820 root.id = 1; 819 root.id = 1;
821 root.role = ui::AX_ROLE_ROOT_WEB_AREA; 820 root.role = ui::AX_ROLE_ROOT_WEB_AREA;
822 root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE); 821 root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE);
823 822
824 ui::AXNodeData combo_box; 823 ui::AXNodeData combo_box;
825 combo_box.id = 2; 824 combo_box.id = 2;
826 combo_box.role = ui::AX_ROLE_COMBO_BOX; 825 combo_box.role = ui::AX_ROLE_COMBO_BOX;
827 combo_box.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_FOCUSED); 826 combo_box.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_FOCUSED);
828 combo_box.SetValue("Test1"); 827 combo_box.SetValue("Test1");
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 // -2 is never a valid offset. 867 // -2 is never a valid offset.
869 LONG caret_offset = -2; 868 LONG caret_offset = -2;
870 LONG n_selections = -2; 869 LONG n_selections = -2;
871 LONG selection_start = -2; 870 LONG selection_start = -2;
872 LONG selection_end = -2; 871 LONG selection_end = -2;
873 872
874 // Test get_caretOffset. 873 // Test get_caretOffset.
875 HRESULT hr = combo_box_accessible->get_caretOffset(&caret_offset);; 874 HRESULT hr = combo_box_accessible->get_caretOffset(&caret_offset);;
876 EXPECT_EQ(S_OK, hr); 875 EXPECT_EQ(S_OK, hr);
877 EXPECT_EQ(1L, caret_offset); 876 EXPECT_EQ(1L, caret_offset);
878 // caret_offset should be -1 when the object is not focused. 877 // The caret should be at the start of the selection.
879 hr = text_field_accessible->get_caretOffset(&caret_offset);; 878 hr = text_field_accessible->get_caretOffset(&caret_offset);;
880 EXPECT_EQ(S_FALSE, hr); 879 EXPECT_EQ(S_OK, hr);
881 EXPECT_EQ(-1L, caret_offset); 880 EXPECT_EQ(1L, caret_offset);
882 881
883 // Move the focus to the text field. 882 // Move the focus to the text field.
884 combo_box.state &= ~(1 << ui::AX_STATE_FOCUSED); 883 combo_box.state &= ~(1 << ui::AX_STATE_FOCUSED);
885 text_field.state |= 1 << ui::AX_STATE_FOCUSED; 884 text_field.state |= 1 << ui::AX_STATE_FOCUSED;
886 manager->SetFocus(text_field_accessible, false /* notify */); 885 manager->SetFocus(text_field_accessible, false /* notify */);
887 ASSERT_EQ(text_field_accessible, 886 ASSERT_EQ(text_field_accessible,
888 manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin()); 887 manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin());
889 888
890 // The caret should be at the start of the selection. 889 // The caret should not have moved.
891 hr = text_field_accessible->get_caretOffset(&caret_offset);; 890 hr = text_field_accessible->get_caretOffset(&caret_offset);;
892 EXPECT_EQ(S_OK, hr); 891 EXPECT_EQ(S_OK, hr);
893 EXPECT_EQ(1L, caret_offset); 892 EXPECT_EQ(1L, caret_offset);
894 893
895 // Test get_nSelections. 894 // Test get_nSelections.
896 hr = combo_box_accessible->get_nSelections(&n_selections);; 895 hr = combo_box_accessible->get_nSelections(&n_selections);;
897 EXPECT_EQ(S_OK, hr); 896 EXPECT_EQ(S_OK, hr);
898 EXPECT_EQ(0L, n_selections); 897 EXPECT_EQ(0L, n_selections);
899 hr = text_field_accessible->get_nSelections(&n_selections);; 898 hr = text_field_accessible->get_nSelections(&n_selections);;
900 EXPECT_EQ(S_OK, hr); 899 EXPECT_EQ(S_OK, hr);
901 EXPECT_EQ(1L, n_selections); 900 EXPECT_EQ(1L, n_selections);
902 901
903 // Test get_selection. 902 // Test get_selection.
904 hr = combo_box_accessible->get_selection( 903 hr = combo_box_accessible->get_selection(
905 0L /* selection_index */, &selection_start, &selection_end);; 904 0L /* selection_index */, &selection_start, &selection_end);;
906 EXPECT_EQ(E_INVALIDARG, hr); // No selections available. 905 EXPECT_EQ(E_INVALIDARG, hr); // No selections available.
907 // Invalid in_args should not modify out_args. 906 // Invalid in_args should not modify out_args.
908 EXPECT_EQ(-2L, selection_start); 907 EXPECT_EQ(-2L, selection_start);
909 EXPECT_EQ(-2L, selection_end); 908 EXPECT_EQ(-2L, selection_end);
910 hr = text_field_accessible->get_selection( 909 hr = text_field_accessible->get_selection(
911 0L /* selection_index */, &selection_start, &selection_end);; 910 0L /* selection_index */, &selection_start, &selection_end);;
912 EXPECT_EQ(S_OK, hr); 911 EXPECT_EQ(S_OK, hr);
913 EXPECT_EQ(1L, selection_start); 912 EXPECT_EQ(1L, selection_start);
914 EXPECT_EQ(2L, selection_end); 913 EXPECT_EQ(2L, selection_end);
915 914
916 manager.reset(); 915 manager.reset();
917 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances()); 916 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
918 } 917 }
919 918
919 TEST_F(BrowserAccessibilityTest, TestCaretInContentEditables) {
920 ui::AXNodeData root;
921 root.id = 1;
922 root.role = ui::AX_ROLE_ROOT_WEB_AREA;
923 root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE);
924
925 ui::AXNodeData div_editable;
926 div_editable.id = 2;
927 div_editable.role = ui::AX_ROLE_DIV;
928 div_editable.state = (1 << ui::AX_STATE_FOCUSABLE);
929
930 ui::AXNodeData text;
931 text.id = 3;
932 text.role = ui::AX_ROLE_STATIC_TEXT;
933 text.SetName("Click ");
934
935 ui::AXNodeData link;
936 link.id = 4;
937 link.role = ui::AX_ROLE_LINK;
938 link.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED);
939 link.SetName("here");
940
941 ui::AXNodeData link_text;
942 link_text.id = 5;
943 link_text.role = ui::AX_ROLE_STATIC_TEXT;
944 link_text.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED);
945 link_text.SetName("here");
946
947 // Place the caret between 'h' and 'e'.
948 root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 4);
949 root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, 1);
950 root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 4);
951 root.AddIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, 1);
952
953 root.child_ids.push_back(2);
954 div_editable.child_ids.push_back(3);
955 div_editable.child_ids.push_back(4);
956 link.child_ids.push_back(5);
957
958 CountedBrowserAccessibility::reset();
959 scoped_ptr<BrowserAccessibilityManager> manager(
960 BrowserAccessibilityManager::Create(
961 MakeAXTreeUpdate(root, div_editable, link, link_text, text),
962 nullptr, new CountedBrowserAccessibilityFactory()));
963 ASSERT_EQ(5, CountedBrowserAccessibility::num_instances());
964
965 ASSERT_NE(nullptr, manager->GetRoot());
966 BrowserAccessibilityWin* root_accessible =
967 manager->GetRoot()->ToBrowserAccessibilityWin();
968 ASSERT_NE(nullptr, root_accessible);
969 ASSERT_EQ(1, root_accessible->PlatformChildCount());
970
971 BrowserAccessibilityWin* div_editable_accessible =
972 root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
973 ASSERT_NE(nullptr, div_editable_accessible);
974 ASSERT_EQ(2, div_editable_accessible->PlatformChildCount());
975
976 // -2 is never a valid offset.
977 LONG caret_offset = -2;
978
979 // The caret should be on the embedded object character.
980 HRESULT hr = div_editable_accessible->get_caretOffset(&caret_offset);;
981 EXPECT_EQ(S_OK, hr);
982 EXPECT_EQ(6L, caret_offset);
983
984 // Move the focus to the content editable.
985 div_editable.state |= 1 << ui::AX_STATE_FOCUSED;
dmazzoni 2015/07/16 19:50:23 I don't think this line is doing anything, you're
986 manager->SetFocus(div_editable_accessible, false /* notify */);
987 ASSERT_EQ(div_editable_accessible,
988 manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin());
989
990 BrowserAccessibilityWin* text_accessible =
991 div_editable_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
992 ASSERT_NE(nullptr, text_accessible);
993 BrowserAccessibilityWin* link_accessible =
994 div_editable_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin();
995 ASSERT_NE(nullptr, link_accessible);
996 ASSERT_EQ(1, link_accessible->PlatformChildCount());
997
998 BrowserAccessibilityWin* link_text_accessible =
999 link_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
1000 ASSERT_NE(nullptr, link_text_accessible);
1001
1002 // The caret should not have moved.
1003 hr = div_editable_accessible->get_caretOffset(&caret_offset);;
1004 EXPECT_EQ(S_OK, hr);
1005 EXPECT_EQ(6L, caret_offset);
1006
1007 hr = link_accessible->get_caretOffset(&caret_offset);;
1008 EXPECT_EQ(S_OK, hr);
1009 EXPECT_EQ(1L, caret_offset);
1010 hr = link_text_accessible->get_caretOffset(&caret_offset);;
1011 EXPECT_EQ(S_OK, hr);
1012 EXPECT_EQ(1L, caret_offset);
1013
1014 manager.reset();
1015 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
1016 }
1017
1018 TEST_F(BrowserAccessibilityTest, TestSelectionInContentEditables) {
1019 ui::AXNodeData root;
1020 root.id = 1;
1021 root.role = ui::AX_ROLE_ROOT_WEB_AREA;
1022 root.state = (1 << ui::AX_STATE_READ_ONLY) | (1 << ui::AX_STATE_FOCUSABLE);
1023
1024 ui::AXNodeData div_editable;
1025 div_editable.id = 2;
1026 div_editable.role = ui::AX_ROLE_DIV;
1027 div_editable.state = (1 << ui::AX_STATE_FOCUSABLE);
1028
1029 ui::AXNodeData text;
1030 text.id = 3;
1031 text.role = ui::AX_ROLE_STATIC_TEXT;
1032 text.SetName("Click ");
1033
1034 ui::AXNodeData link;
1035 link.id = 4;
1036 link.role = ui::AX_ROLE_LINK;
1037 link.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED);
1038 link.SetName("here");
1039
1040 ui::AXNodeData link_text;
1041 link_text.id = 5;
1042 link_text.role = ui::AX_ROLE_STATIC_TEXT;
1043 link_text.state = (1 << ui::AX_STATE_FOCUSABLE) | (1 << ui::AX_STATE_LINKED);
1044 link_text.SetName("here");
1045
1046 // Select the part of the text "lick here".
1047 root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OBJECT_ID, 3);
1048 root.AddIntAttribute(ui::AX_ATTR_ANCHOR_OFFSET, 1);
1049 root.AddIntAttribute(ui::AX_ATTR_FOCUS_OBJECT_ID, 5);
1050 root.AddIntAttribute(ui::AX_ATTR_FOCUS_OFFSET, 4);
1051
1052 root.child_ids.push_back(2);
1053 div_editable.child_ids.push_back(3);
1054 div_editable.child_ids.push_back(4);
1055 link.child_ids.push_back(5);
1056
1057 CountedBrowserAccessibility::reset();
1058 scoped_ptr<BrowserAccessibilityManager> manager(
1059 BrowserAccessibilityManager::Create(
1060 MakeAXTreeUpdate(root, div_editable, link, link_text, text),
1061 nullptr, new CountedBrowserAccessibilityFactory()));
1062 ASSERT_EQ(5, CountedBrowserAccessibility::num_instances());
1063
1064 ASSERT_NE(nullptr, manager->GetRoot());
1065 BrowserAccessibilityWin* root_accessible =
1066 manager->GetRoot()->ToBrowserAccessibilityWin();
1067 ASSERT_NE(nullptr, root_accessible);
1068 ASSERT_EQ(1, root_accessible->PlatformChildCount());
1069
1070 BrowserAccessibilityWin* div_editable_accessible =
1071 root_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
1072 ASSERT_NE(nullptr, div_editable_accessible);
1073 ASSERT_EQ(2, div_editable_accessible->PlatformChildCount());
1074
1075 // -2 is never a valid offset.
1076 LONG caret_offset = -2;
1077 LONG n_selections = -2;
1078 LONG selection_start = -2;
1079 LONG selection_end = -2;
1080
1081 BrowserAccessibilityWin* text_accessible =
1082 div_editable_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
1083 ASSERT_NE(nullptr, text_accessible);
1084 BrowserAccessibilityWin* link_accessible =
1085 div_editable_accessible->PlatformGetChild(1)->ToBrowserAccessibilityWin();
1086 ASSERT_NE(nullptr, link_accessible);
1087 ASSERT_EQ(1, link_accessible->PlatformChildCount());
1088
1089 BrowserAccessibilityWin* link_text_accessible =
1090 link_accessible->PlatformGetChild(0)->ToBrowserAccessibilityWin();
1091 ASSERT_NE(nullptr, link_text_accessible);
1092
1093 // get_nSelections should work on all objects.
1094 HRESULT hr = div_editable_accessible->get_nSelections(&n_selections);;
1095 EXPECT_EQ(S_OK, hr);
1096 EXPECT_EQ(1L, n_selections);
1097 hr = text_accessible->get_nSelections(&n_selections);;
1098 EXPECT_EQ(S_OK, hr);
1099 EXPECT_EQ(1L, n_selections);
1100 hr = link_accessible->get_nSelections(&n_selections);;
1101 EXPECT_EQ(S_OK, hr);
1102 EXPECT_EQ(1L, n_selections);
1103 hr = link_text_accessible->get_nSelections(&n_selections);;
1104 EXPECT_EQ(S_OK, hr);
1105 EXPECT_EQ(1L, n_selections);
1106
1107 // get_selection should be unaffected by focus placement.
1108 hr = div_editable_accessible->get_selection(
1109 0L /* selection_index */, &selection_start, &selection_end);;
1110 EXPECT_EQ(S_OK, hr);
1111 EXPECT_EQ(1L, selection_start);
1112 // selection_end should be after embedded object character.
1113 EXPECT_EQ(7L, selection_end);
1114
1115 hr = text_accessible->get_selection(
1116 0L /* selection_index */, &selection_start, &selection_end);;
1117 EXPECT_EQ(S_OK, hr);
1118 EXPECT_EQ(1L, selection_start);
1119 // No embedded character on this object, only the first part of the text.
1120 EXPECT_EQ(6L, selection_end);
1121 hr = link_accessible->get_selection(
1122 0L /* selection_index */, &selection_start, &selection_end);;
1123 EXPECT_EQ(S_OK, hr);
1124 EXPECT_EQ(0L, selection_start);
1125 EXPECT_EQ(4L, selection_end);
1126 hr = link_text_accessible->get_selection(
1127 0L /* selection_index */, &selection_start, &selection_end);;
1128 EXPECT_EQ(S_OK, hr);
1129 EXPECT_EQ(0L, selection_start);
1130 EXPECT_EQ(4L, selection_end);
1131
1132 // The caret should be at the anchor (the start) of the selection.
1133 hr = div_editable_accessible->get_caretOffset(&caret_offset);;
1134 EXPECT_EQ(S_OK, hr);
1135 EXPECT_EQ(1L, caret_offset);
1136
1137 // Move the focus to the content editable.
1138 div_editable.state |= 1 << ui::AX_STATE_FOCUSED;
1139 manager->SetFocus(div_editable_accessible, false /* notify */);
1140 ASSERT_EQ(div_editable_accessible,
1141 manager->GetFocus(root_accessible)->ToBrowserAccessibilityWin());
1142
1143 // The caret should not have moved.
1144 hr = div_editable_accessible->get_caretOffset(&caret_offset);;
1145 EXPECT_EQ(S_OK, hr);
1146 EXPECT_EQ(1L, caret_offset);
1147
1148 // The HRESULT should be S_FALSE if the caret is not in the given object.
1149 hr = link_accessible->get_caretOffset(&caret_offset);;
1150 EXPECT_EQ(S_FALSE, hr);
1151 EXPECT_EQ(-1L, caret_offset);
1152 hr = link_text_accessible->get_caretOffset(&caret_offset);;
1153 EXPECT_EQ(S_FALSE, hr);
1154 EXPECT_EQ(-1L, caret_offset);
1155
1156 hr = div_editable_accessible->get_selection(
1157 0L /* selection_index */, &selection_start, &selection_end);;
1158 EXPECT_EQ(S_OK, hr);
1159 EXPECT_EQ(1L, selection_start);
1160 EXPECT_EQ(7L, selection_end);
1161
1162 manager.reset();
1163 ASSERT_EQ(0, CountedBrowserAccessibility::num_instances());
1164 }
1165
920 } // namespace content 1166 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698