summaryrefslogtreecommitdiff
path: root/chromium/ui/accessibility/ax_tree_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/accessibility/ax_tree_unittest.cc')
-rw-r--r--chromium/ui/accessibility/ax_tree_unittest.cc313
1 files changed, 255 insertions, 58 deletions
diff --git a/chromium/ui/accessibility/ax_tree_unittest.cc b/chromium/ui/accessibility/ax_tree_unittest.cc
index 05c962720ea..8f2c3ce8541 100644
--- a/chromium/ui/accessibility/ax_tree_unittest.cc
+++ b/chromium/ui/accessibility/ax_tree_unittest.cc
@@ -3138,7 +3138,7 @@ TEST(AXTreeTest, ChildTreeIds) {
}
// Tests GetPosInSet and GetSetSize return the assigned int attribute values.
-TEST(AXTreeTest, TestSetSizePosInSetAssigned) {
+TEST(AXTreeTest, SetSizePosInSetAssigned) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
@@ -3170,8 +3170,8 @@ TEST(AXTreeTest, TestSetSizePosInSetAssigned) {
EXPECT_OPTIONAL_EQ(12, item3->GetSetSize());
}
-// Tests that pos_in_set and set_size can be calculated if not assigned.
-TEST(AXTreeTest, TestSetSizePosInSetUnassigned) {
+// Tests that PosInSet and SetSize can be calculated if not assigned.
+TEST(AXTreeTest, SetSizePosInSetUnassigned) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
@@ -3197,9 +3197,9 @@ TEST(AXTreeTest, TestSetSizePosInSetUnassigned) {
EXPECT_OPTIONAL_EQ(3, item3->GetSetSize());
}
-// Tests pos_in_set can be calculated if unassigned, and set_size can be
+// Tests PosInSet can be calculated if unassigned, and SetSize can be
// assigned on the outerlying ordered set.
-TEST(AXTreeTest, TestSetSizeAssignedInContainer) {
+TEST(AXTreeTest, SetSizeAssignedOnContainer) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
@@ -3215,18 +3215,21 @@ TEST(AXTreeTest, TestSetSizeAssignedInContainer) {
tree_update.nodes[3].role = ax::mojom::Role::kListItem;
AXTree tree(tree_update);
- // Items should inherit set_size from ordered set if not specified.
+ // Items should inherit SetSize from ordered set if not specified.
AXNode* item1 = tree.GetFromId(2);
EXPECT_OPTIONAL_EQ(7, item1->GetSetSize());
+ EXPECT_OPTIONAL_EQ(1, item1->GetPosInSet());
AXNode* item2 = tree.GetFromId(3);
EXPECT_OPTIONAL_EQ(7, item2->GetSetSize());
+ EXPECT_OPTIONAL_EQ(2, item2->GetPosInSet());
AXNode* item3 = tree.GetFromId(4);
EXPECT_OPTIONAL_EQ(7, item3->GetSetSize());
+ EXPECT_OPTIONAL_EQ(3, item3->GetPosInSet());
}
// Tests GetPosInSet and GetSetSize on a list containing various roles.
// Roles for items and associated ordered set should match up.
-TEST(AXTreeTest, TestSetSizePosInSetDiverseList) {
+TEST(AXTreeTest, SetSizePosInSetDiverseList) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(6);
@@ -3261,12 +3264,12 @@ TEST(AXTreeTest, TestSetSizePosInSetDiverseList) {
EXPECT_OPTIONAL_EQ(4, item3->GetPosInSet());
EXPECT_OPTIONAL_EQ(4, item3->GetSetSize());
AXNode* tab = tree.GetFromId(6);
- EXPECT_OPTIONAL_EQ(0, tab->GetPosInSet());
- EXPECT_OPTIONAL_EQ(0, tab->GetSetSize());
+ EXPECT_FALSE(tab->GetPosInSet());
+ EXPECT_FALSE(tab->GetSetSize());
}
// Tests GetPosInSet and GetSetSize on a nested list.
-TEST(AXTreeTest, TestSetSizePosInSetNestedList) {
+TEST(AXTreeTest, SetSizePosInSetNestedList) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(7);
@@ -3307,9 +3310,9 @@ TEST(AXTreeTest, TestSetSizePosInSetNestedList) {
EXPECT_OPTIONAL_EQ(3, outer_item3->GetSetSize());
}
-// Tests pos_in_set can be calculated if one item specifies pos_in_set, but
+// Tests PosInSet can be calculated if one item specifies PosInSet, but
// other assignments are missing.
-TEST(AXTreeTest, TestPosInSetMissing) {
+TEST(AXTreeTest, PosInSetMissing) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
@@ -3339,8 +3342,8 @@ TEST(AXTreeTest, TestPosInSetMissing) {
EXPECT_OPTIONAL_EQ(20, item3->GetSetSize());
}
-// A more difficult test that involves missing pos_in_set and set_size values.
-TEST(AXTreeTest, TestSetSizePosInSetMissingDifficult) {
+// A more difficult test that involves missing PosInSet and SetSize values.
+TEST(AXTreeTest, SetSizePosInSetMissingDifficult) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(6);
@@ -3380,9 +3383,9 @@ TEST(AXTreeTest, TestSetSizePosInSetMissingDifficult) {
EXPECT_OPTIONAL_EQ(11, item5->GetSetSize());
}
-// Tests that code overwrites decreasing set_size assignments to largest of
+// Tests that code overwrites decreasing SetSize assignments to largest of
// assigned values.
-TEST(AXTreeTest, TestSetSizeDecreasing) {
+TEST(AXTreeTest, SetSizeDecreasing) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
@@ -3410,8 +3413,8 @@ TEST(AXTreeTest, TestSetSizeDecreasing) {
EXPECT_OPTIONAL_EQ(5, item3->GetSetSize());
}
-// Tests that code overwrites decreasing pos_in_set values.
-TEST(AXTreeTest, TestPosInSetDecreasing) {
+// Tests that code overwrites decreasing PosInSet values.
+TEST(AXTreeTest, PosInSetDecreasing) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
@@ -3439,10 +3442,10 @@ TEST(AXTreeTest, TestPosInSetDecreasing) {
EXPECT_OPTIONAL_EQ(8, item3->GetSetSize());
}
-// Tests that code overwrites duplicate pos_in_set values. Note this case is
+// Tests that code overwrites duplicate PosInSet values. Note this case is
// tricky; an update to the second element causes an update to the third
// element.
-TEST(AXTreeTest, TestPosInSetDuplicates) {
+TEST(AXTreeTest, PosInSetDuplicates) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
@@ -3473,7 +3476,7 @@ TEST(AXTreeTest, TestPosInSetDuplicates) {
// Tests GetPosInSet and GetSetSize when some list items are nested in a generic
// container.
-TEST(AXTreeTest, TestSetSizePosInSetNestedContainer) {
+TEST(AXTreeTest, SetSizePosInSetNestedContainer) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(7);
@@ -3517,10 +3520,8 @@ TEST(AXTreeTest, TestSetSizePosInSetNestedContainer) {
}
// Tests GetSetSize and GetPosInSet are correct, even when list items change.
-// This test is directed at the caching functionality of pos_in_set and
-// set_size. Tests that previously calculated values are not used after
-// tree is updated.
-TEST(AXTreeTest, TestSetSizePosInSetDeleteItem) {
+// Tests that previously calculated values are not used after tree is updated.
+TEST(AXTreeTest, SetSizePosInSetDeleteItem) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(4);
@@ -3561,9 +3562,9 @@ TEST(AXTreeTest, TestSetSizePosInSetDeleteItem) {
// Tests GetSetSize and GetPosInSet are correct, even when list items change.
// This test adds an item to the front of a list, which invalidates previously
-// calculated pos_in_set and set_size values. Tests that old values are not
+// calculated PosInSet and SetSize values. Tests that old values are not
// used after tree is updated.
-TEST(AXTreeTest, TestSetSizePosInSetAddItem) {
+TEST(AXTreeTest, SetSizePosInSetAddItem) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(4);
@@ -3611,22 +3612,22 @@ TEST(AXTreeTest, TestSetSizePosInSetAddItem) {
EXPECT_OPTIONAL_EQ(4, new_item4->GetSetSize());
}
-// Tests that the outerlying ordered set reports a set_size. Ordered sets
-// should not report a pos_in_set value other than 0, since they are not
+// Tests that the outerlying ordered set reports a SetSize. Ordered sets
+// should not report a PosInSet value other than 0, since they are not
// considered to be items within a set (even when nested).
-TEST(AXTreeTest, TestOrderedSetReportsSetSize) {
+TEST(AXTreeTest, OrderedSetReportsSetSize) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(12);
tree_update.nodes[0].id = 1;
- tree_update.nodes[0].role = ax::mojom::Role::kList; // set_size = 3
+ tree_update.nodes[0].role = ax::mojom::Role::kList; // SetSize = 3
tree_update.nodes[0].child_ids = {2, 3, 4, 7, 8, 9, 12};
tree_update.nodes[1].id = 2;
tree_update.nodes[1].role = ax::mojom::Role::kListItem; // 1 of 3
tree_update.nodes[2].id = 3;
tree_update.nodes[2].role = ax::mojom::Role::kListItem; // 2 of 3
tree_update.nodes[3].id = 4;
- tree_update.nodes[3].role = ax::mojom::Role::kList; // set_size = 2
+ tree_update.nodes[3].role = ax::mojom::Role::kList; // SetSize = 2
tree_update.nodes[3].child_ids = {5, 6};
tree_update.nodes[4].id = 5;
tree_update.nodes[4].role = ax::mojom::Role::kListItem; // 1 of 2
@@ -3635,10 +3636,10 @@ TEST(AXTreeTest, TestOrderedSetReportsSetSize) {
tree_update.nodes[6].id = 7;
tree_update.nodes[6].role = ax::mojom::Role::kListItem; // 3 of 3
tree_update.nodes[7].id = 8;
- tree_update.nodes[7].role = ax::mojom::Role::kList; // set_size = 0
+ tree_update.nodes[7].role = ax::mojom::Role::kList; // SetSize = 0
tree_update.nodes[8].id = 9;
tree_update.nodes[8].role =
- ax::mojom::Role::kList; // set_size = 1 because only 1 item whose role
+ ax::mojom::Role::kList; // SetSize = 1 because only 1 item whose role
// matches
tree_update.nodes[8].child_ids = {10, 11};
tree_update.nodes[9].id = 10;
@@ -3682,8 +3683,8 @@ TEST(AXTreeTest, TestOrderedSetReportsSetSize) {
// Only 1 item whose role matches.
EXPECT_OPTIONAL_EQ(1, inner_list3->GetSetSize());
AXNode* inner_list3_article1 = tree.GetFromId(10);
- EXPECT_OPTIONAL_EQ(0, inner_list3_article1->GetPosInSet());
- EXPECT_OPTIONAL_EQ(0, inner_list3_article1->GetSetSize());
+ EXPECT_FALSE(inner_list3_article1->GetPosInSet());
+ EXPECT_FALSE(inner_list3_article1->GetSetSize());
AXNode* inner_list3_item1 = tree.GetFromId(11);
EXPECT_OPTIONAL_EQ(1, inner_list3_item1->GetPosInSet());
EXPECT_OPTIONAL_EQ(1, inner_list3_item1->GetSetSize());
@@ -3696,7 +3697,7 @@ TEST(AXTreeTest, TestOrderedSetReportsSetSize) {
}
// Tests GetPosInSet and GetSetSize code on invalid input.
-TEST(AXTreeTest, TestSetSizePosInSetInvalid) {
+TEST(AXTreeTest, SetSizePosInSetInvalid) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(3);
@@ -3715,17 +3716,17 @@ TEST(AXTreeTest, TestSetSizePosInSetInvalid) {
EXPECT_FALSE(item1->GetPosInSet());
EXPECT_FALSE(item1->GetSetSize());
AXNode* item2 = tree.GetFromId(2);
- EXPECT_OPTIONAL_EQ(0, item2->GetPosInSet());
- EXPECT_OPTIONAL_EQ(0, item2->GetSetSize());
+ EXPECT_FALSE(item2->GetPosInSet());
+ EXPECT_FALSE(item2->GetSetSize());
AXNode* item3 = tree.GetFromId(3);
- EXPECT_OPTIONAL_EQ(0, item3->GetPosInSet());
- EXPECT_OPTIONAL_EQ(0, item3->GetSetSize());
+ EXPECT_FALSE(item3->GetPosInSet());
+ EXPECT_FALSE(item3->GetSetSize());
}
// Tests GetPosInSet and GetSetSize code on kRadioButtons. Radio buttons
// behave differently than other item-like elements; most notably, they do not
// need to be contained within an ordered set to report a PosInSet or SetSize.
-TEST(AXTreeTest, TestSetSizePosInSetRadioButtons) {
+TEST(AXTreeTest, SetSizePosInSetRadioButtons) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(13);
@@ -3837,13 +3838,13 @@ TEST(AXTreeTest, TestSetSizePosInSetRadioButtons) {
// Tests GetPosInSet and GetSetSize on a list that includes radio buttons.
// Note that radio buttons do not contribute to the SetSize of the outerlying
// list.
-TEST(AXTreeTest, TestSetSizePosInSetRadioButtonsInList) {
+TEST(AXTreeTest, SetSizePosInSetRadioButtonsInList) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(6);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].role =
- ax::mojom::Role::kList; // set_size = 2, since only contains 2 ListItems
+ ax::mojom::Role::kList; // SetSize = 2, since only contains 2 ListItems
tree_update.nodes[0].child_ids = {2, 3, 4, 5, 6};
tree_update.nodes[1].id = 2;
@@ -3888,7 +3889,7 @@ TEST(AXTreeTest, TestSetSizePosInSetRadioButtonsInList) {
// to the tree representation, the three elements are siblings. However,
// due to the presence of the kHierarchicalLevel attribute, they all belong
// to different sets.
-TEST(AXTreeTest, TestSetSizePosInSetFlatTree) {
+TEST(AXTreeTest, SetSizePosInSetFlatTree) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(4);
@@ -3922,7 +3923,7 @@ TEST(AXTreeTest, TestSetSizePosInSetFlatTree) {
// Tests GetPosInSet and GetSetSize on a flat tree representation, where only
// the level is specified.
-TEST(AXTreeTest, TestSetSizePosInSetFlatTreeLevelsOnly) {
+TEST(AXTreeTest, SetSizePosInSetFlatTreeLevelsOnly) {
AXTreeUpdate tree_update;
tree_update.root_id = 1;
tree_update.nodes.resize(9);
@@ -3994,7 +3995,7 @@ TEST(AXTreeTest, TestSetSizePosInSetFlatTreeLevelsOnly) {
// Tests that GetPosInSet and GetSetSize work while a tree is being
// unserialized.
-TEST(AXTreeTest, TestSetSizePosInSetSubtreeDeleted) {
+TEST(AXTreeTest, SetSizePosInSetSubtreeDeleted) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(3);
@@ -4035,7 +4036,7 @@ TEST(AXTreeTest, TestSetSizePosInSetSubtreeDeleted) {
}
// Tests that GetPosInSet and GetSetSize work when there are ignored nodes.
-TEST(AXTreeTest, TestSetSizePosInSetIgnoredItem) {
+TEST(AXTreeTest, SetSizePosInSetIgnoredItem) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(3);
@@ -4083,7 +4084,7 @@ TEST(AXTreeTest, TestSetSizePosInSetIgnoredItem) {
// Tests that kPopUpButtons are assigned the SetSize of the wrapped
// kMenuListPopup, if one is present.
-TEST(AXTreeTest, TestSetSizePosInSetPopUpButton) {
+TEST(AXTreeTest, SetSizePosInSetPopUpButton) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(6);
@@ -4114,7 +4115,7 @@ TEST(AXTreeTest, TestSetSizePosInSetPopUpButton) {
// Tests that PosInSet and SetSize are still correctly calculated when there
// are nodes with role of kUnknown layered between items and ordered set.
-TEST(AXTreeTest, TestSetSizePosInSetUnkown) {
+TEST(AXTreeTest, SetSizePosInSetUnkown) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(5);
@@ -4143,7 +4144,7 @@ TEST(AXTreeTest, TestSetSizePosInSetUnkown) {
EXPECT_OPTIONAL_EQ(2, item2->GetSetSize());
}
-TEST(AXTreeTest, TestSetSizePosInSetMenuItemValidChildOfMenuListPopup) {
+TEST(AXTreeTest, SetSizePosInSetMenuItemValidChildOfMenuListPopup) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(3);
@@ -4166,7 +4167,7 @@ TEST(AXTreeTest, TestSetSizePosInSetMenuItemValidChildOfMenuListPopup) {
EXPECT_OPTIONAL_EQ(2, item2->GetSetSize());
}
-TEST(AXTreeTest, TestSetSizePostInSetListBoxOptionWithGroup) {
+TEST(AXTreeTest, SetSizePostInSetListBoxOptionWithGroup) {
AXTreeUpdate initial_state;
initial_state.root_id = 1;
initial_state.nodes.resize(7);
@@ -4191,16 +4192,212 @@ TEST(AXTreeTest, TestSetSizePostInSetListBoxOptionWithGroup) {
AXNode* listbox_option1 = tree.GetFromId(4);
EXPECT_OPTIONAL_EQ(1, listbox_option1->GetPosInSet());
- EXPECT_OPTIONAL_EQ(2, listbox_option1->GetSetSize());
+ EXPECT_OPTIONAL_EQ(4, listbox_option1->GetSetSize());
AXNode* listbox_option2 = tree.GetFromId(5);
EXPECT_OPTIONAL_EQ(2, listbox_option2->GetPosInSet());
- EXPECT_OPTIONAL_EQ(2, listbox_option2->GetSetSize());
+ EXPECT_OPTIONAL_EQ(4, listbox_option2->GetSetSize());
AXNode* listbox_option3 = tree.GetFromId(6);
- EXPECT_OPTIONAL_EQ(1, listbox_option3->GetPosInSet());
- EXPECT_OPTIONAL_EQ(2, listbox_option3->GetSetSize());
+ EXPECT_OPTIONAL_EQ(3, listbox_option3->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, listbox_option3->GetSetSize());
AXNode* listbox_option4 = tree.GetFromId(7);
- EXPECT_OPTIONAL_EQ(2, listbox_option4->GetPosInSet());
- EXPECT_OPTIONAL_EQ(2, listbox_option4->GetSetSize());
+ EXPECT_OPTIONAL_EQ(4, listbox_option4->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, listbox_option4->GetSetSize());
+}
+
+TEST(AXTreeTest, SetSizePosInSetGroup) {
+ // The behavior of a group changes depending on the context it appears in
+ // i.e. if it appears alone vs. if it is contained within another set-like
+ // element. The below example shows a group standing alone:
+ //
+ // <ul role="group"> <!-- SetSize = 3 -->
+ // <li role="menuitemradio" aria-checked="true">Small</li>
+ // <li role="menuitemradio" aria-checked="false">Medium</li>
+ // <li role="menuitemradio" aria-checked="false">Large</li>
+ // </ul>
+ //
+ // However, when it is contained within another set-like element, like a
+ // listbox, it should simply act like a generic container:
+ //
+ // <div role="listbox"> <!-- SetSize = 3 -->
+ // <div role="option">Red</div> <!-- 1 of 3 -->
+ // <div role="option">Yellow</div> <!-- 2 of 3 -->
+ // <div role="group"> <!-- SetSize = 0 -->
+ // <div role="option">Blue</div> <!-- 3 of 3 -->
+ // </div>
+ // </div>
+ //
+ // Please note: the GetPosInSet and GetSetSize functions take slightly
+ // different code paths when initially run on items vs. the container.
+ // Exercise both code paths in this test.
+
+ AXTreeUpdate tree_update;
+ tree_update.root_id = 1;
+ tree_update.nodes.resize(6);
+ tree_update.nodes[0].id = 1;
+ tree_update.nodes[0].role = ax::mojom::Role::kMenu; // SetSize = 4
+ tree_update.nodes[0].child_ids = {2, 6};
+ tree_update.nodes[1].id = 2;
+ tree_update.nodes[1].role = ax::mojom::Role::kGroup; // SetSize = 0
+ tree_update.nodes[1].child_ids = {3, 4, 5};
+ tree_update.nodes[2].id = 3;
+ tree_update.nodes[2].role = ax::mojom::Role::kMenuItemRadio; // 1 of 4
+ tree_update.nodes[3].id = 4;
+ tree_update.nodes[3].role = ax::mojom::Role::kMenuItemRadio; // 2 of 4
+ tree_update.nodes[4].id = 5;
+ tree_update.nodes[4].role = ax::mojom::Role::kMenuItemRadio; // 3 of 4
+ tree_update.nodes[5].id = 6;
+ tree_update.nodes[5].role = ax::mojom::Role::kMenuItemRadio; // 4 of 4
+ AXTree tree(tree_update);
+
+ // Get data on kMenu first.
+ AXNode* menu = tree.GetFromId(1);
+ EXPECT_OPTIONAL_EQ(4, menu->GetSetSize());
+ AXNode* group = tree.GetFromId(2);
+ EXPECT_FALSE(group->GetSetSize());
+ // The below values should have already been computed and cached.
+ AXNode* item1 = tree.GetFromId(3);
+ EXPECT_OPTIONAL_EQ(1, item1->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, item1->GetSetSize());
+ AXNode* item4 = tree.GetFromId(6);
+ EXPECT_OPTIONAL_EQ(4, item4->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, item4->GetSetSize());
+
+ AXTreeUpdate next_tree_update;
+ next_tree_update.root_id = 1;
+ next_tree_update.nodes.resize(6);
+ next_tree_update.nodes[0].id = 1;
+ next_tree_update.nodes[0].role = ax::mojom::Role::kListBox; // SetSize = 4
+ next_tree_update.nodes[0].child_ids = {2, 6};
+ next_tree_update.nodes[1].id = 2;
+ next_tree_update.nodes[1].role = ax::mojom::Role::kGroup; // SetSize = 0
+ next_tree_update.nodes[1].child_ids = {3, 4, 5};
+ next_tree_update.nodes[2].id = 3;
+ next_tree_update.nodes[2].role = ax::mojom::Role::kListBoxOption; // 1 of 4
+ next_tree_update.nodes[3].id = 4;
+ next_tree_update.nodes[3].role = ax::mojom::Role::kListBoxOption; // 2 of 4
+ next_tree_update.nodes[4].id = 5;
+ next_tree_update.nodes[4].role = ax::mojom::Role::kListBoxOption; // 3 of 4
+ next_tree_update.nodes[5].id = 6;
+ next_tree_update.nodes[5].role = ax::mojom::Role::kListBoxOption; // 4 of 4
+ AXTree next_tree(next_tree_update);
+
+ // Get data on kListBoxOption first.
+ AXNode* option1 = next_tree.GetFromId(3);
+ EXPECT_OPTIONAL_EQ(1, option1->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, option1->GetSetSize());
+ AXNode* option2 = next_tree.GetFromId(4);
+ EXPECT_OPTIONAL_EQ(2, option2->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, option2->GetSetSize());
+ AXNode* option3 = next_tree.GetFromId(5);
+ EXPECT_OPTIONAL_EQ(3, option3->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, option3->GetSetSize());
+ AXNode* option4 = next_tree.GetFromId(6);
+ EXPECT_OPTIONAL_EQ(4, option4->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, option4->GetSetSize());
+ AXNode* next_group = next_tree.GetFromId(2);
+ EXPECT_FALSE(next_group->GetSetSize());
+ // The below value should have already been computed and cached.
+ AXNode* listbox = next_tree.GetFromId(1);
+ EXPECT_OPTIONAL_EQ(4, listbox->GetSetSize());
+
+ // Standalone groups are allowed.
+ AXTreeUpdate third_tree_update;
+ third_tree_update.root_id = 1;
+ third_tree_update.nodes.resize(3);
+ third_tree_update.nodes[0].id = 1;
+ third_tree_update.nodes[0].role = ax::mojom::Role::kGroup;
+ third_tree_update.nodes[0].child_ids = {2, 3};
+ third_tree_update.nodes[1].id = 2;
+ third_tree_update.nodes[1].role = ax::mojom::Role::kListItem;
+ third_tree_update.nodes[2].id = 3;
+ third_tree_update.nodes[2].role = ax::mojom::Role::kListItem;
+ AXTree third_tree(third_tree_update);
+
+ // Ensure that groups can't also stand alone.
+ AXNode* last_group = third_tree.GetFromId(1);
+ EXPECT_OPTIONAL_EQ(2, last_group->GetSetSize());
+ AXNode* list_item1 = third_tree.GetFromId(2);
+ EXPECT_OPTIONAL_EQ(1, list_item1->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(2, list_item1->GetSetSize());
+ AXNode* list_item2 = third_tree.GetFromId(3);
+ EXPECT_OPTIONAL_EQ(2, list_item2->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(2, list_item2->GetSetSize());
+
+ // Test nested groups.
+ AXTreeUpdate last_tree_update;
+ last_tree_update.root_id = 1;
+ last_tree_update.nodes.resize(6);
+ last_tree_update.nodes[0].id = 1;
+ last_tree_update.nodes[0].role = ax::mojom::Role::kMenuBar;
+ last_tree_update.nodes[0].child_ids = {2};
+ last_tree_update.nodes[1].id = 2;
+ last_tree_update.nodes[1].role = ax::mojom::Role::kGroup;
+ last_tree_update.nodes[1].child_ids = {3, 4};
+ last_tree_update.nodes[2].id = 3;
+ last_tree_update.nodes[2].role = ax::mojom::Role::kMenuItemCheckBox;
+ last_tree_update.nodes[3].id = 4;
+ last_tree_update.nodes[3].role = ax::mojom::Role::kGroup;
+ last_tree_update.nodes[3].child_ids = {5, 6};
+ last_tree_update.nodes[4].id = 5;
+ last_tree_update.nodes[4].role = ax::mojom::Role::kMenuItemCheckBox;
+ last_tree_update.nodes[5].id = 6;
+ last_tree_update.nodes[5].role = ax::mojom::Role::kMenuItemCheckBox;
+ AXTree last_tree(last_tree_update);
+
+ AXNode* checkbox1 = last_tree.GetFromId(3);
+ EXPECT_OPTIONAL_EQ(1, checkbox1->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(3, checkbox1->GetSetSize());
+ AXNode* checkbox2 = last_tree.GetFromId(5);
+ EXPECT_OPTIONAL_EQ(2, checkbox2->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(3, checkbox2->GetSetSize());
+ AXNode* checkbox3 = last_tree.GetFromId(6);
+ EXPECT_OPTIONAL_EQ(3, checkbox3->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(3, checkbox3->GetSetSize());
+ AXNode* menu_bar = last_tree.GetFromId(1);
+ EXPECT_OPTIONAL_EQ(3, menu_bar->GetSetSize());
+ AXNode* outer_group = last_tree.GetFromId(2);
+ EXPECT_FALSE(outer_group->GetSetSize());
+ AXNode* inner_group = last_tree.GetFromId(4);
+ EXPECT_FALSE(inner_group->GetSetSize());
+}
+
+TEST(AXTreeTest, SetSizePosInSetHidden) {
+ AXTreeUpdate tree_update;
+ tree_update.root_id = 1;
+ tree_update.nodes.resize(6);
+ tree_update.nodes[0].id = 1;
+ tree_update.nodes[0].role = ax::mojom::Role::kListBox; // SetSize = 4
+ tree_update.nodes[0].child_ids = {2, 3, 4, 5, 6};
+ tree_update.nodes[1].id = 2;
+ tree_update.nodes[1].role = ax::mojom::Role::kListBoxOption; // 1 of 4
+ tree_update.nodes[2].id = 3;
+ tree_update.nodes[2].role = ax::mojom::Role::kListBoxOption; // 2 of 4
+ tree_update.nodes[3].id = 4;
+ tree_update.nodes[3].role = ax::mojom::Role::kListBoxOption; // Hidden
+ tree_update.nodes[3].AddState(ax::mojom::State::kInvisible);
+ tree_update.nodes[4].id = 5;
+ tree_update.nodes[4].role = ax::mojom::Role::kListBoxOption; // 3 of 4
+ tree_update.nodes[5].id = 6;
+ tree_update.nodes[5].role = ax::mojom::Role::kListBoxOption; // 4 of 4
+ AXTree tree(tree_update);
+
+ AXNode* list_box = tree.GetFromId(1);
+ EXPECT_OPTIONAL_EQ(4, list_box->GetSetSize());
+ AXNode* option1 = tree.GetFromId(2);
+ EXPECT_OPTIONAL_EQ(1, option1->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, option1->GetSetSize());
+ AXNode* option2 = tree.GetFromId(3);
+ EXPECT_OPTIONAL_EQ(2, option2->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, option2->GetSetSize());
+ AXNode* option_hidden = tree.GetFromId(4);
+ EXPECT_FALSE(option_hidden->GetPosInSet());
+ EXPECT_FALSE(option_hidden->GetSetSize());
+ AXNode* option3 = tree.GetFromId(5);
+ EXPECT_OPTIONAL_EQ(3, option3->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, option3->GetSetSize());
+ AXNode* option4 = tree.GetFromId(6);
+ EXPECT_OPTIONAL_EQ(4, option4->GetPosInSet());
+ EXPECT_OPTIONAL_EQ(4, option4->GetSetSize());
}
TEST(AXTreeTest, OnNodeWillBeDeletedHasValidUnignoredParent) {