Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: content/browser/accessibility/dump_accessibility_browsertest_base.cc

Issue 787813006: Pull out a base class from DumpAccessibilityTree (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix_legacy_outerwidth
Patch Set: Fix Linux compile Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/accessibility/dump_accessibility_browsertest_base.h"
6
7 #include <set>
8 #include <string>
9 #include <vector>
10
11 #include "base/path_service.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "content/browser/accessibility/accessibility_tree_formatter.h"
17 #include "content/browser/accessibility/browser_accessibility.h"
18 #include "content/browser/accessibility/browser_accessibility_manager.h"
19 #include "content/browser/web_contents/web_contents_impl.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/common/content_paths.h"
22 #include "content/public/common/url_constants.h"
23 #include "content/public/test/content_browser_test.h"
24 #include "content/public/test/content_browser_test_utils.h"
25 #include "content/shell/browser/shell.h"
26 #include "content/test/accessibility_browser_test_utils.h"
27
28 namespace content {
29
30 namespace {
31
32 const char kCommentToken = '#';
33 const char kMarkSkipFile[] = "#<skip";
34 const char kMarkEndOfFile[] = "<-- End-of-file -->";
35 const char kSignalDiff[] = "*";
36
37 } // namespace
38
39 typedef AccessibilityTreeFormatter::Filter Filter;
40
41 DumpAccessibilityTestBase::DumpAccessibilityTestBase() {
42 }
43
44 DumpAccessibilityTestBase::~DumpAccessibilityTestBase() {
45 }
46
47 base::string16
48 DumpAccessibilityTestBase::DumpUnfilteredAccessibilityTreeAsString() {
49 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
50 shell()->web_contents());
51 AccessibilityTreeFormatter formatter(
52 web_contents->GetRootBrowserAccessibilityManager()->GetRoot());
53 std::vector<Filter> filters;
54 filters.push_back(Filter(base::ASCIIToUTF16("*"), Filter::ALLOW));
55 formatter.SetFilters(filters);
56 base::string16 ax_tree_dump;
57 formatter.FormatAccessibilityTree(&ax_tree_dump);
58 return ax_tree_dump;
59 }
60
61 std::vector<int> DumpAccessibilityTestBase::DiffLines(
62 const std::vector<std::string>& expected_lines,
63 const std::vector<std::string>& actual_lines) {
64 int actual_lines_count = actual_lines.size();
65 int expected_lines_count = expected_lines.size();
66 std::vector<int> diff_lines;
67 int i = 0, j = 0;
68 while (i < actual_lines_count && j < expected_lines_count) {
69 if (expected_lines[j].size() == 0 ||
70 expected_lines[j][0] == kCommentToken) {
71 // Skip comment lines and blank lines in expected output.
72 ++j;
73 continue;
74 }
75
76 if (actual_lines[i] != expected_lines[j])
77 diff_lines.push_back(j);
78 ++i;
79 ++j;
80 }
81
82 // Actual file has been fully checked.
83 return diff_lines;
84 }
85
86 void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
87 const std::string& test_html,
88 std::vector<Filter>* filters,
89 std::string* wait_for) {
90 std::vector<std::string> lines;
91 base::SplitString(test_html, '\n', &lines);
92 for (std::vector<std::string>::const_iterator iter = lines.begin();
93 iter != lines.end();
94 ++iter) {
95 const std::string& line = *iter;
96 const std::string& allow_empty_str =
97 AccessibilityTreeFormatter::GetAllowEmptyString();
98 const std::string& allow_str =
99 AccessibilityTreeFormatter::GetAllowString();
100 const std::string& deny_str =
101 AccessibilityTreeFormatter::GetDenyString();
102 const std::string& wait_str = "@WAIT-FOR:";
103 if (StartsWithASCII(line, allow_empty_str, true)) {
104 filters->push_back(
105 Filter(base::UTF8ToUTF16(line.substr(allow_empty_str.size())),
106 Filter::ALLOW_EMPTY));
107 } else if (StartsWithASCII(line, allow_str, true)) {
108 filters->push_back(Filter(base::UTF8ToUTF16(
109 line.substr(allow_str.size())),
110 Filter::ALLOW));
111 } else if (StartsWithASCII(line, deny_str, true)) {
112 filters->push_back(Filter(base::UTF8ToUTF16(
113 line.substr(deny_str.size())),
114 Filter::DENY));
115 } else if (StartsWithASCII(line, wait_str, true)) {
116 *wait_for = line.substr(wait_str.size());
117 }
118 }
119 }
120
121 void DumpAccessibilityTestBase::RunTest(
122 const base::FilePath::CharType* file_path) {
123 NavigateToURL(shell(), GURL(url::kAboutBlankURL));
124
125 // Setup test paths.
126 base::FilePath dir_test_data;
127 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &dir_test_data));
128 base::FilePath test_path(
129 dir_test_data.Append(FILE_PATH_LITERAL("accessibility")));
130 ASSERT_TRUE(base::PathExists(test_path))
131 << test_path.LossyDisplayName();
132
133 base::FilePath html_file = test_path.Append(base::FilePath(file_path));
134 // Output the test path to help anyone who encounters a failure and needs
135 // to know where to look.
136 printf("Testing: %s\n", html_file.MaybeAsASCII().c_str());
137
138 std::string html_contents;
139 base::ReadFileToString(html_file, &html_contents);
140
141 // Read the expected file.
142 std::string expected_contents_raw;
143 base::FilePath expected_file =
144 base::FilePath(html_file.RemoveExtension().value() +
145 AccessibilityTreeFormatter::GetExpectedFileSuffix());
146 base::ReadFileToString(expected_file, &expected_contents_raw);
147
148 // Tolerate Windows-style line endings (\r\n) in the expected file:
149 // normalize by deleting all \r from the file (if any) to leave only \n.
150 std::string expected_contents;
151 base::RemoveChars(expected_contents_raw, "\r", &expected_contents);
152
153 if (!expected_contents.compare(0, strlen(kMarkSkipFile), kMarkSkipFile)) {
154 printf("Skipping this test on this platform.\n");
155 return;
156 }
157
158 // Parse filters and other directives in the test file.
159 std::string wait_for;
160 AddDefaultFilters(&filters_);
161 ParseHtmlForExtraDirectives(html_contents, &filters_, &wait_for);
162
163 // Load the page.
164 base::string16 html_contents16;
165 html_contents16 = base::UTF8ToUTF16(html_contents);
166 GURL url = GetTestUrl("accessibility",
167 html_file.BaseName().MaybeAsASCII().c_str());
168
169 // If there's a @WAIT-FOR directive, set up an accessibility notification
170 // waiter that returns on any event; we'll stop when we get the text we're
171 // waiting for, or time out. Otherwise just wait specifically for
172 // the "load complete" event.
173 scoped_ptr<AccessibilityNotificationWaiter> waiter;
174 if (!wait_for.empty()) {
175 waiter.reset(new AccessibilityNotificationWaiter(
176 shell(), AccessibilityModeComplete, ui::AX_EVENT_NONE));
177 } else {
178 waiter.reset(new AccessibilityNotificationWaiter(
179 shell(), AccessibilityModeComplete, ui::AX_EVENT_LOAD_COMPLETE));
180 }
181
182 // Load the test html.
183 NavigateToURL(shell(), url);
184
185 // Wait for notifications. If there's a @WAIT-FOR directive, break when
186 // the text we're waiting for appears in the dump, otherwise break after
187 // the first notification, which will be a load complete.
188 do {
189 waiter->WaitForNotification();
190 if (!wait_for.empty()) {
191 base::string16 tree_dump = DumpUnfilteredAccessibilityTreeAsString();
192 if (base::UTF16ToUTF8(tree_dump).find(wait_for) != std::string::npos)
193 wait_for.clear();
194 }
195 } while (!wait_for.empty());
196
197 // Call the subclass to dump the output.
198 std::vector<std::string> actual_lines = Dump();
199
200 // Perform a diff (or write the initial baseline).
201 std::vector<std::string> expected_lines;
202 Tokenize(expected_contents, "\n", &expected_lines);
203 // Marking the end of the file with a line of text ensures that
204 // file length differences are found.
205 expected_lines.push_back(kMarkEndOfFile);
206 actual_lines.push_back(kMarkEndOfFile);
207 std::string actual_contents = JoinString(actual_lines, "\n");
208
209 std::vector<int> diff_lines = DiffLines(expected_lines, actual_lines);
210 bool is_different = diff_lines.size() > 0;
211 EXPECT_FALSE(is_different);
212 if (is_different) {
213 OnDiffFailed();
214
215 // Mark the expected lines which did not match actual output with a *.
216 printf("* Line Expected\n");
217 printf("- ---- --------\n");
218 for (int line = 0, diff_index = 0;
219 line < static_cast<int>(expected_lines.size());
220 ++line) {
221 bool is_diff = false;
222 if (diff_index < static_cast<int>(diff_lines.size()) &&
223 diff_lines[diff_index] == line) {
224 is_diff = true;
225 ++diff_index;
226 }
227 printf("%1s %4d %s\n", is_diff? kSignalDiff : "", line + 1,
228 expected_lines[line].c_str());
229 }
230 printf("\nActual\n");
231 printf("------\n");
232 printf("%s\n", actual_contents.c_str());
233 }
234
235 if (!base::PathExists(expected_file)) {
236 base::FilePath actual_file =
237 base::FilePath(html_file.RemoveExtension().value() +
238 AccessibilityTreeFormatter::GetActualFileSuffix());
239
240 EXPECT_TRUE(base::WriteFile(
241 actual_file, actual_contents.c_str(), actual_contents.size()));
242
243 ADD_FAILURE() << "No expectation found. Create it by doing:\n"
244 << "mv " << actual_file.LossyDisplayName() << " "
245 << expected_file.LossyDisplayName();
246 }
247 }
248
249 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698