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

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: Rebaseline last win tests 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..0deee310cb662f36c4acfb4c03bf0864052c0acb 100644
--- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc
+++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -30,6 +30,7 @@
#include "content/public/test/content_browser_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"
namespace content {
@@ -40,6 +41,53 @@ 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;
nasko 2016/01/07 00:07:37 nit: This is a small enough function that it can b
dmazzoni 2016/01/07 19:19:08 Done, though unfortunately it doesn't seem to pass
+}
+
+// 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) {
+ std::string url = frame_tree_node->current_url().spec();
+ if (url != url::kAboutBlankURL)
dcheng 2016/01/07 00:07:11 Just curious: any particular reason to filter out
dmazzoni 2016/01/07 19:19:08 Removed. I added this while debugging but it shoul
dmazzoni 2016/01/11 19:40:53 Turns out this was needed for one test. Consider
+ all_frame_urls->push_back(url);
+ return true;
+}
+
+// Searches recursively and returns true if an accessibility node
David Tseng 2016/01/07 00:02:29 nit: lines can fit more characters.
dmazzoni 2016/01/07 19:19:08 Done.
+// 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 bug 532249 is
nasko 2016/01/07 00:07:37 nit: https://crbug.com/532249 as it will likify an
dmazzoni 2016/01/07 19:19:08 Done.
+ // fixed.
+ if (node->manager()->GetTreeData().url == url &&
+ !node->manager()->GetTreeData().loaded) {
+ return false;
+ }
+
+ return true;
David Tseng 2016/01/07 00:02:29 You could negate the above if clauses and return t
dmazzoni 2016/01/07 19:19:08 Done.
+ }
+
+ for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
+ if (AccessibilityTreeContainsLoadedDocWithUrl(
+ node->PlatformGetChild(i), url)) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace
typedef AccessibilityTreeFormatter::Filter Filter;
@@ -95,7 +143,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 +168,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 +195,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 +245,93 @@ 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();
+ // Navigate frames with the @CROSS-SITE: directive to a cross-site url.
+ const std::string& cross_site_str = "@CROSS-SITE:";
+ FrameTree* frame_tree = web_contents->GetFrameTree();
+ FrameTreeNode* root = frame_tree->root();
+ for (size_t i = 0; i < root->child_count(); ++i) {
+ FrameTreeNode* child_frame_tree_node = root->child_at(i);
+ GURL url = child_frame_tree_node->current_url();
+ std::string path = url.path();
+ auto pos = path.find(cross_site_str);
+ if (pos != std::string::npos) {
+ std::string host = base::StringPrintf("site%d.com", static_cast<int>(i));
dcheng 2016/01/07 00:07:11 Per http://google.github.io/styleguide/cppguide.ht
dmazzoni 2016/01/07 19:19:08 Moot due to comment below.
+ GURL cross_site_url(embedded_test_server()->GetURL(
+ host, path.replace(pos, cross_site_str.size(), "")));
+ NavigateFrameToURL(child_frame_tree_node, cross_site_url);
+
+ SiteInstance* site_instance =
+ child_frame_tree_node->current_frame_host()->GetSiteInstance();
+ EXPECT_NE(web_contents->GetSiteInstance(), site_instance);
}
- } while (!wait_for.empty());
+ }
nasko 2016/01/07 00:07:37 This loop is unnecessary as we have enough facilit
dmazzoni 2016/01/07 19:19:08 Great idea! For some reason I didn't think I could
+
+ // Get the url of every frame in the frame tree.
+ 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 (auto& url : all_frame_urls) {
dcheng 2016/01/07 00:07:11 const auto&, since mutability isn't required
dmazzoni 2016/01/07 19:19:08 Done.
+ 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 (auto& str : wait_for) {
dcheng 2016/01/07 00:07:11 const auto&
dmazzoni 2016/01/07 19:19:08 Done.
+ 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;
+ }
+ }
+
+ // 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