| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/accessibility/one_shot_accessibility_tree_search.h" |
| |
| #include <memory> |
| |
| #include "base/macros.h" |
| #include "base/task_scheduler/task_scheduler.h" |
| #include "content/browser/accessibility/browser_accessibility.h" |
| #include "content/browser/accessibility/browser_accessibility_manager.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| class TestBrowserAccessibilityManager : public BrowserAccessibilityManager { |
| public: |
| TestBrowserAccessibilityManager( |
| const ui::AXTreeUpdate& initial_tree) |
| : BrowserAccessibilityManager(initial_tree, |
| nullptr, |
| new BrowserAccessibilityFactory()) {} |
| }; |
| |
| } // namespace |
| |
| // These tests prevent other tests from being run. crbug.com/514632 |
| #if defined(ANDROID) && defined(ADDRESS_SANITIZER) |
| #define MAYBE_OneShotAccessibilityTreeSearchTest DISABLED_OneShotAccessibilityTreeSearchTets |
| #else |
| #define MAYBE_OneShotAccessibilityTreeSearchTest OneShotAccessibilityTreeSearchTest |
| #endif |
| class MAYBE_OneShotAccessibilityTreeSearchTest : public testing::Test { |
| public: |
| MAYBE_OneShotAccessibilityTreeSearchTest() {} |
| ~MAYBE_OneShotAccessibilityTreeSearchTest() override {} |
| |
| protected: |
| void SetUp() override; |
| |
| std::unique_ptr<BrowserAccessibilityManager> tree_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(MAYBE_OneShotAccessibilityTreeSearchTest); |
| }; |
| |
| void MAYBE_OneShotAccessibilityTreeSearchTest::SetUp() { |
| // In order to mock TestBrowserAccessibilityManager, we need to also make sure |
| // there is a TaskScheduler started. This is because |
| // BrowserAccessibilityStateImpl posts a few tasks which will assert if there |
| // isn't a TaskScheduler. |
| // See: BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl(). |
| base::TaskScheduler::CreateAndStartWithDefaultParams( |
| "OneShotAccessibilityTreeSearchTest"); |
| |
| ui::AXNodeData root; |
| root.id = 1; |
| root.SetName("Document"); |
| root.role = ui::AX_ROLE_ROOT_WEB_AREA; |
| root.child_ids.push_back(2); |
| root.child_ids.push_back(3); |
| root.child_ids.push_back(6); |
| |
| ui::AXNodeData heading; |
| heading.id = 2; |
| heading.SetName("Heading"); |
| heading.role = ui::AX_ROLE_HEADING; |
| |
| ui::AXNodeData list; |
| list.id = 3; |
| list.role = ui::AX_ROLE_LIST; |
| list.child_ids.push_back(4); |
| list.child_ids.push_back(5); |
| |
| ui::AXNodeData list_item_1; |
| list_item_1.id = 4; |
| list_item_1.SetName("Autobots"); |
| list_item_1.role = ui::AX_ROLE_LIST_ITEM; |
| |
| ui::AXNodeData list_item_2; |
| list_item_2.id = 5; |
| list_item_2.SetName("Decepticons"); |
| list_item_2.role = ui::AX_ROLE_LIST_ITEM; |
| |
| ui::AXNodeData footer; |
| footer.id = 6; |
| footer.SetName("Footer"); |
| footer.role = ui::AX_ROLE_FOOTER; |
| footer.AddState(ui::AX_STATE_OFFSCREEN); |
| |
| tree_.reset(new TestBrowserAccessibilityManager( |
| MakeAXTreeUpdate(root, heading, list, list_item_1, list_item_2, footer))); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, GetAll) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| ASSERT_EQ(6U, search.CountMatches()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, NoCycle) { |
| // If you set a result limit of 1, you won't get the root node back as |
| // the first match. |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.SetResultLimit(1); |
| ASSERT_EQ(1U, search.CountMatches()); |
| EXPECT_NE(1, search.GetMatchAtIndex(0)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, ForwardsWithStartNode) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.SetStartNode(tree_->GetFromID(4)); |
| ASSERT_EQ(2U, search.CountMatches()); |
| EXPECT_EQ(5, search.GetMatchAtIndex(0)->GetId()); |
| EXPECT_EQ(6, search.GetMatchAtIndex(1)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, BackwardsWithStartNode) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.SetStartNode(tree_->GetFromID(4)); |
| search.SetDirection(OneShotAccessibilityTreeSearch::BACKWARDS); |
| ASSERT_EQ(3U, search.CountMatches()); |
| EXPECT_EQ(3, search.GetMatchAtIndex(0)->GetId()); |
| EXPECT_EQ(2, search.GetMatchAtIndex(1)->GetId()); |
| EXPECT_EQ(1, search.GetMatchAtIndex(2)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, |
| ForwardsWithStartNodeAndScope) { |
| OneShotAccessibilityTreeSearch search(tree_->GetFromID(4)); |
| search.SetStartNode(tree_->GetFromID(5)); |
| ASSERT_EQ(1U, search.CountMatches()); |
| EXPECT_EQ(6, search.GetMatchAtIndex(0)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, ResultLimitZero) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.SetResultLimit(0); |
| ASSERT_EQ(0U, search.CountMatches()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, ResultLimitFive) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.SetResultLimit(5); |
| ASSERT_EQ(5U, search.CountMatches()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, DescendantsOnlyOfRoot) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.SetStartNode(tree_->GetFromID(1)); |
| search.SetImmediateDescendantsOnly(true); |
| ASSERT_EQ(3U, search.CountMatches()); |
| EXPECT_EQ(2, search.GetMatchAtIndex(0)->GetId()); |
| EXPECT_EQ(3, search.GetMatchAtIndex(1)->GetId()); |
| EXPECT_EQ(6, search.GetMatchAtIndex(2)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, DescendantsOnlyOfNode) { |
| OneShotAccessibilityTreeSearch search(tree_->GetFromID(3)); |
| search.SetImmediateDescendantsOnly(true); |
| ASSERT_EQ(2U, search.CountMatches()); |
| EXPECT_EQ(4, search.GetMatchAtIndex(0)->GetId()); |
| EXPECT_EQ(5, search.GetMatchAtIndex(1)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, |
| DescendantsOnlyOfNodeWithStartNode) { |
| OneShotAccessibilityTreeSearch search(tree_->GetFromID(3)); |
| search.SetStartNode(tree_->GetFromID(4)); |
| search.SetImmediateDescendantsOnly(true); |
| ASSERT_EQ(1U, search.CountMatches()); |
| EXPECT_EQ(5, search.GetMatchAtIndex(0)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, |
| DescendantsOnlyOfNodeWithStartNode2) { |
| OneShotAccessibilityTreeSearch search(tree_->GetFromID(3)); |
| search.SetStartNode(tree_->GetFromID(5)); |
| search.SetImmediateDescendantsOnly(true); |
| ASSERT_EQ(0U, search.CountMatches()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, |
| DescendantsOnlyOfNodeWithStartNodeBackwards) { |
| OneShotAccessibilityTreeSearch search(tree_->GetFromID(3)); |
| search.SetStartNode(tree_->GetFromID(5)); |
| search.SetImmediateDescendantsOnly(true); |
| search.SetDirection(OneShotAccessibilityTreeSearch::BACKWARDS); |
| ASSERT_EQ(1U, search.CountMatches()); |
| EXPECT_EQ(4, search.GetMatchAtIndex(0)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, VisibleOnly) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.SetVisibleOnly(true); |
| ASSERT_EQ(5U, search.CountMatches()); |
| EXPECT_EQ(1, search.GetMatchAtIndex(0)->GetId()); |
| EXPECT_EQ(2, search.GetMatchAtIndex(1)->GetId()); |
| EXPECT_EQ(3, search.GetMatchAtIndex(2)->GetId()); |
| EXPECT_EQ(4, search.GetMatchAtIndex(3)->GetId()); |
| EXPECT_EQ(5, search.GetMatchAtIndex(4)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, CaseInsensitiveStringMatch) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.SetSearchText("eCEptiCOn"); |
| ASSERT_EQ(1U, search.CountMatches()); |
| EXPECT_EQ(5, search.GetMatchAtIndex(0)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, OnePredicate) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.AddPredicate([](BrowserAccessibility* start, |
| BrowserAccessibility* current) { |
| return current->GetRole() == ui::AX_ROLE_LIST_ITEM; |
| }); |
| ASSERT_EQ(2U, search.CountMatches()); |
| EXPECT_EQ(4, search.GetMatchAtIndex(0)->GetId()); |
| EXPECT_EQ(5, search.GetMatchAtIndex(1)->GetId()); |
| } |
| |
| TEST_F(MAYBE_OneShotAccessibilityTreeSearchTest, TwoPredicates) { |
| OneShotAccessibilityTreeSearch search(tree_->GetRoot()); |
| search.AddPredicate([](BrowserAccessibility* start, |
| BrowserAccessibility* current) { |
| return (current->GetRole() == ui::AX_ROLE_LIST || |
| current->GetRole() == ui::AX_ROLE_LIST_ITEM); |
| }); |
| search.AddPredicate([](BrowserAccessibility* start, |
| BrowserAccessibility* current) { |
| return (current->GetId() % 2 == 1); |
| }); |
| ASSERT_EQ(2U, search.CountMatches()); |
| EXPECT_EQ(3, search.GetMatchAtIndex(0)->GetId()); |
| EXPECT_EQ(5, search.GetMatchAtIndex(1)->GetId()); |
| } |
| |
| } // namespace content |