diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 23:55:29 +0000 |
commit | 09911bf300f1a419907a9412154760efd0b7abc3 (patch) | |
tree | f131325fb4e2ad12c6d3504ab75b16dd92facfed /chrome/test/accessibility | |
parent | 586acc5fe142f498261f52c66862fa417c3d52d2 (diff) | |
download | chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.zip chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.gz chromium_src-09911bf300f1a419907a9412154760efd0b7abc3.tar.bz2 |
Add chrome to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/accessibility')
-rw-r--r-- | chrome/test/accessibility/accessibility_tests.cc | 503 | ||||
-rw-r--r-- | chrome/test/accessibility/accessibility_util.cc | 620 | ||||
-rw-r--r-- | chrome/test/accessibility/accessibility_util.h | 136 | ||||
-rw-r--r-- | chrome/test/accessibility/browser_impl.cc | 551 | ||||
-rw-r--r-- | chrome/test/accessibility/browser_impl.h | 134 | ||||
-rw-r--r-- | chrome/test/accessibility/constants.h | 134 | ||||
-rw-r--r-- | chrome/test/accessibility/keyboard_util.cc | 219 | ||||
-rw-r--r-- | chrome/test/accessibility/keyboard_util.h | 62 | ||||
-rw-r--r-- | chrome/test/accessibility/registry_util.cc | 37 | ||||
-rw-r--r-- | chrome/test/accessibility/registry_util.h | 42 | ||||
-rw-r--r-- | chrome/test/accessibility/tab_impl.cc | 389 | ||||
-rw-r--r-- | chrome/test/accessibility/tab_impl.h | 163 |
12 files changed, 2990 insertions, 0 deletions
diff --git a/chrome/test/accessibility/accessibility_tests.cc b/chrome/test/accessibility/accessibility_tests.cc new file mode 100644 index 0000000..84dee3b --- /dev/null +++ b/chrome/test/accessibility/accessibility_tests.cc @@ -0,0 +1,503 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <Objbase.h> +#include <Oleacc.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 "chrome/app/chrome_dll_resource.h" +#include "base/win_util.h" +#include "base/file_util.h" +#include "googleurl/src/gurl.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. +// TODO(sridharg): Alter, when accessibility objects for Chrome Window, Application and +// Client are corrected. +TEST_F(AccessibilityTest, TestChromeBrowserAccObject) { + IAccessible* p_accobj = NULL; + HWND hwnd = GetChromeBrowserWnd(&p_accobj); + ASSERT_TRUE(NULL != hwnd); + ASSERT_TRUE(NULL != p_accobj); + CHK_RELEASE(p_accobj); +} + +// Check accessibility object for toolbar and it's properties Name, Role, State. +// (Add other properties, if their values are fixed all the time.) +TEST_F(AccessibilityTest, TestChromeToolbarAccObject) { + IAccessible* p_accobj = NULL; + GetToolbarWnd(&p_accobj); + ASSERT_TRUE(NULL != p_accobj); + + // Check Name - "Google Chrome Toolbar". + EXPECT_EQ(L"Google Chrome Toolbar", GetName(p_accobj)); + // Check Role - "tool bar". + EXPECT_EQ(L"tool bar", GetRole(p_accobj)); + // Check State - "focusable" + EXPECT_EQ(L"focusable", GetState(p_accobj)); + + CHK_RELEASE(p_accobj); +} + +// Check accessibility object for tabstrip and it's properties Name, Role, +// State. (Add other properties, if their values are fixed all the time.) +TEST_F(AccessibilityTest, TestChromeTabstripAccObject) { + IAccessible* p_accobj = NULL; + GetTabStripWnd(&p_accobj); + ASSERT_TRUE(NULL != p_accobj); + + // Check Name - "Tabstrip". + EXPECT_EQ(L"Tabstrip", GetName(p_accobj)); + // Check Role - "grouping". + EXPECT_EQ(L"grouping", GetRole(p_accobj)); + // Check State - "focusable" + EXPECT_EQ(L"focusable", GetState(p_accobj)); + + CHK_RELEASE(p_accobj); +} + +// Check Browser buttons and their Name, Role, State. +TEST_F(AccessibilityTest, TestChromeButtons) { + HRESULT hr = S_OK; + IAccessible* p_accobj = NULL; + VARIANT button; + + // Get browser accessibility object. + IAccessible* p_browser = NULL; + GetChromeBrowserWnd(&p_browser); + ASSERT_TRUE(NULL != p_browser); + + // Check Minimize button and it's Name, Role, State. + hr = GetBrowserMinimizeButton(&p_accobj, &button); + // It is not complete accessible object, as it is element. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + // Read it's properties. + EXPECT_EQ(L"Minimize", GetName(p_browser, button)); + EXPECT_EQ(L"push button", GetRole(p_browser, button)); + EXPECT_EQ(L"focusable", GetState(p_browser, button)); + CHK_RELEASE(p_accobj); + + // Check Maximize button and it's Name, Role, State. + GetBrowserMaximizeButton(&p_accobj, &button); + // It is an element and not complete accessible object. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + // Read it's properties. + EXPECT_EQ(L"Maximize", GetName(p_browser, button)); + EXPECT_EQ(L"push button", GetRole(p_browser, button)); + EXPECT_EQ(L"focusable", GetState(p_browser, button)); + CHK_RELEASE(p_accobj); + + // Check Restore button and it's Name, Role, State. + GetBrowserRestoreButton(&p_accobj, &button); + // It is an element and not complete accessible object. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + // Read it's properties. + EXPECT_EQ(L"Restore", GetName(p_browser, button)); + EXPECT_EQ(L"push button", GetRole(p_browser, button)); + EXPECT_EQ(L"focusable, invisible", GetState(p_browser, button)); + CHK_RELEASE(p_accobj); + + // Check Close button and it's Name, Role, State. + GetBrowserCloseButton(&p_accobj, &button); + // It is an element and not complete accessible object. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + // Read it's properties. + EXPECT_EQ(L"Close", GetName(p_browser, button)); + EXPECT_EQ(L"push button", GetRole(p_browser, button)); + EXPECT_EQ(L"focusable", GetState(p_browser, button)); + CHK_RELEASE(p_accobj); + + CHK_RELEASE(p_browser); +} + +// Check Star button and their Name, Role, State. +TEST_F(AccessibilityTest, TestStarButton) { + HRESULT hr = S_OK; + IAccessible* p_accobj = NULL; + VARIANT button; + + // Get toolbar accessibility object. + IAccessible* p_toolbar = NULL; + GetToolbarWnd(&p_toolbar); + ASSERT_TRUE(NULL != p_toolbar); + + // Check button and it's Name, Role, State. + hr = GetStarButton(&p_accobj, &button); + // It is not complete accessible object, as it is element. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + // Read it's properties. + EXPECT_EQ(L"Bookmark", GetName(p_toolbar, button)); + EXPECT_EQ(L"push button", GetRole(p_toolbar, button)); + EXPECT_EQ(L"focusable", GetState(p_toolbar, button)); + CHK_RELEASE(p_accobj); + + CHK_RELEASE(p_toolbar); +} + +// Check Star button and their Name, Role, State. +TEST_F(AccessibilityTest, TestStarBtnStatusOnNewTab) { + HRESULT hr = S_OK; + IAccessible* p_accobj = NULL; + VARIANT button; + + // Get toolbar accessibility object. + IAccessible* p_toolbar = NULL; + GetToolbarWnd(&p_toolbar); + ASSERT_TRUE(NULL != p_toolbar); + + // Check button and it's Name, Role, State. + hr = GetStarButton(&p_accobj, &button); + // It is not a complete accessible object, as it is element. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + EXPECT_EQ(L"focusable", GetState(p_toolbar, button)); + + // Now, check Star status in different situations. + scoped_ptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(window.get()); + + // Set URL and check button status. + scoped_ptr<TabProxy> tab1(window->GetTab(0)); + ASSERT_TRUE(tab1.get()); + std::wstring test_file1 = test_data_directory_; + file_util::AppendToPath(&test_file1, L"title1.html"); + tab1->NavigateToURL(net_util::FilePathToFileURL(test_file1)); + Sleep(kWaitForActionMsec); + EXPECT_EQ(L"focusable", GetState(p_toolbar, button)); + + // Add empty new tab and check status. + int old_tab_count = -1; + ASSERT_TRUE(window->GetTabCount(&old_tab_count)); + ASSERT_TRUE(window->ApplyAccelerator(IDC_NEWTAB)); + int new_tab_count; + ASSERT_TRUE(window->WaitForTabCountToChange(old_tab_count, &new_tab_count, + 5000)); + // Check tab count. + ASSERT_GE(new_tab_count, old_tab_count); + // Also, check accessibility object's children. + Sleep(1000); + EXPECT_EQ(L"focusable", GetState(p_toolbar, button)); // ??? + + // Add new tab with URL and check status. + old_tab_count = new_tab_count; + std::wstring test_file2 = test_data_directory_; + file_util::AppendToPath(&test_file2, L"title1.html"); + ASSERT_TRUE(window->AppendTab(net_util::FilePathToFileURL(test_file2))); + ASSERT_TRUE(window->WaitForTabCountToChange(old_tab_count, &new_tab_count, + 5000)); + // Check tab count. Also, check accessibility object's children. + ASSERT_GE(new_tab_count, old_tab_count); + Sleep(kWaitForActionMsec); + EXPECT_EQ(L"focusable", GetState(p_toolbar, button)); + + CHK_RELEASE(p_toolbar); +} + +// Check Back button and their Name, Role, State. +TEST_F(AccessibilityTest, TestBackButton) { + HRESULT hr = S_OK; + IAccessible* p_accobj = NULL; + VARIANT button; + + // Get toolbar accessibility object. + IAccessible* p_toolbar = NULL; + GetToolbarWnd(&p_toolbar); + ASSERT_TRUE(NULL != p_toolbar); + + // Check button and it's Name, Role, State. + hr = GetBackButton(&p_accobj, &button); + // It is not a complete accessible object, as it is element. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + + // Read it's properties. + EXPECT_EQ(L"Back", GetName(p_toolbar, button)); + EXPECT_EQ(L"drop down button", GetRole(p_toolbar, button)); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + CHK_RELEASE(p_accobj); + + CHK_RELEASE(p_toolbar); +} + +// Check Back button and their Name, Role, State. +// This test is disabled. See bug 1119183. +TEST_F(AccessibilityTest, DISABLED_TestBackBtnStatusOnNewTab) { + HRESULT hr = S_OK; + IAccessible* p_accobj = NULL; + VARIANT button; + + // Get toolbar accessibility object. + IAccessible* p_toolbar = NULL; + GetToolbarWnd(&p_toolbar); + ASSERT_TRUE(NULL != p_toolbar); + + // Check button and it's Name, Role, State. + hr = GetBackButton(&p_accobj, &button); + // It is not complete accessible object, as it is element. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + + // Now check Back status in different situations. + scoped_ptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(window.get()); + int old_tab_count = -1; + int new_tab_count = -1; + + // Set URL and check button status. + scoped_ptr<TabProxy> tab1(window->GetTab(0)); + ASSERT_TRUE(tab1.get()); + std::wstring test_file1 = test_data_directory_; + file_util::AppendToPath(&test_file1, L"title1.html"); + tab1->NavigateToURL(net_util::FilePathToFileURL(test_file1)); + Sleep(kWaitForActionMsec); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable", GetState(p_toolbar, button)); + } + // Go Back and check status. + window->ApplyAccelerator(IDC_BACK); + Sleep(kWaitForActionMsec); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + + // Add empty new tab and check status. + ASSERT_TRUE(window->GetTabCount(&old_tab_count)); + ASSERT_TRUE(window->ApplyAccelerator(IDC_NEWTAB)); + ASSERT_TRUE(window->WaitForTabCountToChange(old_tab_count, &new_tab_count, + 5000)); + // Check tab count. Also, check accessibility object's children. + ASSERT_GE(new_tab_count, old_tab_count); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + + // Add new tab with URL and check status. + old_tab_count = new_tab_count; + std::wstring test_file2 = test_data_directory_; + file_util::AppendToPath(&test_file2, L"title1.html"); + ASSERT_TRUE(window->AppendTab(net_util::FilePathToFileURL(test_file2))); + ASSERT_TRUE(window->WaitForTabCountToChange(old_tab_count, &new_tab_count, + 5000)); + // Check tab count. Also, check accessibility object's children. + ASSERT_GE(new_tab_count, old_tab_count); + Sleep(kWaitForActionMsec); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + + CHK_RELEASE(p_toolbar); +} + +// Check Forward button and their Name, Role, State. +TEST_F(AccessibilityTest, TestForwardButton) { + HRESULT hr = S_OK; + IAccessible* p_accobj = NULL; + VARIANT button; + + // Get toolbar accessibility object. + IAccessible* p_toolbar = NULL; + GetToolbarWnd(&p_toolbar); + ASSERT_TRUE(NULL != p_toolbar); + + // Check button and it's Name, Role, State. + hr = GetForwardButton(&p_accobj, &button); + // It is not complete accessible object, as it is element. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + // Read it's properties. + EXPECT_EQ(L"Forward", GetName(p_toolbar, button)); + EXPECT_EQ(L"drop down button", GetRole(p_toolbar, button)); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + CHK_RELEASE(p_accobj); + + CHK_RELEASE(p_toolbar); +} + +// Check Back button and their Name, Role, State. +// This test is disabled. See bug 1119183. +TEST_F(AccessibilityTest, DISABLED_TestForwardBtnStatusOnNewTab) { + HRESULT hr = S_OK; + IAccessible* p_accobj = NULL; + VARIANT button; + + // Get toolbar accessibility object. + IAccessible* p_toolbar = NULL; + GetToolbarWnd(&p_toolbar); + ASSERT_TRUE(NULL != p_toolbar); + + // Check button and it's Name, Role, State. + hr = GetForwardButton(&p_accobj, &button); + // It is not complete accessible object, as it is element. + ASSERT_TRUE(S_FALSE == hr); + ASSERT_TRUE(NULL == p_accobj); + ASSERT_TRUE(VT_I4 == button.vt); + // State "has popup" only supported in XP and higher. + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + + // Now check Back status in different situations. + scoped_ptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); + ASSERT_TRUE(window.get()); + int old_tab_count = -1; + int new_tab_count = -1; + + // Set URL and check button status. + scoped_ptr<TabProxy> tab1(window->GetTab(0)); + ASSERT_TRUE(tab1.get()); + std::wstring test_file1 = test_data_directory_; + file_util::AppendToPath(&test_file1, L"title1.html"); + tab1->NavigateToURL(net_util::FilePathToFileURL(test_file1)); + Sleep(kWaitForActionMsec); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + // Go Back and check status. + window->ApplyAccelerator(IDC_BACK); + Sleep(kWaitForActionMsec); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable", GetState(p_toolbar, button)); + } + // Go Forward and check status. + window->ApplyAccelerator(IDC_FORWARD); + Sleep(kWaitForActionMsec); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + + // Add empty new tab and check status. + ASSERT_TRUE(window->GetTabCount(&old_tab_count)); + ASSERT_TRUE(window->ApplyAccelerator(IDC_NEWTAB)); + ASSERT_TRUE(window->WaitForTabCountToChange(old_tab_count, &new_tab_count, + 5000)); + // Check tab count. + ASSERT_GE(new_tab_count, old_tab_count); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + + // Add new tab with URL and check status. + old_tab_count = new_tab_count; + std::wstring test_file2 = test_data_directory_; + file_util::AppendToPath(&test_file2, L"title1.html"); + ASSERT_TRUE(window->AppendTab(net_util::FilePathToFileURL(test_file2))); + ASSERT_TRUE(window->WaitForTabCountToChange(old_tab_count, &new_tab_count, + 5000)); + // Check tab count. + ASSERT_GE(new_tab_count, old_tab_count); + Sleep(kWaitForActionMsec); + if (win_util::GetWinVersion() > win_util::WINVERSION_2000) { + EXPECT_EQ(L"has popup, focusable, unavailable", + GetState(p_toolbar, button)); + } else { + EXPECT_EQ(L"focusable, unavailable", GetState(p_toolbar, button)); + } + + CHK_RELEASE(p_toolbar); +}
\ No newline at end of file diff --git a/chrome/test/accessibility/accessibility_util.cc b/chrome/test/accessibility/accessibility_util.cc new file mode 100644 index 0000000..43a79a8 --- /dev/null +++ b/chrome/test/accessibility/accessibility_util.cc @@ -0,0 +1,620 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "accessibility_util.h" +#include "constants.h" +#include "chrome/common/win_util.h" +#include "chrome/common/l10n_util.h" +#include "chrome/browser/xp_frame.h" +#include "chrome/browser/vista_frame.h" +#include "generated_resources.h" + +VARIANT g_var_self = {VT_I4, CHILDID_SELF}; + +HWND GetChromeBrowserWnd(IAccessible** ppi_access) { + HRESULT hr = S_OK; + HWND hwnd = NULL; + BSTR str_name; + std::wstring str_role; + + const std::wstring product_name = l10n_util::GetString(IDS_PRODUCT_NAME); + + // Get Chrome window handle. + if (win_util::ShouldUseVistaFrame()) { + hwnd = FindWindow(VISTA_FRAME_CLASSNAME, NULL); + } else { + hwnd = FindWindow(XP_FRAME_CLASSNAME, NULL); + } + + if (NULL == hwnd) { + if (ppi_access) + *ppi_access = NULL; + return hwnd; + } + + // Get accessibility object for Chrome, only if requested. + if (!ppi_access) { + return hwnd; + } + *ppi_access = NULL; + + // Get accessibility object for Chrome Main Window. If failed to get it, + // return only window handle. + IAccessible *pi_acc_root_win = NULL; + hr = AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void**> + (&pi_acc_root_win)); + if ((S_OK != hr) || !pi_acc_root_win) { + return hwnd; + } + + + // Confirm if it is Chrome window using it's accessibility object's + // Name and Role property. If it's not the desired object, return only + // window handle. + hr = pi_acc_root_win->get_accName(g_var_self, &str_name); + if ((S_OK != hr) || (!str_name) || + (0 != _wcsicmp(str_name, product_name.c_str())) ) { + CHK_RELEASE(pi_acc_root_win); + return hwnd; + } + str_role = GetRole(pi_acc_root_win); + if (0 != str_role.compare(BROWSER_WIN_ROLE)) { + CHK_RELEASE(pi_acc_root_win); + return hwnd; + } + + // Get accessibility object for Chrome Window. If failed to get it, + // return only window handle. + INT64 child_cnt = GetChildCount(pi_acc_root_win); + VARIANT *var_array_child = + reinterpret_cast<VARIANT*>(calloc(size_t(child_cnt), + sizeof(VARIANT))); + + if (!var_array_child) { + CHK_RELEASE(pi_acc_root_win); + return hwnd; + } + + hr = GetChildrenArray(pi_acc_root_win, var_array_child); + if (S_OK != hr) { + CHK_RELEASE(pi_acc_root_win); + return hwnd; + } + + // Fetch desired child (Chrome window) of Chrome Main Window. + IAccessible *pi_acc_app = NULL; + GetChildObject(pi_acc_root_win, var_array_child[CHROME_APP_ACC_INDEX], + &pi_acc_app); + if (!pi_acc_app) { + CHK_RELEASE(pi_acc_app); + return hwnd; + } + + // Confirm if it is Chrome application using it's accessibility object's + // Name and Role property. If it's not the desired object, return only + // window handle. + hr = pi_acc_app->get_accName(g_var_self, &str_name); + if ((S_OK != hr) || (!str_name) || + (0 != _wcsicmp(str_name, product_name.c_str())) ) { + CHK_RELEASE(pi_acc_app); + CHK_RELEASE(pi_acc_root_win); + return hwnd; + } + str_role = GetRole(pi_acc_app); + if (0 != str_role.compare(BROWSER_APP_ROLE)) { + CHK_RELEASE(pi_acc_app); + CHK_RELEASE(pi_acc_root_win); + return hwnd; + } + + // Get accessibility object for Chrome Client. If failed, return only + // window handle. + hr = GetChildrenArray(pi_acc_app, var_array_child); + if (S_OK != hr) { + CHK_RELEASE(pi_acc_app); + CHK_RELEASE(pi_acc_root_win); + return hwnd; + } + + // Chrome Window has only one child which is Chrome Client. + GetChildObject(pi_acc_app, var_array_child[CHROME_CLIENT_ACC_INDEX], + ppi_access); + + // 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 = (*ppi_access)->get_accName(g_var_self, &str_name); + if ((S_OK != hr) || (!str_name) || + (0 != _wcsicmp(str_name, product_name.c_str())) ) { + CHK_RELEASE(*ppi_access); + } + str_role = GetRole(*ppi_access); + if (0 != str_role.compare(BROWSER_CLIENT_ROLE)) { + CHK_RELEASE(*ppi_access); + } + + CHK_RELEASE(pi_acc_app); + CHK_RELEASE(pi_acc_root_win); + return hwnd; +} + +HRESULT GetChildWndOf(std::wstring parent_name, unsigned int child_index, + IAccessible** ppi_access, VARIANT* child_var_id) { + HRESULT hr = S_OK; + + // Validate input and initialize. + if (!ppi_access && !child_var_id) + return E_INVALIDARG; + if (ppi_access) + *ppi_access = NULL; + if (child_var_id) + VariantInit(child_var_id); + + // Get accessibility object and window handle for Chrome parent. + IAccessible *pi_parent = NULL; + if (0 == parent_name.compare(BROWSER_STR)) + GetChromeBrowserWnd(&pi_parent); + if (0 == parent_name.compare(TOOLBAR_STR)) + GetToolbarWnd(&pi_parent); + if (0 == parent_name.compare(TABSTRIP_STR)) + GetTabStripWnd(&pi_parent); + + if (!pi_parent) + return E_FAIL; + + // Validate child index. + INT64 child_cnt = GetChildCount(pi_parent); + if (child_index >= child_cnt) { + CHK_RELEASE(pi_parent); + VariantClear(child_var_id); + return E_INVALIDARG; + } + + // Get array of child items of parent object. + VARIANT *var_array_child = + reinterpret_cast<VARIANT*>(calloc(size_t(child_cnt), sizeof(VARIANT))); + if (var_array_child) { + hr = GetChildrenArray(pi_parent, var_array_child); + if (S_OK == hr) { + // Fetch Tabstrip which is child_index'th child of parent object. + if (ppi_access) { + hr = GetChildObject(pi_parent, var_array_child[child_index], + ppi_access); + } + if (child_var_id) { + VariantCopy(child_var_id, var_array_child+child_index); + } + } + free(var_array_child); + } + + CHK_RELEASE(pi_parent); + return hr; +} + +HRESULT GetTabStripWnd(IAccessible** ppi_access) { + return GetChildWndOf(BROWSER_STR, TABSTRIP_ACC_INDEX, ppi_access, NULL); +} + +HRESULT GetToolbarWnd(IAccessible** ppi_access) { + return GetChildWndOf(BROWSER_STR, TOOLBAR_ACC_INDEX, ppi_access, NULL); +} + +HRESULT GetBrowserMinimizeButton(IAccessible** ppi_access, + VARIANT* child_var_id) { + return GetChildWndOf(BROWSER_STR, CHROME_MIN_ACC_INDEX, ppi_access, + child_var_id); +} + +HRESULT GetBrowserMaximizeButton(IAccessible** ppi_access, + VARIANT* child_var_id) { + return GetChildWndOf(BROWSER_STR, CHROME_MAX_ACC_INDEX, ppi_access, + child_var_id); +} + +HRESULT GetBrowserRestoreButton(IAccessible** ppi_access, + VARIANT* child_var_id) { + return GetChildWndOf(BROWSER_STR, CHROME_RESTORE_ACC_INDEX, ppi_access, + child_var_id); +} + +HRESULT GetBrowserCloseButton(IAccessible** ppi_access, + VARIANT* child_var_id) { + return GetChildWndOf(BROWSER_STR, CHROME_CLOSE_ACC_INDEX, ppi_access, + child_var_id); +} + +HRESULT GetStarButton(IAccessible** ppi_access, VARIANT* child_var_id) { + return GetChildWndOf(TOOLBAR_STR, STAR_BTN_INDEX, ppi_access, child_var_id); +} + +HRESULT GetBackButton(IAccessible** ppi_access, VARIANT* child_var_id) { + return GetChildWndOf(TOOLBAR_STR, BACK_BTN_INDEX, ppi_access, child_var_id); +} + +HRESULT GetForwardButton(IAccessible** ppi_access, VARIANT* child_var_id) { + return GetChildWndOf(TOOLBAR_STR, FORWARD_BTN_INDEX, ppi_access, + child_var_id); +} + +HWND GetAddressBarWnd(IAccessible** ppi_access) { + HWND hwnd = NULL; + HWND hwnd_addr_bar = NULL; + + // // Initialize, if requested. + if (ppi_access) { + *ppi_access = 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 (ppi_access && hwnd_addr_bar) { + AccessibleObjectFromWindow(hwnd_addr_bar, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void**>(ppi_access)); + } + } + + return hwnd_addr_bar; +} + +HWND GetFindTextWnd(IAccessible** ppi_access) { + HWND hwnd = NULL; + HWND hwnd_find = NULL; + + // Initialize, if requested. + if (ppi_access) { + *ppi_access = 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 (ppi_access && hwnd_find) { + AccessibleObjectFromWindow(hwnd_find, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void**>(ppi_access)); + } + } + + return hwnd_find; +} + +HWND GetAuthWnd(IAccessible** ppi_access) { + HWND hwnd = NULL; + HWND hwnd_tab = NULL; + HWND hwnd_auth = NULL; + + // Initialize, if requested. + if (ppi_access) { + *ppi_access = NULL; + } + + // Get window handle for Chrome Browser. + hwnd = GetChromeBrowserWnd(NULL); + if (NULL != 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 (ppi_access && hwnd_auth) { + AccessibleObjectFromWindow(hwnd_auth, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void**>(ppi_access)); + } + } + + return hwnd_auth; +} + +HRESULT GetChildObject(IAccessible* pi_access, VARIANT var_child, + IAccessible** ppi_child_access) { + HRESULT hr = S_OK; + IDispatch *p_dispatch = NULL; + + // Validate input. + if ( (pi_access == NULL) || + (ppi_child_access == NULL) ) { + return E_INVALIDARG; + } + + // Check the child type and fetch object accordingly. + if (var_child.vt == VT_DISPATCH) { + var_child.pdispVal-> + QueryInterface(IID_IAccessible, + reinterpret_cast<void**>(ppi_child_access)); + } else if (var_child.vt == VT_I4) { + hr = pi_access->get_accChild(var_child, &p_dispatch); + if ( (hr == S_OK) && + (p_dispatch != NULL) ) { + p_dispatch->QueryInterface(IID_IAccessible, + reinterpret_cast<void**>(ppi_child_access)); + CHK_RELEASE(p_dispatch); + } + } + + return hr; +} + +HRESULT GetParentObject(IAccessible* pi_access, + IAccessible** ppi_parent_access) { + HRESULT hr = S_OK; + IDispatch *p_dispatch = NULL; + + // Validate input. + if ( (pi_access == NULL) || + (ppi_parent_access == NULL) ) { + return E_INVALIDARG; + } + + // Fetch parent object. + hr = pi_access->get_accParent(&p_dispatch); + if ( (hr == S_OK) && + (p_dispatch != NULL) ) { + p_dispatch->QueryInterface(IID_IAccessible, + reinterpret_cast<void**>(ppi_parent_access)); + CHK_RELEASE(p_dispatch); + } + + return hr; +} + +INT64 GetChildCount(IAccessible* pi_access) { + HRESULT hr = S_OK; + long child_cnt = 0; + + // Validate input. Object can have 0 children. So return -1 on invalid input. + if (pi_access == NULL) { + return -1; + } + + // Get child count. + pi_access->get_accChildCount(&child_cnt); + return child_cnt; +} + +HRESULT GetChildrenArray(IAccessible* pi_access, VARIANT* var_array_child) { + HRESULT hr = S_OK; + INT64 child_start = 0; + long child_obtained = 0; + INT64 child_cnt = GetChildCount(pi_access); + + // Validate input. + if ((pi_access == NULL) || (var_array_child == NULL)) { + return E_INVALIDARG; + } + + // Validate every item and initialize it. + int i = 0; + for (; (i < child_cnt) && (var_array_child+i); i++) { + VariantInit(var_array_child+i); + } + + // If all items in array are not initialized, return error. + if (i != child_cnt) { + return E_INVALIDARG; + } + + // Get IDs of child items. + AccessibleChildren(pi_access, + LONG(child_start), + LONG(child_cnt), + var_array_child, + &child_obtained); + return hr; +} + +HRESULT ActivateWnd(IAccessible *pi_access, HWND hwnd) { + HRESULT hr = S_OK; + + // Select and focus the object, if accessibility object is specified. + if (pi_access) { + hr = pi_access->accSelect(SELFLAG_TAKEFOCUS | SELFLAG_TAKESELECTION, + g_var_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 str_name; + + // Validate tab index specified. + if (tab_index < 1) + return NULL; + + // Get accessibility object for Tabstrip. + IAccessible *pi_acc_strip = NULL; + GetTabStripWnd(&pi_acc_strip); + + // Get Tab from Tabstrip and return it's Name. + if (pi_acc_strip) { + INT64 child_cnt = GetChildCount(pi_acc_strip); + VARIANT *var_array_child = + reinterpret_cast<VARIANT*>(calloc(size_t(child_cnt), sizeof(VARIANT))); + if (var_array_child) { + // Get tab object. tab_index = index in child array, because first child + // in tabstrip is '+' button. + hr = GetChildrenArray(pi_acc_strip, var_array_child); + if (S_OK == hr) { + IAccessible *pi_access_temp = NULL; + hr = GetChildObject(pi_acc_strip, var_array_child[tab_index], + &pi_access_temp); + if ((S_OK == hr) && + (var_array_child[tab_index].vt == VT_DISPATCH) && + (pi_access_temp) ) { + hr = pi_access_temp->get_accName(g_var_self, &str_name); + } else if (var_array_child[tab_index].vt == VT_I4) { + hr = pi_acc_strip->get_accName(var_array_child[1], &str_name); + } + CHK_RELEASE(pi_acc_strip); + return str_name; + } + } + + CHK_RELEASE(pi_acc_strip); + } + + return NULL; +} + +INT64 GetTabCnt() { + // Get accessibility object for Tabstrip. + IAccessible *pi_acc_strip = NULL; + GetTabStripWnd(&pi_acc_strip); + + // If Tabstrip is invalid, return -1, to indicate error. + if (!pi_acc_strip) { + return -1; + } + + // Get child count. + INT64 child_cnt = 0; + if (pi_acc_strip) { + child_cnt = GetChildCount(pi_acc_strip); + CHK_RELEASE(pi_acc_strip); + } + + // Don't count 1st child as it is '+' button. + return (child_cnt-1); +} + +std::wstring GetName(IAccessible* pi_access, VARIANT child) { + HRESULT hr = S_OK; + + // Validate input. + if (NULL == pi_access) { + return std::wstring(); + } + + // Get Name. + BSTR name; + hr = pi_access->get_accName(child, &name); + if (S_OK != hr) + return std::wstring(); + + return std::wstring(name); +} + +std::wstring GetRole(IAccessible* pi_access, VARIANT child) { + HRESULT hr = S_OK; + LPTSTR role_str = NULL; + + // Validate input. + if (NULL == pi_access) { + return std::wstring(); + } + + // Get Role. + VARIANT role; + VariantInit(&role); + hr = pi_access->get_accRole(child, &role); + if (S_OK != hr || VT_I4 != role.vt) { + VariantClear(&role); + return std::wstring(); + } + + // Get Role string. + unsigned int role_length = GetRoleText(role.lVal, NULL, 0); + role_str = (LPTSTR)calloc(role_length + 1, sizeof(TCHAR)); + if (role_str) + GetRoleText(role.lVal, role_str, role_length + 1); + + VariantClear(&role); + return std::wstring(role_str); +} + +std::wstring GetState(IAccessible* pi_access, VARIANT child) { + HRESULT hr = S_OK; + LPTSTR state_str = NULL; + std::wstring complete_state; + + // Validate input. + if (NULL == pi_access) { + return std::wstring(); + } + + // Get State. + VARIANT state; + VariantInit(&state); + hr = pi_access->get_accState(child, &state); + if (S_OK != hr || VT_I4 != state.vt) { + VariantClear(&state); + return std::wstring(); + } + + // Treat the "normal" state separately. + if (state.vt == 0) { + unsigned int state_length = GetStateText(state.lVal, NULL, 0); + state_str = (LPTSTR)calloc(state_length + 1, sizeof(TCHAR)); + if (state_str) { + GetStateText(state.lVal, state_str, state_length + 1); + complete_state = std::wstring(state_str); + } + } else { + // Number of bits. + UINT bit_cnt = 32; + // Convert state flags to comma separated list. + for (DWORD dwStateBit = 0x80000000; bit_cnt; bit_cnt--, dwStateBit >>= 1) { + if (state.lVal & dwStateBit) { + unsigned int state_length = GetStateText(dwStateBit, NULL, 0); + state_str = (LPTSTR)calloc(state_length + 1, sizeof(TCHAR)); + if (state_str) { + GetStateText(dwStateBit, state_str, state_length + 1); + if (complete_state.length() > 0) + complete_state.append(L", "); + complete_state.append(state_str); + free(state_str); + } + } + } + } + + VariantClear(&state); + return complete_state; +} diff --git a/chrome/test/accessibility/accessibility_util.h b/chrome/test/accessibility/accessibility_util.h new file mode 100644 index 0000000..77d0f03 --- /dev/null +++ b/chrome/test/accessibility/accessibility_util.h @@ -0,0 +1,136 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_TEST_ACCISSIBILITY_ACCISSIBILITY_UTIL_H__ +#define CHROME_TEST_ACCISSIBILITY_ACCISSIBILITY_UTIL_H__ + +#include <Oleacc.h> +#include <iostream> + +/////////////////////////////////////////////////////////////////////////////// +// Functions and Globals which are using IAccessible interface. +// These are the wrappers to fetch accessible object interface and properties. +/////////////////////////////////////////////////////////////////////////////// + +// Variant ID pointing to object itself. +extern VARIANT g_var_self; + +// Returns window handle to Chrome Browser. Retrives it's(having role as +// client) IAccessible pointer, if requested. +HWND GetChromeBrowserWnd(IAccessible** ppi_access); + +// Returns IAccessible pointer of object's child window, provided parent's name +// and it's 0 based child index. If child is element and not complete object, +// it's variant id is returned with S_FALSE. +HRESULT GetChildWndOf(std::wstring parent_name, unsigned int child_index, + IAccessible** ppi_access, VARIANT* child_var_id); + +// Returns IAccessible pointer for Tabstrip. It does not have window handle. +HRESULT GetTabStripWnd(IAccessible** ppi_access); + +// Returns IAccessible pointer for Toolbar. It does not have window handle. +HRESULT GetToolbarWnd(IAccessible** ppi_access); + +// Returns handle to OmniBox(AddressBar) and IAccessible pointer, if requested. +HWND GetAddressBarWnd(IAccessible** ppi_access); + +// Returns handle to Find box and IAccessible pointer, if requested. +HWND GetFindTextWnd(IAccessible** ppi_access); + +// Returns handle to authentication dialog and IAccessible pointer, if +// requested. +HWND GetAuthWnd(IAccessible** ppi_access); + +// Fetches IAccessible pointer for a child of given the IAccessible pointer +// and desired child id. +HRESULT GetChildObject(IAccessible* pi_access, VARIANT var_child, + IAccessible** ppi_child_access); + +// Fetches IAccessible pointer for a parent of specified IAccessible pointer. +HRESULT GetParentObject(IAccessible* pi_access, + IAccessible** ppi_parent_access); + +// Returns no. of child items of specified IAccessible pointer. If input +// parameter is NULL, -1 is returned. +INT64 GetChildCount(IAccessible* pi_access); + +// Extracts (VARIANT)array of child items of specified IAccessible pointer. +HRESULT GetChildrenArray(IAccessible* pi_access, VARIANT* var_array_child); + +// Activates specified window using IAccessible pointer and/or window handle. +HRESULT ActivateWnd(IAccessible *pi_access, HWND hwnd); + +// Returns title of tab whose index is specified. Tab index starts from 1. +BSTR GetTabName(INT64 tab_index); + +// Returns no. of tabs in tabstrip. If processing fails, it returns -1. +INT64 GetTabCnt(); + +// Returns Name of specified IAccessible pointer or it's child specified by +// variant. +std::wstring GetName(IAccessible* pi_access, VARIANT child = g_var_self); + +// Returns Role of specified IAccessible pointer or it's child specified by +// variant. +std::wstring GetRole(IAccessible* pi_access, VARIANT child = g_var_self); + +// Returns State of specified IAccessible pointer or it's child specified by +// variant. +std::wstring GetState(IAccessible* pi_access, VARIANT child = g_var_self); + +// Returns IAccessible pointer for Chrome Minimize Button. It does not have +// window handle. +HRESULT GetBrowserMinimizeButton(IAccessible** ppi_access, + VARIANT* child_var_id); + +// Returns IAccessible pointer for Chrome Maximize Button. It does not have +// window handle. +HRESULT GetBrowserMaximizeButton(IAccessible** ppi_access, + VARIANT* child_var_id); + +// Returns IAccessible pointer for Chrome Restore Button. It does not have +// window handle. +HRESULT GetBrowserRestoreButton(IAccessible** ppi_access, + VARIANT* child_var_id); + +// Returns IAccessible pointer for Chrome Close Button. It does not have +// window handle. +HRESULT GetBrowserCloseButton(IAccessible** ppi_access, VARIANT* child_var_id); + +// Returns IAccessible pointer for Star Button. It does not have window handle. +HRESULT GetStarButton(IAccessible** ppi_access, VARIANT* child_var_id); + +// Returns IAccessible pointer for Back Button. It does not have window handle. +HRESULT GetBackButton(IAccessible** ppi_access, VARIANT* child_var_id); + +// Returns IAccessible pointer for Forward Button. It does not have window +// handle. +HRESULT GetForwardButton(IAccessible** ppi_access, VARIANT* child_var_id); + +#endif // CHROME_TEST_ACCISSIBILITY_ACCISSIBILITY_UTIL_H__ diff --git a/chrome/test/accessibility/browser_impl.cc b/chrome/test/accessibility/browser_impl.cc new file mode 100644 index 0000000..50eb9f7 --- /dev/null +++ b/chrome/test/accessibility/browser_impl.cc @@ -0,0 +1,551 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#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 CBrowserImpl::Launch(void) { + // TODO: Check if chrome already running. + BSTR chrome_path = SysAllocString(GetChromeExePath()); + BOOL bool_return = 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. + bool_return = ShellExecuteEx(&shell_execute_info); + + if (bool_return && + (INT64(shell_execute_info.hInstApp) > 32) ) { + // TODO: Maintain instance and process handle. + + // Maintain active tab index. + SetActiveTabIndex(1); + + // Create initial tab collection. + UpdateTabCollection(); + + // Chrome launched. + return true; + } + + return false; +} + +bool CBrowserImpl::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 CBrowserImpl::ActivateTab(const INT64 index) { + // Validate index specified. + if (index < 1) { + return false; + } + + // Goto next tab till focused at desired tab. + // TODO: Change implementation when DoDefaultAction() for Tab is exported. + while (active_tab_index_ != index) { + GoToNextTab(NULL); + } + return true; +} + +bool CBrowserImpl::GetActiveTabURL(BSTR* url) { + // Validate input. + if (!url) + return false; + + // TODO: Implement. + return true; +} + +bool CBrowserImpl::GetActiveTabTitle(BSTR* title) { + if (!title) + return false; + + BSTR tab_title = SysAllocString(GetTabName(active_tab_index_)); + *title = SysAllocString(tab_title); + return true; +} + +bool CBrowserImpl::GetActiveTabIndex(INT64* index) { + if (!index) + return false; + + *index = active_tab_index_; + return true; +} + +void CBrowserImpl::SetActiveTabIndex(INT64 index) { + if ((index >= MIN_TAB_INDEX_DIGIT) && (index <= GetTabCnt())) + active_tab_index_ = index; + return; +} + +bool CBrowserImpl::GetActiveTab(CTabImpl** tab) { + return GetTab(active_tab_index_, tab); +} + +bool CBrowserImpl::GetTabCount(INT64* count) { + if (!count) + return false; + + *count = GetTabCnt(); + return true; +} + +bool CBrowserImpl::GetBrowserProcessCount(INT64* count) { + if (!count) + return false; + + // TODO: Add your implementation code here + + return true; +} + +bool CBrowserImpl::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 CBrowserImpl::AddTab(CTabImpl** 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. + CTabImpl *new_tab = new CTabImpl(); + if (!new_tab) + return false; + ChromeTab* tab_data = new_tab->InitTabData(); + new_tab->PutIndex(new_tab_index); + new_tab->PutTitle(GetTabName(new_tab_index)); + new_tab->SetBrowser(this); + + // Update tab collection. + tab_collection_.push_back(tab_data); + + // Create tab object, if requested. + if (tab) + *tab = new_tab; + + return true; +} + +bool CBrowserImpl::GetTab(const INT64 index, CTabImpl** tab) { + // Create tab object, if requested. + if (!tab) + return false; + + if (index > GetTabCnt()) + return false; + + *tab = new CTabImpl(); + if (!*tab) + return false; + + // Fill object. + ChromeTab* tab_data = (*tab)->InitTabData(); + (*tab)->PutIndex(index); + (*tab)->PutTitle(GetTabName(index)); + (*tab)->SetBrowser(this); + + return true; +} + +bool CBrowserImpl::GoToTab(const INT64 index, CTabImpl** 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 *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (pi_access && hwnd) { + // Activate main window and operate key Ctrl+digit. + ActivateWnd(pi_access, hwnd); + ClickKey(hwnd, VK_CONTROL, WORD('0'+index)); + CHK_RELEASE(pi_access); + + // Set focused tab index. + active_tab_index_ = index; + // Return tab object. + if (tab) { + return GetTab(active_tab_index_, tab); + } + } + + return false; +} + +bool CBrowserImpl::GoToNextTab(CTabImpl** tab) { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (pi_access && hwnd) { + // Activate main window and operate key Ctrl+Tab. + ActivateWnd(pi_access, hwnd); + ClickKey(hwnd, VK_CONTROL, VK_TAB); + CHK_RELEASE(pi_access); + + // 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 CBrowserImpl::GoToPrevTab(CTabImpl** tab) { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (pi_access && hwnd) { + // Activate main window and operate key Ctrl+Tab. + ActivateWnd(pi_access, hwnd); + ClickKey(hwnd, VK_SHIFT, VK_CONTROL, VK_TAB); + CHK_RELEASE(pi_access); + + // 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 CBrowserImpl::WaitForChromeToBeVisible(const INT64 interval, + const INT64 timeout, + bool* visible) { + IAccessible *pi_access = NULL; + INT64 time_elapsed = 0; + *visible = false; + + // Check and wait. + while (timeout >= time_elapsed) { + GetTabStripWnd(&pi_access); + if (pi_access) { + *visible = true; + CHK_RELEASE(pi_access); + return true; + } + Sleep(DWORD(interval)); + time_elapsed = time_elapsed + interval; + } + + return false; +} + +bool CBrowserImpl::WaitForTabCountToChange(const INT64 interval, + const INT64 timeout, + bool* changed) { + // TODO: Add your implementation code here + + return true; +} + +bool CBrowserImpl::WaitForTabToBecomeActive(const INT64 index, + const INT64 interval, + const INT64 timeout, + bool* activated) { + // TODO: Add your implementation code here + + return true; +} + +bool CBrowserImpl::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 cElements, lLBound, lUBound; + + // Array is not 1-dimentional. + if (SafeArrayGetDim(key_safe) != 1) + return false; + + // Get array bounds. + hr = SafeArrayGetLBound(key_safe, 1, &lLBound); + if (S_OK !=hr) + return false; + hr = SafeArrayGetUBound(key_safe, 1, &lUBound); + if (S_OK !=hr) + return false; + + // Key combination can be of maximum 3 keys. + cElements = lUBound-lLBound+1; + if (cElements > 3) + return false; + key_cnt = cElements; + + // 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 < cElements; 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 < cElements; i++) { + key_value[i] = GetKeybdKeysVal(key_str_value[i]); + } + } + } + + // Focus on main window and operate keys. + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (pi_access || hwnd) + ActivateWnd(pi_access, 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(pi_access); + + return true; +} + +void CBrowserImpl::UpdateTabCollection(void) { + // Get tab count and browser title. + INT64 tab_cnt = GetTabCnt(); + BSTR browser_title; + GetBrowserTitle(&browser_title); + + // Check tab-collection size and no. 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_; + } + } + } + + // TODO: If tabs are swapped. + // Add implementation here. +} + +void CBrowserImpl::EraseTabCollection(void) { + std::vector<ChromeTab*>::iterator tab_iterator; + for (tab_iterator = tab_collection_.begin(); + tab_iterator != tab_collection_.end(); + tab_iterator++) { + // Relese memory used for data. + CHK_DELETE(*tab_iterator); + } + tab_collection_.clear(); +} + +void CBrowserImpl::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..51fda43 --- /dev/null +++ b/chrome/test/accessibility/browser_impl.h @@ -0,0 +1,134 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_TEST_ACCISSIBILITY_BROWSER_IMPL_H__ +#define CHROME_TEST_ACCISSIBILITY_BROWSER_IMPL_H__ + +#include <vector> + +#include "tab_impl.h" + +///////////////////////////////////////////////////////////////////// +// CBrowserImpl +// 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 CBrowserImpl { + public: + CBrowserImpl() { + 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. + bool GetActiveTabTitle(BSTR* title); + + // Gets active tab index. + bool GetActiveTabIndex(INT64* index); + + // Returns active tab object. + bool GetActiveTab(CTabImpl** 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 + bool GetBrowserTitle(BSTR* title); + + // Adds new tab. Maintain current active tab index. + // Returns created tab, if requested. + bool AddTab(CTabImpl** tab); + + // Returns tab object of specified index. + bool GetTab(const INT64 index, CTabImpl** tab); + + // Activate tab of specified index. Maintain current active tab index. + // Returns created tab, if requested. + bool GoToTab(const INT64 index, CTabImpl** tab); + + // Move to next tab. Maintain current active tab index. + // Returns created tab, if requested. + bool GoToNextTab(CTabImpl** tab); + + // Move to previous tab. Maintain current active tab index. + // Returns created tab, if requested. + bool GoToPrevTab(CTabImpl** 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<ChromeTab*> tab_collection_; +}; + + +#endif // CHROME_TEST_ACCISSIBILITY_BROWSER_IMPL_H__ diff --git a/chrome/test/accessibility/constants.h b/chrome/test/accessibility/constants.h new file mode 100644 index 0000000..bb60d9e --- /dev/null +++ b/chrome/test/accessibility/constants.h @@ -0,0 +1,134 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_TEST_ACCISSIBILITY_CONSTANTS_H__ +#define CHROME_TEST_ACCISSIBILITY_CONSTANTS_H__ + +#include <windows.h> +#include <tchar.h> + +/////////////////////////////////////////////////////////////////// +// Constant Definitations 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_HWNDViewContainer_0") +#define STD_BUTTON _T("Button") +#define AUTH_TITLE _T("Authentication Required - Chrome") +#define CHROME_TAB_CONTENTS _T("Chrome_TabContents") + +#define BROWSER_WIN_ROLE _T("window") +#define BROWSER_APP_ROLE _T("application") +#define BROWSER_CLIENT_ROLE _T("client") + +#define CHROME_APP_ACC_INDEX (3) +#define CHROME_CLIENT_ACC_INDEX (0) + +// Chrome Client chidren. +#define TOOLBAR_ACC_INDEX (0) +#define TABSTRIP_ACC_INDEX (1) +#define CHROME_MIN_ACC_INDEX (3) +#define CHROME_MAX_ACC_INDEX (4) +#define CHROME_RESTORE_ACC_INDEX (5) +#define CHROME_CLOSE_ACC_INDEX (6) + +// Toolbar children. +#define BACK_BTN_INDEX (0) +#define FORWARD_BTN_INDEX (1) +#define RELOAD_BTN_INDEX (2) +#define STAR_BTN_INDEX (4) +#define GO_BTN_INDEX (6) +#define PAGE_BTN_INDEX (7) +#define MENU_BTN_INDEX (8) + +// Digit limits for tab index which can be used in accelerator. +#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") + +// 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_ACCISSIBILITY_CONSTANTS_H__ diff --git a/chrome/test/accessibility/keyboard_util.cc b/chrome/test/accessibility/keyboard_util.cc new file mode 100644 index 0000000..0e42776 --- /dev/null +++ b/chrome/test/accessibility/keyboard_util.cc @@ -0,0 +1,219 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#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..d16b6a9 --- /dev/null +++ b/chrome/test/accessibility/keyboard_util.h @@ -0,0 +1,62 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_TEST_ACCISSIBILITY_KEYBOARD_UTIL_H__ +#define CHROME_TEST_ACCISSIBILITY_KEYBOARD_UTIL_H__ + +#include "constants.h" + +#include <oleauto.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_ACCISSIBILITY_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..287c1df --- /dev/null +++ b/chrome/test/accessibility/registry_util.cc @@ -0,0 +1,37 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "registry_util.h" +#include "constants.h" + +BSTR GetChromeExePath() { + // TODO: once registry contains chrome exe path. + 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..a3024d8 --- /dev/null +++ b/chrome/test/accessibility/registry_util.h @@ -0,0 +1,42 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_TEST_ACCISSIBILITY_REGISTRY_UTIL_H__ +#define CHROME_TEST_ACCISSIBILITY_REGISTRY_UTIL_H__ + +////////////////////////////////////////////////// +// Functions for registry operations. +////////////////////////////////////////////////// + +#include <ocidl.h> + +// Reads chrome installation path from registry. +BSTR GetChromeExePath(); + +#endif // CHROME_TEST_ACCISSIBILITY_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..4393ffc --- /dev/null +++ b/chrome/test/accessibility/tab_impl.cc @@ -0,0 +1,389 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "browser_impl.h" +#include "tab_impl.h" +#include "accessibility_util.h" +#include "keyboard_util.h" +#include "constants.h" + +bool CTabImpl::Close(void) { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (!pi_access || !hwnd) + return false; + + // Activate main window and operate key Ctrl+F4. + ActivateWnd(pi_access, hwnd); + ClickKey(hwnd, VK_CONTROL, VK_F4); + CHK_RELEASE(pi_access); + + // Update tab information in browser object. + my_browser_->CloseTabFromCollection(tab_->index_); + return true; +} + +bool CTabImpl::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 CTabImpl::SetAddressBarText(const BSTR text) { + IAccessible *pi_access = NULL; + HWND hwnd_addr_bar = GetAddressBarWnd(&pi_access); + if (!pi_access || !hwnd_addr_bar) + return false; + + // Activate address bar. + ActivateWnd(pi_access, hwnd_addr_bar); + // Set text to address bar. + SendMessage(hwnd_addr_bar, WM_SETTEXT, 0, LPARAM(text)); + CHK_RELEASE(pi_access); + return true; +} + +bool CTabImpl::NavigateToURL(const BSTR url) { + IAccessible *pi_access = NULL; + HWND hwnd_addr_bar = GetAddressBarWnd(&pi_access); + + if (!pi_access || !hwnd_addr_bar) + return false; + + // Activate address bar. + ActivateWnd(pi_access, 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(pi_access); + return true; +} + +bool CTabImpl::FindInPage(const BSTR find_text) { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (!pi_access || !hwnd) + return false; + + // Activate main window and operate key 'F3' to invoke Find window. + ActivateWnd(pi_access, hwnd); + ClickKey(hwnd, VK_F3); + CHK_RELEASE(pi_access); + + // If no text is to be searched, return. + if (find_text != NULL) { + // TODO: Once FindWindow is exported through Accessibility. + // Instead of sleep, check if FindWindows exists or not. + Sleep(50); + + // Get Find window. + pi_access = NULL; + hwnd = GetFindTextWnd(&pi_access); + if (hwnd) { + HWND hwnd_find_edit = FindWindowEx(hwnd, 0, + CHROME_VIEWS_TEXT_FIELD_EDIT, 0); + if (hwnd_find_edit) { + ActivateWnd(pi_access, 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(pi_access); + + return true; +} + +bool CTabImpl::Reload(void) { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (!pi_access || !hwnd) + return false; + + // Operate key F5. + ActivateWnd(pi_access, hwnd); + ClickKey(hwnd, VK_F5); + CHK_RELEASE(pi_access); + return true; +} + +bool CTabImpl::Duplicate(CTabImpl** tab) { + // TODO: Add your implementation code here + return true; +} + +bool CTabImpl::IsAuthDialogVisible() { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (!pi_access || !hwnd) + return false; + + // Activate main window. + ActivateWnd(pi_access, hwnd); + CHK_RELEASE(pi_access); + + // Check for Authentication Window. + pi_access = NULL; + hwnd = GetAuthWnd(&pi_access); + if (!hwnd || !pi_access) { + CHK_RELEASE(pi_access); + return false; + } + return true; +} + +bool CTabImpl::SetAuthDialog(const BSTR user_name, const BSTR password) { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (!pi_access || !hwnd) + return false; + + // Activate main window. + ActivateWnd(pi_access, hwnd); + CHK_RELEASE(pi_access); + + // Get editbox for user name and password. + pi_access = NULL; + hwnd = GetAuthWnd(&pi_access); + if (!hwnd) { + CHK_RELEASE(pi_access); + 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(pi_access); + 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(pi_access); + return false; + } + + // Activate Tab. + SetActiveWindow(GetParent(hwnd)); + // Activate Authentication window. + ActivateWnd(pi_access, 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(pi_access); + return true; +} + +bool CTabImpl::CancelAuthDialog(void) { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (!pi_access || !hwnd) + return false; + + // Activate main window. + ActivateWnd(pi_access, hwnd); + CHK_RELEASE(pi_access); + + // Get editbox for user name which is after password. + pi_access = NULL; + hwnd = GetAuthWnd(&pi_access); + if (!hwnd) { + CHK_RELEASE(pi_access); + return false; + } + + // Get Cancel button. + HWND cancel_button_container = + FindWindowEx(hwnd, 0, CHROME_VIEWS_NATIVE_CTRL_CONTNR, 0); + if (!cancel_button_container) { + CHK_RELEASE(pi_access); + return false; + } + HWND cancel_button = FindWindowEx(cancel_button_container, 0, STD_BUTTON, 0); + if (!cancel_button) { + CHK_RELEASE(pi_access); + return false; + } + + // Click Cancel button. + SetActiveWindow(cancel_button_container); + SetActiveWindow(cancel_button); + SendMessage(cancel_button, BM_CLICK, 0, 0); + + return true; +} + +bool CTabImpl::UseAuthDialog(void) { + IAccessible *pi_access = NULL; + HWND hwnd = GetChromeBrowserWnd(&pi_access); + if (!pi_access || !hwnd) + return false; + + // Activate main window. + ActivateWnd(pi_access, hwnd); + CHK_RELEASE(pi_access); + + // Get editbox for user name which is after password. + pi_access = NULL; + hwnd = GetAuthWnd(&pi_access); + if (!hwnd) { + CHK_RELEASE(pi_access); + return false; + } + + // Get Ok button. + HWND cancel_button_container = + FindWindowEx(hwnd, 0, CHROME_VIEWS_NATIVE_CTRL_CONTNR, 0); + if (!cancel_button_container) { + CHK_RELEASE(pi_access); + 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(pi_access); + return false; + } + HWND ok_button = FindWindowEx(ok_button_container, 0, STD_BUTTON, 0); + if (!ok_button) { + CHK_RELEASE(pi_access); + return false; + } + + // Click Ok. + SetActiveWindow(ok_button_container); + SetActiveWindow(ok_button); + SendMessage(ok_button, BM_CLICK, 0, 0); + + return true; +} + +bool CTabImpl::Activate(void) { + // TODO: Add your implementation code here + + return true; +} + +bool CTabImpl::WaitForTabToBecomeActive(const INT64 interval, + const INT64 timeout) { + // TODO: Add your implementation code here + + return true; +} + +bool CTabImpl::WaitForTabToGetLoaded(const INT64 interval, + const INT64 timeout) { + // TODO: Add your implementation code here + + return true; +} + +bool CTabImpl::IsSSLLockPresent(bool* present) { + // TODO: Add your implementation code here + + return true; +} + +bool CTabImpl::IsSSLSoftError(bool* soft_err) { + // TODO: Add your implementation code here + + return true; +} + +bool CTabImpl::OpenPageCertificateDialog(void) { + // TODO: Add your implementation code here + + return true; +} + +bool CTabImpl::ClosePageCertificateDialog(void) { + // TODO: Add your implementation code here + + return true; +} + +bool CTabImpl::GoBack(void) { + // TODO: Add your implementation code here + + return true; +} + +bool CTabImpl::GoForward(void) { + // TODO: Add your implementation code here + + return true; +} diff --git a/chrome/test/accessibility/tab_impl.h b/chrome/test/accessibility/tab_impl.h new file mode 100644 index 0000000..8bc5773 --- /dev/null +++ b/chrome/test/accessibility/tab_impl.h @@ -0,0 +1,163 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CHROME_TEST_ACCISSIBILITY_TAB_IMPL_H__ +#define CHROME_TEST_ACCISSIBILITY_TAB_IMPL_H__ + +#include "constants.h" + +#include <oleauto.h> + +///////////////////////////////////////////////////////////////////// +// CTabImpl +// 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 CBrowserImpl; + +// Structure storing Tab parameters. +struct ChromeTab { + INT64 index_; + BSTR title_; +}; + +class CTabImpl { + public: + CTabImpl(): tab_(NULL), my_browser_(NULL) { + } + + 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(CTabImpl** 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 index of this tab. + void PutIndex(INT64 index) { + if (index < 0) + return; + if (!tab_) + InitTabData(); + tab_->index_ = index; + } + + // Sets title of this tab. + void PutTitle(BSTR title) { + if (!tab_) + InitTabData(); + tab_->title_ = SysAllocString(title); + } + + // Sets browser to which tab belongs. + bool SetBrowser(CBrowserImpl *browser) { + if (browser) + my_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_; + } + + // TODO + 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. + CBrowserImpl *my_browser_; +}; + + +#endif // CHROME_TEST_ACCISSIBILITY_TAB_IMPL_H__ |