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
3 // found in the LICENSE file.
5 #import <Cocoa/Cocoa.h>
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/browser/accessibility/browser_accessibility_cocoa.h"
11 #include "content/browser/accessibility/browser_accessibility_manager.h"
12 #include "content/browser/accessibility/browser_accessibility_manager_mac.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #import "testing/gtest_mac.h"
15 #import "ui/gfx/test/ui_cocoa_test_helper.h"
19 class BrowserAccessibilityTest : public ui::CocoaTest {
21 void SetUp() override {
23 RebuildAccessibilityTree();
27 void RebuildAccessibilityTree() {
30 root.location.set_width(500);
31 root.location.set_height(100);
32 root.role = ui::AX_ROLE_ROOT_WEB_AREA;
33 root.AddStringAttribute(ui::AX_ATTR_HELP, "HelpText");
34 root.child_ids.push_back(1001);
35 root.child_ids.push_back(1002);
37 ui::AXNodeData child1;
39 child1.SetName("Child1");
40 child1.location.set_width(250);
41 child1.location.set_height(100);
42 child1.role = ui::AX_ROLE_BUTTON;
44 ui::AXNodeData child2;
46 child2.location.set_x(250);
47 child2.location.set_width(250);
48 child2.location.set_height(100);
49 child2.role = ui::AX_ROLE_HEADING;
52 new BrowserAccessibilityManagerMac(
54 MakeAXTreeUpdate(root, child1, child2),
56 accessibility_.reset([manager_->GetRoot()->ToBrowserAccessibilityCocoa()
60 base::scoped_nsobject<BrowserAccessibilityCocoa> accessibility_;
61 scoped_ptr<BrowserAccessibilityManager> manager_;
65 TEST_F(BrowserAccessibilityTest, HitTestTest) {
66 BrowserAccessibilityCocoa* firstChild =
67 [accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
68 EXPECT_NSEQ(@"Child1",
69 [firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
72 // Test doing a hit test on the edge of a child.
73 TEST_F(BrowserAccessibilityTest, EdgeHitTest) {
74 BrowserAccessibilityCocoa* firstChild =
75 [accessibility_ accessibilityHitTest:NSZeroPoint];
76 EXPECT_NSEQ(@"Child1",
77 [firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
80 // This will test a hit test with invalid coordinates. It is assumed that
81 // the hit test has been narrowed down to this object or one of its children
82 // so it should return itself since it has no better hit result.
83 TEST_F(BrowserAccessibilityTest, InvalidHitTestCoordsTest) {
84 BrowserAccessibilityCocoa* hitTestResult =
85 [accessibility_ accessibilityHitTest:NSMakePoint(-50, 50)];
86 EXPECT_NSEQ(accessibility_, hitTestResult);
89 // Test to ensure querying standard attributes works.
90 TEST_F(BrowserAccessibilityTest, BasicAttributeTest) {
91 NSString* helpText = [accessibility_
92 accessibilityAttributeValue:NSAccessibilityHelpAttribute];
93 EXPECT_NSEQ(@"HelpText", helpText);
96 // Test querying for an invalid attribute to ensure it doesn't crash.
97 TEST_F(BrowserAccessibilityTest, InvalidAttributeTest) {
98 NSString* shouldBeNil = [accessibility_
99 accessibilityAttributeValue:@"NSAnInvalidAttribute"];
100 EXPECT_TRUE(shouldBeNil == nil);
103 TEST_F(BrowserAccessibilityTest, RetainedDetachedObjectsReturnNil) {
104 // Get the first child.
105 BrowserAccessibilityCocoa* retainedFirstChild =
106 [accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
107 EXPECT_NSEQ(@"Child1", [retainedFirstChild
108 accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
110 // Retain it. This simulates what the system might do with an
111 // accessibility object.
112 [retainedFirstChild retain];
114 // Rebuild the accessibility tree, which should detach |retainedFirstChild|.
115 RebuildAccessibilityTree();
117 // Now any attributes we query should return nil.
118 EXPECT_EQ(nil, [retainedFirstChild
119 accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
121 // Don't leak memory in the test.
122 [retainedFirstChild release];
125 } // namespace content