Home | History | Annotate | Download | only in test
      1 // Copyright 2013 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/test/accessibility_browser_test_utils.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "base/strings/string_util.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "content/browser/frame_host/render_frame_host_impl.h"
     12 #include "content/browser/renderer_host/render_widget_host_view_base.h"
     13 #include "content/browser/web_contents/web_contents_impl.h"
     14 #include "content/common/view_message_enums.h"
     15 #include "content/public/browser/web_contents.h"
     16 #include "content/public/common/url_constants.h"
     17 #include "content/public/test/test_utils.h"
     18 #include "content/shell/browser/shell.h"
     19 #include "ui/accessibility/ax_node.h"
     20 
     21 namespace content {
     22 
     23 AccessibilityNotificationWaiter::AccessibilityNotificationWaiter(Shell* shell)
     24     : event_to_wait_for_(ui::AX_EVENT_NONE),
     25       loop_runner_(new MessageLoopRunner()),
     26       event_target_id_(0),
     27       weak_factory_(this) {
     28   WebContents* web_contents = shell->web_contents();
     29   frame_host_ = static_cast<RenderFrameHostImpl*>(
     30       web_contents->GetMainFrame());
     31   frame_host_->SetAccessibilityCallbackForTesting(
     32       base::Bind(&AccessibilityNotificationWaiter::OnAccessibilityEvent,
     33                  weak_factory_.GetWeakPtr()));
     34 }
     35 
     36 AccessibilityNotificationWaiter::AccessibilityNotificationWaiter(
     37     Shell* shell,
     38     AccessibilityMode accessibility_mode,
     39     ui::AXEvent event_type)
     40     : event_to_wait_for_(event_type),
     41       loop_runner_(new MessageLoopRunner()),
     42       event_target_id_(0),
     43       weak_factory_(this) {
     44   WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
     45       shell->web_contents());
     46   frame_host_ = static_cast<RenderFrameHostImpl*>(
     47       web_contents->GetMainFrame());
     48   frame_host_->SetAccessibilityCallbackForTesting(
     49       base::Bind(&AccessibilityNotificationWaiter::OnAccessibilityEvent,
     50                  weak_factory_.GetWeakPtr()));
     51   web_contents->AddAccessibilityMode(accessibility_mode);
     52 }
     53 
     54 AccessibilityNotificationWaiter::AccessibilityNotificationWaiter(
     55     RenderFrameHostImpl* frame_host,
     56     ui::AXEvent event_type)
     57     : frame_host_(frame_host),
     58       event_to_wait_for_(event_type),
     59       loop_runner_(new MessageLoopRunner()),
     60       event_target_id_(0),
     61       weak_factory_(this) {
     62   frame_host_->SetAccessibilityCallbackForTesting(
     63       base::Bind(&AccessibilityNotificationWaiter::OnAccessibilityEvent,
     64                  weak_factory_.GetWeakPtr()));
     65 }
     66 
     67 AccessibilityNotificationWaiter::~AccessibilityNotificationWaiter() {
     68 }
     69 
     70 void AccessibilityNotificationWaiter::WaitForNotification() {
     71   loop_runner_->Run();
     72 
     73   // Each loop runner can only be called once. Create a new one in case
     74   // the caller wants to call this again to wait for the next notification.
     75   loop_runner_ = new MessageLoopRunner();
     76 }
     77 
     78 const ui::AXTree& AccessibilityNotificationWaiter::GetAXTree() const {
     79   return *frame_host_->GetAXTreeForTesting();
     80 }
     81 
     82 void AccessibilityNotificationWaiter::OnAccessibilityEvent(
     83     ui::AXEvent event_type, int event_target_id) {
     84    if (!IsAboutBlank() && (event_to_wait_for_ == ui::AX_EVENT_NONE ||
     85                           event_to_wait_for_ == event_type)) {
     86     event_target_id_ = event_target_id;
     87     loop_runner_->Quit();
     88   }
     89 }
     90 
     91 bool AccessibilityNotificationWaiter::IsAboutBlank() {
     92   // Skip any accessibility notifications related to "about:blank",
     93   // to avoid a possible race condition between the test beginning
     94   // listening for accessibility events and "about:blank" loading.
     95   const ui::AXNodeData& root = GetAXTree().GetRoot()->data();
     96   for (size_t i = 0; i < root.string_attributes.size(); ++i) {
     97     if (root.string_attributes[i].first != ui::AX_ATTR_DOC_URL)
     98       continue;
     99     const std::string& doc_url = root.string_attributes[i].second;
    100     return doc_url == url::kAboutBlankURL;
    101   }
    102   return false;
    103 }
    104 
    105 }  // namespace content
    106