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. 4 5 #include <vector> 6 7 #include "ash/test/ash_test_base.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "chrome/browser/ui/ash/accessibility/ax_tree_source_ash.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 #include "ui/accessibility/ax_enums.h" 12 #include "ui/accessibility/ax_node.h" 13 #include "ui/accessibility/ax_serializable_tree.h" 14 #include "ui/accessibility/ax_tree_serializer.h" 15 #include "ui/accessibility/ax_tree_update.h" 16 #include "ui/aura/window.h" 17 #include "ui/views/accessibility/ax_aura_obj_cache.h" 18 #include "ui/views/accessibility/ax_aura_obj_wrapper.h" 19 #include "ui/views/controls/textfield/textfield.h" 20 #include "ui/views/test/views_test_base.h" 21 #include "ui/views/widget/widget.h" 22 23 using views::AXAuraObjCache; 24 using views::AXAuraObjWrapper; 25 using views::Textfield; 26 using views::View; 27 using views::Widget; 28 29 // Helper to count the number of nodes in a tree. 30 size_t GetSize(AXAuraObjWrapper* tree) { 31 size_t count = 1; 32 33 std::vector<AXAuraObjWrapper*> out_children; 34 tree->GetChildren(&out_children); 35 36 for (size_t i = 0; i < out_children.size(); ++i) 37 count += GetSize(out_children[i]); 38 39 return count; 40 } 41 42 class AXTreeSourceAshTest : public ash::test::AshTestBase { 43 public: 44 AXTreeSourceAshTest() {} 45 virtual ~AXTreeSourceAshTest() {} 46 47 virtual void SetUp() OVERRIDE { 48 AshTestBase::SetUp(); 49 50 widget_ = new Widget(); 51 Widget::InitParams init_params(Widget::InitParams::TYPE_POPUP); 52 init_params.parent = CurrentContext(); 53 widget_->Init(init_params); 54 55 content_ = new View(); 56 widget_->SetContentsView(content_); 57 58 textfield_ = new Textfield(); 59 textfield_->SetText(base::ASCIIToUTF16("Value")); 60 content_->AddChildView(textfield_); 61 } 62 63 protected: 64 Widget* widget_; 65 View* content_; 66 Textfield* textfield_; 67 68 private: 69 DISALLOW_COPY_AND_ASSIGN(AXTreeSourceAshTest); 70 }; 71 72 TEST_F(AXTreeSourceAshTest, Accessors) { 73 AXTreeSourceAsh ax_tree; 74 ASSERT_TRUE(ax_tree.GetRoot()); 75 76 // ID's should start at 1 and there should be a root. 77 ASSERT_EQ(1, ax_tree.GetRoot()->GetID()); 78 79 // Grab the content view directly from cache to avoid walking down the tree. 80 AXAuraObjWrapper* content = 81 AXAuraObjCache::GetInstance()->GetOrCreate(content_); 82 std::vector<AXAuraObjWrapper*> content_children; 83 ax_tree.GetChildren(content, &content_children); 84 ASSERT_EQ(1U, content_children.size()); 85 86 // Walk down to the text field and assert it is what we expect. 87 AXAuraObjWrapper* textfield = content_children[0]; 88 AXAuraObjWrapper* cached_textfield = 89 AXAuraObjCache::GetInstance()->GetOrCreate(textfield_); 90 ASSERT_EQ(cached_textfield, textfield); 91 std::vector<AXAuraObjWrapper*> textfield_children; 92 ax_tree.GetChildren(textfield, &textfield_children); 93 ASSERT_EQ(0U, textfield_children.size()); 94 95 ASSERT_EQ(content, textfield->GetParent()); 96 97 // Try walking up the tree to the root. 98 AXAuraObjWrapper* root_finder = content; 99 AXAuraObjWrapper* test_root = NULL; 100 while ((root_finder = ax_tree.GetParent(root_finder))) 101 test_root = root_finder; 102 ASSERT_EQ(ax_tree.GetRoot(), test_root); 103 } 104 105 TEST_F(AXTreeSourceAshTest, Serialization) { 106 AXTreeSourceAsh ax_tree; 107 ui::AXTreeSerializer<AXAuraObjWrapper*> ax_serializer(&ax_tree); 108 ui::AXTreeUpdate out_update; 109 110 // This is the initial serialization. 111 ax_serializer.SerializeChanges(ax_tree.GetRoot(), &out_update); 112 113 // We should get an update per node. 114 ASSERT_EQ(GetSize(ax_tree.GetRoot()), out_update.nodes.size()); 115 116 // Try removing some child views and re-adding. 117 content_->RemoveAllChildViews(false /* delete_children */); 118 content_->AddChildView(textfield_); 119 120 // Grab the textfield since serialization only walks up the tree (not down 121 // from root). 122 AXAuraObjWrapper* textfield_wrapper = 123 AXAuraObjCache::GetInstance()->GetOrCreate(textfield_); 124 125 // Now, re-serialize. 126 ui::AXTreeUpdate out_update2; 127 ax_serializer.SerializeChanges(textfield_wrapper, &out_update2); 128 129 // We should have far fewer updates this time around. 130 ASSERT_EQ(2U, out_update2.nodes.size()); 131 ASSERT_EQ(ui::AX_ROLE_CLIENT, 132 out_update2.nodes[0].role); 133 134 ASSERT_EQ(textfield_wrapper->GetID(), out_update2.nodes[1].id); 135 ASSERT_EQ(ui::AX_ROLE_TEXT_FIELD, 136 out_update2.nodes[1].role); 137 } 138 139 TEST_F(AXTreeSourceAshTest, DoDefault) { 140 AXTreeSourceAsh ax_tree; 141 142 // Grab a wrapper to |DoDefault| (click). 143 AXAuraObjWrapper* textfield_wrapper = 144 AXAuraObjCache::GetInstance()->GetOrCreate(textfield_); 145 146 // Click and verify focus. 147 ASSERT_FALSE(textfield_->HasFocus()); 148 textfield_wrapper->DoDefault(); 149 ASSERT_TRUE(textfield_->HasFocus()); 150 } 151 152 TEST_F(AXTreeSourceAshTest, Focus) { 153 AXTreeSourceAsh ax_tree; 154 155 // Grab a wrapper to focus. 156 AXAuraObjWrapper* textfield_wrapper = 157 AXAuraObjCache::GetInstance()->GetOrCreate(textfield_); 158 159 // Focus and verify. 160 ASSERT_FALSE(textfield_->HasFocus()); 161 textfield_wrapper->Focus(); 162 ASSERT_TRUE(textfield_->HasFocus()); 163 } 164