OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
6 | 6 |
7 #include "base/memory/scoped_nsobject.h" | 7 #include "base/memory/scoped_nsobject.h" |
8 #include "base/test/test_timeouts.h" | 8 #include "base/test/test_timeouts.h" |
9 #include "chrome/common/chrome_switches.h" | 9 #include "chrome/common/chrome_switches.h" |
10 #include "chrome/test/ui/ui_test.h" | 10 #include "chrome/test/ui/ui_test.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 | 24 |
25 virtual void SetUp() { | 25 virtual void SetUp() { |
26 UITest::SetUp(); | 26 UITest::SetUp(); |
27 SetupObservedNotifications(); | 27 SetupObservedNotifications(); |
28 Initialize(); | 28 Initialize(); |
29 } | 29 } |
30 | 30 |
31 // Called to insert an event for validation. | 31 // Called to insert an event for validation. |
32 // This is a order sensitive expectation. | 32 // This is a order sensitive expectation. |
33 void AddExpectedEvent(NSString* notificationName) { | 33 void AddExpectedEvent(NSString* notificationName) { |
34 [AccessibilityMacUITest::expectedEvents addObject:notificationName]; | 34 [expectedEvents_ addObject:notificationName]; |
35 } | 35 } |
36 | 36 |
37 // Assert that there are no remaining expected events. | 37 // Assert that there are no remaining expected events. |
38 // CFRunLoop necessary to receive AX callbacks. | 38 // CFRunLoop necessary to receive AX callbacks. |
39 // Assumes that there is at least one expected event. | 39 // Assumes that there is at least one expected event. |
40 // The runloop stops only if we receive all expected notifications. | 40 // The runloop stops only if we receive all expected notifications. |
41 void WaitAndAssertAllEventsObserved() { | 41 void WaitAndAssertAllEventsObserved() { |
42 ASSERT_GE([expectedEvents count], 1U); | 42 ASSERT_GE([expectedEvents_ count], 1U); |
43 CFRunLoopRunInMode( | 43 CFRunLoopRunInMode( |
44 kCFRunLoopDefaultMode, | 44 kCFRunLoopDefaultMode, |
45 TestTimeouts::action_max_timeout_ms() / 1000, false); | 45 TestTimeouts::action_max_timeout_ms() / 1000, false); |
46 ASSERT_EQ(0U, [AccessibilityMacUITest::expectedEvents count]); | 46 ASSERT_EQ(0U, [expectedEvents_ count]); |
47 } | 47 } |
48 | 48 |
49 // The Callback handler added to each AXUIElement. | 49 // The Callback handler added to each AXUIElement. |
50 static void EventReceiver( | 50 static void EventReceiver( |
51 AXObserverRef observerRef, | 51 AXObserverRef observerRef, |
52 AXUIElementRef element, | 52 AXUIElementRef element, |
53 CFStringRef notificationName, | 53 CFStringRef notificationName, |
54 void *refcon) { | 54 void *refcon) { |
55 if ([[AccessibilityMacUITest::expectedEvents objectAtIndex:0] | 55 AccessibilityMacUITest* this_pointer = |
| 56 reinterpret_cast<AccessibilityMacUITest*>(refcon); |
| 57 if ([[this_pointer->expectedEvents_ objectAtIndex:0] |
56 isEqualToString:(NSString*)notificationName]) { | 58 isEqualToString:(NSString*)notificationName]) { |
57 [AccessibilityMacUITest::expectedEvents removeObjectAtIndex:0]; | 59 [this_pointer->expectedEvents_ removeObjectAtIndex:0]; |
58 } | 60 } |
59 | 61 |
60 if ([AccessibilityMacUITest::expectedEvents count] == 0) { | 62 if ([this_pointer->expectedEvents_ count] == 0) { |
61 CFRunLoopStop(CFRunLoopGetCurrent()); | 63 CFRunLoopStop(CFRunLoopGetCurrent()); |
62 } | 64 } |
63 | 65 |
64 // TODO(dtseng): currently refreshing on all notifications; scope later. | 66 // TODO(dtseng): currently refreshing on all notifications; scope later. |
65 AccessibilityMacUITest::SetAllObserversOnDescendants( | 67 this_pointer->SetAllObserversOnDescendants(element, observerRef); |
66 element, observerRef); | |
67 } | 68 } |
68 | 69 |
69 private: | 70 private: |
70 // Perform AX setup. | 71 // Perform AX setup. |
71 void Initialize() { | 72 void Initialize() { |
72 AccessibilityMacUITest::expectedEvents.reset([[NSMutableArray alloc] init]); | 73 expectedEvents_.reset([[NSMutableArray alloc] init]); |
73 | 74 |
74 // Construct the Chrome AXUIElementRef. | 75 // Construct the Chrome AXUIElementRef. |
75 ASSERT_NE(-1, browser_process_id()); | 76 ASSERT_NE(-1, browser_process_id()); |
76 AXUIElementRef browserUiElement = | 77 AXUIElementRef browserUiElement = |
77 AXUIElementCreateApplication(browser_process_id()); | 78 AXUIElementCreateApplication(browser_process_id()); |
78 ASSERT_TRUE(browserUiElement); | 79 ASSERT_TRUE(browserUiElement); |
79 | 80 |
80 // Setup our callbacks. | 81 // Setup our callbacks. |
81 AXObserverRef observerRef; | 82 AXObserverRef observerRef; |
82 ASSERT_EQ(kAXErrorSuccess, | 83 ASSERT_EQ(kAXErrorSuccess, |
83 AXObserverCreate(browser_process_id(), | 84 AXObserverCreate(browser_process_id(), |
84 AccessibilityMacUITest::EventReceiver, | 85 AccessibilityMacUITest::EventReceiver, |
85 &observerRef)); | 86 &observerRef)); |
86 SetAllObserversOnDescendants(browserUiElement, observerRef); | 87 SetAllObserversOnDescendants(browserUiElement, observerRef); |
87 | 88 |
88 // Add the observer to the current message loop. | 89 // Add the observer to the current message loop. |
89 CFRunLoopAddSource( | 90 CFRunLoopAddSource( |
90 [[NSRunLoop currentRunLoop] getCFRunLoop], | 91 [[NSRunLoop currentRunLoop] getCFRunLoop], |
91 AXObserverGetRunLoopSource(observerRef), | 92 AXObserverGetRunLoopSource(observerRef), |
92 kCFRunLoopDefaultMode); | 93 kCFRunLoopDefaultMode); |
93 } | 94 } |
94 | 95 |
95 // Taken largely from AXNotificationConstants.h | 96 // Taken largely from AXNotificationConstants.h |
96 // (substituted NSAccessibility* to avoid casting). | 97 // (substituted NSAccessibility* to avoid casting). |
97 static void SetupObservedNotifications() { | 98 void SetupObservedNotifications() { |
98 AccessibilityMacUITest::observedNotifications.reset( | 99 observedNotifications_.reset( |
99 [[NSArray alloc] initWithObjects: | 100 [[NSArray alloc] initWithObjects: |
100 | 101 |
101 // focus notifications | 102 // focus notifications |
102 NSAccessibilityMainWindowChangedNotification, | 103 NSAccessibilityMainWindowChangedNotification, |
103 NSAccessibilityFocusedWindowChangedNotification, | 104 NSAccessibilityFocusedWindowChangedNotification, |
104 NSAccessibilityFocusedUIElementChangedNotification, | 105 NSAccessibilityFocusedUIElementChangedNotification, |
105 | 106 |
106 // application notifications | 107 // application notifications |
107 NSAccessibilityApplicationActivatedNotification, | 108 NSAccessibilityApplicationActivatedNotification, |
108 NSAccessibilityApplicationDeactivatedNotification, | 109 NSAccessibilityApplicationDeactivatedNotification, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 NSAccessibilitySelectedColumnsChangedNotification, | 143 NSAccessibilitySelectedColumnsChangedNotification, |
143 NSAccessibilitySelectedTextChangedNotification, | 144 NSAccessibilitySelectedTextChangedNotification, |
144 NSAccessibilityTitleChangedNotification, | 145 NSAccessibilityTitleChangedNotification, |
145 | 146 |
146 // Webkit specific notifications. | 147 // Webkit specific notifications. |
147 @"AXLoadComplete", | 148 @"AXLoadComplete", |
148 nil]); | 149 nil]); |
149 } | 150 } |
150 | 151 |
151 // Observe AX notifications on element and all descendants. | 152 // Observe AX notifications on element and all descendants. |
152 static void SetAllObserversOnDescendants( | 153 void SetAllObserversOnDescendants( |
153 AXUIElementRef element, | 154 AXUIElementRef element, |
154 AXObserverRef observerRef) { | 155 AXObserverRef observerRef) { |
155 SetAllObservers(element, observerRef); | 156 SetAllObservers(element, observerRef); |
156 CFTypeRef childrenRef; | 157 CFTypeRef childrenRef; |
157 if ((AXUIElementCopyAttributeValue( | 158 if ((AXUIElementCopyAttributeValue( |
158 element, kAXChildrenAttribute, &childrenRef)) == kAXErrorSuccess) { | 159 element, kAXChildrenAttribute, &childrenRef)) == kAXErrorSuccess) { |
159 NSArray* children = (NSArray*)childrenRef; | 160 NSArray* children = (NSArray*)childrenRef; |
160 for (uint32 i = 0; i < [children count]; ++i) { | 161 for (uint32 i = 0; i < [children count]; ++i) { |
161 SetAllObserversOnDescendants( | 162 SetAllObserversOnDescendants( |
162 (AXUIElementRef)[children objectAtIndex:i], observerRef); | 163 (AXUIElementRef)[children objectAtIndex:i], observerRef); |
163 } | 164 } |
164 } | 165 } |
165 } | 166 } |
166 | 167 |
167 // Add observers for all notifications we know about. | 168 // Add observers for all notifications we know about. |
168 static void SetAllObservers( | 169 void SetAllObservers( |
169 AXUIElementRef element, | 170 AXUIElementRef element, |
170 AXObserverRef observerRef) { | 171 AXObserverRef observerRef) { |
171 for (NSString* notification in | 172 for (NSString* notification in observedNotifications_.get()) { |
172 AccessibilityMacUITest::observedNotifications.get()) { | |
173 AXObserverAddNotification( | 173 AXObserverAddNotification( |
174 observerRef, element, (CFStringRef)notification, nil); | 174 observerRef, element, (CFStringRef)notification, this); |
175 } | 175 } |
176 } | 176 } |
177 | 177 |
178 // Used to keep track of events received during the lifetime of the tests. | 178 // Used to keep track of events received during the lifetime of the tests. |
179 static scoped_nsobject<NSMutableArray> expectedEvents; | 179 scoped_nsobject<NSMutableArray> expectedEvents_; |
180 // NSString collection of all AX notifications. | 180 // NSString collection of all AX notifications. |
181 static scoped_nsobject<NSArray> observedNotifications; | 181 scoped_nsobject<NSArray> observedNotifications_; |
182 }; | 182 }; |
183 | 183 |
184 scoped_nsobject<NSMutableArray> AccessibilityMacUITest::expectedEvents; | |
185 scoped_nsobject<NSArray> AccessibilityMacUITest::observedNotifications; | |
186 | |
187 TEST_F(AccessibilityMacUITest, TestInitialPageNotifications) { | 184 TEST_F(AccessibilityMacUITest, TestInitialPageNotifications) { |
188 // Browse to a new page. | 185 // Browse to a new page. |
189 GURL tree_url( | 186 GURL tree_url( |
190 "data:text/html,<html><head><title>Accessibility Mac Test</title></head>" | 187 "data:text/html,<html><head><title>Accessibility Mac Test</title></head>" |
191 "<body><input type='button' value='push' /><input type='checkbox' />" | 188 "<body><input type='button' value='push' /><input type='checkbox' />" |
192 "</body></html>"); | 189 "</body></html>"); |
193 NavigateToURLAsync(tree_url); | 190 NavigateToURLAsync(tree_url); |
194 | 191 |
195 // Test for navigation. | 192 // Test for navigation. |
196 AddExpectedEvent(@"AXLoadComplete"); | 193 AddExpectedEvent(@"AXLoadComplete"); |
197 | 194 |
198 // Check all the expected Mac notifications. | 195 // Check all the expected Mac notifications. |
199 WaitAndAssertAllEventsObserved(); | 196 WaitAndAssertAllEventsObserved(); |
200 } | 197 } |
OLD | NEW |