diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-26 01:35:35 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-26 01:35:35 +0000 |
commit | 3f3e0fe124cdfe3cb1d96c4f256813ffcaabee40 (patch) | |
tree | a4b408efdff83320bee982353581011d80e6b469 /chrome | |
parent | dc12fef1b3d560bf860292454a945559968555de (diff) | |
download | chromium_src-3f3e0fe124cdfe3cb1d96c4f256813ffcaabee40.zip chromium_src-3f3e0fe124cdfe3cb1d96c4f256813ffcaabee40.tar.gz chromium_src-3f3e0fe124cdfe3cb1d96c4f256813ffcaabee40.tar.bz2 |
Revert cl 19315 to see if it fixes the builds.
TBR=klink
BUG=none
Review URL: http://codereview.chromium.org/149049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19331 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser_views_accessibility_unittest.cc | 202 | ||||
-rw-r--r-- | chrome/browser/browser_window.h | 4 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.h | 1 | ||||
-rw-r--r-- | chrome/chrome.gyp | 20 | ||||
-rw-r--r-- | chrome/test/accessibility/accessibility_tests.cc | 425 | ||||
-rw-r--r-- | chrome/test/accessibility/accessibility_util.cc | 553 | ||||
-rw-r--r-- | chrome/test/accessibility/accessibility_util.h | 143 | ||||
-rw-r--r-- | chrome/test/accessibility/browser_impl.cc | 512 | ||||
-rw-r--r-- | chrome/test/accessibility/browser_impl.h | 115 | ||||
-rw-r--r-- | chrome/test/accessibility/constants.h | 98 | ||||
-rw-r--r-- | chrome/test/accessibility/keyboard_util.cc | 194 | ||||
-rw-r--r-- | chrome/test/accessibility/keyboard_util.h | 36 | ||||
-rw-r--r-- | chrome/test/accessibility/registry_util.cc | 14 | ||||
-rw-r--r-- | chrome/test/accessibility/registry_util.h | 17 | ||||
-rw-r--r-- | chrome/test/accessibility/tab_impl.cc | 365 | ||||
-rw-r--r-- | chrome/test/accessibility/tab_impl.h | 135 |
17 files changed, 2625 insertions, 213 deletions
diff --git a/chrome/browser/browser_views_accessibility_unittest.cc b/chrome/browser/browser_views_accessibility_unittest.cc deleted file mode 100644 index 247f4cd..0000000 --- a/chrome/browser/browser_views_accessibility_unittest.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this -// source code is governed by a BSD-style license that can be found in the -// LICENSE file. - -#include <oleacc.h> - -#include "app/l10n_util.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/view_ids.h" -#include "chrome/browser/views/toolbar_view.h" -#include "chrome/test/in_process_browser_test.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "views/accessibility/view_accessibility_wrapper.h" -#include "views/widget/root_view.h" -#include "views/widget/widget_win.h" - -namespace { - -VARIANT id_self = {VT_I4, CHILDID_SELF}; - -// Dummy class to force creation of ATL module, needed by COM to instantiate -// ViewAccessibility. -class TestAtlModule : public CAtlDllModuleT< TestAtlModule > {}; -TestAtlModule test_atl_module_; - -class BrowserViewsAccessibilityTest : public InProcessBrowserTest { - public: - BrowserViewsAccessibilityTest() { - ::CoInitialize(NULL); - } - - ~BrowserViewsAccessibilityTest() { - ::CoUninitialize(); - } - - // Retrieves and initializes an instance of ToolbarView. - ToolbarView* GetToolbarView() { - BrowserWindow* browser_window = browser()->window(); - - if (!browser_window) - return NULL; - - BrowserWindowTesting* browser_window_testing = - browser_window->GetBrowserWindowTesting(); - - if (!browser_window_testing) - return NULL; - - return browser_window_testing->GetToolbarView(); - } - - // Retrieve and verify the accessibility object for the given View. - void TestViewAccessibilityObject(views::View* view, std::wstring name, - long role) { - ASSERT_TRUE(NULL != view); - - // Initialize View accessibility information. - view->SetAccessibleName(name); - - IAccessible* acc_obj = NULL; - HRESULT hr = view->GetViewAccessibilityWrapper()->GetInstance( - IID_IAccessible, reinterpret_cast<void**>(&acc_obj)); - ASSERT_EQ(S_OK, hr); - ASSERT_TRUE(NULL != acc_obj); - - TestAccessibilityInfo(acc_obj, name, role); - } - - // Verifies MSAA Name and Role properties of the given IAccessible. - void TestAccessibilityInfo(IAccessible* acc_obj, std::wstring name, - long role) { - // Verify MSAA Name property. - BSTR acc_name; - - HRESULT hr = acc_obj->get_accName(id_self, &acc_name); - ASSERT_EQ(S_OK, hr); - EXPECT_STREQ(acc_name, name.c_str()); - - // Verify MSAA Role property. - VARIANT acc_role; - ::VariantInit(&acc_role); - - hr = acc_obj->get_accRole(id_self, &acc_role); - ASSERT_EQ(S_OK, hr); - EXPECT_EQ(VT_I4, acc_role.vt); - EXPECT_EQ(role, acc_role.lVal); - - ::VariantClear(&acc_role); - } -}; - -// Retrieve accessibility object for main window and verify accessibility info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestChromeWindowAccObj) { - BrowserWindow* browser_window = browser()->window(); - ASSERT_TRUE(NULL != browser_window); - - HWND hwnd = browser_window->GetNativeHandle(); - ASSERT_TRUE(NULL != hwnd); - - // Get accessibility object. - IAccessible* acc_obj = NULL; - HRESULT hr = ::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible, - reinterpret_cast<void**>(&acc_obj)); - ASSERT_EQ(S_OK, hr); - ASSERT_TRUE(NULL != acc_obj); - - TestAccessibilityInfo(acc_obj, l10n_util::GetString(IDS_PRODUCT_NAME), - ROLE_SYSTEM_WINDOW); - - acc_obj->Release(); -} - -// Retrieve accessibility object for root view, and verify accessibility info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestRootViewAccObj) { - views::WidgetWin* window = new views::WidgetWin; - - // Verify root view MSAA name and role. - TestViewAccessibilityObject(window->GetRootView(), - l10n_util::GetString(IDS_PRODUCT_NAME), - ROLE_SYSTEM_APPLICATION); -} - -// Retrieve accessibility object for toolbar view and verify accessibility info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestToolbarViewAccObj) { - // Verify toolbar MSAA name and role. - TestViewAccessibilityObject(GetToolbarView(), - l10n_util::GetString(IDS_ACCNAME_TOOLBAR), - ROLE_SYSTEM_TOOLBAR); -} - -// Retrieve accessibility object for Back button and verify accessibility info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestBackButtonAccObj) { - // Verify Back button MSAA name and role. - TestViewAccessibilityObject( - GetToolbarView()->GetViewByID(VIEW_ID_BACK_BUTTON), - l10n_util::GetString(IDS_ACCNAME_BACK), ROLE_SYSTEM_BUTTONDROPDOWN); -} - -// Retrieve accessibility object for Forward button and verify accessibility -// info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestForwardButtonAccObj) { - // Verify Forward button MSAA name and role. - TestViewAccessibilityObject( - GetToolbarView()->GetViewByID(VIEW_ID_FORWARD_BUTTON), - l10n_util::GetString(IDS_ACCNAME_FORWARD), ROLE_SYSTEM_BUTTONDROPDOWN); -} - -// Retrieve accessibility object for Reload button and verify accessibility -// info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestReloadButtonAccObj) { - // Verify Reload button MSAA name and role. - TestViewAccessibilityObject( - GetToolbarView()->GetViewByID(VIEW_ID_RELOAD_BUTTON), - l10n_util::GetString(IDS_ACCNAME_RELOAD), ROLE_SYSTEM_PUSHBUTTON); -} - -// Retrieve accessibility object for Home button and verify accessibility info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestHomeButtonAccObj) { - // Verify Home button MSAA name and role. - TestViewAccessibilityObject( - GetToolbarView()->GetViewByID(VIEW_ID_HOME_BUTTON), - l10n_util::GetString(IDS_ACCNAME_HOME), ROLE_SYSTEM_PUSHBUTTON); -} - -// Retrieve accessibility object for Star button and verify accessibility info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestStarButtonAccObj) { - // Verify Star button MSAA name and role. - TestViewAccessibilityObject( - GetToolbarView()->GetViewByID(VIEW_ID_STAR_BUTTON), - l10n_util::GetString(IDS_ACCNAME_STAR), ROLE_SYSTEM_PUSHBUTTON); -} - -// Retrieve accessibility object for Go button and verify accessibility info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestGoButtonAccObj) { - // Verify Go button MSAA name and role. - TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_GO_BUTTON), - l10n_util::GetString(IDS_ACCNAME_GO), - ROLE_SYSTEM_PUSHBUTTON); -} - -// Retrieve accessibility object for Page menu button and verify accessibility -// info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestPageMenuAccObj) { - // Verify Page menu button MSAA name and role. - TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_PAGE_MENU), - l10n_util::GetString(IDS_ACCNAME_PAGE), - ROLE_SYSTEM_BUTTONDROPDOWN); -} - -// Retrieve accessibility object for App menu button and verify accessibility -// info. -IN_PROC_BROWSER_TEST_F(BrowserViewsAccessibilityTest, TestAppMenuAccObj) { - // Verify App menu button MSAA name and role. - TestViewAccessibilityObject(GetToolbarView()->GetViewByID(VIEW_ID_APP_MENU), - l10n_util::GetString(IDS_ACCNAME_APP), - ROLE_SYSTEM_BUTTONDROPDOWN); -} - -} // Namespace. - diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h index fa4fe39..2c558aa 100644 --- a/chrome/browser/browser_window.h +++ b/chrome/browser/browser_window.h @@ -19,7 +19,6 @@ class StatusBubble; class TabContents; class TabContentsContainer; class TemplateURL; -class ToolbarView; namespace gfx { class Rect; @@ -240,9 +239,6 @@ class BrowserWindowTesting { // Returns the TabContentsContainer. virtual views::View* GetTabContentsContainerView() const = 0; - - // Returns the ToolbarView. - virtual ToolbarView* GetToolbarView() const = 0; #endif }; diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index b4f8844..9088f32 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -947,10 +947,6 @@ views::View* BrowserView::GetTabContentsContainerView() const { return contents_container_->GetFocusView(); } -ToolbarView* BrowserView::GetToolbarView() const { - return toolbar_; -} - /////////////////////////////////////////////////////////////////////////////// // BrowserView, NotificationObserver implementation: diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index fd28301..4ca85c4 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -241,7 +241,6 @@ class BrowserView : public BrowserWindow, virtual BookmarkBarView* GetBookmarkBarView() const; virtual LocationBarView* GetLocationBarView() const; virtual views::View* GetTabContentsContainerView() const; - virtual ToolbarView* GetToolbarView() const; // Overridden from NotificationObserver: virtual void Observe(NotificationType type, diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index f869f90..d7ea225 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -3180,6 +3180,18 @@ 'common/logging_chrome_uitest.cc', 'common/net/cache_uitest.cc', 'common/pref_service_uitest.cc', + 'test/accessibility/accessibility_tests.cc', + 'test/accessibility/accessibility_util.cc', + 'test/accessibility/accessibility_util.h', + 'test/accessibility/browser_impl.cc', + 'test/accessibility/browser_impl.h', + 'test/accessibility/constants.h', + 'test/accessibility/keyboard_util.cc', + 'test/accessibility/keyboard_util.h', + 'test/accessibility/registry_util.cc', + 'test/accessibility/registry_util.h', + 'test/accessibility/tab_impl.cc', + 'test/accessibility/tab_impl.h', 'test/automation/automation_proxy_uitest.cc', 'test/automated_ui_tests/automated_ui_test_test.cc', 'test/chrome_process_util_uitest.cc', @@ -3265,6 +3277,12 @@ 'browser/ssl/ssl_uitest.cc', 'browser/views/find_bar_win_uitest.cc', 'common/logging_chrome_uitest.cc', + 'test/accessibility/accessibility_tests.cc', + 'test/accessibility/accessibility_util.cc', + 'test/accessibility/browser_impl.cc', + 'test/accessibility/keyboard_util.cc', + 'test/accessibility/registry_util.cc', + 'test/accessibility/tab_impl.cc', 'test/ui/npapi_uitest.cc', 'test/ui/sandbox_uitests.cc', 'worker/worker_uitest.cc', @@ -3341,7 +3359,6 @@ 'browser/browser_commands_unittest.cc', 'browser/browser_theme_provider_unittest.cc', 'browser/browser_unittest.cc', - 'browser/browser_views_accessibility_unittest.cc', 'browser/debugger/devtools_remote_message_unittest.cc', 'browser/debugger/devtools_remote_listen_socket_unittest.cc', 'browser/debugger/devtools_remote_listen_socket_unittest.h', @@ -3668,7 +3685,6 @@ # Need to port browser_with_test_window_test.* first 'browser/browser_commands_unittest.cc', 'browser/browser_unittest.cc', - 'browser/browser_views_accessibility_unittest.cc', # Need to port browser/automation/ui_controls.h 'browser/extensions/extension_process_manager_unittest.cc', 'browser/extensions/test_extension_loader.cc', diff --git a/chrome/test/accessibility/accessibility_tests.cc b/chrome/test/accessibility/accessibility_tests.cc new file mode 100644 index 0000000..8b0cafb --- /dev/null +++ b/chrome/test/accessibility/accessibility_tests.cc @@ -0,0 +1,425 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <oleacc.h> + +#include "app/l10n_util.h" +#include "base/file_path.h" +#include "base/win_util.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/test/accessibility/accessibility_util.h" +#include "chrome/test/ui/ui_test.h" +#include "chrome/test/automation/browser_proxy.h" +#include "chrome/test/automation/window_proxy.h" +#include "chrome/test/automation/tab_proxy.h" +#include "grit/chromium_strings.h" +#include "grit/generated_resources.h" +#include "net/base/net_util.h" + +namespace { + +#define CHK_RELEASE(obj) { if (obj) { (obj)->Release(); (obj) = NULL; } } + +class AccessibilityTest : public UITest { + protected: + AccessibilityTest() { + show_window_ = true; + CoInitialize(NULL); + } + ~AccessibilityTest() { + CoUninitialize(); + } +}; +} // Namespace. + +// Check browser handle and accessibility object browser client. +TEST_F(AccessibilityTest, DISABLED_TestChromeBrowserAccObject) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + + ASSERT_TRUE(NULL != hwnd); + ASSERT_TRUE(NULL != acc_obj); + + CHK_RELEASE(acc_obj); +} + +// Check accessibility object for toolbar and its properties Name, Role, State. +TEST_F(AccessibilityTest, DISABLED_TestChromeToolbarAccObject) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + hr = GetToolbarAccessible(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check Name - IDS_ACCNAME_TOOLBAR. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_TOOLBAR), GetName(acc_obj)); + // Check Role - "tool bar". + EXPECT_EQ(ROLE_SYSTEM_TOOLBAR, GetRole(acc_obj)); + // Check State - "focusable" + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + + CHK_RELEASE(acc_obj); +} + +// Check accessibility object for tabstrip and its properties Name, Role, +// State. +TEST_F(AccessibilityTest, DISABLED_TestChromeTabstripAccObject) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + hr = GetTabStripAccessible(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check Name - IDS_ACCNAME_TABSTRIP. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_TABSTRIP), GetName(acc_obj)); + // Check Role - "grouping". + EXPECT_EQ(ROLE_SYSTEM_GROUPING, GetRole(acc_obj)); + // Check State - "focusable" + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + + CHK_RELEASE(acc_obj); +} + +// This test is disabled for now, see issue 2243. +// Check Browser buttons and their Name, Role, State. +TEST_F(AccessibilityTest, DISABLED_TestChromeButtons) { + // TODO(klink): Implement with indexing from ViewIDs. +} + +// Check Back button and its Name, Role, State. +TEST_F(AccessibilityTest, DISABLED_TestBackButton) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for Back button. + hr = GetBackButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_BACK), GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_BUTTONDROPDOWN, GetRole(acc_obj)); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + } else { + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + } + + CHK_RELEASE(acc_obj); +} + +// Check Back button and its Name, Role, State, upon adding a new tab. +TEST_F(AccessibilityTest, DISABLED_TestBackBtnStatusOnNewTab) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for Back button. + hr = GetBackButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_BACK), GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_BUTTONDROPDOWN, GetRole(acc_obj)); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + + // Now check Back status in different situations. + scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(window.get()); + int tab_count = -1; + + // Set URL and check button status. + scoped_refptr<TabProxy> tab1(window->GetTab(0)); + ASSERT_TRUE(tab1.get()); + FilePath test_file1(test_data_directory_); + test_file1 = test_file1.AppendASCII("title1.html"); + tab1->NavigateToURL(net::FilePathToFileURL(test_file1)); + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | STATE_SYSTEM_FOCUSABLE, + GetState(acc_obj)); + // Go Back and check status. + window->ApplyAccelerator(IDC_BACK); + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + + // Add empty new tab and check status. + ASSERT_TRUE(window->GetTabCount(&tab_count)); + ASSERT_TRUE(window->ApplyAccelerator(IDC_NEW_TAB)); + ASSERT_TRUE(window->WaitForTabCountToBecome(tab_count + 1, + action_max_timeout_ms())); + // Check accessibility object's children. + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + + // Add new tab with URL and check status. + ASSERT_TRUE(window->GetTabCount(&tab_count)); + FilePath test_file2(test_data_directory_); + test_file2 = test_file2.AppendASCII("title1.html"); + ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(test_file2))); + ASSERT_TRUE(window->WaitForTabCountToBecome(tab_count + 1, + action_max_timeout_ms())); + // Check accessibility object's children. + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + CHK_RELEASE(acc_obj); +} + +// Check Forward button and its Name, Role, State. +TEST_F(AccessibilityTest, DISABLED_TestForwardButton) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for Forward button. + hr = GetForwardButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_FORWARD), + GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_BUTTONDROPDOWN, GetRole(acc_obj)); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + } else { + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + } + + CHK_RELEASE(acc_obj); +} + +// Check Forward button and its Name, Role, State, upon adding a new tab. +TEST_F(AccessibilityTest, DISABLED_TestForwardBtnStatusOnNewTab) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for Forward button. + hr = GetForwardButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_FORWARD), + GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_BUTTONDROPDOWN, GetRole(acc_obj)); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + } else { + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + } + + // Now check Back status in different situations. + scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(window.get()); + int tab_count = -1; + + // Set URL and check button status. + scoped_refptr<TabProxy> tab1(window->GetTab(0)); + ASSERT_TRUE(tab1.get()); + FilePath test_file1(test_data_directory_); + test_file1 = test_file1.AppendASCII("title1.html"); + tab1->NavigateToURL(net::FilePathToFileURL(test_file1)); + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + // Go Back and check status. + window->ApplyAccelerator(IDC_BACK); + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | STATE_SYSTEM_FOCUSABLE, + GetState(acc_obj)); + // Go Forward and check status. + window->ApplyAccelerator(IDC_FORWARD); + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + + // Add empty new tab and check status. + ASSERT_TRUE(window->GetTabCount(&tab_count)); + ASSERT_TRUE(window->ApplyAccelerator(IDC_NEW_TAB)); + ASSERT_TRUE(window->WaitForTabCountToBecome(tab_count + 1, + action_max_timeout_ms())); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + + // Add new tab with URL and check status. + ASSERT_TRUE(window->GetTabCount(&tab_count)); + FilePath test_file2(test_data_directory_); + test_file2 = test_file2.AppendASCII("title1.html"); + ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(test_file2))); + ASSERT_TRUE(window->WaitForTabCountToBecome(tab_count + 1, + action_max_timeout_ms())); + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | + STATE_SYSTEM_FOCUSABLE | + STATE_SYSTEM_UNAVAILABLE, + GetState(acc_obj)); + CHK_RELEASE(acc_obj); +} + +// Check Star button and its Name, Role, State. +TEST_F(AccessibilityTest, DISABLED_TestStarButton) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for Star button. + hr = GetStarButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_STAR), GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_PUSHBUTTON, GetRole(acc_obj)); + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + + CHK_RELEASE(acc_obj); +} + +// Check Star button and its Name, Role, State, upon adding a new tab. +TEST_F(AccessibilityTest, DISABLED_TestStarBtnStatusOnNewTab) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for Star button. + hr = GetStarButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_STAR), GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_PUSHBUTTON, GetRole(acc_obj)); + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + + // Now, check Star status in different situations. + scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(window.get()); + + // Set URL and check button status. + scoped_refptr<TabProxy> tab1(window->GetTab(0)); + ASSERT_TRUE(tab1.get()); + FilePath test_file1(test_data_directory_); + test_file1 = test_file1.AppendASCII("title1.html"); + tab1->NavigateToURL(net::FilePathToFileURL(test_file1)); + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + + // Add empty new tab and check status. + int tab_count = -1; + ASSERT_TRUE(window->GetTabCount(&tab_count)); + ASSERT_TRUE(window->ApplyAccelerator(IDC_NEW_TAB)); + ASSERT_TRUE(window->WaitForTabCountToBecome(tab_count + 1, + action_max_timeout_ms())); + // Check tab count. Also, check accessibility object's state. + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + + // Add new tab with URL and check status. + ASSERT_TRUE(window->GetTabCount(&tab_count)); + FilePath test_file2(test_data_directory_); + test_file2 = test_file2.AppendASCII("title1.html"); + ASSERT_TRUE(window->AppendTab(net::FilePathToFileURL(test_file2))); + ASSERT_TRUE(window->WaitForTabCountToBecome(tab_count + 1, + action_max_timeout_ms())); + // Check tab count. Also, check accessibility object's state. + Sleep(sleep_timeout_ms()); + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + + CHK_RELEASE(acc_obj); +} + +// Check Go button and its Name, Role, State. +TEST_F(AccessibilityTest, DISABLED_TestGoButton) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for Go button. + hr = GetGoButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_GO), GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_PUSHBUTTON, GetRole(acc_obj)); + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + + CHK_RELEASE(acc_obj); +} + +// Check Page menu button and its Name, Role, State. +TEST_F(AccessibilityTest, DISABLED_TestPageMenuButton) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for Page menu button. + hr = GetPageMenuButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_PAGE), GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_BUTTONDROPDOWN, GetRole(acc_obj)); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | STATE_SYSTEM_FOCUSABLE, + GetState(acc_obj)); + } else { + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + } + + CHK_RELEASE(acc_obj); +} + +// Check App (wrench) menu button and its Name, Role, State. +TEST_F(AccessibilityTest, DISABLED_TestAppMenuButton) { + HRESULT hr = S_OK; + IAccessible* acc_obj = NULL; + + // Retrieve IAccessible for App menu button. + hr = GetAppMenuButton(&acc_obj); + ASSERT_TRUE(S_OK == hr); + ASSERT_TRUE(NULL != acc_obj); + + // Check button and its Name, Role, State. + EXPECT_EQ(l10n_util::GetString(IDS_ACCNAME_APP), GetName(acc_obj)); + EXPECT_EQ(ROLE_SYSTEM_BUTTONDROPDOWN, GetRole(acc_obj)); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(STATE_SYSTEM_HASPOPUP | STATE_SYSTEM_FOCUSABLE, + GetState(acc_obj)); + } else { + EXPECT_EQ(STATE_SYSTEM_FOCUSABLE, GetState(acc_obj)); + } + + CHK_RELEASE(acc_obj); +} diff --git a/chrome/test/accessibility/accessibility_util.cc b/chrome/test/accessibility/accessibility_util.cc new file mode 100644 index 0000000..0861cc2 --- /dev/null +++ b/chrome/test/accessibility/accessibility_util.cc @@ -0,0 +1,553 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/test/accessibility/accessibility_util.h" + +#include "app/l10n_util.h" +#include "base/win_util.h" +#include "chrome/browser/view_ids.h" +#include "chrome/test/accessibility/constants.h" +#include "grit/chromium_strings.h" +#include "grit/generated_resources.h" + +VARIANT id_self = {VT_I4, CHILDID_SELF}; + +// TODO(beng): clean this up +static const wchar_t* kBrowserWindowKey = L"__BROWSER_WINDOW__"; + +static BOOL CALLBACK WindowEnumProc(HWND hwnd, LPARAM data) { + std::wstring class_name = win_util::GetClassName(hwnd); + if (class_name == CHROME_HWND_VIEW_CONTAINER) { + HANDLE window_interface = GetProp(hwnd, kBrowserWindowKey); + if (window_interface) { + HWND* out = reinterpret_cast<HWND*>(data); + *out = hwnd; + return FALSE; + } + } + return TRUE; +} + +HWND GetChromeBrowserWnd(IAccessible** acc_obj) { + HWND hwnd = NULL; + + EnumWindows(WindowEnumProc, reinterpret_cast<LPARAM>(&hwnd)); + + if (!hwnd) { + CHK_RELEASE(*acc_obj); + return NULL; + } + + // Get accessibility object for Chrome, only if requested (not NULL). + if (!acc_obj) + return hwnd; + + *acc_obj = NULL; + + // Get accessibility object for Chrome Main Window. If failed to get it, + // return only window handle. + IAccessible* root_acc_obj = NULL; + HRESULT hr = S_OK; + hr = AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void**>(&root_acc_obj)); + if ((S_OK != hr) || !root_acc_obj) + return hwnd; + + const std::wstring product_name = l10n_util::GetString(IDS_PRODUCT_NAME); + BSTR name; + + // Confirm if it is Chrome Main Window using its accessibility object's + // Name and Role property. If it's not the desired object, return only + // window handle. + hr = root_acc_obj->get_accName(id_self, &name); + if ((S_OK != hr) || (!name) || + (0 != _wcsicmp(name, product_name.c_str())) ) { + CHK_RELEASE(root_acc_obj); + return hwnd; + } + if (ROLE_SYSTEM_WINDOW != GetRole(root_acc_obj)) { + CHK_RELEASE(root_acc_obj); + return hwnd; + } + + // Get accessibility child objects for Chrome Main Window. If failed, return + // only window handle. + INT64 child_cnt = GetChildCount(root_acc_obj); + VARIANT* children = reinterpret_cast<VARIANT*>(calloc(size_t(child_cnt), + sizeof(VARIANT))); + + if (!children) { + CHK_RELEASE(root_acc_obj); + return hwnd; + } + + hr = GetChildrenArray(root_acc_obj, children); + if (S_OK != hr) { + CHK_RELEASE(root_acc_obj); + free(children); + return hwnd; + } + + // Fetch desired child (Chrome App Window) of Chrome Main Window. + IAccessible* app_acc_obj = NULL; + GetChildAccObject(root_acc_obj, children[CHROME_APP_ACC_INDEX], &app_acc_obj); + if (!app_acc_obj) { + CHK_RELEASE(app_acc_obj); + free(children); + return hwnd; + } + + // Confirm if it is Chrome App Window by using it's accessibility object's + // Name and Role property. If it's not the desired object, return only + // window handle. + hr = app_acc_obj->get_accName(id_self, &name); + if ((S_OK != hr) || (!name) || + (0 != _wcsicmp(name, product_name.c_str())) ) { + CHK_RELEASE(app_acc_obj); + CHK_RELEASE(root_acc_obj); + free(children); + return hwnd; + } + if (ROLE_SYSTEM_APPLICATION != GetRole(app_acc_obj)) { + CHK_RELEASE(app_acc_obj); + CHK_RELEASE(root_acc_obj); + free(children); + return hwnd; + } + + // Get accessibility object for Chrome Client. If failed, return only + // window handle. + hr = GetChildrenArray(app_acc_obj, children); + if (S_OK != hr) { + CHK_RELEASE(app_acc_obj); + CHK_RELEASE(root_acc_obj); + free(children); + return hwnd; + } + + // Chrome Window has only one child which is Chrome Client. + GetChildAccObject(app_acc_obj, children[CHROME_CLIENT_ACC_INDEX], acc_obj); + + // Done using [children] array. + free(children); + + // Confirm if it is Chrome client using it's accessibility object's Name + // and Role property. If it's not the desired object, return only window + // handle. + hr = (*acc_obj)->get_accName(id_self, &name); + if ((S_OK != hr) || (!name) || + (0 != _wcsicmp(name, product_name.c_str())) ) { + CHK_RELEASE(*acc_obj); + } + if (ROLE_SYSTEM_CLIENT != GetRole(*acc_obj)) + CHK_RELEASE(*acc_obj); + + CHK_RELEASE(app_acc_obj); + CHK_RELEASE(root_acc_obj); + return hwnd; +} + +HRESULT GetChildAccessible(std::wstring parent_name, unsigned int child_index, + IAccessible** acc_obj) { + // Validate input and initialize. + if (!acc_obj) + return E_INVALIDARG; + + *acc_obj = NULL; + + // Get accessibility object and window handle for Chrome parent. + IAccessible* parent = NULL; + if (0 == parent_name.compare(BROWSER_STR)) + GetChromeBrowserWnd(&parent); + if (0 == parent_name.compare(BROWSER_VIEW_STR)) + GetBrowserViewAccessible(&parent); + if (0 == parent_name.compare(TOOLBAR_STR)) + GetToolbarAccessible(&parent); + if (0 == parent_name.compare(TABSTRIP_STR)) + GetTabStripAccessible(&parent); + + if (!parent) + return E_FAIL; + + bool get_iaccessible = false; + + // Validate child index. + INT64 child_cnt = GetChildCount(parent); + if (child_index >= child_cnt) + get_iaccessible = true; + + HRESULT hr = S_OK; + + if (get_iaccessible) { + // Child retrieved by child index, potentially further down the hierarchy. + VARIANT child_var; + child_var.vt = VT_I4; + child_var.lVal = child_index; + hr = GetChildAccObject(parent, child_var, acc_obj); + } else { + // Get array of child items of parent object. + VARIANT* children = reinterpret_cast<VARIANT*>(calloc(size_t(child_cnt), + sizeof(VARIANT))); + if (children) { + hr = GetChildrenArray(parent, children); + if (S_OK == hr) { + // Fetch child IAccessible. + if (acc_obj) + hr = GetChildAccObject(parent, children[child_index], acc_obj); + } + free(children); + } + } + + CHK_RELEASE(parent); + return hr; +} + +HRESULT GetTabStripAccessible(IAccessible** acc_obj) { + return GetChildAccessible(BROWSER_VIEW_STR, TABSTRIP_ACC_INDEX, acc_obj); +} + +HRESULT GetBrowserViewAccessible(IAccessible** acc_obj) { + return GetChildAccessible(BROWSER_STR, BROWSER_VIEW_ACC_INDEX, acc_obj); +} + +HRESULT GetToolbarAccessible(IAccessible** acc_obj) { + return GetChildAccessible(BROWSER_VIEW_STR, VIEW_ID_TOOLBAR, acc_obj); +} + +HRESULT GetBrowserMinimizeButton(IAccessible** acc_obj) { + return GetChildAccessible(BROWSER_STR, CHROME_MIN_ACC_INDEX, acc_obj); +} + +HRESULT GetBrowserMaximizeButton(IAccessible** acc_obj) { + return GetChildAccessible(BROWSER_STR, CHROME_MAX_ACC_INDEX, acc_obj); +} + +HRESULT GetBrowserRestoreButton(IAccessible** acc_obj) { + return GetChildAccessible(BROWSER_STR, CHROME_RESTORE_ACC_INDEX, acc_obj); +} + +HRESULT GetBrowserCloseButton(IAccessible** acc_obj) { + return GetChildAccessible(BROWSER_STR, CHROME_CLOSE_ACC_INDEX, acc_obj); +} + +HRESULT GetBackButton(IAccessible** acc_obj) { + return GetChildAccessible(TOOLBAR_STR, VIEW_ID_BACK_BUTTON, acc_obj); +} + +HRESULT GetForwardButton(IAccessible** acc_obj) { + return GetChildAccessible(TOOLBAR_STR, VIEW_ID_FORWARD_BUTTON, acc_obj); +} + +HRESULT GetStarButton(IAccessible** acc_obj) { + return GetChildAccessible(TOOLBAR_STR, VIEW_ID_STAR_BUTTON, acc_obj); +} + +HRESULT GetGoButton(IAccessible** acc_obj) { + return GetChildAccessible(TOOLBAR_STR, VIEW_ID_GO_BUTTON, acc_obj); +} + +HRESULT GetPageMenuButton(IAccessible** acc_obj) { + return GetChildAccessible(TOOLBAR_STR, VIEW_ID_PAGE_MENU, acc_obj); +} + +HRESULT GetAppMenuButton(IAccessible** acc_obj) { + return GetChildAccessible(TOOLBAR_STR, VIEW_ID_APP_MENU, acc_obj); +} + +HWND GetAddressBarWnd(IAccessible** acc_obj) { + // Initialize, if requested. + if (acc_obj) + *acc_obj = NULL; + + HWND hwnd = NULL; + HWND hwnd_addr_bar = NULL; + + // Get window handle for Chrome Browser. + hwnd = GetChromeBrowserWnd(NULL); + if (NULL != hwnd) { + // Get AddressBar/OmniBox (edit box) window handle. + hwnd_addr_bar = FindWindowEx(hwnd, 0, CHROME_AUTOCOMPLETE_EDIT, NULL); + + // Get accessibility object for address bar, if requested. + if (acc_obj && hwnd_addr_bar) { + AccessibleObjectFromWindow(hwnd_addr_bar, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void**>(acc_obj)); + } + } + + return hwnd_addr_bar; +} + +HWND GetFindTextWnd(IAccessible** acc_obj) { + // Initialize, if requested. + if (acc_obj) + *acc_obj = NULL; + + HWND hwnd = NULL; + HWND hwnd_find = NULL; + + // Get window handle for Chrome Browser. + hwnd = GetChromeBrowserWnd(NULL); + if (NULL != hwnd) { + // Get handle of a window, which is contains edit box for Find string. + hwnd_find = FindWindowEx(hwnd, 0, CHROME_HWND_VIEW_CONTAINER, NULL); + + // Get accessibility object, if requested. + if (acc_obj && hwnd_find) { + AccessibleObjectFromWindow(hwnd_find, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void**>(acc_obj)); + } + } + + return hwnd_find; +} + +HWND GetAuthWnd(IAccessible** acc_obj) { + // Initialize, if requested. + if (acc_obj) + *acc_obj = NULL; + + HWND hwnd = NULL; + HWND hwnd_tab = NULL; + HWND hwnd_auth = NULL; + + // Get window handle for Chrome Browser. + hwnd = GetChromeBrowserWnd(NULL); + if (hwnd) { + // Get window handle for tab. + hwnd_tab = FindWindowEx(hwnd, 0, CHROME_TAB_CONTENTS, NULL); + if (!hwnd_tab) + return hwnd_auth; + + // Get handle for Authentication window. + hwnd_auth = FindWindowEx(hwnd_tab, 0, CHROME_HWND_VIEW_CONTAINER, + AUTH_TITLE); + + // Get accessibility object, if requested. + if (acc_obj && hwnd_auth) { + AccessibleObjectFromWindow(hwnd_auth, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void**>(acc_obj)); + } + } + + return hwnd_auth; +} + +HRESULT GetChildAccObject(IAccessible* acc_obj, VARIANT child, + IAccessible** child_acc_obj) { + // Validate input. + if (!acc_obj || !child_acc_obj) + return E_INVALIDARG; + + HRESULT hr = S_OK; + IDispatch* disp = NULL; + + // Check the child type and fetch object accordingly. + if (child.vt == VT_DISPATCH) { + child.pdispVal-> + QueryInterface(IID_IAccessible, + reinterpret_cast<void**>(child_acc_obj)); + } else if (child.vt == VT_I4) { + hr = acc_obj->get_accChild(child, &disp); + if ((hr == S_OK) && disp) { + disp->QueryInterface(IID_IAccessible, + reinterpret_cast<void**>(child_acc_obj)); + CHK_RELEASE(disp); + } + } + + return hr; +} + +HRESULT GetParentAccObject(IAccessible* acc_obj, IAccessible** parent_acc_obj) { + // Validate input. + if (!acc_obj || !parent_acc_obj) + return E_INVALIDARG; + + HRESULT hr = S_OK; + IDispatch* disp = NULL; + + // Fetch parent object. + hr = acc_obj->get_accParent(&disp); + if ((hr == S_OK) && disp) { + disp->QueryInterface(IID_IAccessible, + reinterpret_cast<void**>(parent_acc_obj)); + CHK_RELEASE(disp); + } + + return hr; +} + +INT64 GetChildCount(IAccessible* acc_obj) { + HRESULT hr = S_OK; + LONG child_cnt = 0; + + // Validate input. Object can have 0 children, so return -1 on invalid input. + if (!acc_obj) + return -1; + + // Get child count. + acc_obj->get_accChildCount(&child_cnt); + return child_cnt; +} + +HRESULT GetChildrenArray(IAccessible* acc_obj, VARIANT* children) { + HRESULT hr = S_OK; + INT64 child_start = 0; + LONG child_obtained = 0; + INT64 child_cnt = GetChildCount(acc_obj); + + // Validate input. + if (!acc_obj || !children) + return E_INVALIDARG; + + // Validate every item and initialize it. + int i = 0; + for (; (i < child_cnt) && (children + i); i++) { + VariantInit(children + i); + } + + // If all items in array are not initialized, return error. + if (i != child_cnt) + return E_FAIL; + + // Get IDs of child items. + AccessibleChildren(acc_obj, LONG(child_start), LONG(child_cnt), children, + &child_obtained); + return hr; +} + +HRESULT ActivateWnd(IAccessible* acc_obj, HWND hwnd) { + HRESULT hr = S_OK; + + // Select and focus the object, if accessibility object is specified. + if (acc_obj) + hr = acc_obj->accSelect(SELFLAG_TAKEFOCUS | SELFLAG_TAKESELECTION, id_self); + + // Send message to window, if window handle is specified. + if (hwnd) + SetActiveWindow(hwnd); + + return hr; +} + +BSTR GetTabName(INT64 tab_index) { + HRESULT hr = S_OK; + BSTR name; + + // Validate tab index specified. + if (tab_index < 1) + return NULL; + + // Get accessibility object for Tabstrip. + IAccessible* tab_strip_acc_obj = NULL; + GetTabStripAccessible(&tab_strip_acc_obj); + + // Get Tab from Tabstrip and return it's Name. + if (tab_strip_acc_obj) { + INT64 child_cnt = GetChildCount(tab_strip_acc_obj); + VARIANT* children = reinterpret_cast<VARIANT*>(calloc(size_t(child_cnt), + sizeof(VARIANT))); + if (children) { + // Get tab object. tab_index = index in child array, because first child + // in tabstrip is '+' button. + hr = GetChildrenArray(tab_strip_acc_obj, children); + if (S_OK == hr) { + IAccessible* temp_acc_obj = NULL; + hr = GetChildAccObject(tab_strip_acc_obj, children[tab_index], + &temp_acc_obj); + if ((S_OK == hr) && (children[tab_index].vt == VT_DISPATCH) && + (temp_acc_obj)) { + hr = temp_acc_obj->get_accName(id_self, &name); + } else if (children[tab_index].vt == VT_I4) { + hr = tab_strip_acc_obj->get_accName(children[1], &name); + } + CHK_RELEASE(temp_acc_obj); + CHK_RELEASE(tab_strip_acc_obj); + return name; + } + } + CHK_RELEASE(tab_strip_acc_obj); + } + + return NULL; +} + +INT64 GetTabCnt() { + // Get accessibility object for Tabstrip. + IAccessible* tab_strip_acc_obj = NULL; + GetTabStripAccessible(&tab_strip_acc_obj); + + // If Tabstrip is invalid, return -1 to indicate error. + if (!tab_strip_acc_obj) + return -1; + + // Get child count. + INT64 child_cnt = 0; + child_cnt = GetChildCount(tab_strip_acc_obj); + CHK_RELEASE(tab_strip_acc_obj); + + // Don't count 1st child as it is '+' button. + return (child_cnt - 1); +} + +std::wstring GetName(IAccessible* acc_obj, VARIANT child) { + HRESULT hr = S_OK; + + // Validate input. + if (!acc_obj) + return std::wstring(); + + // Get Name. + BSTR name; + hr = acc_obj->get_accName(child, &name); + if (S_OK != hr) + return std::wstring(); + + return std::wstring(name); +} + +LONG GetRole(IAccessible* acc_obj, VARIANT child) { + HRESULT hr = S_OK; + LPTSTR role_str = NULL; + + // Validate input. + if (!acc_obj) + return -1; + + // Get Role. + VARIANT role; + VariantInit(&role); + hr = acc_obj->get_accRole(child, &role); + if (S_OK != hr || VT_I4 != role.vt) { + VariantClear(&role); + return -1; + } + + // Return the role value + return role.lVal; +} + +LONG GetState(IAccessible* acc_obj, VARIANT child) { + HRESULT hr = S_OK; + LPTSTR state_str = NULL; + std::wstring complete_state; + + // Validate input. + if (!acc_obj) + return -1; + + // Get State. + VARIANT state; + VariantInit(&state); + hr = acc_obj->get_accState(child, &state); + if (S_OK != hr || VT_I4 != state.vt) { + VariantClear(&state); + return -1; + } + + VariantClear(&state); + return state.lVal; +} diff --git a/chrome/test/accessibility/accessibility_util.h b/chrome/test/accessibility/accessibility_util.h new file mode 100644 index 0000000..0659be8 --- /dev/null +++ b/chrome/test/accessibility/accessibility_util.h @@ -0,0 +1,143 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_ACCESSIBILITY_ACCESSIBILITY_UTIL_H_ +#define CHROME_TEST_ACCESSIBILITY_ACCESSIBILITY_UTIL_H_ + +#include <oleacc.h> + +#include "base/string_util.h" + +/////////////////////////////////////////////////////////////////////////////// +// Functions and Globals that use the IAccessible interface. +// These are the wrappers to fetch accessible object interface and properties. +/////////////////////////////////////////////////////////////////////////////// + +// Variant ID pointing to object itself. +extern VARIANT id_self; + +// Returns window handle to Chrome Browser, along with (if requested) its +// IAccessible implementation, by calling AccessibleObjectFromWindow on the +// window handle. The IAccessible hierarchy (root->app->client) is also verified +// in terms of accessible name and role. If [acc_obj] is NULL, only the window +// handle is returned. +HWND GetChromeBrowserWnd(IAccessible** acc_obj); + +// Returns IAccessible pointer of object's child window, provided [parent_name] +// and its (0-based) [child_index]. If child is a leaf element (has no children) +// its variant id is returned with S_FALSE. +HRESULT GetChildAccessible(std::wstring parent_name, unsigned int child_index, + IAccessible** acc_obj); + +// Returns IAccessible pointer for Tabstrip (does not have a window handle), by +// calling upon GetChildAccessible. Will never be a leaf element, as it always +// has at least one child. +HRESULT GetTabStripAccessible(IAccessible** acc_obj); + +// Returns IAccessible pointer for BrowserView (does not have a window handle), +// by calling upon GetChildAccessible. Will never be a leaf element, as it +// always has at least one child. +HRESULT GetBrowserViewAccessible(IAccessible** acc_obj); + +// Returns IAccessible pointer for Toolbar (does not have a window handle), by +// calling upon GetChildAccessible. Will never be a leaf element, as it always +// has at least one child. +HRESULT GetToolbarAccessible(IAccessible** acc_obj); + +// Returns window handle to OmniBox(AddressBar) and IAccessible pointer (if +// requested), by calling AccessibleObjectFromWindow on the window handle. If +// [acc_obj] is NULL, only the window handle is returned. +HWND GetAddressBarWnd(IAccessible** acc_obj); + +// Returns window handle to Find edit box and IAccessible pointer (if +// requested), by calling AccessibleObjectFromWindow on the window handle. If +// [acc_obj] is NULL, only the window handle is returned. +HWND GetFindTextWnd(IAccessible** acc_obj); + +// Returns window handle to Authentication dialog and IAccessible pointer (if +// requested), by calling AccessibleObjectFromWindow on the window handle. If +// [acc_obj] is NULL, only the window handle is returned. +HWND GetAuthWnd(IAccessible** acc_obj); + +// Fetches IAccessible pointer for a child, given the IAccessible for the parent +// ([acc_obj]) and a child id (passed in with the [child] VARIANT). Retrieves +// the child by calling get_accChild on [acc_obj]. +HRESULT GetChildAccObject(IAccessible* acc_obj, VARIANT child, + IAccessible** child_acc_obj); + +// Fetches IAccessible pointer for the parent of specified IAccessible object +// (by calling get_accParent on [acc_obj]). +HRESULT GetParentAccObject(IAccessible* acc_obj, IAccessible** parent_acc_obj); + +// Returns number of children for the specified IAccessible. If [acc_obj] +// parameter is NULL, -1 is returned. +INT64 GetChildCount(IAccessible* acc_obj); + +// Extracts (VARIANT)array of child items of specified IAccessible pointer, +// by calling the AccessibleChildren function in MSAA. +HRESULT GetChildrenArray(IAccessible* acc_obj, VARIANT* children); + +// Activates specified window using IAccessible pointer and/or window handle. +// Also calls accSelect on [acc_obj] to set accessibility focus and selection. +HRESULT ActivateWnd(IAccessible* acc_obj, HWND hwnd); + +// Returns title of tab whose index is specified. Tab index starts from 1. +BSTR GetTabName(INT64 tab_index); + +// Returns number of tabs in tabstrip. If processing fails, it returns -1. +INT64 GetTabCnt(); + +// Returns Name of specified [acc_obj] or its [child], by calling get_accName. +// If input is invalid, an empty std::wstring is returned. +std::wstring GetName(IAccessible* acc_obj, VARIANT child = id_self); + +// Returns Role of specified [acc_obj] or its [child], by calling get_accRole. A +// returned value of -1 indicates error. +LONG GetRole(IAccessible* acc_obj, VARIANT child = id_self); + +// Returns State of specified [acc_obj] or its [child], by calling get_accState. +// A returned value of -1 indicates error. +LONG GetState(IAccessible* acc_obj, VARIANT child = id_self); + +// Returns IAccessible pointer for Chrome Minimize Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetBrowserMinimizeButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome Maximize Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetBrowserMaximizeButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome Restore Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetBrowserRestoreButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome Close Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetBrowserCloseButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome Back Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetBackButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome Forward Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetForwardButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome Star Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetStarButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome Go Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetGoButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome Page Menu Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetPageMenuButton(IAccessible** acc_obj); + +// Returns IAccessible pointer for Chrome App Menu Button, by calling +// GetChildAccessible. It does not have window handle. +HRESULT GetAppMenuButton(IAccessible** acc_obj); + +#endif // CHROME_TEST_ACCESSIBILITY_ACCESSIBILITY_UTIL_H_ diff --git a/chrome/test/accessibility/browser_impl.cc b/chrome/test/accessibility/browser_impl.cc new file mode 100644 index 0000000..f1ea023 --- /dev/null +++ b/chrome/test/accessibility/browser_impl.cc @@ -0,0 +1,512 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/test/accessibility/browser_impl.h" + +#include <shellapi.h> + +#include "chrome/test/accessibility/accessibility_util.h" +#include "chrome/test/accessibility/keyboard_util.h" +#include "chrome/test/accessibility/registry_util.h" + +bool BrowserImpl::Launch(void) { + // TODO(klink): Check if chrome already running. + BSTR chrome_path = SysAllocString(GetChromeExePath()); + BOOL success = FALSE; + + // Initialize and fill up structure. + SHELLEXECUTEINFO shell_execute_info; + memset(&shell_execute_info, 0, sizeof(SHELLEXECUTEINFO)); + shell_execute_info.cbSize = sizeof(SHELLEXECUTEINFO); + // To get Process handle. + shell_execute_info.fMask = SEE_MASK_NOCLOSEPROCESS; + shell_execute_info.nShow = SW_SHOW; + shell_execute_info.lpFile = + reinterpret_cast<TCHAR*>(malloc(sizeof(TCHAR) * + SysStringLen(chrome_path))); + _tcscpy_s((TCHAR*)(shell_execute_info.lpFile), SysStringLen(chrome_path), + chrome_path); + + // Execute. + success = ShellExecuteEx(&shell_execute_info); + + if (success && (INT64(shell_execute_info.hInstApp) > 32)) { + // TODO(klink): Maintain instance and process handle. + + // Maintain active tab index. + SetActiveTabIndex(1); + + // Create initial tab collection. + UpdateTabCollection(); + + // Chrome launched. + SysFreeString(chrome_path); + return true; + } + + SysFreeString(chrome_path); + return false; +} + +bool BrowserImpl::Quit(void) { + // Cleanup. + EraseTabCollection(); + + // Send close message to browser window. + HWND hwnd = GetChromeBrowserWnd(NULL); + if (!hwnd) + return false; + SendMessage(hwnd, WM_CLOSE, 0, 0); + return true; +} + +bool BrowserImpl::ActivateTab(const INT64 index) { + // Validate index specified. + if (index < 1) + return false; + + // Goto next tab till focused at desired tab. + while (active_tab_index_ != index) { + GoToNextTab(NULL); + } + return true; +} + +bool BrowserImpl::GetActiveTabURL(BSTR* url) { + // Validate input. + if (!url) + return false; + + return true; +} + +bool BrowserImpl::GetActiveTabTitle(BSTR* title) { + if (!title) + return false; + + *title = SysAllocString(GetTabName(active_tab_index_)); + return true; +} + +bool BrowserImpl::GetActiveTabIndex(INT64* index) { + if (!index) + return false; + + *index = active_tab_index_; + return true; +} + +void BrowserImpl::SetActiveTabIndex(INT64 index) { + if ((index >= MIN_TAB_INDEX_DIGIT) && (index <= GetTabCnt())) + active_tab_index_ = index; + return; +} + +bool BrowserImpl::GetActiveTab(TabImpl** tab) { + return GetTab(active_tab_index_, tab); +} + +bool BrowserImpl::GetTabCount(INT64* count) { + if (!count) + return false; + + *count = GetTabCnt(); + return true; +} + +bool BrowserImpl::GetBrowserProcessCount(INT64* count) { + if (!count) + return false; + + return true; +} + +bool BrowserImpl::GetBrowserTitle(BSTR* title) { + if (!title) + return false; + + HWND hwnd = GetChromeBrowserWnd(NULL); + if (!hwnd) + return false; + + int text_length = GetWindowTextLength(hwnd); + *title = SysAllocStringLen(NULL, text_length); + GetWindowText(hwnd, *title, text_length); + return true; +} + +bool BrowserImpl::AddTab(TabImpl** tab) { + // Add new tab. + HWND hwnd = GetChromeBrowserWnd(NULL); + if (!hwnd) + return false; + ClickKey(hwnd, VK_CONTROL, 'T'); + + // Update active tab index. + INT64 new_tab_index = GetTabCnt(); + if (-1 == new_tab_index) + return false; + SetActiveTabIndex(new_tab_index); + + // Fill object. + TabImpl* new_tab = new TabImpl(); + if (!new_tab) + return false; + ChromeTab* tab_data = new_tab->InitTabData(); + new_tab->set_index(new_tab_index); + new_tab->set_title(GetTabName(new_tab_index)); + new_tab->set_browser(this); + + // Create a copy for storage, in case the caller deletes this newly created + // TabImpl before [tab_collection_] is done using [tab_data]. + ChromeTab* tab_data_copy = tab_data; + + // Update tab collection. + tab_collection_.push_back(linked_ptr<ChromeTab>(tab_data_copy)); + + // Create tab object, if requested. + if (tab) + *tab = new_tab; + + return true; +} + +bool BrowserImpl::GetTab(const INT64 index, TabImpl** tab) { + // Create tab object, if requested. + if (!tab) + return false; + + if (index > GetTabCnt()) + return false; + + *tab = new TabImpl(); + if (!*tab) + return false; + + // Fill object. + ChromeTab* tab_data = (*tab)->InitTabData(); + (*tab)->set_index(index); + (*tab)->set_title(GetTabName(index)); + (*tab)->set_browser(this); + + return true; +} + +bool BrowserImpl::GoToTab(const INT64 index, TabImpl** tab) { + // Validate input. + if (index > MAX_TAB_INDEX_DIGIT) + return false; + + // Stay on current tab, if index doesnot exist. + if ((0 == index) || (GetTabCnt() < index)) + return true; + + // Move to a tab (indexed 1 to 9). + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (acc_obj && hwnd) { + // Activate main window and operate key Ctrl+digit. + ActivateWnd(acc_obj, hwnd); + ClickKey(hwnd, VK_CONTROL, WORD('0'+index)); + CHK_RELEASE(acc_obj); + + // Set focused tab index. + active_tab_index_ = index; + // Return tab object. + if (tab) { + return GetTab(active_tab_index_, tab); + } + } + + return false; +} + +bool BrowserImpl::GoToNextTab(TabImpl** tab) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (acc_obj && hwnd) { + // Activate main window and operate key Ctrl+Tab. + ActivateWnd(acc_obj, hwnd); + ClickKey(hwnd, VK_CONTROL, VK_TAB); + CHK_RELEASE(acc_obj); + + // Set focused tab index. + if (active_tab_index_ == GetTabCnt()) { + active_tab_index_ = 1; + } else { + active_tab_index_ = active_tab_index_ + 1; + } + + // Return tab object. + if (tab) { + return GetTab(active_tab_index_, tab); + } + } + + return false; +} + +bool BrowserImpl::GoToPrevTab(TabImpl** tab) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (acc_obj && hwnd) { + // Activate main window and operate key Ctrl+Tab. + ActivateWnd(acc_obj, hwnd); + ClickKey(hwnd, VK_SHIFT, VK_CONTROL, VK_TAB); + CHK_RELEASE(acc_obj); + + // Set focused tab index. + if (active_tab_index_ == 1) { + active_tab_index_ = GetTabCnt(); + } else { + active_tab_index_ = active_tab_index_ - 1; + } + + // Return tab object. + if (tab) { + return GetTab(active_tab_index_, tab); + } + } + + return false; +} + +bool BrowserImpl::WaitForChromeToBeVisible(const INT64 interval, + const INT64 timeout, bool* visible) { + IAccessible* acc_obj = NULL; + INT64 time_elapsed = 0; + *visible = false; + + // Check and wait. + while (timeout >= time_elapsed) { + GetTabStripAccessible(&acc_obj); + if (acc_obj) { + *visible = true; + CHK_RELEASE(acc_obj); + return true; + } + Sleep(DWORD(interval)); + time_elapsed = time_elapsed + interval; + } + + return false; +} + +bool BrowserImpl::WaitForTabCountToChange(const INT64 interval, + const INT64 timeout, bool* changed) { + return true; +} + +bool BrowserImpl::WaitForTabToBecomeActive(const INT64 index, + const INT64 interval, + const INT64 timeout, + bool* activated) { + return true; +} + +bool BrowserImpl::ApplyAccelerator(VARIANT keys) { + // Input should be -array of enum or strings or -IDispatch (jscript array + // object). + if ((keys.vt != (VT_ARRAY|VT_BSTR)) && // Array of string values. + (keys.vt != (VT_ARRAY|VT_I4)) && // Array of enum values. + (!(keys.vt & VT_DISPATCH)) ) { // Object. + return false; + } + + // Array to store keys in a single combination. Currently, valid keyboard + // -input combination can constitute of at the most 3 keys. + KEYBD_KEYS key_value[3]; + // Initialize key count. + int key_cnt = 0; + // Get variant array from object. + IDispatch* disp = NULL; + + // Not array of string values or integers. + if ((keys.vt != (VT_ARRAY|VT_BSTR)) && + (keys.vt != (VT_ARRAY|VT_I4)) ) { + // Retrive IDispatch. + if (keys.vt & VT_BYREF) + disp = *(keys.ppdispVal); + else + disp = keys.pdispVal; + + // Get array length. + DISPPARAMS params; + FillMemory(¶ms, sizeof(DISPPARAMS), 0); + VARIANT res; + DISPID id; + LPOLESTR ln = L"length"; + if (S_OK != disp->GetIDsOfNames(IID_NULL, &ln, 1, LOCALE_USER_DEFAULT, + &id)) { + return false; + } + + if (S_OK != disp->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, + DISPATCH_PROPERTYGET, ¶ms, &res, NULL, + NULL)) { + return false; + } + + VARIANT len; + VariantInit(&len); + VariantChangeType(&len, &res, 0, VT_I4); + if (len.lVal > 3) + return false; + key_cnt = len.lVal; + + // Add elements to safe array. + for (int i = 0; i < len.lVal; i++) { + // Fetch element. + wchar_t wstr[5]; + memset(wstr, 0, 5*sizeof(wchar_t)); + wsprintf(wstr, L"%d", i); + LPOLESTR olestr = wstr; + + if (S_OK != disp->GetIDsOfNames(IID_NULL, &olestr, 1, + LOCALE_USER_DEFAULT, &id)) { + return false; + } + + if (S_OK != disp->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, + DISPATCH_PROPERTYGET, ¶ms, &res, NULL, + NULL)) { + return false; + } + + VARIANT value; + VariantInit(&value); + VariantChangeType(&value, &res, 0, VT_BSTR); + + // Translate and add key to array. + key_value[i] = GetKeybdKeysVal(value.bstrVal); + + VariantClear(&value); + } + + VariantClear(&len); + } else { + // Directly fetch array. + SAFEARRAY* key_safe = NULL; + key_safe = V_ARRAY(&keys); + + // Operate on Variant Array. + HRESULT hr = S_OK; + LONG num_elements, lower_bound, upper_bound; + + // Array is not 1-dimentional. + if (SafeArrayGetDim(key_safe) != 1) + return false; + + // Get array bounds. + hr = SafeArrayGetLBound(key_safe, 1, &lower_bound); + if (S_OK !=hr) + return false; + hr = SafeArrayGetUBound(key_safe, 1, &upper_bound); + if (S_OK !=hr) + return false; + + // Key combination can be of maximum 3 keys. + num_elements = upper_bound - lower_bound + 1; + if (num_elements > 3) + return false; + key_cnt = num_elements; + + // Read the data in array. + if (keys.vt == (VT_ARRAY|VT_I4)) { + KEYBD_KEYS* read_keys; + hr = SafeArrayAccessData(key_safe, reinterpret_cast<void **>(&read_keys)); + if (S_OK != hr) + return false; + for (int i = 0; i < num_elements; i++) { + key_value[i] = read_keys[i]; + } + } else if (keys.vt == (VT_ARRAY|VT_BSTR)) { + BSTR* key_str_value; + hr = SafeArrayAccessData(key_safe, + reinterpret_cast<void **>(&key_str_value)); + if (S_OK != hr) + return false; + + // Translate and add key to array. + for (int i = 0; i < num_elements; i++) { + key_value[i] = GetKeybdKeysVal(key_str_value[i]); + } + } + } + + // Focus on main window and operate keys. + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (acc_obj || hwnd) + ActivateWnd(acc_obj, hwnd); + + if (1 == key_cnt) + ClickKey(hwnd, key_value[0]); + else if (2 == key_cnt) + ClickKey(hwnd, key_value[0], key_value[1]); + else if (3 == key_cnt) + ClickKey(hwnd, key_value[0], key_value[1], key_value[2]); + + CHK_RELEASE(acc_obj); + + return true; +} + +void BrowserImpl::UpdateTabCollection(void) { + // Get tab count and browser title. + INT64 tab_cnt = GetTabCnt(); + BSTR browser_title; + GetBrowserTitle(&browser_title); + + // Check tab-collection size and number of existing tabs, work accordingly. + + // First time creation. + if (0 == tab_collection_.size()) { + EraseTabCollection(); + for (int i = 0; i < tab_cnt; i++) { + tab_collection_[i]->index_ = i + 1; + tab_collection_[i]->title_ = + SysAllocString(GetTabName(tab_collection_[i]->index_)); + if (browser_title == tab_collection_[i]->title_) { + active_tab_index_ = tab_collection_[i]->index_; + } + } + } + SysFreeString(browser_title); + + // TODO(klink): Add implementation here to handle if tabs are reordered, + // rather than created. +} + +void BrowserImpl::EraseTabCollection(void) { + tab_collection_.clear(); +} + +void BrowserImpl::CloseTabFromCollection(INT64 index) { + std::vector <ChromeTab*>::size_type collection_size = tab_collection_.size(); + // Validate tab index. + if ((index < MIN_TAB_INDEX_DIGIT) || + (static_cast<unsigned int>(index) > collection_size)) { + return; + } + + // Index starts from 1. + tab_collection_.erase(tab_collection_.begin() + static_cast<int>(index) - 1); + + // Now update tab collection data. + collection_size = tab_collection_.size(); + + // Check if tab deleted is last tab. + if (index-1 == collection_size) { + // Change active tab index, only if tab deleted is last tab. + active_tab_index_ = index - 1; + } else { + for (std::vector <ChromeTab*>::size_type i = + static_cast<unsigned int>(index) - 1; + i < collection_size; + i++) { + tab_collection_[i]->index_--; + } + } +} diff --git a/chrome/test/accessibility/browser_impl.h b/chrome/test/accessibility/browser_impl.h new file mode 100644 index 0000000..ce05054 --- /dev/null +++ b/chrome/test/accessibility/browser_impl.h @@ -0,0 +1,115 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_ACCESSIBILITY_BROWSER_IMPL_H_ +#define CHROME_TEST_ACCESSIBILITY_BROWSER_IMPL_H_ + +#include <oleacc.h> +#include <vector> + +#include "base/linked_ptr.h" +#include "chrome/test/accessibility/tab_impl.h" + +///////////////////////////////////////////////////////////////////// +// BrowserImpl +// It is a wrapper to Browser specific functionalities. +// Note: +// In most of the tasks, keyboard messages are used for now. +// DoDefaultAction() will be called on accessibility objects, +// once implementation is available in chrome accessibility server. +// And keyboard messages will be tested using ApplyAccelerator(). +///////////////////////////////////////////////////////////////////// + +class BrowserImpl { + public: + BrowserImpl() { + active_tab_index_ = 0; + } + + // Starts Chrome. Sets active tab index. + bool Launch(void); + + // Closes Chrome. + bool Quit(void); + + // Activates the specified tab. + bool ActivateTab(const INT64 index); + + // Returns URL of the active tab. + bool GetActiveTabURL(BSTR* url); + + // Gets active tab's title. Note that it is the caller's responsibility to + // call SysFreeString on [title]. + bool GetActiveTabTitle(BSTR* title); + + // Gets active tab index. + bool GetActiveTabIndex(INT64* index); + + // Returns active tab object. + bool GetActiveTab(TabImpl** tab); + + // Returns no. of tabs in tabstrip. + bool GetTabCount(INT64* count); + + bool GetBrowserProcessCount(INT64* count); + + // Reads browser title, which is also a active tab's title. Note that it is + // the caller's responsibility to call SysFreeString on [title]. + bool GetBrowserTitle(BSTR* title); + + // Adds new tab. Maintain current active tab index. Returns created tab, if + // requested. Note that it is the caller's responsibility to delete [tab]. + bool AddTab(TabImpl** tab); + + // Returns tab object of specified index. Note that it is the caller's + // responsibility to delete [tab]. + bool GetTab(const INT64 index, TabImpl** tab); + + // Activate tab of specified index. Maintain current active tab index. Returns + // created tab, if requested. Note that it is the caller's responsibility to + // delete [tab]. + bool GoToTab(const INT64 index, TabImpl** tab); + + // Move to next tab. Maintain current active tab index. Returns created tab, + // if requested. Note that it is the caller's responsibility to delete [tab]. + bool GoToNextTab(TabImpl** tab); + + // Move to previous tab. Maintain current active tab index. Returns created + // tab, if requested. Note that it is the caller's responsibility to delete + // [tab]. + bool GoToPrevTab(TabImpl** tab); + + // Wait for chrome window to be visible. It checks for accessibility object + // for tabstrip after every 'interval' for the specified 'timeout'. + bool WaitForChromeToBeVisible(const INT64 interval, const INT64 timeout, + bool* visible); + bool WaitForTabCountToChange(const INT64 interval, const INT64 timeout, + bool* changed); + bool WaitForTabToBecomeActive(const INT64 index, const INT64 interval, + const INT64 timeout, bool* activated); + + // Sends keyboard message. Sends accelerators. + bool ApplyAccelerator(VARIANT keys); + + // Sets active tab index. + void SetActiveTabIndex(INT64 index); + + // Removed tab from tab collection vector. + void CloseTabFromCollection(INT64 index); + + // Updates tab collection vector. + void UpdateTabCollection(void); + + // Removes tab from tab collection vector. + void EraseTabCollection(void); + + private: + // Index of active tab. + INT64 active_tab_index_; + + // Collection of tab data. + std::vector<linked_ptr<ChromeTab> > tab_collection_; +}; + +#endif // CHROME_TEST_ACCESSIBILITY_BROWSER_IMPL_H_ diff --git a/chrome/test/accessibility/constants.h b/chrome/test/accessibility/constants.h new file mode 100644 index 0000000..ecaa736 --- /dev/null +++ b/chrome/test/accessibility/constants.h @@ -0,0 +1,98 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_ACCESSIBILITY_CONSTANTS_H_ +#define CHROME_TEST_ACCESSIBILITY_CONSTANTS_H_ + +#include <windows.h> +#include <tchar.h> + +/////////////////////////////////////////////////////////////////// +// Constants definitions specific to Chrome Accessibility Tests. +/////////////////////////////////////////////////////////////////// + +// Safe delete and release operations. +#define CHK_RELEASE(obj) { if (obj) { (obj)->Release(); (obj) = NULL; } } +#define CHK_DELETE(obj) { if (obj) { delete (obj); (obj) = NULL; } } + +// Chrome Accessibility Tests specific strings. +#define CHROME_PATH _T("C:\\Program Files\\Google\\Chrome\\Chrome.exe") +#define CHROME_VIEWS_TEXT_FIELD_EDIT _T("ChromeViewsTextFieldEdit") +#define CHROME_AUTOCOMPLETE_EDIT _T("Chrome_AutocompleteEdit") +#define CHROME_VIEWS_NATIVE_CTRL_CONTNR _T("ChromeViewsNativeControlContainer") +#define CHROME_HWND_VIEW_CONTAINER _T("Chrome_WidgetWin_0") +#define STD_BUTTON _T("Button") +#define AUTH_TITLE _T("Authentication Required - Chrome") +#define CHROME_TAB_CONTENTS _T("Chrome_TabContents") + +// Index for accessing specific children in the MSAA hierarchy. +// TODO(klink): Remove the need for these. +#define CHROME_APP_ACC_INDEX (3) +#define CHROME_CLIENT_ACC_INDEX (0) +#define BROWSER_VIEW_ACC_INDEX (4) + +// Chrome Client chidren. These UI elements cannot take MSAA focus, and +// therefore have no ViewID associated. +#define TABSTRIP_ACC_INDEX (0) +#define CHROME_MIN_ACC_INDEX (0) +#define CHROME_MAX_ACC_INDEX (1) +#define CHROME_RESTORE_ACC_INDEX (2) +#define CHROME_CLOSE_ACC_INDEX (3) + +// Tab index limits for bounds checking in Accessibility Tests. +#define MAX_TAB_INDEX_DIGIT (9) +#define MIN_TAB_INDEX_DIGIT (1) + +// Object Names. +#define BROWSER_STR _T("browser") +#define TOOLBAR_STR _T("toolbar") +#define TABSTRIP_STR _T("tabstrip") +#define TAB_STR _T("tab") +#define BROWSER_VIEW_STR _T("browser_view") + +// Enums for keyboard keys. These values are directed to virtual-key values. +enum KEYBD_KEYS { + KEY_F3 = VK_F3, + KEY_F4 = VK_F4, + KEY_F5 = VK_F5, + KEY_F6 = VK_F6, + KEY_ALT = VK_MENU, + KEY_CONTROL = VK_CONTROL, + KEY_SHIFT = VK_SHIFT, + KEY_ENTER = VK_RETURN, + KEY_TAB = VK_TAB, + KEY_BACK = VK_BACK, + KEY_HOME = VK_HOME, + KEY_END = VK_END, + KEY_ESC = VK_ESCAPE, + KEY_INSERT = VK_INSERT, + KEY_DELETE = VK_DELETE, + KEY_LEFT = VK_LEFT, + KEY_RIGHT = VK_RIGHT, + KEY_PLUS = VK_ADD, + KEY_MINUS = VK_SUBTRACT, + KEY_0 = '0', + KEY_1 = '1', + KEY_2 = '2', + KEY_3 = '3', + KEY_4 = '4', + KEY_5 = '5', + KEY_6 = '6', + KEY_7 = '7', + KEY_8 = '8', + KEY_9 = '9', + KEY_D = 'D', + KEY_F = 'F', + KEY_G = 'G', + KEY_K = 'K', + KEY_L = 'L', + KEY_N = 'N', + KEY_O = 'O', + KEY_R = 'R', + KEY_T = 'T', + KEY_W = 'W', + KEY_INVALID = -1 +}; + +#endif // CHROME_TEST_ACCESSIBILITY_CONSTANTS_H_ diff --git a/chrome/test/accessibility/keyboard_util.cc b/chrome/test/accessibility/keyboard_util.cc new file mode 100644 index 0000000..c0a90f3 --- /dev/null +++ b/chrome/test/accessibility/keyboard_util.cc @@ -0,0 +1,194 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "keyboard_util.h" + +void ClickKey(HWND hwnd, WORD key) { + INPUT input[2]; + memset(&input, 0, sizeof(INPUT)*2); + + // Press key. + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = key; + input[0].ki.dwFlags = 0; + + // Release key. + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = key; + input[1].ki.dwFlags = KEYEVENTF_KEYUP; + + SendInput(2, input, sizeof(INPUT)); +} + +void ClickKey(HWND hwnd, WORD extended_key, WORD key) { + INPUT input[4]; + memset(&input, 0, sizeof(INPUT)*4); + + // Press extended key. + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = extended_key; + input[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY; + + // Press key. + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = key; + input[1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY; + + // Release key. + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = key; + input[2].ki.dwFlags = KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP; + + // Release key. + input[3].type = INPUT_KEYBOARD; + input[3].ki.wVk = extended_key; + input[3].ki.dwFlags = KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP; + + SendInput(4, input, sizeof(INPUT)); +} + +void ClickKey(HWND hwnd, WORD extended_key1, WORD extended_key2, WORD key) { + INPUT input[6]; + memset(&input, 0, sizeof(INPUT)*6); + + // Press extended key1. + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = extended_key1; + input[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY; + + // Press extended key2. + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = extended_key2; + input[1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY; + + // Press key. + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = key; + input[2].ki.dwFlags = KEYEVENTF_EXTENDEDKEY; + + // Release key. + input[3].type = INPUT_KEYBOARD; + input[3].ki.wVk = key; + input[3].ki.dwFlags = KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP; + + // Release extended key2. + input[4].type = INPUT_KEYBOARD; + input[4].ki.wVk = extended_key2; + input[4].ki.dwFlags = KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP; + + // Release extended key1. + input[5].type = INPUT_KEYBOARD; + input[5].ki.wVk = extended_key1; + input[5].ki.dwFlags = KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP; + + SendInput(6, input, sizeof(INPUT)); +} + +void PressKey(HWND hwnd, WORD key) { + SendMessage(hwnd, WM_KEYDOWN, key, 0); + SendMessage(hwnd, WM_CHAR, key, 0); +} + +void ReleaseKey(HWND hwnd, WORD key) { + SendMessage(hwnd, WM_KEYUP, key, 0); +} + +KEYBD_KEYS GetKeybdKeysVal(BSTR str) { + if (0 == wcslen(str)) + return KEY_INVALID; + + if (0 == _wcsicmp(str, L"F3")) + return KEY_F3; + if (0 == _wcsicmp(str, L"F4")) + return KEY_F4; + if (0 == _wcsicmp(str, L"F5")) + return KEY_F5; + if (0 == _wcsicmp(str, L"F6")) + return KEY_F6; + if (0 == _wcsicmp(str, L"ALT")) + return KEY_ALT; + if (0 == _wcsicmp(str, L"ALTER")) + return KEY_ALT; + if (0 == _wcsicmp(str, L"CTRL")) + return KEY_CONTROL; + if (0 == _wcsicmp(str, L"CONTROL")) + return KEY_CONTROL; + if (0 == _wcsicmp(str, L"SHIFT")) + return KEY_SHIFT; + if (0 == _wcsicmp(str, L"ENTER")) + return KEY_ENTER; + if (0 == _wcsicmp(str, L"RETURN")) + return KEY_ENTER; + if (0 == _wcsicmp(str, L"TAB")) + return KEY_TAB; + if (0 == _wcsicmp(str, L"BACK")) + return KEY_BACK; + if (0 == _wcsicmp(str, L"HOME")) + return KEY_HOME; + if (0 == _wcsicmp(str, L"END")) + return KEY_END; + if (0 == _wcsicmp(str, L"ESC")) + return KEY_ESC; + if (0 == _wcsicmp(str, L"ESCAPE")) + return KEY_ESC; + if (0 == _wcsicmp(str, L"INSERT")) + return KEY_INSERT; + if (0 == _wcsicmp(str, L"INS")) + return KEY_INSERT; + if (0 == _wcsicmp(str, L"DEL")) + return KEY_DELETE; + if (0 == _wcsicmp(str, L"DELETE")) + return KEY_DELETE; + if (0 == _wcsicmp(str, L"LEFT")) + return KEY_LEFT; + if (0 == _wcsicmp(str, L"RIGHT")) + return KEY_RIGHT; + if (0 == _wcsicmp(str, L"0")) + return KEY_0; + if (0 == _wcsicmp(str, L"1")) + return KEY_1; + if (0 == _wcsicmp(str, L"2")) + return KEY_2; + if (0 == _wcsicmp(str, L"3")) + return KEY_3; + if (0 == _wcsicmp(str, L"4")) + return KEY_4; + if (0 == _wcsicmp(str, L"5")) + return KEY_5; + if (0 == _wcsicmp(str, L"6")) + return KEY_6; + if (0 == _wcsicmp(str, L"7")) + return KEY_7; + if (0 == _wcsicmp(str, L"8")) + return KEY_8; + if (0 == _wcsicmp(str, L"9")) + return KEY_9; + if (0 == _wcsicmp(str, L"D")) + return KEY_D; + if (0 == _wcsicmp(str, L"F")) + return KEY_F; + if (0 == _wcsicmp(str, L"G")) + return KEY_G; + if (0 == _wcsicmp(str, L"K")) + return KEY_K; + if (0 == _wcsicmp(str, L"L")) + return KEY_L; + if (0 == _wcsicmp(str, L"N")) + return KEY_N; + if (0 == _wcsicmp(str, L"O")) + return KEY_O; + if (0 == _wcsicmp(str, L"R")) + return KEY_R; + if (0 == _wcsicmp(str, L"T")) + return KEY_T; + if (0 == _wcsicmp(str, L"W")) + return KEY_W; + if (0 == _wcsicmp(str, L"+")) + return KEY_PLUS; + if (0 == _wcsicmp(str, L"-")) + return KEY_MINUS; + + // No key found. + return KEY_INVALID; +} diff --git a/chrome/test/accessibility/keyboard_util.h b/chrome/test/accessibility/keyboard_util.h new file mode 100644 index 0000000..de10c4580 --- /dev/null +++ b/chrome/test/accessibility/keyboard_util.h @@ -0,0 +1,36 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_ACCESSIBILITY_KEYBOARD_UTIL_H_ +#define CHROME_TEST_ACCESSIBILITY_KEYBOARD_UTIL_H_ + +#include <wtypes.h> + +#include "chrome/test/accessibility/constants.h" + +////////////////////////////////////////////////////// +// Function declarations to automate keyboard events. +////////////////////////////////////////////////////// + +// Enqueue keyboard message for a key. Currently, hwnd is not used. +void ClickKey(HWND hwnd, WORD key); + +// Enqueue keyboard message for a combination of 2 keys. Currently, hwnd is +// not used. +void ClickKey(HWND hwnd, WORD key, WORD extended_key); + +// Enqueue keyboard message for a combination of 2 keys. +// Currently, hwnd is not used. +void ClickKey(HWND hwnd, WORD key, WORD extended_key1, WORD extended_key2); + +// Sends key-down message to window. +void PressKey(HWND hwnd, WORD key); + +// Sends key-up message to window. +void ReleaseKey(HWND hwnd, WORD key); + +// Returns native enum values for a key-string specified. +KEYBD_KEYS GetKeybdKeysVal(BSTR str); + +#endif // CHROME_TEST_ACCESSIBILITY_KEYBOARD_UTIL_H_ diff --git a/chrome/test/accessibility/registry_util.cc b/chrome/test/accessibility/registry_util.cc new file mode 100644 index 0000000..249a207 --- /dev/null +++ b/chrome/test/accessibility/registry_util.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/test/accessibility/registry_util.h" + +#include <ocidl.h> + +#include "chrome/test/accessibility/constants.h" + +BSTR GetChromeExePath() { + BSTR chrome_exe_path = SysAllocString(CHROME_PATH); + return chrome_exe_path; +} diff --git a/chrome/test/accessibility/registry_util.h b/chrome/test/accessibility/registry_util.h new file mode 100644 index 0000000..b9ba65c --- /dev/null +++ b/chrome/test/accessibility/registry_util.h @@ -0,0 +1,17 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_ACCESSIBILITY_REGISTRY_UTIL_H_ +#define CHROME_TEST_ACCESSIBILITY_REGISTRY_UTIL_H_ + +////////////////////////////////////////////////// +// Functions for registry operations. +////////////////////////////////////////////////// + +#include <wtypes.h> + +// Reads chrome installation path from registry. +BSTR GetChromeExePath(); + +#endif // CHROME_TEST_ACCESSIBILITY_REGISTRY_UTIL_H_ diff --git a/chrome/test/accessibility/tab_impl.cc b/chrome/test/accessibility/tab_impl.cc new file mode 100644 index 0000000..ada90fe --- /dev/null +++ b/chrome/test/accessibility/tab_impl.cc @@ -0,0 +1,365 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/test/accessibility/tab_impl.h" + +#include <oleacc.h> + +#include "chrome/test/accessibility/accessibility_util.h" +#include "chrome/test/accessibility/browser_impl.h" +#include "chrome/test/accessibility/keyboard_util.h" + + +TabImpl::~TabImpl() { + if (tab_) { + SysFreeString(tab_->title_); + delete tab_; + } +} + +bool TabImpl::Close(void) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (!acc_obj || !hwnd) + return false; + + // Activate main window and operate key Ctrl+F4. + ActivateWnd(acc_obj, hwnd); + ClickKey(hwnd, VK_CONTROL, VK_F4); + CHK_RELEASE(acc_obj); + + // Update tab information in browser object. + browser_->CloseTabFromCollection(tab_->index_); + return true; +} + +bool TabImpl::GetTitle(BSTR* title) { + // Validation. + if (!title) + return false; + + // Read Tab name and store it in local member and return same value. + BSTR tab_title = GetTabName(tab_->index_); + *title = SysAllocString(tab_title); + tab_->title_ = SysAllocString(tab_title); + return true; +} + +bool TabImpl::SetAddressBarText(const BSTR text) { + IAccessible* acc_obj = NULL; + HWND hwnd_addr_bar = GetAddressBarWnd(&acc_obj); + if (!acc_obj || !hwnd_addr_bar) + return false; + + // Activate address bar. + ActivateWnd(acc_obj, hwnd_addr_bar); + // Set text to address bar. + SendMessage(hwnd_addr_bar, WM_SETTEXT, 0, LPARAM(text)); + CHK_RELEASE(acc_obj); + return true; +} + +bool TabImpl::NavigateToURL(const BSTR url) { + IAccessible* acc_obj = NULL; + HWND hwnd_addr_bar = GetAddressBarWnd(&acc_obj); + + if (!acc_obj || !hwnd_addr_bar) + return false; + + // Activate address bar. + ActivateWnd(acc_obj, hwnd_addr_bar); + // Set text to address bar. + SendMessage(hwnd_addr_bar, WM_SETTEXT, 0, LPARAM(url)); + // Click Enter. Window is activated above for this. + ClickKey(hwnd_addr_bar, VK_RETURN); + CHK_RELEASE(acc_obj); + return true; +} + +bool TabImpl::FindInPage(const BSTR find_text) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (!acc_obj || !hwnd) + return false; + + // Activate main window and operate key 'F3' to invoke Find window. + ActivateWnd(acc_obj, hwnd); + ClickKey(hwnd, VK_F3); + CHK_RELEASE(acc_obj); + + // If no text is to be searched, return. + if (find_text != NULL) { + // TODO(klink): Once FindWindow is exported through Accessibility. + // Instead of sleep, check if FindWindows exists or not. + Sleep(50); + + // Get Find window. + acc_obj = NULL; + hwnd = GetFindTextWnd(&acc_obj); + if (hwnd) { + HWND hwnd_find_edit = FindWindowEx(hwnd, 0, CHROME_VIEWS_TEXT_FIELD_EDIT, + 0); + if (hwnd_find_edit) { + ActivateWnd(acc_obj, hwnd); + ActivateWnd(NULL, hwnd_find_edit); + // Set text in Find window edit box. + WCHAR* strTemp = + reinterpret_cast<WCHAR*>(calloc(wcslen(find_text), sizeof(WCHAR))); + wcscpy_s(strTemp, wcslen(find_text), find_text); + for (size_t i = 0; i < wcslen(strTemp); i++) { + SendMessage(hwnd_find_edit, WM_KEYDOWN, strTemp[i], 0); + SendMessage(hwnd_find_edit, WM_CHAR, strTemp[i], 0); + SendMessage(hwnd_find_edit, WM_KEYUP, strTemp[i], 0); + } + } + } + } + CHK_RELEASE(acc_obj); + + return true; +} + +bool TabImpl::Reload(void) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (!acc_obj || !hwnd) + return false; + + // Operate key F5. + ActivateWnd(acc_obj, hwnd); + ClickKey(hwnd, VK_F5); + CHK_RELEASE(acc_obj); + return true; +} + +bool TabImpl::Duplicate(TabImpl** tab) { + return true; +} + +bool TabImpl::IsAuthDialogVisible() { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (!acc_obj || !hwnd) + return false; + + // Activate main window. + ActivateWnd(acc_obj, hwnd); + CHK_RELEASE(acc_obj); + + // Check for Authentication Window. + acc_obj = NULL; + hwnd = GetAuthWnd(&acc_obj); + if (!hwnd || !acc_obj) { + CHK_RELEASE(acc_obj); + return false; + } + CHK_RELEASE(acc_obj); + return true; +} + +bool TabImpl::SetAuthDialog(const BSTR user_name, const BSTR password) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (!acc_obj || !hwnd) + return false; + + // Activate main window. + ActivateWnd(acc_obj, hwnd); + CHK_RELEASE(acc_obj); + + // Get editbox for user name and password. + acc_obj = NULL; + hwnd = GetAuthWnd(&acc_obj); + if (!hwnd) { + CHK_RELEASE(acc_obj); + return false; + } + + // Get handle to password edit box. + HWND hwnd_auth_pwd = FindWindowEx(hwnd, 0, CHROME_VIEWS_TEXT_FIELD_EDIT, 0); + if (!hwnd_auth_pwd) { + CHK_RELEASE(acc_obj); + return false; + } + + // Child after password edit box is edit box for name. + HWND hwnd_auth_name = FindWindowEx(hwnd, hwnd_auth_pwd, + CHROME_VIEWS_TEXT_FIELD_EDIT, 0); + if (!hwnd_auth_name) { + CHK_RELEASE(acc_obj); + return false; + } + + // Activate Tab. + SetActiveWindow(GetParent(hwnd)); + // Activate Authentication window. + ActivateWnd(acc_obj, hwnd); + + // Activate edit box for name. + ActivateWnd(NULL, hwnd_auth_name); + + // Set user name. + if (user_name != NULL) { + WCHAR* strTemp = + reinterpret_cast<WCHAR*>(calloc(wcslen(user_name), sizeof(WCHAR))); + wcscpy_s(strTemp, wcslen(user_name), user_name); + for (size_t i = 0; i < wcslen(strTemp); i++) { + SendMessage(hwnd_auth_name, WM_KEYDOWN, strTemp[i], 0); + SendMessage(hwnd_auth_name, WM_CHAR, strTemp[i], 0); + SendMessage(hwnd_auth_name, WM_KEYUP, strTemp[i], 0); + } + } + + // Activate edit box for password. + ActivateWnd(NULL, hwnd_auth_pwd); + + // Set password. + if (password != NULL) { + // set text + WCHAR* strTemp = reinterpret_cast<WCHAR*>(calloc(wcslen(password), + sizeof(WCHAR))); + wcscpy_s(strTemp, wcslen(password), password); + for (size_t i = 0; i < wcslen(strTemp); i++) { + SendMessage(hwnd_auth_pwd, WM_KEYDOWN, strTemp[i], 0); + SendMessage(hwnd_auth_pwd, WM_CHAR, strTemp[i], 0); + SendMessage(hwnd_auth_pwd, WM_KEYUP, strTemp[i], 0); + } + } + + CHK_RELEASE(acc_obj); + return true; +} + +bool TabImpl::CancelAuthDialog(void) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (!acc_obj || !hwnd) + return false; + + // Activate main window. + ActivateWnd(acc_obj, hwnd); + CHK_RELEASE(acc_obj); + + // Get editbox for user name which is after password. + acc_obj = NULL; + hwnd = GetAuthWnd(&acc_obj); + if (!hwnd) { + CHK_RELEASE(acc_obj); + return false; + } + + // Get Cancel button. + HWND cancel_button_container = FindWindowEx(hwnd, 0, + CHROME_VIEWS_NATIVE_CTRL_CONTNR, + 0); + if (!cancel_button_container) { + CHK_RELEASE(acc_obj); + return false; + } + HWND cancel_button = FindWindowEx(cancel_button_container, 0, STD_BUTTON, 0); + if (!cancel_button) { + CHK_RELEASE(acc_obj); + return false; + } + + // Click Cancel button. + SetActiveWindow(cancel_button_container); + SetActiveWindow(cancel_button); + SendMessage(cancel_button, BM_CLICK, 0, 0); + + CHK_RELEASE(acc_obj); + return true; +} + +bool TabImpl::UseAuthDialog(void) { + IAccessible* acc_obj = NULL; + HWND hwnd = GetChromeBrowserWnd(&acc_obj); + if (!acc_obj || !hwnd) + return false; + + // Activate main window. + ActivateWnd(acc_obj, hwnd); + CHK_RELEASE(acc_obj); + + // Get editbox for user name which is after password. + acc_obj = NULL; + hwnd = GetAuthWnd(&acc_obj); + if (!hwnd) { + CHK_RELEASE(acc_obj); + return false; + } + + // Get Ok button. + HWND cancel_button_container = FindWindowEx(hwnd, 0, + CHROME_VIEWS_NATIVE_CTRL_CONTNR, + 0); + if (!cancel_button_container) { + CHK_RELEASE(acc_obj); + return false; + } + + // Ok button is located after cancel button in window hierarchy. + HWND ok_button_container = FindWindowEx(hwnd, cancel_button_container, + CHROME_VIEWS_NATIVE_CTRL_CONTNR, 0); + if (!ok_button_container) { + CHK_RELEASE(acc_obj); + return false; + } + HWND ok_button = FindWindowEx(ok_button_container, 0, STD_BUTTON, 0); + if (!ok_button) { + CHK_RELEASE(acc_obj); + return false; + } + + // Click Ok. + SetActiveWindow(ok_button_container); + SetActiveWindow(ok_button); + SendMessage(ok_button, BM_CLICK, 0, 0); + + CHK_RELEASE(acc_obj); + return true; +} + +void TabImpl::set_title(BSTR title) { + if (!tab_) + InitTabData(); + tab_->title_ = SysAllocString(title); +} + +bool TabImpl::Activate(void) { + return true; +} + +bool TabImpl::WaitForTabToBecomeActive(const INT64 interval, + const INT64 timeout) { + return true; +} + +bool TabImpl::WaitForTabToGetLoaded(const INT64 interval, const INT64 timeout) { + return true; +} + +bool TabImpl::IsSSLLockPresent(bool* present) { + return true; +} + +bool TabImpl::IsSSLSoftError(bool* soft_err) { + return true; +} + +bool TabImpl::OpenPageCertificateDialog(void) { + return true; +} + +bool TabImpl::ClosePageCertificateDialog(void) { + return true; +} + +bool TabImpl::GoBack(void) { + return true; +} + +bool TabImpl::GoForward(void) { + return true; +} diff --git a/chrome/test/accessibility/tab_impl.h b/chrome/test/accessibility/tab_impl.h new file mode 100644 index 0000000..0a20d92 --- /dev/null +++ b/chrome/test/accessibility/tab_impl.h @@ -0,0 +1,135 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_TEST_ACCESSIBILITY_TAB_IMPL_H_ +#define CHROME_TEST_ACCESSIBILITY_TAB_IMPL_H_ + +#include <wtypes.h> + +#include "constants.h" + +///////////////////////////////////////////////////////////////////// +// TabImpl +// It is a wrapper to Tab specific functionalities. +// Note: +// In most of the tasks, keyboard messages are used for now. +// DoDefaultAction() will be called on accessibility objects, +// once implementation is available in chrome accessibility server. +// And keyboard messages will be tested using ApplyAccelerator(). +///////////////////////////////////////////////////////////////////// + +// Forward declaration. +class BrowserImpl; + +// Structure storing Tab parameters. +struct ChromeTab { + INT64 index_; + BSTR title_; +}; + +class TabImpl { + public: + TabImpl(): tab_(NULL), browser_(NULL) {} + + ~TabImpl(); + + public: + // Close this tab. + bool Close(void); + + // Returns title of this tab. + bool GetTitle(BSTR* title); + + // Sets the URL in address bar. + bool SetAddressBarText(const BSTR text); + + // Sets the URL and navigates tab to the page. + bool NavigateToURL(const BSTR url); + + // Find string by invoking Find Window. + bool FindInPage(const BSTR find_text); + + // Reloads/Refreshes the tab-page. + bool Reload(void); + + // Duplicates this tab. + bool Duplicate(TabImpl** tab); + + // Returns true of Authentication dialog is opena nd visible. + bool IsAuthDialogVisible(); + + // Invokes authentication dialog with specified user name and password. + bool SetAuthDialog(const BSTR user_name, const BSTR password); + + // Cancels invoked authentication dialog. + bool CancelAuthDialog(void); + + // Authenticates with the credentials set in authentication dialog and + // closes it. + bool UseAuthDialog(void); + + // Activates this tab. + bool Activate(void); + + // Waits for specified time with the specified interval to get the tab + // activated. + bool WaitForTabToBecomeActive(const INT64 interval, const INT64 timeout); + + // Waits for specified time with the specified interval to get the tab-page + // loaded with URL. + bool WaitForTabToGetLoaded(const INT64 interval, const INT64 timeout); + + // Sets title of this tab. + void set_title(BSTR title); + + // Sets index of this tab. + void set_index(INT64 index) { + if (index < 0) + return; + if (!tab_) + InitTabData(); + tab_->index_ = index; + } + + // Sets browser to which tab belongs. + bool set_browser(BrowserImpl* browser) { + if (browser) + browser_ = browser; + else + return false; + + return true; + } + + // Initialize data specific to tab. + ChromeTab* InitTabData() { + if (tab_) + CHK_DELETE(tab_); + + tab_ = new ChromeTab(); + if (!tab_) + return NULL; + + memset(tab_, 0, sizeof(ChromeTab)); + return tab_; + } + + // To be implemeted. + bool IsSSLLockPresent(bool* present); + bool IsSSLSoftError(bool* soft_err); + bool OpenPageCertificateDialog(void); + bool ClosePageCertificateDialog(void); + bool GoBack(void); + bool GoForward(void); + + private: + // Structure to store tab data. + ChromeTab* tab_; + + // Pointer to browser to which this tab belongs. + BrowserImpl* browser_; +}; + + +#endif // CHROME_TEST_ACCISSIBILITY_TAB_IMPL_H_ |