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

Unified Diff: content/browser/accessibility/dump_accessibility_browsertest_base.cc

Issue 1552683002: Enable DumpAccessibilityTree tests to use cross-process iframes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Get rid of lambdas due to MSVC bug Created 4 years, 11 months 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/accessibility/dump_accessibility_browsertest_base.cc
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
index b5dd3296ef3106a32025b15a1a7cf93b335578a6..29bc7cc9d196948bb8dd64795b2e1edf0e5ff5e1 100644
--- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc
+++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -26,10 +26,15 @@
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
+#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/accessibility_browser_test_utils.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
namespace content {
@@ -40,6 +45,46 @@ const char kMarkSkipFile[] = "#<skip";
const char kMarkEndOfFile[] = "<-- End-of-file -->";
const char kSignalDiff[] = "*";
+// Helper function to be used with FrameTree::ForEach, so that
+// AccessibilityNotificationWaiter can listen for accessibility
+// events in all frames.
+bool ListenToFrame(AccessibilityNotificationWaiter* waiter,
+ FrameTreeNode* frame_tree_node) {
+ waiter->ListenToAdditionalFrame(frame_tree_node->current_frame_host());
+ return true;
+}
+
+// Helper function to be used with FrameTree::ForEach, to get the
+// url of all frames.
+bool GetFrameUrl(std::vector<std::string>* all_frame_urls,
+ FrameTreeNode* frame_tree_node) {
+ all_frame_urls->push_back(frame_tree_node->current_url().spec());
+ return true;
+}
+
+// Searches recursively and returns true if an accessibility node is found
+// that represents a fully loaded web document with the given url.
+bool AccessibilityTreeContainsLoadedDocWithUrl(BrowserAccessibility* node,
+ const std::string& url) {
+ if ((node->GetRole() == ui::AX_ROLE_WEB_AREA ||
+ node->GetRole() == ui::AX_ROLE_ROOT_WEB_AREA) &&
+ node->GetStringAttribute(ui::AX_ATTR_URL) == url) {
+ // If possible, ensure the doc has finished loading. That's currently
+ // not possible with same-process iframes until http://crbug.com/532249
nasko 2016/01/08 22:57:45 nit: httpS ;)
dmazzoni 2016/01/11 19:04:41 Done.
+ // is fixed.
+ return (node->manager()->GetTreeData().url != url ||
+ node->manager()->GetTreeData().loaded);
+ }
+
+ for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
+ if (AccessibilityTreeContainsLoadedDocWithUrl(
+ node->PlatformGetChild(i), url)) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace
typedef AccessibilityTreeFormatter::Filter Filter;
@@ -50,6 +95,17 @@ DumpAccessibilityTestBase::DumpAccessibilityTestBase() {
DumpAccessibilityTestBase::~DumpAccessibilityTestBase() {
}
+void DumpAccessibilityTestBase::SetUpCommandLine(
+ base::CommandLine* command_line) {
+ IsolateAllSitesForTesting(command_line);
+}
+
+void DumpAccessibilityTestBase::SetUpOnMainThread() {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ SetupCrossSiteRedirector(embedded_test_server());
+}
+
base::string16
DumpAccessibilityTestBase::DumpUnfilteredAccessibilityTreeAsString() {
scoped_ptr<AccessibilityTreeFormatter> formatter(
@@ -95,7 +151,7 @@ std::vector<int> DumpAccessibilityTestBase::DiffLines(
void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
const std::string& test_html,
std::vector<Filter>* filters,
- std::string* wait_for) {
+ std::vector<std::string>* wait_for) {
for (const std::string& line :
base::SplitString(test_html, "\n", base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL)) {
@@ -120,7 +176,7 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
Filter::DENY));
} else if (base::StartsWith(line, wait_str,
base::CompareCase::SENSITIVE)) {
- *wait_for = line.substr(wait_str.size());
+ wait_for->push_back(line.substr(wait_str.size()));
}
}
}
@@ -147,6 +203,10 @@ void DumpAccessibilityTestBase::RunTest(
void DumpAccessibilityTestBase::RunTestForPlatform(
const base::FilePath file_path, const char* file_dir) {
+ WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
+ shell()->web_contents());
+ web_contents->AddAccessibilityMode(AccessibilityModeComplete);
+
formatter_.reset(CreateAccessibilityTreeFormatter());
// Disable the "hot tracked" state (set when the mouse is hovering over
@@ -193,42 +253,73 @@ void DumpAccessibilityTestBase::RunTestForPlatform(
}
// Parse filters and other directives in the test file.
- std::string wait_for;
+ std::vector<std::string> wait_for;
AddDefaultFilters(&filters_);
ParseHtmlForExtraDirectives(html_contents, &filters_, &wait_for);
// Load the page.
- base::string16 html_contents16;
- html_contents16 = base::UTF8ToUTF16(html_contents);
- GURL url = GetTestUrl(file_dir, file_path.BaseName().MaybeAsASCII().c_str());
-
- // If there's a @WAIT-FOR directive, set up an accessibility notification
- // waiter that returns on any event; we'll stop when we get the text we're
- // waiting for, or time out. Otherwise just wait specifically for
- // the "load complete" event.
- scoped_ptr<AccessibilityNotificationWaiter> waiter;
- if (!wait_for.empty()) {
- waiter.reset(new AccessibilityNotificationWaiter(
- shell(), AccessibilityModeComplete, ui::AX_EVENT_NONE));
- } else {
- waiter.reset(new AccessibilityNotificationWaiter(
- shell(), AccessibilityModeComplete, ui::AX_EVENT_LOAD_COMPLETE));
- }
+ GURL url(embedded_test_server()->GetURL(
+ "/" + std::string(file_dir) + "/" + file_path.BaseName().MaybeAsASCII()));
// Load the test html.
NavigateToURL(shell(), url);
- // Wait for notifications. If there's a @WAIT-FOR directive, break when
- // the text we're waiting for appears in the dump, otherwise break after
- // the first notification, which will be a load complete.
- do {
- waiter->WaitForNotification();
- if (!wait_for.empty()) {
- base::string16 tree_dump = DumpUnfilteredAccessibilityTreeAsString();
- if (base::UTF16ToUTF8(tree_dump).find(wait_for) != std::string::npos)
- wait_for.clear();
+ // Get the url of every frame in the frame tree.
+ FrameTree* frame_tree = web_contents->GetFrameTree();
+ std::vector<std::string> all_frame_urls;
+ frame_tree->ForEach(base::Bind(GetFrameUrl, &all_frame_urls));
+
+ // Wait for the accessibility tree to fully load for all frames,
+ // by searching for the WEB_AREA node in the accessibility tree
+ // with the url of each frame in our frame tree. Note that this
+ // doesn't support cases where there are two iframes with the
+ // exact same url. If all frames haven't loaded yet, set up a
+ // listener for accessibility events on any frame and block
+ // until the next one is received.
+ //
+ // If the original page has a @WAIT-FOR directive, don't break until
+ // the text we're waiting for appears in the full text dump of the
+ // accessibility tree, either.
+ for (;;) {
+ VLOG(1) << "Top of loop";
+ RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(
+ web_contents->GetMainFrame());
+ BrowserAccessibility* accessibility_root =
+ main_frame->browser_accessibility_manager()->GetRoot();
+
+ // Check to see if all frames have loaded.
+ bool all_frames_loaded = true;
+ for (const auto& url : all_frame_urls) {
+ if (!AccessibilityTreeContainsLoadedDocWithUrl(accessibility_root, url)) {
+ VLOG(1) << "Still waiting on this frame to load: " << url;
+ all_frames_loaded = false;
+ break;
+ }
+ }
+
+ // Check to see if the @WAIT-FOR text has appeared yet.
+ bool all_wait_for_strings_found = true;
+ base::string16 tree_dump = DumpUnfilteredAccessibilityTreeAsString();
+ for (const auto& str : wait_for) {
+ if (base::UTF16ToUTF8(tree_dump).find(str) == std::string::npos) {
+ VLOG(1) << "Still waiting on this text to be found: " << str;
+ all_wait_for_strings_found = false;
+ break;
+ }
}
- } while (!wait_for.empty());
+
+ // If all frames have loaded and the @WAIT-FOR text has appeared,
+ // we're done.
+ if (all_frames_loaded && all_wait_for_strings_found)
+ break;
+
+ // Block until the next accessibility notification in any frame.
+ VLOG(1) << "Waiting until the next accessibility event";
+ AccessibilityNotificationWaiter accessibility_waiter(main_frame,
+ ui::AX_EVENT_NONE);
+ frame_tree->ForEach(base::Bind(ListenToFrame, &accessibility_waiter));
+ accessibility_waiter.WaitForNotification();
+ }
// Call the subclass to dump the output.
std::vector<std::string> actual_lines = Dump();

Powered by Google App Engine
This is Rietveld 408576698