| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CHROME_FRAME_TEST_CHROME_FRAME_UI_TEST_UTILS_H_ | |
| 6 #define CHROME_FRAME_TEST_CHROME_FRAME_UI_TEST_UTILS_H_ | |
| 7 | |
| 8 #include <oleacc.h> | |
| 9 | |
| 10 #include <string> | |
| 11 #include <vector> | |
| 12 | |
| 13 #include "base/files/file_path.h" | |
| 14 #include "base/memory/ref_counted.h" | |
| 15 #include "base/win/scoped_comptr.h" | |
| 16 #include "base/win/scoped_variant.h" | |
| 17 #include "chrome_frame/test/win_event_receiver.h" | |
| 18 | |
| 19 namespace gfx { | |
| 20 class Rect; | |
| 21 } | |
| 22 | |
| 23 namespace chrome_frame_test { | |
| 24 | |
| 25 // Wrapper for MSAA/IAccessible2 accessibility objects. IAccessible2 is an | |
| 26 // open standard which serves as a complement to MSAA and specifies additional | |
| 27 // interfaces and methods. Chrome currently supports a subset of this API. | |
| 28 // | |
| 29 // In MSAA, there are two types of objects. The first, called an object or full | |
| 30 // object, has its own IAccessible interface. The second, called a simple | |
| 31 // element, does not have its own IAccessible interface and cannot have | |
| 32 // children. Simple elements must be referenced by combination of the parent | |
| 33 // object and the element's id in MSAA. This class handles this distinction | |
| 34 // transparently to the client. | |
| 35 class AccObject : public base::RefCounted<AccObject> { | |
| 36 public: | |
| 37 typedef std::vector<scoped_refptr<AccObject> > RefCountedAccObjectVector; | |
| 38 | |
| 39 // Creates an AccObject with an IAccessible and child id. |accessible| must | |
| 40 // not be NULL. |child_id| must always be CHILDID_SELF unless this AccObject | |
| 41 // is a simple element. | |
| 42 AccObject(IAccessible* accessible, int child_id = CHILDID_SELF); | |
| 43 | |
| 44 // Creates an AccObject corresponding to the given window. May return NULL | |
| 45 // if there is not accessible object for the window. The client owns the | |
| 46 // created AccObject. | |
| 47 static AccObject* CreateFromWindow(HWND hwnd); | |
| 48 | |
| 49 // Creates an AccObject corresponding to the object that generated a | |
| 50 // WinEvent. Returns NULL on failure. | |
| 51 static AccObject* CreateFromEvent(HWND hwnd, LONG object_id, LONG child_id); | |
| 52 | |
| 53 // Creates an AccObject from querying the given IDispatch. May return NULL | |
| 54 // if the object does not implement IAccessible. The client owns the created | |
| 55 // AccObject. | |
| 56 static AccObject* CreateFromDispatch(IDispatch* dispatch); | |
| 57 | |
| 58 // Creates an AccObject corresponding to the accessible object at the screen | |
| 59 // coordinates given. Returns NULL on failure. The client owns the created | |
| 60 // AccObject. | |
| 61 // Note: This does not work in Chrome. | |
| 62 static AccObject* CreateFromPoint(int x, int y); | |
| 63 | |
| 64 // Performs the default action on this object. Returns whether the action | |
| 65 // performed successfully. Will cause test failure if unsuccessful. | |
| 66 // Note: This does not work for selecting menu items if the desktop is locked. | |
| 67 bool DoDefaultAction(); | |
| 68 | |
| 69 // Posts a left click message at this object's center point to the window | |
| 70 // containing this object. | |
| 71 bool LeftClick(); | |
| 72 | |
| 73 // Posts a right click message at this object's center point to the window | |
| 74 // containing this object. | |
| 75 bool RightClick(); | |
| 76 | |
| 77 // Focuses this object. Returns whether the object receives focus. Will cause | |
| 78 // test failure if the object is not focused. | |
| 79 bool Focus(); | |
| 80 | |
| 81 // Selects this object. Returns whether the object is now selected. Will cause | |
| 82 // test failure if the object is not selected. | |
| 83 bool Select(); | |
| 84 | |
| 85 // Sets the value of the object. Will cause test failure if unsuccessful. | |
| 86 bool SetValue(const std::wstring& value); | |
| 87 | |
| 88 // Gets the name of the object and returns true on success. | |
| 89 bool GetName(std::wstring* name); | |
| 90 | |
| 91 // Gets the role text of the object and returns true on success. | |
| 92 bool GetRoleText(std::wstring* role_text); | |
| 93 | |
| 94 // Gets the value of the object and returns true on success. | |
| 95 bool GetValue(std::wstring* value); | |
| 96 | |
| 97 // Gets the state of the object and returns true on success. | |
| 98 bool GetState(int* state); | |
| 99 | |
| 100 // Gets the location of the object in screen coordinates and returns true | |
| 101 // on success. | |
| 102 bool GetLocation(gfx::Rect* location); | |
| 103 | |
| 104 // Gets the location of the object relative to the containing window's | |
| 105 // client rect. | |
| 106 bool GetLocationInClient(gfx::Rect* location); | |
| 107 | |
| 108 // Gets the parent of the object. May return NULL. | |
| 109 AccObject* GetParent(); | |
| 110 | |
| 111 // Gets the children of this object and returns true on success. |objects| | |
| 112 // will not be modified unless if the operation is successful. | |
| 113 bool GetChildren(RefCountedAccObjectVector* objects); | |
| 114 | |
| 115 // Gets the number of children of this object and returns true on success. | |
| 116 bool GetChildCount(int* child_count); | |
| 117 | |
| 118 // Gets an object resulting from the navigation and returns true if the | |
| 119 // navigation completed successfully. Even if true, |object| may still | |
| 120 // refer to a NULL object if no object was found from the navigation. | |
| 121 // |navigation_type| may be any navigation constant, such as NAVDIR_NEXT. | |
| 122 // Note: This method uses a deprecated IAccessible method. | |
| 123 bool GetFromNavigation(long navigation_type, | |
| 124 scoped_refptr<AccObject>* object); | |
| 125 | |
| 126 // Gets the window containing this object and returns true on success. This | |
| 127 // method will return false if the object is not contained within a window. | |
| 128 bool GetWindow(HWND* window); | |
| 129 | |
| 130 // Gets the class name for the window containing this object and returns true | |
| 131 // on success. If this object does not have a window, this will return false. | |
| 132 bool GetWindowClassName(std::wstring* class_name); | |
| 133 | |
| 134 // Gets the range of text that is selected in this object. If no text is | |
| 135 // selected, |start_offset| and |end_offset| will be set to 0. Returns true | |
| 136 // on success. | |
| 137 // Requires IAccessible2 support. | |
| 138 bool GetSelectionRange(int* start_offset, int* end_offset); | |
| 139 | |
| 140 // Gets the text that is selected in this object. Returns true on success. | |
| 141 // Requires IAccessible2 support. | |
| 142 bool GetSelectedText(std::wstring* text); | |
| 143 | |
| 144 // Returns whether this object is a simple element. | |
| 145 bool IsSimpleElement(); | |
| 146 | |
| 147 // Returns whether the two AccObjects point to the same accessibility object. | |
| 148 // |other| can safely be NULL. | |
| 149 bool Equals(AccObject* other); | |
| 150 | |
| 151 // Returns a description of this object. | |
| 152 std::wstring GetDescription(); | |
| 153 | |
| 154 // Returns a description of this object and it's accessibility tree. This | |
| 155 // description will be ended by a newline. | |
| 156 std::wstring GetTree(); | |
| 157 | |
| 158 private: | |
| 159 friend class base::RefCounted<AccObject>; | |
| 160 ~AccObject() {} | |
| 161 | |
| 162 // Creates an AccObject using the given variant, returning NULL on failure. | |
| 163 // The variant should be of type |VT_I4| referring to the id of a child of | |
| 164 // |object|, or of type |VT_DISPATCH|. This method is useful for converting | |
| 165 // the variant returned by many of the IAccessible methods into an AccObject. | |
| 166 static AccObject* CreateFromVariant(AccObject* object, | |
| 167 const VARIANT& variant); | |
| 168 | |
| 169 // Posts the given mouse button down and up messages at this object's center. | |
| 170 // Returns true on success. | |
| 171 bool PostMouseClickAtCenter(int button_down, int button_up); | |
| 172 | |
| 173 // Helper method for posting mouse button messages. | |
| 174 bool PostMouseButtonMessages(int button_up, int button_down, int x, int y); | |
| 175 | |
| 176 base::win::ScopedComPtr<IAccessible> accessible_; | |
| 177 base::win::ScopedVariant child_id_; | |
| 178 | |
| 179 DISALLOW_COPY_AND_ASSIGN(AccObject); | |
| 180 }; | |
| 181 | |
| 182 // Finds an accessibility object with properties that match the specified | |
| 183 // matching patterns. These patterns can include the standard * and ? wildcards. | |
| 184 class AccObjectMatcher { | |
| 185 public: | |
| 186 // Create a matcher from the given string. |matcher| should include matching | |
| 187 // patterns for each property separated by colons. Matching patterns must | |
| 188 // be specified from left to right in the following order: | |
| 189 // 1) Name | |
| 190 // 2) Role Text: A string representation of a Windows object role, which can | |
| 191 // be found by using the win32 GetRoleText function. E.g., | |
| 192 // ROLE_SYSTEM_ALERT should be represented as 'alert', and | |
| 193 // ROLE_SYSTEM_MENUPOPUP should be represented as 'popup menu'. | |
| 194 // 3) Value | |
| 195 // Matching patterns can be blank, essentially equal to *. | |
| 196 // Literal *, ?, and : characters can be escaped with a backslash. | |
| 197 AccObjectMatcher(const std::wstring& name = L"", | |
| 198 const std::wstring& role_text = L"", | |
| 199 const std::wstring& value = L""); | |
| 200 | |
| 201 // Finds the first object which satisfies this matcher and sets as |match|. | |
| 202 // This searches the accessibility tree (including |object| itself) of | |
| 203 // |object| in a pre-order fasion. If no object is matched, |match| will be | |
| 204 // NULL. Returns true if no error occured while trying to find a match. It is | |
| 205 // possible to use this method to test for an object's non-existence. | |
| 206 bool Find(AccObject* object, scoped_refptr<AccObject>* match) const; | |
| 207 | |
| 208 // Same as above except that it searches within the accessibility tree of the | |
| 209 // given window, which must support the IAccessible interface. | |
| 210 bool FindInWindow(HWND hwnd, scoped_refptr<AccObject>* match) const; | |
| 211 | |
| 212 // Returns whether |object| satisfies this matcher. | |
| 213 bool DoesMatch(AccObject* object) const; | |
| 214 | |
| 215 // Return a description of the matcher, for debugging/logging purposes. | |
| 216 std::wstring GetDescription() const; | |
| 217 | |
| 218 private: | |
| 219 bool FindHelper(AccObject* object, scoped_refptr<AccObject>* match) const; | |
| 220 | |
| 221 std::wstring name_; | |
| 222 std::wstring role_text_; | |
| 223 std::wstring value_; | |
| 224 }; | |
| 225 | |
| 226 // Observes various accessibility events. | |
| 227 class AccEventObserver : public WinEventListener { | |
| 228 public: | |
| 229 AccEventObserver(); | |
| 230 virtual ~AccEventObserver(); | |
| 231 | |
| 232 // Begins watching for a value changed event for an accessibility object that | |
| 233 // satisfies |matcher|. Once the event occurs, this observer will stop | |
| 234 // watching. | |
| 235 void WatchForOneValueChange(const AccObjectMatcher& matcher); | |
| 236 | |
| 237 // Called when the DOM accessibility tree for the page is ready. | |
| 238 virtual void OnAccDocLoad(HWND hwnd) = 0; | |
| 239 | |
| 240 // Called when an accessibility object value changes. Only called if the | |
| 241 // observer was set to watch for it. | |
| 242 virtual void OnAccValueChange(HWND hwnd, AccObject* object, | |
| 243 const std::wstring& new_value) = 0; | |
| 244 | |
| 245 // Called when the text caret moves within the given object. This is | |
| 246 // triggered when the text selection changes also. | |
| 247 virtual void OnTextCaretMoved(HWND hwnd, AccObject* object) = 0; | |
| 248 | |
| 249 // Called when a new menu is shown. | |
| 250 virtual void OnMenuPopup(HWND hwnd) = 0; | |
| 251 | |
| 252 private: | |
| 253 class EventHandler : public base::RefCounted<EventHandler> { | |
| 254 public: | |
| 255 explicit EventHandler(AccEventObserver* observer); | |
| 256 | |
| 257 // Examines the given event and invokes the corresponding method of its | |
| 258 // observer. | |
| 259 void Handle(DWORD event, HWND hwnd, LONG object_id, LONG child_id); | |
| 260 | |
| 261 AccEventObserver* observer_; | |
| 262 }; | |
| 263 | |
| 264 // Overriden from WinEventListener. | |
| 265 virtual void OnEventReceived(DWORD event, HWND hwnd, LONG object_id, | |
| 266 LONG child_id); | |
| 267 | |
| 268 scoped_refptr<EventHandler> event_handler_; | |
| 269 bool is_watching_; | |
| 270 AccObjectMatcher watching_for_matcher_; | |
| 271 WinEventReceiver event_receiver_; | |
| 272 }; | |
| 273 | |
| 274 // Finds an AccObject from the given window that satisfied |matcher|. | |
| 275 // Will cause test failure in case of error or if no match is found in the | |
| 276 // accessibility tree of the specified window. Returns whether the object was | |
| 277 // found. | |
| 278 bool FindAccObjectInWindow(HWND hwnd, const AccObjectMatcher& matcher, | |
| 279 scoped_refptr<AccObject>* object); | |
| 280 | |
| 281 // Writes the accessibility tree for the given window to standard out. Used for | |
| 282 // debugging/logging. | |
| 283 void DumpAccessibilityTreeForWindow(HWND hwnd); | |
| 284 | |
| 285 // Returns whether the desktop is unlocked. | |
| 286 bool IsDesktopUnlocked(); | |
| 287 | |
| 288 // Returns the location of the IAccessible2 COM proxy stub DLL. | |
| 289 base::FilePath GetIAccessible2ProxyStubPath(); | |
| 290 | |
| 291 } // namespace chrome_frame_test | |
| 292 | |
| 293 #endif // CHROME_FRAME_TEST_CHROME_FRAME_UI_TEST_UTILS_H_ | |
| OLD | NEW |