From aef706dd457876220036e7ca2b28ea86aa963dd5 Mon Sep 17 00:00:00 2001 From: "dmazzoni@chromium.org" Date: Wed, 1 Aug 2012 22:07:07 +0000 Subject: [PATCH] Allow filters in accessibility tests to specify which attributes to check. With this change, a DumpAccessibilityTree test can specify filters to control which attributes are printed. This keeps each test expectation file small and readable, while making it easy to test for all sorts of attributes, including obscure ones. Each platform will have a few attributes that print by default, like the role and name. HTML files add rules of this form to override the defaults: @MAC-DENY:subrole* @MAC-DENY:value* @MAC-ALLOW:description* You can also specify @MAC-ALLOW:* or @WIN-ALLOW:* if you want to dump everything - helpful during development sometimes. BUG=124314 Review URL: https://chromiumcodereview.appspot.com/10662003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149510 0039d316-1c4b-4281-b951-d872f2087c98 --- .../accessibility/browser_accessibility_win.h | 11 +- .../dump_accessibility_tree_browsertest.cc | 262 +++++++++++------- .../dump_accessibility_tree_helper.cc | 47 ++++ .../dump_accessibility_tree_helper.h | 35 +++ .../dump_accessibility_tree_helper_mac.mm | 49 ++-- .../dump_accessibility_tree_helper_win.cc | 67 +++-- content/common/accessibility_node_data.cc | 1 + .../test/accessibility_test_utils_win.h | 6 + content/test/accessibility_test_utils_win.cc | 46 ++- .../data/accessibility/a-expected-win.txt | 8 +- content/test/data/accessibility/a.html | 3 + .../aria-application-expected-mac.txt | 2 +- .../aria-application-expected-win.txt | 4 +- .../data/accessibility/aria-application.html | 3 + ...ntenteditable-descendants-expected-win.txt | 42 +-- .../contenteditable-descendants.html | 5 + .../accessibility/footer-expected-mac.txt | 4 +- .../accessibility/footer-expected-win.txt | 6 +- content/test/data/accessibility/footer.html | 3 + .../list-markers-expected-mac.txt | 34 +-- .../data/accessibility/ul-expected-mac.txt | 22 +- .../data/accessibility/ul-expected-win.txt | 22 +- 22 files changed, 448 insertions(+), 234 deletions(-) diff --git a/content/browser/accessibility/browser_accessibility_win.h b/content/browser/accessibility/browser_accessibility_win.h index 03f70a75aac8c6..c4385d083e4e66 100644 --- a/content/browser/accessibility/browser_accessibility_win.h +++ b/content/browser/accessibility/browser_accessibility_win.h @@ -747,9 +747,14 @@ BrowserAccessibilityWin REFIID iid, void** object); - // Accessors to IA2 role and state. - int32 ia2_role() { return ia2_role_; } - int32 ia2_state() { return ia2_state_; } + // Accessors. + int32 ia_role() const { return ia_role_; } + int32 ia_state() const { return ia_state_; } + int32 ia2_role() const { return ia2_role_; } + int32 ia2_state() const { return ia2_state_; } + const std::vector& ia2_attributes() const { + return ia2_attributes_;\ + } private: // Add one to the reference count and return the same object. Always diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index c8e508ce5046ae..7a3862044358c6 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc @@ -2,11 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include #include #include #include "base/logging.h" #include "base/path_service.h" +#include "base/string_split.h" #include "base/string_util.h" #include "base/string16.h" #include "base/utf_string_conversions.h" @@ -26,8 +28,6 @@ #include "testing/gtest/include/gtest/gtest.h" namespace { -// Required to enter html content into a url. - static const std::string kUrlPreamble = "data:text/html,\n"; static const char kCommentToken = '#'; static const char* kMarkSkipFile = "# DiffLines(std::vector& expected_lines, - std::vector& actual_lines) { + std::vector& actual_lines) { int actual_lines_count = actual_lines.size(); int expected_lines_count = expected_lines.size(); std::vector diff_lines; @@ -74,16 +74,42 @@ class DumpAccessibilityTreeTest : public ContentBrowserTest { return diff_lines; } + void AddDefaultFilters(std::set* allow_filters, + std::set* deny_filters) { + allow_filters->insert(ASCIIToUTF16("FOCUSABLE")); + allow_filters->insert(ASCIIToUTF16("READONLY")); + } + + void ParseFilters(const std::string& test_html, + std::set* allow_filters, + std::set* deny_filters) { + std::vector lines; + base::SplitString(test_html, '\n', &lines); + for (std::vector::const_iterator iter = lines.begin(); + iter != lines.end(); + ++iter) { + const std::string& line = *iter; + const std::string& allow_str = helper_.GetAllowString(); + const std::string& deny_str = helper_.GetDenyString(); + if (StartsWithASCII(line, allow_str, true)) + allow_filters->insert(UTF8ToUTF16(line.substr(allow_str.size()))); + else if (StartsWithASCII(line, deny_str, true)) + deny_filters->insert(UTF8ToUTF16(line.substr(deny_str.size()))); + } + } + + void RunTest(const FilePath::CharType* file_path); + DumpAccessibilityTreeHelper helper_; }; -IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, - DISABLED_PlatformTreeDifferenceTest) { +void DumpAccessibilityTreeTest::RunTest(const FilePath::CharType* file_path) { + NavigateToURL(shell(), GURL("about:blank")); RenderWidgetHostViewPort* host_view = static_cast( shell()->web_contents()->GetRenderWidgetHostView()); - RenderWidgetHost* host = host_view->GetRenderWidgetHost(); - RenderViewHostImpl* view_host = - static_cast(RenderWidgetHostImpl::From(host)); + RenderWidgetHostImpl* host = + RenderWidgetHostImpl::From(host_view->GetRenderWidgetHost()); + RenderViewHostImpl* view_host = static_cast(host); view_host->set_save_accessibility_tree_for_testing(true); view_host->SetAccessibilityMode(AccessibilityModeComplete); @@ -94,107 +120,141 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, EXPECT_TRUE(file_util::PathExists(test_path)) << test_path.LossyDisplayName(); + FilePath html_file = test_path.Append(FilePath(file_path)); // Output the test path to help anyone who encounters a failure and needs // to know where to look. - printf("Path to test files: %s\n", test_path.MaybeAsASCII().c_str()); - - // Grab all HTML files. - file_util::FileEnumerator file_enumerator(test_path, - false, - file_util::FileEnumerator::FILES, - FILE_PATH_LITERAL("*.html")); - - // TODO(dtseng): Make each of these a gtest with script. - FilePath html_file(file_enumerator.Next()); - ASSERT_FALSE(html_file.empty()); - do { - std::string html_contents; - file_util::ReadFileToString(html_file, &html_contents); - - // Read the expected file. - std::string expected_contents_raw; - FilePath expected_file = - FilePath(html_file.RemoveExtension().value() + - helper_.GetExpectedFileSuffix()); - file_util::ReadFileToString( - expected_file, - &expected_contents_raw); - - // Tolerate Windows-style line endings (\r\n) in the expected file: - // normalize by deleting all \r from the file (if any) to leave only \n. - std::string expected_contents; - RemoveChars(expected_contents_raw, "\r", &expected_contents); - - if (!expected_contents.compare(0, strlen(kMarkSkipFile), kMarkSkipFile)) { - printf("Skipping %s\n", html_file.BaseName().MaybeAsASCII().c_str()); - continue; - } + printf("Testing: %s\n", html_file.MaybeAsASCII().c_str()); + + std::string html_contents; + file_util::ReadFileToString(html_file, &html_contents); + + // Parse filters in the test file. + std::set allow_filters; + std::set deny_filters; + AddDefaultFilters(&allow_filters, &deny_filters); + ParseFilters(html_contents, &allow_filters, &deny_filters); + helper_.SetFilters(allow_filters, deny_filters); - printf("Testing %s\n", html_file.BaseName().MaybeAsASCII().c_str()); - - // Load the page. - WindowedNotificationObserver tree_updated_observer( - NOTIFICATION_RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED, - NotificationService::AllSources()); - string16 html_contents16; - html_contents16 = UTF8ToUTF16(html_contents); - GURL url(UTF8ToUTF16(kUrlPreamble) + html_contents16); - NavigateToURL(shell(), url); - - // Wait for the tree. - tree_updated_observer.Wait(); - - // Perform a diff (or write the initial baseline). - string16 actual_contents_utf16; - helper_.DumpAccessibilityTree( - host_view->GetBrowserAccessibilityManager()->GetRoot(), - &actual_contents_utf16); - std::string actual_contents = UTF16ToUTF8(actual_contents_utf16); - std::vector actual_lines, expected_lines; - Tokenize(actual_contents, "\n", &actual_lines); - Tokenize(expected_contents, "\n", &expected_lines); - // Marking the end of the file with a line of text ensures that - // file length differences are found. - expected_lines.push_back(kMarkEndOfFile); - actual_lines.push_back(kMarkEndOfFile); - - std::vector diff_lines = DiffLines(expected_lines, actual_lines); - bool is_different = diff_lines.size() > 0; - EXPECT_FALSE(is_different); - if (is_different) { - // Mark the expected lines which did not match actual output with a *. - printf("* Line Expected\n"); - printf("- ---- --------\n"); - for (int line = 0, diff_index = 0; - line < static_cast(expected_lines.size()); - ++line) { - bool is_diff = false; - if (diff_index < static_cast(diff_lines.size()) && - diff_lines[diff_index] == line) { - is_diff = true; - ++ diff_index; - } - printf("%1s %4d %s\n", is_diff? kSignalDiff : "", line + 1, - expected_lines[line].c_str()); + // Read the expected file. + std::string expected_contents_raw; + FilePath expected_file = + FilePath(html_file.RemoveExtension().value() + + helper_.GetExpectedFileSuffix()); + file_util::ReadFileToString( + expected_file, + &expected_contents_raw); + + // Tolerate Windows-style line endings (\r\n) in the expected file: + // normalize by deleting all \r from the file (if any) to leave only \n. + std::string expected_contents; + RemoveChars(expected_contents_raw, "\r", &expected_contents); + + if (!expected_contents.compare(0, strlen(kMarkSkipFile), kMarkSkipFile)) { + printf("Skipping this test on this platform.\n"); + return; + } + + // Load the page. + WindowedNotificationObserver tree_updated_observer( + NOTIFICATION_RENDER_VIEW_HOST_ACCESSIBILITY_TREE_UPDATED, + NotificationService::AllSources()); + string16 html_contents16; + html_contents16 = UTF8ToUTF16(html_contents); + GURL url = GetTestUrl("accessibility", + html_file.BaseName().MaybeAsASCII().c_str()); + NavigateToURL(shell(), url); + + // Wait for the tree. + tree_updated_observer.Wait(); + + // Perform a diff (or write the initial baseline). + string16 actual_contents_utf16; + helper_.DumpAccessibilityTree( + host_view->GetBrowserAccessibilityManager()->GetRoot(), + &actual_contents_utf16); + std::string actual_contents = UTF16ToUTF8(actual_contents_utf16); + std::vector actual_lines, expected_lines; + Tokenize(actual_contents, "\n", &actual_lines); + Tokenize(expected_contents, "\n", &expected_lines); + // Marking the end of the file with a line of text ensures that + // file length differences are found. + expected_lines.push_back(kMarkEndOfFile); + actual_lines.push_back(kMarkEndOfFile); + + std::vector diff_lines = DiffLines(expected_lines, actual_lines); + bool is_different = diff_lines.size() > 0; + EXPECT_FALSE(is_different); + if (is_different) { + // Mark the expected lines which did not match actual output with a *. + printf("* Line Expected\n"); + printf("- ---- --------\n"); + for (int line = 0, diff_index = 0; + line < static_cast(expected_lines.size()); + ++line) { + bool is_diff = false; + if (diff_index < static_cast(diff_lines.size()) && + diff_lines[diff_index] == line) { + is_diff = true; + ++ diff_index; } - printf("\nActual\n"); - printf("------\n"); - printf("%s\n", actual_contents.c_str()); + printf("%1s %4d %s\n", is_diff? kSignalDiff : "", line + 1, + expected_lines[line].c_str()); } + printf("\nActual\n"); + printf("------\n"); + printf("%s\n", actual_contents.c_str()); + } - if (!file_util::PathExists(expected_file)) { - FilePath actual_file = - FilePath(html_file.RemoveExtension().value() + - helper_.GetActualFileSuffix()); + if (!file_util::PathExists(expected_file)) { + FilePath actual_file = + FilePath(html_file.RemoveExtension().value() + + helper_.GetActualFileSuffix()); - EXPECT_TRUE(file_util::WriteFile( - actual_file, actual_contents.c_str(), actual_contents.size())); + EXPECT_TRUE(file_util::WriteFile( + actual_file, actual_contents.c_str(), actual_contents.size())); - ADD_FAILURE() << "No expectation found. Create it by doing:\n" - << "mv " << actual_file.LossyDisplayName() << " " - << expected_file.LossyDisplayName(); - } - } while (!(html_file = file_enumerator.Next()).empty()); + ADD_FAILURE() << "No expectation found. Create it by doing:\n" + << "mv " << actual_file.LossyDisplayName() << " " + << expected_file.LossyDisplayName(); + } +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityA) { + RunTest(FILE_PATH_LITERAL("a.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAName) { + RunTest(FILE_PATH_LITERAL("a-name.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAOnclick) { + RunTest(FILE_PATH_LITERAL("a-onclick.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, + AccessibilityAriaApplication) { + RunTest(FILE_PATH_LITERAL("aria-application.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAWithImg) { + RunTest(FILE_PATH_LITERAL("a-with-img.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, + AccessibilityContenteditableDescendants) { + RunTest(FILE_PATH_LITERAL("contenteditable-descendants.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityFooter) { + RunTest(FILE_PATH_LITERAL("footer.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityListMarkers) { + RunTest(FILE_PATH_LITERAL("list-markers.html")); +} + +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityUl) { + RunTest(FILE_PATH_LITERAL("ul.html")); } } // namespace content diff --git a/content/browser/accessibility/dump_accessibility_tree_helper.cc b/content/browser/accessibility/dump_accessibility_tree_helper.cc index 1d667c95267620..cd540070c5eeaa 100644 --- a/content/browser/accessibility/dump_accessibility_tree_helper.cc +++ b/content/browser/accessibility/dump_accessibility_tree_helper.cc @@ -4,12 +4,21 @@ #include "content/browser/accessibility/dump_accessibility_tree_helper.h" +#include "base/logging.h" #include "base/memory/scoped_ptr.h" +#include "base/string_util.h" namespace { const int kIndentSpaces = 4; } +DumpAccessibilityTreeHelper::DumpAccessibilityTreeHelper() { + Initialize(); +} + +DumpAccessibilityTreeHelper::~DumpAccessibilityTreeHelper() { +} + void DumpAccessibilityTreeHelper::DumpAccessibilityTree( BrowserAccessibility* node, string16* contents) { RecursiveDumpAccessibilityTree(node, contents, 0); @@ -28,3 +37,41 @@ void DumpAccessibilityTreeHelper::RecursiveDumpAccessibilityTree( indent + kIndentSpaces); } } + +void DumpAccessibilityTreeHelper::SetFilters( + const std::set& allow_filters, + const std::set& deny_filters) { + allow_filters_ = allow_filters; + deny_filters_ = deny_filters; +} + +bool DumpAccessibilityTreeHelper::MatchesFilters( + const string16& text, bool default_result) { + std::set::const_iterator iter = allow_filters_.begin(); + for (iter = allow_filters_.begin(); iter != allow_filters_.end(); ++iter) { + if (MatchPattern(text, *iter)) + return true; + } + for (iter = deny_filters_.begin(); iter != deny_filters_.end(); ++iter) { + if (MatchPattern(text, *iter)) + return false; + } + return default_result; +} + +void DumpAccessibilityTreeHelper::StartLine() { + line_.clear(); +} + +void DumpAccessibilityTreeHelper::Add( + bool include_by_default, const string16& attr) { + if (!MatchesFilters(attr, include_by_default)) + return; + if (!line_.empty()) + line_ += ASCIIToUTF16(" "); + line_ += attr; +} + +string16 DumpAccessibilityTreeHelper::FinishLine() { + return line_; +} diff --git a/content/browser/accessibility/dump_accessibility_tree_helper.h b/content/browser/accessibility/dump_accessibility_tree_helper.h index 314ef7419256d5..0a63872961f9ab 100644 --- a/content/browser/accessibility/dump_accessibility_tree_helper.h +++ b/content/browser/accessibility/dump_accessibility_tree_helper.h @@ -5,6 +5,8 @@ #ifndef CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_TREE_HELPER_H_ #define CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_TREE_HELPER_H_ +#include + #include "base/file_path.h" #include "base/string16.h" #include "base/utf_string_conversions.h" @@ -15,10 +17,18 @@ // implemented. class DumpAccessibilityTreeHelper { public: + DumpAccessibilityTreeHelper(); + virtual ~DumpAccessibilityTreeHelper(); + // Dumps a BrowserAccessibility tree into a string. void DumpAccessibilityTree(BrowserAccessibility* node, string16* contents); + // Set regular expression filters that apply to each component of every + // line before it's output. + void SetFilters(const std::set& allow_filters, + const std::set& deny_filters); + // Suffix of the expectation file corresponding to html file. // Example: // HTML test: test-file.html @@ -27,6 +37,20 @@ class DumpAccessibilityTreeHelper { const FilePath::StringType GetActualFileSuffix() const; const FilePath::StringType GetExpectedFileSuffix() const; + // A platform-specific string that indicates a given line in a file + // is an allow or deny filter. Example: + // Mac values: + // GetAllowString() -> "@MAC-ALLOW:" + // GetDenyString() -> "@MAC-DENY:" + // Example html: + // + //

