Home | History | Annotate | Download | only in accessibility
      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.
      4 
      5 #import <Cocoa/Cocoa.h>
      6 
      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/base/test/ui_cocoa_test_helper.h"
     16 
     17 @interface MockAccessibilityDelegate :
     18     NSView<BrowserAccessibilityDelegateCocoa>
     19 
     20 - (NSPoint)accessibilityPointInScreen:(NSPoint)origin
     21                                  size:(NSSize)size;
     22 - (void)doDefaultAction:(int32)accessibilityObjectId;
     23 - (void)accessibilitySetTextSelection:(int32)accId
     24                           startOffset:(int32)startOffset
     25                             endOffset:(int32)endOffset;
     26 - (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility;
     27 - (void)setAccessibilityFocus:(BOOL)focus
     28               accessibilityId:(int32)accessibilityObjectId;
     29 - (NSWindow*)window;
     30 
     31 @end
     32 
     33 @implementation MockAccessibilityDelegate
     34 
     35 - (NSPoint)accessibilityPointInScreen:(NSPoint)origin
     36                                  size:(NSSize)size {
     37   return NSZeroPoint;
     38 }
     39 - (void)doDefaultAction:(int32)accessibilityObjectId {
     40 }
     41 - (void)accessibilitySetTextSelection:(int32)accId
     42                           startOffset:(int32)startOffset
     43                             endOffset:(int32)endOffset {
     44 }
     45 - (void)performShowMenuAction:(BrowserAccessibilityCocoa*)accessibility {
     46 }
     47 - (void)setAccessibilityFocus:(BOOL)focus
     48               accessibilityId:(int32)accessibilityObjectId {
     49 }
     50 - (NSWindow*)window {
     51   return nil;
     52 }
     53 
     54 @end
     55 
     56 namespace content {
     57 
     58 class BrowserAccessibilityTest : public ui::CocoaTest {
     59  public:
     60   virtual void SetUp() {
     61     CocoaTest::SetUp();
     62     RebuildAccessibilityTree();
     63   }
     64 
     65  protected:
     66   void RebuildAccessibilityTree() {
     67     AccessibilityNodeData root;
     68     root.id = 1000;
     69     root.location.set_width(500);
     70     root.location.set_height(100);
     71     root.role = blink::WebAXRoleRootWebArea;
     72     root.AddStringAttribute(AccessibilityNodeData::ATTR_HELP, "HelpText");
     73     root.child_ids.push_back(1001);
     74     root.child_ids.push_back(1002);
     75 
     76     AccessibilityNodeData child1;
     77     child1.id = 1001;
     78     child1.SetName("Child1");
     79     child1.location.set_width(250);
     80     child1.location.set_height(100);
     81     child1.role = blink::WebAXRoleButton;
     82 
     83     AccessibilityNodeData child2;
     84     child2.id = 1002;
     85     child2.location.set_x(250);
     86     child2.location.set_width(250);
     87     child2.location.set_height(100);
     88     child2.role = blink::WebAXRoleHeading;
     89 
     90     delegate_.reset([[MockAccessibilityDelegate alloc] init]);
     91     manager_.reset(
     92         new BrowserAccessibilityManagerMac(delegate_, root, NULL));
     93     manager_->UpdateNodesForTesting(child1, child2);
     94     accessibility_.reset([manager_->GetRoot()->ToBrowserAccessibilityCocoa()
     95         retain]);
     96   }
     97 
     98   base::scoped_nsobject<MockAccessibilityDelegate> delegate_;
     99   base::scoped_nsobject<BrowserAccessibilityCocoa> accessibility_;
    100   scoped_ptr<BrowserAccessibilityManager> manager_;
    101 };
    102 
    103 // Standard hit test.
    104 TEST_F(BrowserAccessibilityTest, HitTestTest) {
    105   BrowserAccessibilityCocoa* firstChild =
    106       [accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
    107   EXPECT_NSEQ(@"Child1",
    108       [firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
    109 }
    110 
    111 // Test doing a hit test on the edge of a child.
    112 TEST_F(BrowserAccessibilityTest, EdgeHitTest) {
    113   BrowserAccessibilityCocoa* firstChild =
    114       [accessibility_ accessibilityHitTest:NSZeroPoint];
    115   EXPECT_NSEQ(@"Child1",
    116       [firstChild accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
    117 }
    118 
    119 // This will test a hit test with invalid coordinates.  It is assumed that
    120 // the hit test has been narrowed down to this object or one of its children
    121 // so it should return itself since it has no better hit result.
    122 TEST_F(BrowserAccessibilityTest, InvalidHitTestCoordsTest) {
    123   BrowserAccessibilityCocoa* hitTestResult =
    124       [accessibility_ accessibilityHitTest:NSMakePoint(-50, 50)];
    125   EXPECT_NSEQ(accessibility_, hitTestResult);
    126 }
    127 
    128 // Test to ensure querying standard attributes works.
    129 TEST_F(BrowserAccessibilityTest, BasicAttributeTest) {
    130   NSString* helpText = [accessibility_
    131       accessibilityAttributeValue:NSAccessibilityHelpAttribute];
    132   EXPECT_NSEQ(@"HelpText", helpText);
    133 }
    134 
    135 // Test querying for an invalid attribute to ensure it doesn't crash.
    136 TEST_F(BrowserAccessibilityTest, InvalidAttributeTest) {
    137   NSString* shouldBeNil = [accessibility_
    138       accessibilityAttributeValue:@"NSAnInvalidAttribute"];
    139   EXPECT_TRUE(shouldBeNil == nil);
    140 }
    141 
    142 TEST_F(BrowserAccessibilityTest, RetainedDetachedObjectsReturnNil) {
    143   // Get the first child.
    144   BrowserAccessibilityCocoa* retainedFirstChild =
    145       [accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
    146   EXPECT_NSEQ(@"Child1", [retainedFirstChild
    147       accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
    148 
    149   // Retain it. This simulates what the system might do with an
    150   // accessibility object.
    151   [retainedFirstChild retain];
    152 
    153   // Rebuild the accessibility tree, which should detach |retainedFirstChild|.
    154   RebuildAccessibilityTree();
    155 
    156   // Now any attributes we query should return nil.
    157   EXPECT_EQ(nil, [retainedFirstChild
    158       accessibilityAttributeValue:NSAccessibilityTitleAttribute]);
    159 
    160   // Don't leak memory in the test.
    161   [retainedFirstChild release];
    162 }
    163 
    164 }  // namespace content
    165