This source file includes following definitions.
- GetAccessibleFromResultVariant
- QueryIAccessible2
- RecursiveFindNodeInAccessibilityTree
- LoadInitialAccessibilityTreeFromHtml
- GetRendererAccessible
- ExecuteScript
- state_
- state_
- state_
- AppendExpectedChild
- CheckAccessible
- SetExpectedValue
- SetExpectedState
- CheckAccessibleName
- CheckAccessibleRole
- CheckIA2Role
- CheckAccessibleValue
- CheckAccessibleState
- CheckAccessibleChildren
- RoleVariantToString
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
- IN_PROC_BROWSER_TEST_F
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/accessibility_browser_test_utils.h"
#include "third_party/iaccessible2/ia2_api_all.h"
#include "third_party/isimpledom/ISimpleDOMNode.h"
#if defined(ARCH_CPU_X86_64)
#define MAYBE(x) DISABLED_##x
#else
#define MAYBE(x) x
#endif
namespace content {
namespace {
base::win::ScopedComPtr<IAccessible> GetAccessibleFromResultVariant(
IAccessible* parent,
VARIANT* var) {
base::win::ScopedComPtr<IAccessible> ptr;
switch (V_VT(var)) {
case VT_DISPATCH: {
IDispatch* dispatch = V_DISPATCH(var);
if (dispatch)
ptr.QueryFrom(dispatch);
break;
}
case VT_I4: {
base::win::ScopedComPtr<IDispatch> dispatch;
HRESULT hr = parent->get_accChild(*var, dispatch.Receive());
EXPECT_TRUE(SUCCEEDED(hr));
if (dispatch)
dispatch.QueryInterface(ptr.Receive());
break;
}
}
return ptr;
}
HRESULT QueryIAccessible2(IAccessible* accessible, IAccessible2** accessible2) {
base::win::ScopedComPtr<IServiceProvider> service_provider;
HRESULT hr = accessible->QueryInterface(service_provider.Receive());
return SUCCEEDED(hr) ?
service_provider->QueryService(IID_IAccessible2, accessible2) : hr;
}
void RecursiveFindNodeInAccessibilityTree(IAccessible* node,
int32 expected_role,
const std::wstring& expected_name,
int32 depth,
bool* found) {
base::win::ScopedBstr name_bstr;
base::win::ScopedVariant childid_self(CHILDID_SELF);
node->get_accName(childid_self, name_bstr.Receive());
std::wstring name(name_bstr, name_bstr.Length());
base::win::ScopedVariant role;
node->get_accRole(childid_self, role.Receive());
ASSERT_EQ(VT_I4, role.type());
for (int i = 0; i < depth; i++)
printf(" ");
printf("role=%d name=%s\n", V_I4(&role), base::WideToUTF8(name).c_str());
if (expected_role == V_I4(&role) && expected_name == name) {
*found = true;
return;
}
LONG child_count = 0;
HRESULT hr = node->get_accChildCount(&child_count);
ASSERT_EQ(S_OK, hr);
scoped_ptr<VARIANT[]> child_array(new VARIANT[child_count]);
LONG obtained_count = 0;
hr = AccessibleChildren(
node, 0, child_count, child_array.get(), &obtained_count);
ASSERT_EQ(S_OK, hr);
ASSERT_EQ(child_count, obtained_count);
for (int index = 0; index < obtained_count; index++) {
base::win::ScopedComPtr<IAccessible> child_accessible(
GetAccessibleFromResultVariant(node, &child_array.get()[index]));
if (child_accessible) {
RecursiveFindNodeInAccessibilityTree(
child_accessible.get(), expected_role, expected_name, depth + 1,
found);
if (*found)
return;
}
}
}
class AccessibilityWinBrowserTest : public ContentBrowserTest {
public:
AccessibilityWinBrowserTest();
virtual ~AccessibilityWinBrowserTest();
protected:
void LoadInitialAccessibilityTreeFromHtml(const std::string& html);
IAccessible* GetRendererAccessible();
void ExecuteScript(const std::wstring& script);
private:
DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest);
};
AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() {
}
AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() {
}
void AccessibilityWinBrowserTest::LoadInitialAccessibilityTreeFromHtml(
const std::string& html) {
AccessibilityNotificationWaiter waiter(
shell(), AccessibilityModeComplete,
ui::AX_EVENT_LOAD_COMPLETE);
GURL html_data_url("data:text/html," + html);
NavigateToURL(shell(), html_data_url);
waiter.WaitForNotification();
}
IAccessible* AccessibilityWinBrowserTest::GetRendererAccessible() {
HWND hwnd_render_widget_host_view =
shell()->web_contents()->GetRenderWidgetHostView()->GetNativeView();
const int32 kIdCustom = 1;
SendMessage(
hwnd_render_widget_host_view, WM_GETOBJECT, OBJID_CLIENT, kIdCustom);
IAccessible* accessible;
HRESULT hr = AccessibleObjectFromWindow(
hwnd_render_widget_host_view, OBJID_CLIENT,
IID_IAccessible, reinterpret_cast<void**>(&accessible));
EXPECT_EQ(S_OK, hr);
EXPECT_NE(accessible, reinterpret_cast<IAccessible*>(NULL));
return accessible;
}
void AccessibilityWinBrowserTest::ExecuteScript(const std::wstring& script) {
shell()->web_contents()->GetMainFrame()->ExecuteJavaScript(script);
}
class AccessibleChecker {
public:
AccessibleChecker(const std::wstring& expected_name,
int32 expected_role,
const std::wstring& expected_value);
AccessibleChecker(const std::wstring& expected_name,
int32 expected_role,
int32 expected_ia2_role,
const std::wstring& expected_value);
AccessibleChecker(const std::wstring& expected_name,
const std::wstring& expected_role,
int32 expected_ia2_role,
const std::wstring& expected_value);
void AppendExpectedChild(AccessibleChecker* expected_child);
void CheckAccessible(IAccessible* accessible);
void SetExpectedValue(const std::wstring& expected_value);
void SetExpectedState(LONG expected_state);
private:
typedef std::vector<AccessibleChecker*> AccessibleCheckerVector;
void CheckAccessibleName(IAccessible* accessible);
void CheckAccessibleRole(IAccessible* accessible);
void CheckIA2Role(IAccessible* accessible);
void CheckAccessibleValue(IAccessible* accessible);
void CheckAccessibleState(IAccessible* accessible);
void CheckAccessibleChildren(IAccessible* accessible);
base::string16 RoleVariantToString(const base::win::ScopedVariant& role);
std::wstring name_;
base::win::ScopedVariant role_;
int32 ia2_role_;
std::wstring value_;
LONG state_;
AccessibleCheckerVector children_;
};
AccessibleChecker::AccessibleChecker(const std::wstring& expected_name,
int32 expected_role,
const std::wstring& expected_value)
: name_(expected_name),
role_(expected_role),
ia2_role_(expected_role),
value_(expected_value),
state_(-1) {
}
AccessibleChecker::AccessibleChecker(const std::wstring& expected_name,
int32 expected_role,
int32 expected_ia2_role,
const std::wstring& expected_value)
: name_(expected_name),
role_(expected_role),
ia2_role_(expected_ia2_role),
value_(expected_value),
state_(-1) {
}
AccessibleChecker::AccessibleChecker(const std::wstring& expected_name,
const std::wstring& expected_role,
int32 expected_ia2_role,
const std::wstring& expected_value)
: name_(expected_name),
role_(expected_role.c_str()),
ia2_role_(expected_ia2_role),
value_(expected_value),
state_(-1) {
}
void AccessibleChecker::AppendExpectedChild(
AccessibleChecker* expected_child) {
children_.push_back(expected_child);
}
void AccessibleChecker::CheckAccessible(IAccessible* accessible) {
SCOPED_TRACE("while checking " +
base::UTF16ToUTF8(RoleVariantToString(role_)));
CheckAccessibleName(accessible);
CheckAccessibleRole(accessible);
CheckIA2Role(accessible);
CheckAccessibleValue(accessible);
CheckAccessibleState(accessible);
CheckAccessibleChildren(accessible);
}
void AccessibleChecker::SetExpectedValue(const std::wstring& expected_value) {
value_ = expected_value;
}
void AccessibleChecker::SetExpectedState(LONG expected_state) {
state_ = expected_state;
}
void AccessibleChecker::CheckAccessibleName(IAccessible* accessible) {
base::win::ScopedBstr name;
base::win::ScopedVariant childid_self(CHILDID_SELF);
HRESULT hr = accessible->get_accName(childid_self, name.Receive());
if (name_.empty()) {
EXPECT_EQ(S_FALSE, hr);
} else {
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(name_, std::wstring(name, name.Length()));
}
}
void AccessibleChecker::CheckAccessibleRole(IAccessible* accessible) {
base::win::ScopedVariant role;
base::win::ScopedVariant childid_self(CHILDID_SELF);
HRESULT hr = accessible->get_accRole(childid_self, role.Receive());
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(0, role_.Compare(role))
<< "Expected role: " << RoleVariantToString(role_)
<< "\nGot role: " << RoleVariantToString(role);
}
void AccessibleChecker::CheckIA2Role(IAccessible* accessible) {
base::win::ScopedComPtr<IAccessible2> accessible2;
HRESULT hr = QueryIAccessible2(accessible, accessible2.Receive());
ASSERT_EQ(S_OK, hr);
long ia2_role = 0;
hr = accessible2->role(&ia2_role);
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(ia2_role_, ia2_role)
<< "Expected ia2 role: " << IAccessible2RoleToString(ia2_role_)
<< "\nGot ia2 role: " << IAccessible2RoleToString(ia2_role);
}
void AccessibleChecker::CheckAccessibleValue(IAccessible* accessible) {
base::win::ScopedVariant role;
base::win::ScopedVariant childid_self(CHILDID_SELF);
HRESULT hr = accessible->get_accRole(childid_self, role.Receive());
ASSERT_EQ(S_OK, hr);
if (role.type() == VT_I4 && V_I4(&role) == ROLE_SYSTEM_DOCUMENT)
return;
base::win::ScopedBstr value;
hr = accessible->get_accValue(childid_self, value.Receive());
EXPECT_EQ(S_OK, hr);
EXPECT_EQ(value_, std::wstring(value, value.Length()));
}
void AccessibleChecker::CheckAccessibleState(IAccessible* accessible) {
if (state_ < 0)
return;
base::win::ScopedVariant state;
base::win::ScopedVariant childid_self(CHILDID_SELF);
HRESULT hr = accessible->get_accState(childid_self, state.Receive());
EXPECT_EQ(S_OK, hr);
ASSERT_EQ(VT_I4, state.type());
LONG obj_state = V_I4(&state);
obj_state &= ~(STATE_SYSTEM_OFFSCREEN | STATE_SYSTEM_HOTTRACKED);
EXPECT_EQ(state_, obj_state)
<< "Expected state: " << IAccessibleStateToString(state_)
<< "\nGot state: " << IAccessibleStateToString(obj_state);
}
void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {
LONG child_count = 0;
HRESULT hr = parent->get_accChildCount(&child_count);
EXPECT_EQ(S_OK, hr);
ASSERT_EQ(child_count, children_.size());
scoped_ptr<VARIANT[]> child_array(new VARIANT[child_count]);
LONG obtained_count = 0;
hr = AccessibleChildren(parent, 0, child_count,
child_array.get(), &obtained_count);
ASSERT_EQ(S_OK, hr);
ASSERT_EQ(child_count, obtained_count);
VARIANT* child = child_array.get();
for (AccessibleCheckerVector::iterator child_checker = children_.begin();
child_checker != children_.end();
++child_checker, ++child) {
base::win::ScopedComPtr<IAccessible> child_accessible(
GetAccessibleFromResultVariant(parent, child));
ASSERT_TRUE(child_accessible.get());
(*child_checker)->CheckAccessible(child_accessible);
}
}
base::string16 AccessibleChecker::RoleVariantToString(
const base::win::ScopedVariant& role) {
if (role.type() == VT_I4)
return IAccessibleRoleToString(V_I4(&role));
if (role.type() == VT_BSTR)
return base::string16(V_BSTR(&role), SysStringLen(V_BSTR(&role)));
return base::string16();
}
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(TestBusyAccessibilityTree)) {
NavigateToURL(shell(), GURL(kAboutBlankURL));
AccessibleChecker document1_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
document1_checker.SetExpectedState(
STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED |
STATE_SYSTEM_BUSY);
document1_checker.CheckAccessible(GetRendererAccessible());
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
DISABLED_TestRendererAccessibilityTree) {
LoadInitialAccessibilityTreeFromHtml(
"<html><head><title>Accessibility Win Test</title></head>"
"<body><input type='button' value='push' /><input type='checkbox' />"
"</body></html>");
AccessibleChecker button_checker(L"push", ROLE_SYSTEM_PUSHBUTTON,
std::wstring());
AccessibleChecker checkbox_checker(std::wstring(), ROLE_SYSTEM_CHECKBUTTON,
std::wstring());
AccessibleChecker body_checker(std::wstring(), L"body", IA2_ROLE_SECTION,
std::wstring());
AccessibleChecker document2_checker(L"Accessibility Win Test",
ROLE_SYSTEM_DOCUMENT, std::wstring());
body_checker.AppendExpectedChild(&button_checker);
body_checker.AppendExpectedChild(&checkbox_checker);
document2_checker.AppendExpectedChild(&body_checker);
document2_checker.CheckAccessible(GetRendererAccessible());
base::win::ScopedComPtr<IAccessible> document_accessible(
GetRendererAccessible());
ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
base::win::ScopedComPtr<IDispatch> parent_dispatch;
HRESULT hr = document_accessible->get_accParent(parent_dispatch.Receive());
EXPECT_EQ(S_OK, hr);
EXPECT_NE(parent_dispatch, reinterpret_cast<IDispatch*>(NULL));
NavigateToURL(shell(), GURL(kAboutBlankURL));
base::win::ScopedBstr name;
base::win::ScopedVariant childid_self(CHILDID_SELF);
hr = document_accessible->get_accName(childid_self, name.Receive());
ASSERT_EQ(E_FAIL, hr);
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
DISABLED_TestNotificationActiveDescendantChanged) {
LoadInitialAccessibilityTreeFromHtml(
"<ul tabindex='-1' role='radiogroup' aria-label='ul'>"
"<li id='li'>li</li></ul>");
AccessibleChecker list_marker_checker(L"\x2022", ROLE_SYSTEM_TEXT,
std::wstring());
AccessibleChecker static_text_checker(L"li", ROLE_SYSTEM_TEXT,
std::wstring());
AccessibleChecker list_item_checker(std::wstring(), ROLE_SYSTEM_LISTITEM,
std::wstring());
list_item_checker.SetExpectedState(STATE_SYSTEM_READONLY);
AccessibleChecker radio_group_checker(L"ul", ROLE_SYSTEM_GROUPING,
IA2_ROLE_SECTION, std::wstring());
radio_group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
list_item_checker.AppendExpectedChild(&list_marker_checker);
list_item_checker.AppendExpectedChild(&static_text_checker);
radio_group_checker.AppendExpectedChild(&list_item_checker);
document_checker.AppendExpectedChild(&radio_group_checker);
document_checker.CheckAccessible(GetRendererAccessible());
scoped_ptr<AccessibilityNotificationWaiter> waiter(
new AccessibilityNotificationWaiter(
shell(), AccessibilityModeComplete,
ui::AX_EVENT_FOCUS));
ExecuteScript(L"document.body.children[0].focus()");
waiter->WaitForNotification();
radio_group_checker.SetExpectedState(
STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED);
document_checker.CheckAccessible(GetRendererAccessible());
waiter.reset(new AccessibilityNotificationWaiter(
shell(), AccessibilityModeComplete,
ui::AX_EVENT_FOCUS));
ExecuteScript(
L"document.body.children[0].setAttribute('aria-activedescendant', 'li')");
waiter->WaitForNotification();
list_item_checker.SetExpectedState(
STATE_SYSTEM_READONLY | STATE_SYSTEM_FOCUSED);
radio_group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
document_checker.CheckAccessible(GetRendererAccessible());
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(TestNotificationCheckedStateChanged)) {
LoadInitialAccessibilityTreeFromHtml(
"<body><input type='checkbox' /></body>");
AccessibleChecker checkbox_checker(std::wstring(), ROLE_SYSTEM_CHECKBUTTON,
std::wstring());
checkbox_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
AccessibleChecker body_checker(std::wstring(), L"body", IA2_ROLE_SECTION,
std::wstring());
AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
body_checker.AppendExpectedChild(&checkbox_checker);
document_checker.AppendExpectedChild(&body_checker);
document_checker.CheckAccessible(GetRendererAccessible());
scoped_ptr<AccessibilityNotificationWaiter> waiter(
new AccessibilityNotificationWaiter(
shell(), AccessibilityModeComplete,
ui::AX_EVENT_CHECKED_STATE_CHANGED));
ExecuteScript(L"document.body.children[0].checked=true");
waiter->WaitForNotification();
checkbox_checker.SetExpectedState(
STATE_SYSTEM_CHECKED | STATE_SYSTEM_FOCUSABLE);
document_checker.CheckAccessible(GetRendererAccessible());
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(TestNotificationChildrenChanged)) {
LoadInitialAccessibilityTreeFromHtml("<body role=group></body>");
AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
std::wstring());
AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
document_checker.AppendExpectedChild(&group_checker);
document_checker.CheckAccessible(GetRendererAccessible());
scoped_ptr<AccessibilityNotificationWaiter> waiter(
new AccessibilityNotificationWaiter(
shell(),
AccessibilityModeComplete,
ui::AX_EVENT_CHILDREN_CHANGED));
ExecuteScript(L"document.body.innerHTML='<b>new text</b>'");
waiter->WaitForNotification();
AccessibleChecker text_checker(L"new text", ROLE_SYSTEM_TEXT, std::wstring());
group_checker.AppendExpectedChild(&text_checker);
document_checker.CheckAccessible(GetRendererAccessible());
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(TestNotificationChildrenChanged2)) {
LoadInitialAccessibilityTreeFromHtml(
"<div role=group style='visibility: hidden'>text</div>");
AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
document_checker.CheckAccessible(GetRendererAccessible());
scoped_ptr<AccessibilityNotificationWaiter> waiter(
new AccessibilityNotificationWaiter(
shell(), AccessibilityModeComplete,
ui::AX_EVENT_CHILDREN_CHANGED));
ExecuteScript(L"document.body.children[0].style.visibility='visible'");
waiter->WaitForNotification();
AccessibleChecker static_text_checker(L"text", ROLE_SYSTEM_TEXT,
std::wstring());
AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
std::wstring());
document_checker.AppendExpectedChild(&group_checker);
group_checker.AppendExpectedChild(&static_text_checker);
document_checker.CheckAccessible(GetRendererAccessible());
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(TestNotificationFocusChanged)) {
LoadInitialAccessibilityTreeFromHtml("<div role=group tabindex='-1'></div>");
SCOPED_TRACE("Check initial tree");
AccessibleChecker group_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
std::wstring());
group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
document_checker.AppendExpectedChild(&group_checker);
document_checker.CheckAccessible(GetRendererAccessible());
scoped_ptr<AccessibilityNotificationWaiter> waiter(
new AccessibilityNotificationWaiter(
shell(), AccessibilityModeComplete,
ui::AX_EVENT_FOCUS));
ExecuteScript(L"document.body.children[0].focus()");
waiter->WaitForNotification();
SCOPED_TRACE("Check updated tree after focusing div");
group_checker.SetExpectedState(
STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_FOCUSED);
document_checker.CheckAccessible(GetRendererAccessible());
waiter.reset(
new AccessibilityNotificationWaiter(
shell(), AccessibilityModeComplete,
ui::AX_EVENT_BLUR));
base::win::ScopedComPtr<IAccessible> document_accessible(
GetRendererAccessible());
ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
base::win::ScopedVariant childid_self(CHILDID_SELF);
HRESULT hr = document_accessible->accSelect(SELFLAG_TAKEFOCUS, childid_self);
ASSERT_EQ(S_OK, hr);
waiter->WaitForNotification();
SCOPED_TRACE("Check updated tree after focusing document again");
group_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
document_checker.CheckAccessible(GetRendererAccessible());
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(TestNotificationValueChanged)) {
LoadInitialAccessibilityTreeFromHtml(
"<body><input type='text' value='old value'/></body>");
AccessibleChecker text_field_checker(std::wstring(), ROLE_SYSTEM_TEXT,
L"old value");
text_field_checker.SetExpectedState(STATE_SYSTEM_FOCUSABLE);
AccessibleChecker body_checker(std::wstring(), L"body", IA2_ROLE_SECTION,
std::wstring());
AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
body_checker.AppendExpectedChild(&text_field_checker);
document_checker.AppendExpectedChild(&body_checker);
document_checker.CheckAccessible(GetRendererAccessible());
scoped_ptr<AccessibilityNotificationWaiter> waiter(
new AccessibilityNotificationWaiter(
shell(), AccessibilityModeComplete,
ui::AX_EVENT_VALUE_CHANGE));
ExecuteScript(L"document.body.children[0].value='new value'");
waiter->WaitForNotification();
text_field_checker.SetExpectedValue(L"new value");
document_checker.CheckAccessible(GetRendererAccessible());
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(ContainsRendererAccessibilityTree)) {
LoadInitialAccessibilityTreeFromHtml(
"<html><head><title>MyDocument</title></head>"
"<body>Content</body></html>");
HWND browser_hwnd = shell()->window();
base::win::ScopedComPtr<IAccessible> browser_accessible;
HRESULT hr = AccessibleObjectFromWindow(
browser_hwnd,
OBJID_WINDOW,
IID_IAccessible,
reinterpret_cast<void**>(browser_accessible.Receive()));
ASSERT_EQ(S_OK, hr);
bool found = false;
RecursiveFindNodeInAccessibilityTree(
browser_accessible.get(), ROLE_SYSTEM_DOCUMENT, L"MyDocument", 0, &found);
ASSERT_EQ(found, true);
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
DISABLED_TestToggleButtonRoleAndStates) {
AccessibleChecker* button_checker;
std::string button_html("data:text/html,");
AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
AccessibleChecker body_checker(std::wstring(), L"body", IA2_ROLE_SECTION,
std::wstring());
document_checker.AppendExpectedChild(&body_checker);
#define ADD_BUTTON(html, ia2_role, state) \
button_html += html; \
button_checker = new AccessibleChecker(L"x", ROLE_SYSTEM_PUSHBUTTON, \
ia2_role, std::wstring()); \
button_checker->SetExpectedState(state); \
body_checker.AppendExpectedChild(button_checker)
ADD_BUTTON("<span role='button' aria-pressed='false'>x</span>",
IA2_ROLE_TOGGLE_BUTTON, 0);
ADD_BUTTON("<span role='button' aria-pressed='true'>x</span>",
IA2_ROLE_TOGGLE_BUTTON, STATE_SYSTEM_PRESSED);
ADD_BUTTON("<span role='button' aria-pressed='mixed'>x</span>",
IA2_ROLE_TOGGLE_BUTTON, STATE_SYSTEM_MIXED);
ADD_BUTTON("<span role='button' aria-pressed='xyz'>x</span>",
IA2_ROLE_TOGGLE_BUTTON, 0);
ADD_BUTTON("<span role='button' aria-pressed=''>x</span>",
ROLE_SYSTEM_PUSHBUTTON, 0);
ADD_BUTTON("<span role='button' aria-pressed>x</span>",
ROLE_SYSTEM_PUSHBUTTON, 0);
ADD_BUTTON("<span role='button' aria-pressed='undefined'>x</span>",
ROLE_SYSTEM_PUSHBUTTON, 0);
ADD_BUTTON("<span role='button'>x</span>", ROLE_SYSTEM_PUSHBUTTON, 0);
ADD_BUTTON("<input type='button' aria-pressed='true' value='x'/>",
IA2_ROLE_TOGGLE_BUTTON, STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_PRESSED);
ADD_BUTTON("<input type='button' aria-pressed='false' value='x'/>",
IA2_ROLE_TOGGLE_BUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<input type='button' aria-pressed='mixed' value='x'>",
IA2_ROLE_TOGGLE_BUTTON, STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_MIXED);
ADD_BUTTON("<input type='button' aria-pressed='xyz' value='x'/>",
IA2_ROLE_TOGGLE_BUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<input type='button' aria-pressed='' value='x'/>",
ROLE_SYSTEM_PUSHBUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<input type='button' aria-pressed value='x'>",
ROLE_SYSTEM_PUSHBUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<input type='button' aria-pressed='undefined' value='x'>",
ROLE_SYSTEM_PUSHBUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<input type='button' value='x'>",
ROLE_SYSTEM_PUSHBUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<button aria-pressed='true'>x</button>",
IA2_ROLE_TOGGLE_BUTTON, STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_PRESSED);
ADD_BUTTON("<button aria-pressed='false'>x</button>",
IA2_ROLE_TOGGLE_BUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<button aria-pressed='mixed'>x</button>", IA2_ROLE_TOGGLE_BUTTON,
STATE_SYSTEM_FOCUSABLE | STATE_SYSTEM_MIXED);
ADD_BUTTON("<button aria-pressed='xyz'>x</button>", IA2_ROLE_TOGGLE_BUTTON,
STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<button aria-pressed=''>x</button>",
ROLE_SYSTEM_PUSHBUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<button aria-pressed>x</button>",
ROLE_SYSTEM_PUSHBUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<button aria-pressed='undefined'>x</button>",
ROLE_SYSTEM_PUSHBUTTON, STATE_SYSTEM_FOCUSABLE);
ADD_BUTTON("<button>x</button>", ROLE_SYSTEM_PUSHBUTTON,
STATE_SYSTEM_FOCUSABLE);
#undef ADD_BUTTON
LoadInitialAccessibilityTreeFromHtml(button_html);
document_checker.CheckAccessible(GetRendererAccessible());
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
MAYBE(SupportsISimpleDOM)) {
LoadInitialAccessibilityTreeFromHtml(
"<body><input type='checkbox' /></body>");
base::win::ScopedComPtr<IAccessible> document_accessible(
GetRendererAccessible());
ASSERT_NE(document_accessible.get(), reinterpret_cast<IAccessible*>(NULL));
base::win::ScopedComPtr<IServiceProvider> service_provider;
HRESULT hr = static_cast<IAccessible*>(document_accessible)->QueryInterface(
service_provider.Receive());
ASSERT_EQ(S_OK, hr);
const GUID refguid = {0x0c539790, 0x12e4, 0x11cf,
0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8};
base::win::ScopedComPtr<ISimpleDOMNode> document_isimpledomnode;
hr = static_cast<IServiceProvider *>(service_provider)->QueryService(
refguid, IID_ISimpleDOMNode,
reinterpret_cast<void**>(document_isimpledomnode.Receive()));
ASSERT_EQ(S_OK, hr);
base::win::ScopedBstr node_name;
short name_space_id;
base::win::ScopedBstr node_value;
unsigned int num_children;
unsigned int unique_id;
unsigned short node_type;
hr = document_isimpledomnode->get_nodeInfo(
node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
&unique_id, &node_type);
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(NODETYPE_DOCUMENT, node_type);
EXPECT_EQ(1, num_children);
node_name.Reset();
node_value.Reset();
base::win::ScopedComPtr<ISimpleDOMNode> body_isimpledomnode;
hr = document_isimpledomnode->get_firstChild(
body_isimpledomnode.Receive());
ASSERT_EQ(S_OK, hr);
hr = body_isimpledomnode->get_nodeInfo(
node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
&unique_id, &node_type);
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(L"body", std::wstring(node_name, node_name.Length()));
EXPECT_EQ(NODETYPE_ELEMENT, node_type);
EXPECT_EQ(1, num_children);
node_name.Reset();
node_value.Reset();
base::win::ScopedComPtr<ISimpleDOMNode> checkbox_isimpledomnode;
hr = body_isimpledomnode->get_firstChild(
checkbox_isimpledomnode.Receive());
ASSERT_EQ(S_OK, hr);
hr = checkbox_isimpledomnode->get_nodeInfo(
node_name.Receive(), &name_space_id, node_value.Receive(), &num_children,
&unique_id, &node_type);
ASSERT_EQ(S_OK, hr);
EXPECT_EQ(L"input", std::wstring(node_name, node_name.Length()));
EXPECT_EQ(NODETYPE_ELEMENT, node_type);
EXPECT_EQ(0, num_children);
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, MAYBE(TestRoleGroup)) {
LoadInitialAccessibilityTreeFromHtml(
"<fieldset></fieldset><div role=group></div>");
AccessibleChecker grouping1_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
std::wstring());
AccessibleChecker grouping2_checker(std::wstring(), ROLE_SYSTEM_GROUPING,
std::wstring());
AccessibleChecker document_checker(std::wstring(), ROLE_SYSTEM_DOCUMENT,
std::wstring());
document_checker.AppendExpectedChild(&grouping1_checker);
document_checker.AppendExpectedChild(&grouping2_checker);
document_checker.CheckAccessible(GetRendererAccessible());
}
}