Text

+ const std::string GetAllowString() const; + const std::string GetDenyString() const; + protected: void RecursiveDumpAccessibilityTree(BrowserAccessibility* node, string16* contents, @@ -38,6 +62,17 @@ class DumpAccessibilityTreeHelper { string16 ToString(BrowserAccessibility* node, char* prefix); void Initialize(); + + bool MatchesFilters(const string16& text, bool default_result); + void StartLine(); + void Add(bool include_by_default, const string16& attr); + string16 FinishLine(); + + std::set allow_filters_; + std::set deny_filters_; + string16 line_; + + DISALLOW_COPY_AND_ASSIGN(DumpAccessibilityTreeHelper); }; #endif // CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_TREE_HELPER_H_ diff --git a/content/browser/accessibility/dump_accessibility_tree_helper_mac.mm b/content/browser/accessibility/dump_accessibility_tree_helper_mac.mm index 04b72e02a738e6..8c4549ba22d284 100644 --- a/content/browser/accessibility/dump_accessibility_tree_helper_mac.mm +++ b/content/browser/accessibility/dump_accessibility_tree_helper_mac.mm @@ -11,26 +11,35 @@ #include "content/browser/accessibility/browser_accessibility_cocoa.h" #include "content/browser/accessibility/browser_accessibility_mac.h" +namespace { +string16 Format(BrowserAccessibility* node, + const char *prefix, + SEL selector, + const char *suffix) { + BrowserAccessibilityCocoa* cocoa_node = node->ToBrowserAccessibilityCocoa(); + NSString* format_str = + [NSString stringWithFormat:@"%s%%@%s", prefix, suffix]; + NSString* tmp = [NSString stringWithFormat:format_str, + [cocoa_node performSelector:selector]]; + return UTF8ToUTF16([tmp cStringUsingEncoding:NSUTF8StringEncoding]); +} +} + void DumpAccessibilityTreeHelper::Initialize() {} string16 DumpAccessibilityTreeHelper::ToString(BrowserAccessibility* node, char* prefix) { - BrowserAccessibilityCocoa* cocoa_node = node->ToBrowserAccessibilityCocoa(); - NSString* dump = - [NSString stringWithFormat:@"%s%@ " - "subrole=%@ " - "roleDescription='%@' " - "title='%@' " - "value='%@'\n", - prefix, - [cocoa_node role], - [cocoa_node subrole], - [cocoa_node roleDescription], - [cocoa_node title], - [cocoa_node value]]; - std::string tempVal = [dump cStringUsingEncoding:NSUTF8StringEncoding]; - - return UTF8ToUTF16(tempVal); + StartLine(); + Add(true, Format(node, "", @selector(role), "")); + Add(true, Format(node, "subrole=", @selector(subrole), "")); + Add(false, Format(node, "roleDescription='", + @selector(roleDescription), + "'")); + Add(true, Format(node, "title='", @selector(title), "'")); + Add(true, Format(node, "value='", @selector(value), "'")); + Add(false, Format(node, "description='", @selector(description), "'")); + Add(false, Format(node, "help='", @selector(help), "'")); + return ASCIIToUTF16(prefix) + FinishLine() + ASCIIToUTF16("\n"); } const FilePath::StringType DumpAccessibilityTreeHelper::GetActualFileSuffix() @@ -42,3 +51,11 @@ const { return FILE_PATH_LITERAL("-expected-mac.txt"); } + +const std::string DumpAccessibilityTreeHelper::GetAllowString() const { + return "@MAC-ALLOW:"; +} + +const std::string DumpAccessibilityTreeHelper::GetDenyString() const { + return "@MAC-DENY:"; +} diff --git a/content/browser/accessibility/dump_accessibility_tree_helper_win.cc b/content/browser/accessibility/dump_accessibility_tree_helper_win.cc index 6d75527b197bbf..6aae2becc2f19c 100644 --- a/content/browser/accessibility/dump_accessibility_tree_helper_win.cc +++ b/content/browser/accessibility/dump_accessibility_tree_helper_win.cc @@ -12,38 +12,60 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "content/browser/accessibility/browser_accessibility_win.h" +#include "content/common/accessibility_node_data.h" #include "content/public/test/accessibility_test_utils_win.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/iaccessible2/ia2_api_all.h" +#include "ui/base/win/atl_module.h" +void DumpAccessibilityTreeHelper::Initialize() { + ui::win::CreateATLModuleIfNeeded(); +} + string16 DumpAccessibilityTreeHelper::ToString( BrowserAccessibility* node, char* prefix) { BrowserAccessibilityWin* acc_obj = node->ToBrowserAccessibilityWin(); - // Get state string. + // Get the computed name. VARIANT variant_self; variant_self.vt = VT_I4; variant_self.lVal = CHILDID_SELF; - VARIANT msaa_state_variant; - HRESULT hresult = acc_obj->get_accState(variant_self, &msaa_state_variant); - EXPECT_EQ(S_OK, hresult); - EXPECT_EQ(VT_I4, msaa_state_variant.vt); - string16 state_str = IAccessibleStateToString(msaa_state_variant.lVal); - string16 state2_str = IAccessible2StateToString(acc_obj->ia2_state()); - if (!state2_str.empty()) { - if (!state_str.empty()) - state_str += L","; - state_str += state2_str; - } + CComBSTR msaa_name_variant; + HRESULT hresult = acc_obj->get_accName(variant_self, &msaa_name_variant); + string16 name; + if (S_OK == hresult) + name = msaa_name_variant.m_str; - // Get role string. - string16 role_str = IAccessible2RoleToString(acc_obj->ia2_role()); + // Get state strings. + std::vector state_strings; + IAccessibleStateToStringVector(acc_obj->ia_state(), &state_strings); + IAccessible2StateToStringVector(acc_obj->ia2_state(), &state_strings); - return UTF8ToUTF16(prefix) + - role_str + - L" name='" + acc_obj->name() + - L"' state=" + state_str + L"\n"; + // Get the description and attributes. + string16 description; + acc_obj->GetStringAttribute(content::AccessibilityNodeData::ATTR_DESCRIPTION, + &description); + const std::vector& ia2_attributes = acc_obj->ia2_attributes(); + + // Build the line. + StartLine(); + Add(true, IAccessible2RoleToString(acc_obj->ia2_role())); + Add(true, L"name='" + name + L"'"); + for (std::vector::const_iterator it = state_strings.begin(); + it != state_strings.end(); + ++it) { + Add(false, *it); + } + for (std::vector::const_iterator it = ia2_attributes.begin(); + it != ia2_attributes.end(); + ++it) { + Add(false, *it); + } + Add(false, L"role_name='" + acc_obj->role_name() + L"'"); + Add(false, L"value='" + acc_obj->value() + L"'"); + Add(false, L"description='" + description + L"'"); + return UTF8ToUTF16(prefix) + FinishLine() + ASCIIToUTF16("\n"); } const FilePath::StringType DumpAccessibilityTreeHelper::GetActualFileSuffix() @@ -55,3 +77,12 @@ const FilePath::StringType DumpAccessibilityTreeHelper::GetExpectedFileSuffix() const { return FILE_PATH_LITERAL("-expected-win.txt"); } + + +const std::string DumpAccessibilityTreeHelper::GetAllowString() const { + return "@WIN-ALLOW:"; +} + +const std::string DumpAccessibilityTreeHelper::GetDenyString() const { + return "@WIN-DENY:"; +} diff --git a/content/common/accessibility_node_data.cc b/content/common/accessibility_node_data.cc index dc55432a6c88a7..aced0cdb7c5a54 100644 --- a/content/common/accessibility_node_data.cc +++ b/content/common/accessibility_node_data.cc @@ -73,6 +73,7 @@ std::string AccessibilityNodeData::DebugString(bool recursive) const { case ROLE_DOCUMENT: result += " DOCUMENT"; break; case ROLE_DRAWER: result += " DRAWER"; break; case ROLE_EDITABLE_TEXT: result += " EDITABLE_TEXT"; break; + case ROLE_FOOTER: result += " FOOTER"; break; case ROLE_GRID: result += " GRID"; break; case ROLE_GROUP: result += " GROUP"; break; case ROLE_GROW_AREA: result += " GROW_AREA"; break; diff --git a/content/public/test/accessibility_test_utils_win.h b/content/public/test/accessibility_test_utils_win.h index bd3fe9e91499b8..e1b9b8fd25ffc8 100644 --- a/content/public/test/accessibility_test_utils_win.h +++ b/content/public/test/accessibility_test_utils_win.h @@ -5,12 +5,18 @@ #ifndef CONTENT_PUBLIC_TEST_ACCESSIBILITY_TEST_UTILS_WIN_H_ #define CONTENT_PUBLIC_TEST_ACCESSIBILITY_TEST_UTILS_WIN_H_ +#include + #include "base/basictypes.h" #include "base/string16.h" string16 IAccessibleRoleToString(int32 ia_role); string16 IAccessible2RoleToString(int32 ia_role); string16 IAccessibleStateToString(int32 ia_state); +void IAccessibleStateToStringVector(int32 ia_state, + std::vector* result); string16 IAccessible2StateToString(int32 ia2_state); +void IAccessible2StateToStringVector(int32 ia_state, + std::vector* result); #endif // CONTENT_PUBLIC_TEST_ACCESSIBILITY_TEST_UTILS_WIN_H_ diff --git a/content/test/accessibility_test_utils_win.cc b/content/test/accessibility_test_utils_win.cc index eaeacaae8c367f..9c3f1879307196 100644 --- a/content/test/accessibility_test_utils_win.cc +++ b/content/test/accessibility_test_utils_win.cc @@ -230,38 +230,36 @@ string16 IAccessible2RoleToString(int32 ia_role) { return AccessibilityRoleStateMap::GetInstance()->ia2_role_string_map[ia_role]; } -string16 IAccessibleStateToString(int32 ia_state) { - string16 state_str; +void IAccessibleStateToStringVector(int32 ia_state, + std::vector* result) { const std::map& state_string_map = AccessibilityRoleStateMap::GetInstance()->ia_state_string_map; std::map::const_iterator it; - - for (it = state_string_map.begin(); - it != state_string_map.end(); - ++it) { - if (it->first & ia_state) { - if (!state_str.empty()) - state_str += L","; - state_str += it->second; - } + for (it = state_string_map.begin(); it != state_string_map.end(); ++it) { + if (it->first & ia_state) + result->push_back(it->second); } - return state_str; } -string16 IAccessible2StateToString(int32 ia2_state) { - string16 state_str; +string16 IAccessibleStateToString(int32 ia_state) { + std::vector strings; + IAccessibleStateToStringVector(ia_state, &strings); + return JoinString(strings, ','); +} + +void IAccessible2StateToStringVector(int32 ia2_state, + std::vector* result) { const std::map& state_string_map = AccessibilityRoleStateMap::GetInstance()->ia2_state_string_map; std::map::const_iterator it; - - for (it = state_string_map.begin(); - it != state_string_map.end(); - ++it) { - if (it->first & ia2_state) { - if (!state_str.empty()) - state_str += L","; - state_str += it->second; - } + for (it = state_string_map.begin(); it != state_string_map.end(); ++it) { + if (it->first & ia2_state) + result->push_back(it->second); } - return state_str; +} + +string16 IAccessible2StateToString(int32 ia2_state) { + std::vector strings; + IAccessible2StateToStringVector(ia2_state, &strings); + return JoinString(strings, ','); } diff --git a/content/test/data/accessibility/a-expected-win.txt b/content/test/data/accessibility/a-expected-win.txt index d5c9b7dddfeb47..41b96483db3a0e 100644 --- a/content/test/data/accessibility/a-expected-win.txt +++ b/content/test/data/accessibility/a-expected-win.txt @@ -1,4 +1,4 @@ -ROLE_SYSTEM_DOCUMENT name='' state=FOCUSED,READONLY,FOCUSABLE - IA2_ROLE_SECTION name='' state=READONLY - ROLE_SYSTEM_LINK name='normal link' state=FOCUSABLE,LINKED - ROLE_SYSTEM_TEXT name='normal link' state=READONLY,LINKED +ROLE_SYSTEM_DOCUMENT name='' READONLY FOCUSABLE + IA2_ROLE_SECTION name='' READONLY + ROLE_SYSTEM_LINK name='normal link' FOCUSABLE LINKED + ROLE_SYSTEM_TEXT name='normal link' READONLY LINKED diff --git a/content/test/data/accessibility/a.html b/content/test/data/accessibility/a.html index 8a7d55fc2d64b3..4cd8c19cfc7721 100644 --- a/content/test/data/accessibility/a.html +++ b/content/test/data/accessibility/a.html @@ -1,3 +1,6 @@ + normal link diff --git a/content/test/data/accessibility/aria-application-expected-mac.txt b/content/test/data/accessibility/aria-application-expected-mac.txt index 85109223f76a52..441fb0f4d39d3c 100644 --- a/content/test/data/accessibility/aria-application-expected-mac.txt +++ b/content/test/data/accessibility/aria-application-expected-mac.txt @@ -1,2 +1,2 @@ -AXWebArea subrole=(null) roleDescription='HTML content' title='' value='' +AXWebArea subrole=(null) title='' value='' AXGroup subrole=AXLandmarkApplication roleDescription='application' title='' value='' diff --git a/content/test/data/accessibility/aria-application-expected-win.txt b/content/test/data/accessibility/aria-application-expected-win.txt index e121405052a36a..0eda87d29675ed 100644 --- a/content/test/data/accessibility/aria-application-expected-win.txt +++ b/content/test/data/accessibility/aria-application-expected-win.txt @@ -1,2 +1,2 @@ -ROLE_SYSTEM_DOCUMENT name='' state=FOCUSED,READONLY,FOCUSABLE - IA2_ROLE_SECTION name='' state=READONLY +ROLE_SYSTEM_DOCUMENT name='' READONLY FOCUSABLE + IA2_ROLE_SECTION name='' READONLY diff --git a/content/test/data/accessibility/aria-application.html b/content/test/data/accessibility/aria-application.html index f2b14b4a10399f..eeaeccf4d1e670 100644 --- a/content/test/data/accessibility/aria-application.html +++ b/content/test/data/accessibility/aria-application.html @@ -1,3 +1,6 @@ + diff --git a/content/test/data/accessibility/contenteditable-descendants-expected-win.txt b/content/test/data/accessibility/contenteditable-descendants-expected-win.txt index a3c4998bba509e..ea0e3b6c93bdcd 100644 --- a/content/test/data/accessibility/contenteditable-descendants-expected-win.txt +++ b/content/test/data/accessibility/contenteditable-descendants-expected-win.txt @@ -1,21 +1,21 @@ -ROLE_SYSTEM_DOCUMENT name='' state=FOCUSED,READONLY,FOCUSABLE - IA2_ROLE_PARAGRAPH name='' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_TEXT name='Contentditable with ' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_LINK name='link' state=LINKED,IA2_STATE_EDITABLE - ROLE_SYSTEM_TEXT name='link' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_TEXT name=' and ' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_GRAPHIC name='image' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_TEXT name=' and ' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_PUSHBUTTON name='button' state=FOCUSABLE,IA2_STATE_EDITABLE - ROLE_SYSTEM_TABLE name='' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_ROW name='' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_CELL name='' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_TEXT name='Always expose editable tables as tables' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_COLUMN name='' state=UNAVAILABLE,IA2_STATE_EDITABLE - IA2_ROLE_SECTION name='' state=UNAVAILABLE,IA2_STATE_EDITABLE - ROLE_SYSTEM_LIST name='' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_LISTITEM name='' state=IA2_STATE_EDITABLE - ROLE_SYSTEM_TEXT name='1' state=READONLY - ROLE_SYSTEM_TEXT name='Editable list item' state=IA2_STATE_EDITABLE - IA2_ROLE_PARAGRAPH name='' state=FOCUSABLE,IA2_STATE_EDITABLE - ROLE_SYSTEM_TEXT name='Keep the role, just change the state' state=IA2_STATE_EDITABLE +ROLE_SYSTEM_DOCUMENT name='' READONLY FOCUSABLE + IA2_ROLE_PARAGRAPH name='' IA2_STATE_EDITABLE + ROLE_SYSTEM_TEXT name='Contentditable with ' IA2_STATE_EDITABLE + ROLE_SYSTEM_LINK name='link' LINKED IA2_STATE_EDITABLE + ROLE_SYSTEM_TEXT name='link' LINKED IA2_STATE_EDITABLE + ROLE_SYSTEM_TEXT name=' and ' IA2_STATE_EDITABLE + ROLE_SYSTEM_GRAPHIC name='image' IA2_STATE_EDITABLE + ROLE_SYSTEM_TEXT name=' and ' IA2_STATE_EDITABLE + ROLE_SYSTEM_PUSHBUTTON name='button' FOCUSABLE IA2_STATE_EDITABLE + ROLE_SYSTEM_TABLE name='' IA2_STATE_EDITABLE + ROLE_SYSTEM_ROW name='' IA2_STATE_EDITABLE + ROLE_SYSTEM_CELL name='' IA2_STATE_EDITABLE + ROLE_SYSTEM_TEXT name='Always expose editable tables as tables' IA2_STATE_EDITABLE + ROLE_SYSTEM_COLUMN name='' UNAVAILABLE IA2_STATE_EDITABLE + IA2_ROLE_SECTION name='' UNAVAILABLE IA2_STATE_EDITABLE + ROLE_SYSTEM_LIST name='' IA2_STATE_EDITABLE + ROLE_SYSTEM_LISTITEM name='' IA2_STATE_EDITABLE + ROLE_SYSTEM_TEXT name='1' READONLY + ROLE_SYSTEM_TEXT name='Editable list item' IA2_STATE_EDITABLE + IA2_ROLE_PARAGRAPH name='' FOCUSABLE IA2_STATE_EDITABLE + ROLE_SYSTEM_TEXT name='Keep the role, just change the state' IA2_STATE_EDITABLE diff --git a/content/test/data/accessibility/contenteditable-descendants.html b/content/test/data/accessibility/contenteditable-descendants.html index 43c86b6859d335..f6050965ea5c46 100644 --- a/content/test/data/accessibility/contenteditable-descendants.html +++ b/content/test/data/accessibility/contenteditable-descendants.html @@ -1,3 +1,8 @@ +

Contentditable with link and image and

Always expose editable tables as tables
diff --git a/content/test/data/accessibility/footer-expected-mac.txt b/content/test/data/accessibility/footer-expected-mac.txt index 06aa3c3b6bff46..09dece12102172 100644 --- a/content/test/data/accessibility/footer-expected-mac.txt +++ b/content/test/data/accessibility/footer-expected-mac.txt @@ -1,3 +1,3 @@ -AXWebArea subrole=(null) roleDescription='HTML content' title='' value='' +AXWebArea subrole=(null) title='' value='' AXGroup subrole=AXLandmarkContentInfo roleDescription='footer' title='' value='' - AXStaticText subrole=(null) roleDescription='text' title='' value='Footer element' + AXStaticText subrole=(null) title='' value='Footer element' diff --git a/content/test/data/accessibility/footer-expected-win.txt b/content/test/data/accessibility/footer-expected-win.txt index 76fc78a6103adf..3cb58f9bf6d8d6 100644 --- a/content/test/data/accessibility/footer-expected-win.txt +++ b/content/test/data/accessibility/footer-expected-win.txt @@ -1,3 +1,3 @@ -ROLE_SYSTEM_DOCUMENT name='' state=FOCUSED,READONLY,FOCUSABLE - IA2_ROLE_FOOTER name='' state=READONLY - ROLE_SYSTEM_TEXT name='Footer element' state=READONLY +ROLE_SYSTEM_DOCUMENT name='' READONLY FOCUSABLE + IA2_ROLE_FOOTER name='' READONLY + ROLE_SYSTEM_TEXT name='Footer element' READONLY diff --git a/content/test/data/accessibility/footer.html b/content/test/data/accessibility/footer.html index ac430d217a1682..f33523ea9fba40 100644 --- a/content/test/data/accessibility/footer.html +++ b/content/test/data/accessibility/footer.html @@ -1,3 +1,6 @@ + diff --git a/content/test/data/accessibility/list-markers-expected-mac.txt b/content/test/data/accessibility/list-markers-expected-mac.txt index 758ce02690638e..29e72523485ce1 100644 --- a/content/test/data/accessibility/list-markers-expected-mac.txt +++ b/content/test/data/accessibility/list-markers-expected-mac.txt @@ -1,17 +1,17 @@ -AXWebArea subrole=(null) roleDescription='HTML content' title='' value='' - AXList subrole=AXContentList roleDescription='list' title='' value='' - AXGroup subrole=(null) roleDescription='group' title='' value='' - AXListMarker subrole=(null) roleDescription='AXListMarker' title='' value='•' - AXStaticText subrole=(null) roleDescription='text' title='' value='First item properly groups itself despite ' - AXStaticText subrole=(null) roleDescription='text' title='' value='bolded' - AXStaticText subrole=(null) roleDescription='text' title='' value=' text.' - AXGroup subrole=(null) roleDescription='group' title='' value='' - AXListMarker subrole=(null) roleDescription='AXListMarker' title='' value='•' - AXStaticText subrole=(null) roleDescription='text' title='' value='This should also be ' - AXStaticText subrole=(null) roleDescription='text' title='' value='seen' - AXStaticText subrole=(null) roleDescription='text' title='' value=' as a group.' - AXGroup subrole=(null) roleDescription='group' title='' value='' - AXListMarker subrole=(null) roleDescription='AXListMarker' title='' value='•' - AXStaticText subrole=(null) roleDescription='text' title='' value='Some ' - AXStaticText subrole=(null) roleDescription='text' title='' value='more' - AXStaticText subrole=(null) roleDescription='text' title='' value=' text.' +AXWebArea subrole=(null) title='' value='' + AXList subrole=AXContentList title='' value='' + AXGroup subrole=(null) title='' value='' + AXListMarker subrole=(null) title='' value='•' + AXStaticText subrole=(null) title='' value='First item properly groups itself despite ' + AXStaticText subrole=(null) title='' value='bolded' + AXStaticText subrole=(null) title='' value=' text.' + AXGroup subrole=(null) title='' value='' + AXListMarker subrole=(null) title='' value='•' + AXStaticText subrole=(null) title='' value='This should also be ' + AXStaticText subrole=(null) title='' value='seen' + AXStaticText subrole=(null) title='' value=' as a group.' + AXGroup subrole=(null) title='' value='' + AXListMarker subrole=(null) title='' value='•' + AXStaticText subrole=(null) title='' value='Some ' + AXStaticText subrole=(null) title='' value='more' + AXStaticText subrole=(null) title='' value=' text.' diff --git a/content/test/data/accessibility/ul-expected-mac.txt b/content/test/data/accessibility/ul-expected-mac.txt index ee3d356fece99f..ddda508a0624ff 100644 --- a/content/test/data/accessibility/ul-expected-mac.txt +++ b/content/test/data/accessibility/ul-expected-mac.txt @@ -1,11 +1,11 @@ -AXWebArea subrole=(null) roleDescription='HTML content' title='' value='' - AXList subrole=AXContentList roleDescription='list' title='' value='' - AXGroup subrole=(null) roleDescription='group' title='' value='' - AXListMarker subrole=(null) roleDescription='AXListMarker' title='' value='•' - AXStaticText subrole=(null) roleDescription='text' title='' value='Item 1' - AXGroup subrole=(null) roleDescription='group' title='' value='' - AXListMarker subrole=(null) roleDescription='AXListMarker' title='' value='•' - AXStaticText subrole=(null) roleDescription='text' title='' value='Item 2' - AXGroup subrole=(null) roleDescription='group' title='' value='' - AXListMarker subrole=(null) roleDescription='AXListMarker' title='' value='•' - AXStaticText subrole=(null) roleDescription='text' title='' value='Item 3' +AXWebArea subrole=(null) title='' value='' + AXList subrole=AXContentList title='' value='' + AXGroup subrole=(null) title='' value='' + AXListMarker subrole=(null) title='' value='•' + AXStaticText subrole=(null) title='' value='Item 1' + AXGroup subrole=(null) title='' value='' + AXListMarker subrole=(null) title='' value='•' + AXStaticText subrole=(null) title='' value='Item 2' + AXGroup subrole=(null) title='' value='' + AXListMarker subrole=(null) title='' value='•' + AXStaticText subrole=(null) title='' value='Item 3' diff --git a/content/test/data/accessibility/ul-expected-win.txt b/content/test/data/accessibility/ul-expected-win.txt index f46b02b7cfd4d2..7c3ad1bb370062 100644 --- a/content/test/data/accessibility/ul-expected-win.txt +++ b/content/test/data/accessibility/ul-expected-win.txt @@ -1,11 +1,11 @@ -ROLE_SYSTEM_DOCUMENT name='' state=FOCUSED,READONLY,FOCUSABLE - ROLE_SYSTEM_LIST name='' state=READONLY - ROLE_SYSTEM_LISTITEM name='' state=READONLY - ROLE_SYSTEM_TEXT name='•' state=READONLY - ROLE_SYSTEM_TEXT name='Item 1' state=READONLY - ROLE_SYSTEM_LISTITEM name='' state=READONLY - ROLE_SYSTEM_TEXT name='•' state=READONLY - ROLE_SYSTEM_TEXT name='Item 2' state=READONLY - ROLE_SYSTEM_LISTITEM name='' state=READONLY - ROLE_SYSTEM_TEXT name='•' state=READONLY - ROLE_SYSTEM_TEXT name='Item 3' state=READONLY +ROLE_SYSTEM_DOCUMENT name='' READONLY FOCUSABLE + ROLE_SYSTEM_LIST name='' READONLY + ROLE_SYSTEM_LISTITEM name='' READONLY + ROLE_SYSTEM_TEXT name='•' READONLY + ROLE_SYSTEM_TEXT name='Item 1' READONLY + ROLE_SYSTEM_LISTITEM name='' READONLY + ROLE_SYSTEM_TEXT name='•' READONLY + ROLE_SYSTEM_TEXT name='Item 2' READONLY + ROLE_SYSTEM_LISTITEM name='' READONLY + ROLE_SYSTEM_TEXT name='•' READONLY + ROLE_SYSTEM_TEXT name='Item 3' READONLY