AXElements 0.6.0beta1 → 0.6.0beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -1
- data/docs/Debugging.markdown +23 -4
- data/lib/AXElements.rb +1 -0
- data/lib/ax_elements/accessibility.rb +3 -1
- data/lib/ax_elements/accessibility/graph.rb +118 -0
- data/lib/ax_elements/inspector.rb +7 -2
- data/lib/ax_elements/version.rb +1 -1
- data/test/test_inspector.rb +10 -1
- metadata +4 -2
data/Rakefile
CHANGED
data/docs/Debugging.markdown
CHANGED
@@ -4,6 +4,27 @@ This document includes instructions on using AXElements' built in
|
|
4
4
|
tools to help you debug issues with your scripts, or in cases where
|
5
5
|
you might find a bug in AXElements itself or MacRuby.
|
6
6
|
|
7
|
+
## Visibility
|
8
|
+
|
9
|
+
Sometimes an object that should be visible to accessibility does not
|
10
|
+
show up. Sometimes it will be invisible to the Accessibility Inspector
|
11
|
+
and sometimes it will be invisible to AXElements. This is because the
|
12
|
+
inspector uses hit testing to find objects and AXElements uses the
|
13
|
+
`children` and `parent` attributes (usually). Depending on which part
|
14
|
+
of the accessibility protocol is not being implemented correctly, one
|
15
|
+
or both tools might fail to work.
|
16
|
+
|
17
|
+
Fortunately, failures in the accessibility API are few and far
|
18
|
+
between. The one big,
|
19
|
+
[known issue](http://openradar.appspot.com/6832098) is with menu bar
|
20
|
+
items; you cannot work around this issue without hacking into private
|
21
|
+
Apple APIs. Specifically, you would need to override built in
|
22
|
+
accessibility methods in the class that implement the user interface
|
23
|
+
for NSStatusItem, which is a private class; or you could build your
|
24
|
+
status bar item as an NSMenuExtra, which is another private class. You
|
25
|
+
can find more tips on augmenting accessibility for apps in the
|
26
|
+
{file:docs/AccessibilityTips.markdown Accessibility Tips} document.
|
27
|
+
|
7
28
|
## Trees
|
8
29
|
|
9
30
|
Sometimes you need to see the big picture, the whole UI tree at
|
@@ -41,8 +62,6 @@ but the text tree dump method uses {Accessibility::DFEnumerator}.
|
|
41
62
|
|
42
63
|
### Dot Graph
|
43
64
|
|
44
|
-
__NOTE__: This feature isn't actually done yet. Coming soon, I promise.
|
45
|
-
|
46
65
|
For super fancy text trees, AXElements can generate dot graphs for
|
47
66
|
consumption by [Graphviz](http://www.graphviz.org/). In this case, you
|
48
67
|
want to call {Accessibility.graph} and pass the root of the tree you
|
@@ -62,8 +81,8 @@ AXElements was that you could not search through the menu bar causing
|
|
62
81
|
a text dump to fail in a very difficult to trace manner.
|
63
82
|
|
64
83
|
In these cases you will need to use your deductive reasoning to figure
|
65
|
-
out where the problem is coming from. Fortunately,
|
66
|
-
|
84
|
+
out where the problem is coming from. Fortunately, AXElements has some
|
85
|
+
tools to help you along the way.
|
67
86
|
|
68
87
|
## All The Way Up
|
69
88
|
|
data/lib/AXElements.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ax_elements'
|
@@ -0,0 +1,118 @@
|
|
1
|
+
##
|
2
|
+
# They see me graphing, they hatin, patrollin they can't catch me graphin' dirty.
|
3
|
+
class Accessibility::Graph
|
4
|
+
|
5
|
+
##
|
6
|
+
# Exploit the ordering of a breadth-first enumeration to simplify the
|
7
|
+
# creation of edges for the graph. This only works because the UI
|
8
|
+
# hiearchy is a simple tree.
|
9
|
+
#
|
10
|
+
# @return [Array<Accessibility::Graph::Node>]
|
11
|
+
attr_reader :edge_queue
|
12
|
+
|
13
|
+
##
|
14
|
+
# List of nodes in the UI hierarchy.
|
15
|
+
#
|
16
|
+
# @return [Array<Accessibility::Graph::Node>]
|
17
|
+
attr_reader :nodes
|
18
|
+
|
19
|
+
##
|
20
|
+
# A node in the UI hierarchy. Used by {Accessibility::Graph} in order
|
21
|
+
# to build Graphviz dot graphs.
|
22
|
+
class Node
|
23
|
+
|
24
|
+
# @return [AX::Element]
|
25
|
+
attr_reader :ref
|
26
|
+
|
27
|
+
##
|
28
|
+
# Unique identifier for the node.
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
attr_reader :id
|
32
|
+
|
33
|
+
##
|
34
|
+
# Label to use for displaying the node.
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
attr_reader :label
|
38
|
+
|
39
|
+
##
|
40
|
+
# Shape to draw the node as.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
attr_reader :shape
|
44
|
+
|
45
|
+
##
|
46
|
+
# Colour to fill the node with.
|
47
|
+
#
|
48
|
+
# @return [String]
|
49
|
+
attr_reader :colour
|
50
|
+
|
51
|
+
# @param [AX::Element]
|
52
|
+
def initialize element
|
53
|
+
@ref = element
|
54
|
+
@id = "element_#{element.object_id}"
|
55
|
+
@label = element.class.to_s
|
56
|
+
@shape = 3 # based on size?
|
57
|
+
@colour = 3 # rotate a la minitest?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# List of edges in the graph.
|
63
|
+
#
|
64
|
+
# @return [Hash{Accessibility::Graph::Node=>Accessibility::Graph::Node}]
|
65
|
+
attr_reader :edges
|
66
|
+
|
67
|
+
# @param [AX::Element]
|
68
|
+
def initialize root
|
69
|
+
@nodes = []
|
70
|
+
@edges = {}
|
71
|
+
@edge_queue = [:root] # hack
|
72
|
+
add_node root
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Construct the list of nodes and edges for the graph...
|
77
|
+
def build!
|
78
|
+
Accessibility::BFEnumerator.new(nodes.first.ref).each do |element|
|
79
|
+
add_node element
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
#
|
85
|
+
#
|
86
|
+
# @return [String]
|
87
|
+
def to_s
|
88
|
+
graph = "digraph {\n"
|
89
|
+
graph << nodes_list
|
90
|
+
graph << edges_list
|
91
|
+
graph << "}\n"
|
92
|
+
end
|
93
|
+
|
94
|
+
def nodes_list
|
95
|
+
nodes.reduce('') do |string, node|
|
96
|
+
string << "#{node.name} [label=\"#{node.label}\"]\n"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def edges_list
|
101
|
+
edges.delete_if { |_,v| v == :root } # remove hack
|
102
|
+
edges.reduce('') do |string, pair|
|
103
|
+
string << "#{pair.second.name} -> #{pair.first.name}\n"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def add_node element
|
108
|
+
node = Node.new(element)
|
109
|
+
nodes << node
|
110
|
+
edges[node] = edge_queue.shift
|
111
|
+
if element.respond_to? :children
|
112
|
+
element.size_of(:children).times do
|
113
|
+
edge_queue << node
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -37,7 +37,8 @@ module Accessibility::PPInspector
|
|
37
37
|
if val.kind_of? NSString
|
38
38
|
return " #{val.inspect}" unless val.empty?
|
39
39
|
else
|
40
|
-
|
40
|
+
# we assume that nil is not a legitimate value
|
41
|
+
return " value=#{val.inspect}" unless val.nil?
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -71,7 +72,11 @@ module Accessibility::PPInspector
|
|
71
72
|
# @return [String]
|
72
73
|
def pp_position
|
73
74
|
position = attribute :position
|
74
|
-
|
75
|
+
if position
|
76
|
+
" (#{position.x}, #{position.y})"
|
77
|
+
else
|
78
|
+
::EMPTY_STRING
|
79
|
+
end
|
75
80
|
end
|
76
81
|
|
77
82
|
##
|
data/lib/ax_elements/version.rb
CHANGED
data/test/test_inspector.rb
CHANGED
@@ -24,7 +24,10 @@ class TestPPInspector < MiniTest::Unit::TestCase
|
|
24
24
|
assert_match /value=3.14/, pp_identifier
|
25
25
|
|
26
26
|
@attribute = ''
|
27
|
-
assert_match
|
27
|
+
assert_match ::EMPTY_STRING, pp_identifier
|
28
|
+
|
29
|
+
@attribute = nil
|
30
|
+
assert_match ::EMPTY_STRING, pp_identifier
|
28
31
|
end
|
29
32
|
|
30
33
|
def test_identifier_using_title
|
@@ -73,6 +76,12 @@ class TestPPInspector < MiniTest::Unit::TestCase
|
|
73
76
|
assert_match /\(3\.14, -5\.0\)/, pp_position
|
74
77
|
end
|
75
78
|
|
79
|
+
# this sometimes happens, even though it shouldn't
|
80
|
+
def test_position_is_nil
|
81
|
+
@attribute = nil
|
82
|
+
assert_equal ::EMPTY_STRING, pp_position
|
83
|
+
end
|
84
|
+
|
76
85
|
def test_children_pluralizes_properly
|
77
86
|
@size_of = 2
|
78
87
|
assert_match /2 children/, pp_children
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: AXElements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 5
|
5
|
-
version: 0.6.
|
5
|
+
version: 0.6.0beta2
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mark Rada
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-10-02 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -123,6 +123,7 @@ extra_rdoc_files:
|
|
123
123
|
- README.markdown
|
124
124
|
files:
|
125
125
|
- lib/ax_elements/accessibility/enumerators.rb
|
126
|
+
- lib/ax_elements/accessibility/graph.rb
|
126
127
|
- lib/ax_elements/accessibility/language.rb
|
127
128
|
- lib/ax_elements/accessibility/qualifier.rb
|
128
129
|
- lib/ax_elements/accessibility.rb
|
@@ -139,6 +140,7 @@ files:
|
|
139
140
|
- lib/ax_elements/notification.rb
|
140
141
|
- lib/ax_elements/version.rb
|
141
142
|
- lib/ax_elements.rb
|
143
|
+
- lib/AXElements.rb
|
142
144
|
- lib/minitest/ax_elements.rb
|
143
145
|
- lib/mouse.rb
|
144
146
|
- lib/rspec/expectations/ax_elements.rb
|