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 #include <oleacc.h> 6 7 #include "base/utf_string_conversions.h" 8 #include "base/win/scoped_comptr.h" 9 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser_window.h" 11 #include "chrome/browser/ui/view_ids.h" 12 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" 13 #include "chrome/browser/ui/views/frame/browser_view.h" 14 #include "chrome/browser/ui/views/toolbar_view.h" 15 #include "chrome/common/url_constants.h" 16 #include "chrome/test/in_process_browser_test.h" 17 #include "chrome/test/ui_test_utils.h" 18 #include "grit/chromium_strings.h" 19 #include "grit/generated_resources.h" 20 #include "ui/base/accessibility/accessibility_types.h" 21 #include "ui/base/l10n/l10n_util.h" 22 #include "views/accessibility/native_view_accessibility_win.h" 23 #include "views/widget/root_view.h" 24 #include "views/widget/widget_win.h" 25 #include "views/window/window.h" 26 27 namespace { 28 29 VARIANT id_self = {VT_I4, CHILDID_SELF}; 30 31 // Dummy class to force creation of ATL module, needed by COM to instantiate 32 // NativeViewAccessibilityWin. 33 class TestAtlModule : public CAtlDllModuleT<TestAtlModule> {}; 34 TestAtlModule test_atl_module_; 35 36 } // namespace 37 38 class BrowserViewsAccessibilityTest : public InProcessBrowserTest { 39 public: 40 BrowserViewsAccessibilityTest() { 41 ::CoInitialize(NULL); 42 } 43 44 ~BrowserViewsAccessibilityTest() { 45 ::CoUninitialize(); 46 } 47 48 // Retrieves an instance of BrowserWindowTesting 49 BrowserWindowTesting* GetBrowserWindowTesting() { 50 BrowserWindow* browser_window = browser()->window(); 51 52 if (!browser_window) 53 return NULL; 54 55 return browser_window->GetBrowserWindowTesting(); 56 } 57 58 // Retrieve an instance of BrowserView 59 BrowserView* GetBrowserView() { 60 return BrowserView::GetBrowserViewForNativeWindow( 61 browser()->window()->GetNativeHandle()); 62 } 63 64 // Retrieves and initializes an instance of ToolbarView. 65 ToolbarView* GetToolbarView() { 66 BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting(); 67 68 if (!browser_window_testing) 69 return NULL; 70 71 return browser_window_testing->GetToolbarView(); 72 } 73 74 // Retrieves and initializes an instance of BookmarkBarView. 75 BookmarkBarView* GetBookmarkBarView() { 76 BrowserWindowTesting* browser_window_testing = GetBrowserWindowTesting(); 77 78 if (!browser_window_testing) 79 return NULL; 80 81 return browser_window_testing->GetBookmarkBarView(); 82 } 83 84 // Retrieves and verifies the accessibility object for the given View. 85 void TestViewAccessibilityObject(views::View* view, std::wstring name, 86 int32 role) { 87 ASSERT_TRUE(NULL != view); 88 89 TestAccessibilityInfo( 90 NativeViewAccessibilityWin::GetAccessibleForView(view), 91 name, 92 role); 93 } 94 95 96 // Verifies MSAA Name and Role properties of the given IAccessible. 97 void TestAccessibilityInfo(IAccessible* acc_obj, std::wstring name, 98 int32 role) { 99 // Verify MSAA Name property. 100 BSTR acc_name; 101 102 HRESULT hr = acc_obj->get_accName(id_self, &acc_name); 103 ASSERT_EQ(S_OK, hr); 104 EXPECT_STREQ(acc_name, name.c_str()); 105 106 // Verify MSAA Role property. 107 VARIANT acc_role; 108 ::VariantInit(&acc_role); 109 110 hr = acc_obj->get_accRole(id_self, &acc_role); 111 ASSERT_EQ(S_OK, hr); 112 EXPECT_EQ(VT_I4, acc_role.vt); 113 EXPECT_EQ(role, acc_role.lVal); 114 115 ::VariantClear(&acc_role); 116 ::SysFreeString(acc_name); 117 } 118 }; 119 120 // Retrieve accessibility object for main window and verify accessibility info. 121 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, 122 TestChromeWindowAccObj) { 123 BrowserWindow* browser_window = browser()->window(); 124 ASSERT_TRUE(NULL != browser_window); 125 126 HWND hwnd = browser_window->GetNativeHandle(); 127 ASSERT_TRUE(NULL != hwnd); 128 129 // Get accessibility object. 130 base::win::ScopedComPtr<IAccessible> acc_obj; 131 HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible, 132 reinterpret_cast<void**>(&acc_obj)); 133 ASSERT_EQ(S_OK, hr); 134 ASSERT_TRUE(NULL != acc_obj); 135 136 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutBlankURL)); 137 std::wstring title = UTF16ToWide(l10n_util::GetStringFUTF16( 138 IDS_BROWSER_WINDOW_TITLE_FORMAT, 139 ASCIIToUTF16(chrome::kAboutBlankURL))); 140 TestAccessibilityInfo(acc_obj, title, ROLE_SYSTEM_WINDOW); 141 } 142 143 // Retrieve accessibility object for non client view and verify accessibility 144 // info. 145 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestNonClientViewAccObj) { 146 views::View* non_client_view = 147 GetBrowserView()->GetWindow()->non_client_view(); 148 149 TestViewAccessibilityObject(non_client_view, 150 UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)), 151 ROLE_SYSTEM_WINDOW); 152 } 153 154 // Retrieve accessibility object for browser root view and verify 155 // accessibility info. 156 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, 157 TestBrowserRootViewAccObj) { 158 views::View* browser_root_view = 159 GetBrowserView()->frame()->GetFrameView()->GetRootView(); 160 161 TestViewAccessibilityObject( 162 browser_root_view, 163 UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)), 164 ROLE_SYSTEM_APPLICATION); 165 } 166 167 // Retrieve accessibility object for browser view and verify accessibility info. 168 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBrowserViewAccObj) { 169 // Verify root view MSAA name and role. 170 TestViewAccessibilityObject( 171 GetBrowserView(), 172 UTF16ToWide(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)), 173 ROLE_SYSTEM_CLIENT); 174 } 175 176 // Retrieve accessibility object for toolbar view and verify accessibility info. 177 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) { 178 // Verify toolbar MSAA name and role. 179 TestViewAccessibilityObject( 180 GetToolbarView(), 181 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_TOOLBAR)), 182 ROLE_SYSTEM_TOOLBAR); 183 } 184 185 // Retrieve accessibility object for Back button and verify accessibility info. 186 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) { 187 // Verify Back button MSAA name and role. 188 TestViewAccessibilityObject( 189 GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON), 190 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK)), 191 ROLE_SYSTEM_BUTTONDROPDOWN); 192 } 193 194 // Retrieve accessibility object for Forward button and verify accessibility 195 // info. 196 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) { 197 // Verify Forward button MSAA name and role. 198 TestViewAccessibilityObject( 199 GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON), 200 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_FORWARD)), 201 ROLE_SYSTEM_BUTTONDROPDOWN); 202 } 203 204 // Retrieve accessibility object for Reload button and verify accessibility 205 // info. 206 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) { 207 // Verify Reload button MSAA name and role. 208 TestViewAccessibilityObject( 209 GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON), 210 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_RELOAD)), 211 ROLE_SYSTEM_PUSHBUTTON); 212 } 213 214 // Retrieve accessibility object for Home button and verify accessibility info. 215 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) { 216 // Verify Home button MSAA name and role. 217 TestViewAccessibilityObject( 218 GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON), 219 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_HOME)), 220 ROLE_SYSTEM_PUSHBUTTON); 221 } 222 223 // Retrieve accessibility object for Star button and verify accessibility info. 224 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, 225 TestStarButtonAccObj) { 226 // Verify Star button MSAA name and role. 227 TestViewAccessibilityObject( 228 GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON), 229 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_STAR)), 230 ROLE_SYSTEM_PUSHBUTTON); 231 } 232 233 // Retrieve accessibility object for App menu button and verify accessibility 234 // info. 235 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) { 236 // Verify App menu button MSAA name and role. 237 TestViewAccessibilityObject( 238 GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU), 239 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_APP)), 240 ROLE_SYSTEM_BUTTONMENU); 241 } 242 243 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, 244 TestBookmarkBarViewAccObj) { 245 TestViewAccessibilityObject( 246 GetBookmarkBarView(), 247 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_BOOKMARKS)), 248 ROLE_SYSTEM_TOOLBAR); 249 } 250 251 IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, 252 TestAboutChromeViewAccObj) { 253 // Firstly, test that the WindowDelegate got updated. 254 views::Window* about_chrome_window = 255 GetBrowserView()->DoShowAboutChromeDialog(); 256 EXPECT_STREQ( 257 about_chrome_window->window_delegate()->GetWindowTitle().c_str(), 258 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ABOUT_CHROME_TITLE)).c_str()); 259 EXPECT_EQ(about_chrome_window->window_delegate()->GetAccessibleWindowRole(), 260 ui::AccessibilityTypes::ROLE_DIALOG); 261 262 // Also test the accessibility object directly. 263 IAccessible* acc_obj = NULL; 264 HRESULT hr = 265 ::AccessibleObjectFromWindow(about_chrome_window->GetNativeWindow(), 266 OBJID_CLIENT, 267 IID_IAccessible, 268 reinterpret_cast<void**>(&acc_obj)); 269 ASSERT_EQ(S_OK, hr); 270 ASSERT_TRUE(NULL != acc_obj); 271 272 TestAccessibilityInfo( 273 acc_obj, 274 UTF16ToWide(l10n_util::GetStringUTF16(IDS_ABOUT_CHROME_TITLE)), 275 ROLE_SYSTEM_DIALOG); 276 277 acc_obj->Release(); 278 } 279