1 // Copyright 2019 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 #ifndef CONTENT_PUBLIC_BROWSER_ACCESSIBILITY_TREE_FORMATTER_H_
6 #define CONTENT_PUBLIC_BROWSER_ACCESSIBILITY_TREE_FORMATTER_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/files/file_path.h"
15 #include "base/macros.h"
16 #include "base/process/process_handle.h"
17 #include "base/strings/string16.h"
18 #include "base/strings/string_piece.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/values.h"
21 #include "content/common/content_export.h"
22 #include "ui/gfx/native_widget_types.h"
23 
24 namespace base {
25 class CommandLine;
26 }
27 
28 namespace ui {
29 class AXPlatformNodeDelegate;
30 }
31 
32 namespace content {
33 
34 class AccessibilityTestExpectationsLocator {
35  public:
36   // Suffix of the expectation file corresponding to html file.
37   // Overridden by each platform subclass.
38   // Example:
39   // HTML test:      test-file.html
40   // Expected:       test-file-expected-mac.txt.
41   virtual base::FilePath::StringType GetExpectedFileSuffix() = 0;
42 
43   // Some Platforms expect different outputs depending on the version.
44   // Most test outputs are identical but this allows a version specific
45   // expected file to be used.
46   virtual base::FilePath::StringType GetVersionSpecificExpectedFileSuffix() = 0;
47 
48  protected:
49   virtual ~AccessibilityTestExpectationsLocator() = default;
50 };
51 
52 // A utility class for formatting platform-specific accessibility information,
53 // for use in testing, debugging, and developer tools.
54 // This is extended by a subclass for each platform where accessibility is
55 // implemented.
56 class CONTENT_EXPORT AccessibilityTreeFormatter
57     : public AccessibilityTestExpectationsLocator {
58  public:
59   // A single property filter specification. See GetAllowString() and
60   // GetDenyString() for more information.
61   struct PropertyFilter {
62     enum Type { ALLOW, ALLOW_EMPTY, DENY };
63     base::string16 match_str;
64     Type type;
65 
PropertyFilterPropertyFilter66     PropertyFilter(base::string16 match_str, Type type)
67         : match_str(match_str), type(type) {}
68   };
69 
70   // A single node filter specification  which will exclude any node where the
71   // value of the named property matches the given pattern.
72   //
73   // This can be used to exclude nodes based on properties like role, for
74   // example to exclude all inlineTextBox nodes under blink we would use a
75   // NodeFilter of the form:
76   //   {property='internalRole', pattern='inlineTextBox'};
77   struct NodeFilter {
78     std::string property;
79     base::string16 pattern;
80 
NodeFilterNodeFilter81     NodeFilter(std::string property, base::string16 pattern)
82         : property(property), pattern(pattern) {}
83   };
84 
85   // Create the appropriate native subclass of AccessibilityTreeFormatter.
86   static std::unique_ptr<AccessibilityTreeFormatter> Create();
87 
88   // Get a set of factory methods to create tree-formatters, one for each test
89   // pass; see |DumpAccessibilityTestBase|.
90   using FormatterFactory = std::unique_ptr<AccessibilityTreeFormatter> (*)();
91   using CommandLineHelper = void (*)(base::CommandLine* command_line);
92   struct TestPass {
93     const char* name;
94     FormatterFactory create_formatter;
95     CommandLineHelper set_up_command_line;
96   };
97   static std::vector<TestPass> GetTestPasses();
98 
99   // Gets the test pass at the given index.
100   static TestPass GetTestPass(size_t index);
101 
102   virtual void AddDefaultFilters(
103       std::vector<PropertyFilter>* property_filters) = 0;
104 
105   static bool MatchesPropertyFilters(
106       const std::vector<PropertyFilter>& property_filters,
107       const base::string16& text,
108       bool default_result);
109 
110   // Check if the given dictionary matches any of the supplied NodeFilter(s).
111   static bool MatchesNodeFilters(const std::vector<NodeFilter>& node_filters,
112                                  const base::DictionaryValue& dict);
113 
114   // Build an accessibility tree for any process with a window.
115   virtual std::unique_ptr<base::DictionaryValue>
116   BuildAccessibilityTreeForProcess(base::ProcessId pid) = 0;
117 
118   // Build an accessibility tree for any window.
119   virtual std::unique_ptr<base::DictionaryValue>
120   BuildAccessibilityTreeForWindow(gfx::AcceleratedWidget widget) = 0;
121 
122   // Build an accessibility tree for an application with a name matching the
123   // given pattern.
124   virtual std::unique_ptr<base::DictionaryValue>
125   BuildAccessibilityTreeForPattern(const base::StringPiece& pattern) = 0;
126 
127   // Returns a filtered accesibility tree using the current property and node
128   // filters.
129   virtual std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree(
130       const base::DictionaryValue& dict) = 0;
131 
132   // Dumps a BrowserAccessibility tree into a string.
133   virtual void FormatAccessibilityTree(const base::DictionaryValue& tree_node,
134                                        base::string16* contents) = 0;
135 
136   // Test version of FormatAccessibilityTree().
137   // |root| must be non-null and must be in web content.
138   virtual void FormatAccessibilityTreeForTesting(
139       ui::AXPlatformNodeDelegate* root,
140       base::string16* contents) = 0;
141 
142   // Set regular expression filters that apply to each property of every node
143   // before it's output.
144   virtual void SetPropertyFilters(
145       const std::vector<PropertyFilter>& property_filters) = 0;
146 
147   // Set regular expression filters that apply to every node before output.
148   virtual void SetNodeFilters(const std::vector<NodeFilter>& node_filters) = 0;
149 
150   // If true, the internal accessibility id of each node will be included
151   // in its output.
152   virtual void set_show_ids(bool show_ids) = 0;
153 
154   // A string that indicates a given line in a file is an allow-empty,
155   // allow or deny filter. Overridden by each platform subclass. Example:
156   // Mac values:
157   //   GetAllowEmptyString() -> "@MAC-ALLOW-EMPTY:"
158   //   GetAllowString() -> "@MAC-ALLOW:"
159   //   GetDenyString() -> "@MAC-DENY:"
160   //   GetDenyNodeString() -> "@MAC-DENY-NODE:"
161   // Example html:
162   // <!--
163   // @MAC-ALLOW-EMPTY:description*
164   // @MAC-ALLOW:roleDescription*
165   // @MAC-DENY:subrole*
166   // @BLINK-DENY-NODE:internalRole=inlineTextBox
167   // -->
168   // <p>Text</p>
169   virtual const std::string GetAllowEmptyString() = 0;
170   virtual const std::string GetAllowString() = 0;
171   virtual const std::string GetDenyString() = 0;
172   virtual const std::string GetDenyNodeString() = 0;
173 };
174 
175 }  // namespace content
176 
177 #endif  // CONTENT_PUBLIC_BROWSER_ACCESSIBILITY_TREE_FORMATTER_H_
178