summaryrefslogtreecommitdiffstats
path: root/content/test/accessibility_browser_test_utils.cc
blob: d44439bbe4e3da91409ef46954ed5c2f35f1ff18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/test/accessibility_browser_test_utils.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/view_message_enums.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "ui/accessibility/ax_node.h"

namespace content {

AccessibilityNotificationWaiter::AccessibilityNotificationWaiter(Shell* shell)
    : event_to_wait_for_(ui::AX_EVENT_NONE),
      loop_runner_(new MessageLoopRunner()),
      event_target_id_(0),
      weak_factory_(this) {
  WebContents* web_contents = shell->web_contents();
  frame_host_ = static_cast<RenderFrameHostImpl*>(
      web_contents->GetMainFrame());
  frame_host_->SetAccessibilityCallbackForTesting(
      base::Bind(&AccessibilityNotificationWaiter::OnAccessibilityEvent,
                 weak_factory_.GetWeakPtr()));
}

AccessibilityNotificationWaiter::AccessibilityNotificationWaiter(
    Shell* shell,
    AccessibilityMode accessibility_mode,
    ui::AXEvent event_type)
    : event_to_wait_for_(event_type),
      loop_runner_(new MessageLoopRunner()),
      event_target_id_(0),
      weak_factory_(this) {
  WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
      shell->web_contents());
  frame_host_ = static_cast<RenderFrameHostImpl*>(
      web_contents->GetMainFrame());
  frame_host_->SetAccessibilityCallbackForTesting(
      base::Bind(&AccessibilityNotificationWaiter::OnAccessibilityEvent,
                 weak_factory_.GetWeakPtr()));
  web_contents->AddAccessibilityMode(accessibility_mode);
}

AccessibilityNotificationWaiter::AccessibilityNotificationWaiter(
    RenderFrameHostImpl* frame_host,
    ui::AXEvent event_type)
    : frame_host_(frame_host),
      event_to_wait_for_(event_type),
      loop_runner_(new MessageLoopRunner()),
      event_target_id_(0),
      weak_factory_(this) {
  frame_host_->SetAccessibilityCallbackForTesting(
      base::Bind(&AccessibilityNotificationWaiter::OnAccessibilityEvent,
                 weak_factory_.GetWeakPtr()));
}

AccessibilityNotificationWaiter::~AccessibilityNotificationWaiter() {
}

void AccessibilityNotificationWaiter::ListenToAdditionalFrame(
    RenderFrameHostImpl* frame_host) {
  frame_host->SetAccessibilityCallbackForTesting(
      base::Bind(&AccessibilityNotificationWaiter::OnAccessibilityEvent,
                 weak_factory_.GetWeakPtr()));
}

void AccessibilityNotificationWaiter::WaitForNotification() {
  loop_runner_->Run();

  // Each loop runner can only be called once. Create a new one in case
  // the caller wants to call this again to wait for the next notification.
  loop_runner_ = new MessageLoopRunner();
}

const ui::AXTree& AccessibilityNotificationWaiter::GetAXTree() const {
  CR_DEFINE_STATIC_LOCAL(ui::AXTree, empty_tree, ());
  const ui::AXTree* tree = frame_host_->GetAXTreeForTesting();
  if (tree)
    return *tree;
  return empty_tree;
}

void AccessibilityNotificationWaiter::OnAccessibilityEvent(
    ui::AXEvent event_type, int event_target_id) {
   if (!IsAboutBlank() && (event_to_wait_for_ == ui::AX_EVENT_NONE ||
                          event_to_wait_for_ == event_type)) {
    event_target_id_ = event_target_id;
    loop_runner_->Quit();
  }
}

bool AccessibilityNotificationWaiter::IsAboutBlank() {
  // Skip any accessibility notifications related to "about:blank",
  // to avoid a possible race condition between the test beginning
  // listening for accessibility events and "about:blank" loading.
  return GetAXTree().data().url == url::kAboutBlankURL;
}

}  // namespace content