AXElements 1.0.0.alpha11 → 1.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/History.markdown +11 -1
  2. data/README.markdown +10 -8
  3. data/Rakefile +1 -1
  4. data/lib/accessibility/dsl.rb +5 -2
  5. data/lib/accessibility/factory.rb +134 -78
  6. data/lib/accessibility/qualifier.rb +2 -0
  7. data/lib/accessibility/system_info.rb +82 -17
  8. data/lib/accessibility/translator.rb +17 -17
  9. data/lib/accessibility/version.rb +1 -1
  10. data/lib/ax/application.rb +11 -16
  11. data/lib/ax/element.rb +21 -34
  12. data/lib/ax/systemwide.rb +2 -2
  13. data/lib/ax_elements.rb +7 -1
  14. data/lib/ax_elements/active_support_selections.rb +10 -0
  15. data/lib/ax_elements/mri.rb +57 -0
  16. data/lib/ax_elements/nsarray_compat.rb +97 -17
  17. data/rakelib/gem.rake +12 -3
  18. data/rakelib/test.rake +0 -6
  19. data/test/helper.rb +10 -20
  20. data/test/integration/accessibility/test_dsl.rb +6 -14
  21. data/test/integration/accessibility/test_enumerators.rb +0 -1
  22. data/test/integration/accessibility/test_graph.rb +1 -0
  23. data/test/integration/accessibility/test_qualifier.rb +2 -2
  24. data/test/integration/ax/test_application.rb +2 -2
  25. data/test/sanity/accessibility/test_factory.rb +2 -2
  26. data/test/sanity/accessibility/test_pretty_printer.rb +2 -2
  27. data/test/sanity/ax/test_application.rb +1 -1
  28. data/test/sanity/ax/test_element.rb +2 -2
  29. data/test/sanity/ax_elements/test_nsobject_inspect.rb +4 -2
  30. metadata +28 -36
  31. data/ext/accessibility/core/core.c +0 -26
  32. data/lib/accessibility/core.rb +0 -943
  33. data/lib/accessibility/highlighter.rb +0 -86
  34. data/lib/accessibility/statistics.rb +0 -57
  35. data/lib/ax_elements/core_graphics_workaround.rb +0 -7
  36. data/lib/ax_elements/vendor/inflection_data.rb +0 -66
  37. data/lib/ax_elements/vendor/inflections.rb +0 -176
  38. data/lib/ax_elements/vendor/inflector.rb +0 -306
  39. data/lib/minitest/ax_elements.rb +0 -180
  40. data/lib/rspec/expectations/ax_elements.rb +0 -234
  41. data/test/integration/accessibility/test_core.rb +0 -18
  42. data/test/integration/minitest/test_ax_elements.rb +0 -89
  43. data/test/integration/rspec/expectations/test_ax_elements.rb +0 -102
  44. data/test/sanity/accessibility/test_highlighter.rb +0 -56
  45. data/test/sanity/accessibility/test_statistics.rb +0 -57
  46. data/test/sanity/minitest/test_ax_elements.rb +0 -17
  47. data/test/sanity/rspec/expectations/test_ax_elements.rb +0 -15
  48. data/test/test_core.rb +0 -454
@@ -1,180 +0,0 @@
1
- require 'ax/element'
2
- require 'accessibility/qualifier'
3
- require 'accessibility/dsl'
4
-
5
- ##
6
- # AXElements assertions for MiniTest.
7
- # [Learn more about minitest.](https://github.com/seattlerb/minitest)
8
- class MiniTest::Assertions
9
-
10
- ##
11
- # Test that an element has a specific child. For example, test
12
- # that a table has a row with certain contents. You can pass any
13
- # filters that you normally would during a search, including a block.
14
- #
15
- # @example
16
- #
17
- # assert_has_child table, :row, static_text: { value: 'Mark' }
18
- #
19
- # @param parent [AX::Element]
20
- # @param kind [#to_s]
21
- # @param filters [Hash]
22
- # @yield Optional block used for filtering
23
- # @return [AX::Element]
24
- def assert_has_child parent, kind, filters = {}, &block
25
- msg = message {
26
- child = ax_search_id kind, filters, block
27
- "Expected #{parent.inspect} to have #{child} as a child"
28
- }
29
- result = ax_check_children parent, kind, filters, block
30
- refute result.blank?, msg
31
- result
32
- end
33
-
34
- ##
35
- # Test that an element has a specifc descendent. For example, test
36
- # that a window contains a specific label. You can pass any filters
37
- # that you normally would during a search, including a block.
38
- #
39
- # @example
40
- #
41
- # assert_has_descendent window, :static_text, value: /Cake/
42
- #
43
- # @param ancestor [AX::Element]
44
- # @param kind [#to_s]
45
- # @param filters [Hash]
46
- # @yield Optional block used for filtering
47
- # @return [AX::Element]
48
- def assert_has_descendent ancestor, kind, filters = {}, &block
49
- msg = message {
50
- descendent = ax_search_id kind, filters, block
51
- "Expected #{ancestor.inspect} to have #{descendent} as a descendent"
52
- }
53
- result = ax_check_descendent ancestor, kind, filters, block
54
- refute result.blank?, msg
55
- result
56
- end
57
- alias_method :assert_has_descendant, :assert_has_descendent
58
-
59
- ##
60
- # Test that an element will have a child/descendent soon. This method
61
- # will block until the element is found or a timeout occurs.
62
- #
63
- # This is a minitest front end to using {DSL#wait_for}, so any
64
- # parameters you would normally pass to that method will work here.
65
- # This also means that you must include either a `parent` key or an
66
- # `ancestor` key as one of the filters.
67
- #
68
- # @param kind [#to_s]
69
- # @param filters [Hash]
70
- # @yield An optional block to be used in the search qualifier
71
- def assert_shortly_has kind, filters = {}, &block
72
- # need to know if parent/ancestor now because wait_for eats some keys
73
- (ancest = filters[:ancestor]) || (parent = filters[:parent])
74
- msg = message {
75
- descend = ax_search_id kind, filters, block
76
- if ancest
77
- "Expected #{ancest.inspect} to have descendent #{descend} before a timeout occurred"
78
- else
79
- "Expected #{parent.inspect} to have child #{descend} before a timeout occurred"
80
- end
81
- }
82
- result = wait_for kind, filters, &block
83
- refute result.blank?, msg
84
- result
85
- end
86
-
87
- ##
88
- # Test that an element _does not_ have a specific child. For example,
89
- # test that a row is no longer in a table. You can pass any filters
90
- # that you normally would during a search, including a block.
91
- #
92
- # @example
93
- #
94
- # refute_has_child table, :row, id: 'MyRow'
95
- #
96
- # @param parent [AX::Element]
97
- # @param kind [#to_s]
98
- # @param filters [Hash]
99
- # @yield An optional block to be used in the search qualifier
100
- # @return [nil]
101
- def refute_has_child parent, kind, filters = {}, &block
102
- result = ax_check_children parent, kind, filters, block
103
- msg = message {
104
- "Expected #{parent.inspect} NOT to have #{result} as a child"
105
- }
106
- assert result.blank?, msg
107
- result
108
- end
109
-
110
- ##
111
- # Test that an element _does not_ have a specific descendent. For
112
- # example, test that a window does not contain a spinning progress
113
- # indicator anymore.
114
- #
115
- # @example
116
- #
117
- # refute_has_descendent window, :busy_indicator
118
- #
119
- # @param ancestor [AX::Element]
120
- # @param kind [#to_s]
121
- # @param filters [Hash]
122
- # @yield An optional block to be used in the search qualifier
123
- # @return [nil,Array()]
124
- def refute_has_descendent ancestor, kind, filters = {}, &block
125
- result = ax_check_descendent ancestor, kind, filters, block
126
- msg = message {
127
- "Expected #{ancestor.inspect} NOT to have #{result} as a descendent"
128
- }
129
- assert result.blank?, msg
130
- result
131
- end
132
- alias_method :refute_has_descendant, :refute_has_descendent
133
-
134
- ##
135
- # @todo Does having this assertion make sense? I've only added it
136
- # for the time being because OCD demands it.
137
- #
138
- # Test that an element will NOT have a child/descendent soon. This
139
- # method will block until the element is found or a timeout occurs.
140
- #
141
- # This is a minitest front end to using {DSL#wait_for}, so any
142
- # parameters you would normally pass to that method will work here.
143
- # This also means that you must include either a `parent` key or an
144
- # `ancestor` key as one of the filters.
145
- #
146
- # @param kind [#to_s]
147
- # @param filters [Hash]
148
- # @yield An optional block to be used in the search qualifier
149
- # @return [nil]
150
- def refute_shortly_has kind, filters = {}, &block
151
- result = wait_for kind, filters, &block
152
- msg = message {
153
- if ancest = filters[:ancestor]
154
- "Expected #{ancest.inspect} NOT to have #{result.inspect} as a descendent"
155
- else
156
- parent = filters[:parent]
157
- "Expected #{parent.inspect} NOT to have #{result.inspect} as a child"
158
- end
159
- }
160
- assert result.blank?, msg
161
- result
162
- end
163
-
164
-
165
- private
166
-
167
- def ax_search_id kind, filters, block
168
- Accessibility::Qualifier.new(kind, filters, &block).describe
169
- end
170
-
171
- def ax_check_children parent, kind, filters, block
172
- q = Accessibility::Qualifier.new(kind, filters, &block)
173
- parent.children.find { |x| q.qualifies? x }
174
- end
175
-
176
- def ax_check_descendent ancestor, kind, filters, block
177
- ancestor.search(kind, filters, &block)
178
- end
179
-
180
- end
@@ -1,234 +0,0 @@
1
- require 'accessibility/dsl'
2
- require 'accessibility/qualifier'
3
- require 'ax/element'
4
-
5
- module Accessibility
6
-
7
- ##
8
- # @abstract
9
- #
10
- # Base class for RSpec matchers used with AXElements.
11
- class AbstractMatcher
12
-
13
- # @return [#to_s]
14
- attr_reader :kind
15
-
16
- # @return [Hash{Symbol=>Object}]
17
- attr_reader :filters
18
-
19
- # @return [Proc]
20
- attr_reader :block
21
-
22
- # @param kind [#to_s]
23
- # @param filters [Hash]
24
- # @yield Optional block used for search filtering
25
- def initialize kind, filters, &block
26
- @kind, @filters, @block = kind, filters, block
27
- end
28
-
29
- # @param element [AX::Element]
30
- def does_not_match? element
31
- !matches?(element)
32
- end
33
-
34
-
35
- private
36
-
37
- # @return [Accessibility::Qualifier]
38
- def qualifier
39
- @qualifier ||= Accessibility::Qualifier.new(kind, filters, &block)
40
- end
41
- end
42
-
43
- ##
44
- # Custom matcher for RSpec to check if an element has the specified
45
- # child element.
46
- class HasChildMatcher < AbstractMatcher
47
- # @param parent [AX::Element]
48
- def matches? parent
49
- @parent = parent
50
- @result = parent.children.find { |x| qualifier.qualifies? x }
51
- !@result.blank?
52
- end
53
-
54
- # @return [String]
55
- def failure_message_for_should
56
- "Expected #@parent to have child #{qualifier.describe}"
57
- end
58
-
59
- # @return [String]
60
- def failure_message_for_should_not
61
- "Expected #@parent to NOT have child #@result"
62
- end
63
-
64
- # @return [String]
65
- def description
66
- "should have a child that matches #{qualifier.describe}"
67
- end
68
- end
69
-
70
- ##
71
- # Custom matcher for RSpec to check if an element has the specified
72
- # descendent element.
73
- class HasDescendentMatcher < AbstractMatcher
74
- # @param ancestor [AX::Element]
75
- def matches? ancestor
76
- @ancestor = ancestor
77
- @result = ancestor.search(kind, filters, &block)
78
- !@result.blank?
79
- end
80
-
81
- # @return [String]
82
- def failure_message_for_should
83
- "Expected #@ancestor to have descendent #{qualifier.describe}"
84
- end
85
-
86
- # @return [String]
87
- def failure_message_for_should_not
88
- "Expected #@ancestor to NOT have descendent #@result"
89
- end
90
-
91
- # @return [String]
92
- def description
93
- "should have a descendent matching #{qualifier.describe}"
94
- end
95
- end
96
-
97
- ##
98
- # Custom matcher for RSpec to check if an element has the specified
99
- # child element within a grace period. Used for testing things
100
- # after an asynchronous action is performed.
101
- class HasChildShortlyMatcher < AbstractMatcher
102
- include DSL
103
-
104
- # @param parent [AX::Element]
105
- def matches? parent
106
- @filters[:parent] = @parent = parent
107
- @result = wait_for kind, filters, &block
108
- !@result.blank?
109
- end
110
-
111
- # @return [String]
112
- def failure_message_for_should
113
- "Expected #@parent to have child #{qualifier.describe} before a timeout occurred"
114
- end
115
-
116
- # @return [String]
117
- def failure_message_for_should_not
118
- "Expected #@parent to NOT have child #@result before a timeout occurred"
119
- end
120
-
121
- # @return [String]
122
- def description
123
- "should have a child that matches #{qualifier.describe} before a timeout occurs"
124
- end
125
- end
126
-
127
- ##
128
- # Custom matcher for RSpec to check if an element has the specified
129
- # descendent element within a grace period. Used for testing things
130
- # after an asynchronous action is performed.
131
- class HasDescendentShortlyMatcher < AbstractMatcher
132
- include DSL
133
-
134
- # @param ancestor [AX::Element]
135
- def matches? ancestor
136
- @filters[:ancestor] = @ancestor = ancestor
137
- @result = wait_for kind, filters, &block
138
- !@result.blank?
139
- end
140
-
141
- # @return [String]
142
- def failure_message_for_should
143
- "Expected #@ancestor to have descendent #{qualifier.describe} before a timeout occurred"
144
- end
145
-
146
- # @return [String]
147
- def failure_message_for_should_not
148
- "Expected #@ancestor to NOT have descendent #@result before a timeout occurred"
149
- end
150
-
151
- # @return [String]
152
- def description
153
- "should have a descendent matching #{qualifier.describe} before a timeout occurs"
154
- end
155
- end
156
- end
157
-
158
-
159
- ##
160
- # Assert that the receiving element has the specified child element. You
161
- # can use any filters you would normally use in a search, including
162
- # a block.
163
- #
164
- # @example
165
- #
166
- # window.toolbar.should have_child(:search_field)
167
- # table.should have_child(:row, static_text: { value: /42/ })
168
- #
169
- # search_field.should_not have_child(:busy_indicator)
170
- #
171
- # @param kind [#to_s]
172
- # @param filters [Hash]
173
- # @yield An optional block to be used as part of the search qualifier
174
- def have_child kind, filters = {}, &block
175
- Accessibility::HasChildMatcher.new kind, filters, &block
176
- end
177
-
178
- ##
179
- # Assert that the given element has the specified descendent. You can
180
- # pass any parameters you normally would use during a search,
181
- # including a block.
182
- #
183
- # @example
184
- #
185
- # app.main_window.should have_descendent(:button, title: 'Press Me')
186
- #
187
- # row.should_not have_descendent(:check_box)
188
- #
189
- # @param kind [#to_s]
190
- # @param filters [Hash]
191
- # @yield An optional block to be used as part of the search qualifier
192
- def have_descendent kind, filters = {}, &block
193
- Accessibility::HasDescendentMatcher.new kind, filters, &block
194
- end
195
- alias :have_descendant :have_descendent
196
-
197
- ##
198
- # Assert that the given element has the specified child soon. This
199
- # method will block until the child is found or a timeout occurs. You
200
- # can pass any parameters you normally would use during a search,
201
- # including a block.
202
- #
203
- # @example
204
- #
205
- # app.main_window.should shortly_have_child(:row, static_text: { value: 'Cake' })
206
- #
207
- # row.should_not shortly_have_child(:check_box)
208
- #
209
- # @param kind [#to_s]
210
- # @param filters [Hash]
211
- # @yield An optional block to be used as part of the search qualifier
212
- def shortly_have_child kind, filters = {}, &block
213
- Accessibility::HasChildShortlyMatcher.new(kind, filters, &block)
214
- end
215
-
216
- ##
217
- # Assert that the given element has the specified descendent soon. This
218
- # method will block until the descendent is found or a timeout occurs.
219
- # You can pass any parameters you normally would use during a search,
220
- # including a block.
221
- #
222
- # @example
223
- #
224
- # app.main_window.should shortly_have_child(:row, static_text: { value: 'Cake' })
225
- #
226
- # row.should_not shortly_have_child(:check_box)
227
- #
228
- # @param kind [#to_s]
229
- # @param filters [Hash]
230
- # @yield An optional block to be used as part of the search qualifier
231
- def shortly_have_descendent kind, filters = {}, &block
232
- Accessibility::HasDescendentShortlyMatcher.new kind, filters, &block
233
- end
234
- alias :shortly_have_descendant :shortly_have_descendent
@@ -1,18 +0,0 @@
1
- require 'test/integration/helper'
2
-
3
- class TestAccessibilityCore < MiniTest::Unit::TestCase
4
-
5
- # this assumes that radar://10040865 is not fixed
6
- # once it is fixed, this case becomes less of an
7
- # issue anyways
8
- def test_nil_children_returns_empty_array
9
- app = app_with_name 'AXElementsTester'
10
- menu = app.menu_bar_item(title: 'Help')
11
- press menu
12
-
13
- assert_empty menu.search_field.children
14
- ensure
15
- cancel menu if menu
16
- end
17
-
18
- end
@@ -1,89 +0,0 @@
1
- require 'test/integration/helper'
2
- require 'minitest/ax_elements'
3
-
4
- class TestMiniTestAssertions < MiniTest::Unit::TestCase
5
-
6
- def test_assert_has_child
7
- expected = app.window
8
-
9
- assert_equal expected, assert_has_child(app, :window)
10
- assert_equal expected, assert_has_child(app, :window, title: 'AXElementsTester')
11
-
12
- assert_has_child(app, :window) { |_| @got_called = true }
13
- assert @got_called
14
- end
15
-
16
- def test_assert_has_child_raises_in_failure_cases
17
- e = assert_raises(MiniTest::Assertion) { assert_has_child app, :button }
18
- assert_match /to have Button as a child/, e.message
19
-
20
- e = assert_raises(MiniTest::Assertion) { assert_has_child app, :button, title: "Press" }
21
- assert_match %r{to have Button\(title: "Press"\) as a child}, e.message
22
- end
23
-
24
- def test_assert_has_descendent
25
- expected = app.main_window.check_box
26
-
27
- assert_equal expected, assert_has_descendent(app,:check_box)
28
- assert_equal expected, assert_has_descendent(app,:check_box, title: /Box/)
29
-
30
- assert_has_descendent(app, :check_box) { |_| @got_called = true }
31
- assert @got_called
32
- end
33
-
34
- def test_assert_has_descendent_raises_in_failure_cases
35
- e = assert_raises(MiniTest::Assertion) {
36
- assert_has_descendent(app.main_window.slider, :window, title: /Cake/)
37
- }
38
- assert_match /to have Window\(title: \/Cake\/\) as a descendent/, e.message
39
- end
40
-
41
- def test_assert_shortly_has
42
- assert_equal app.window, assert_shortly_has(:window, parent: app)
43
- assert_equal app.check_box, assert_shortly_has(:check_box, ancestor: app)
44
-
45
- assert_shortly_has(:window, parent: app) { @got_called = true }
46
- assert @got_called
47
- end
48
-
49
- def test_assert_shortly_has_raises_in_failure_cases
50
- e = assert_raises(MiniTest::Assertion) { assert_shortly_has(:button, parent: app, timeout: 0) }
51
- assert_match /to have child Button before a timeout occurred/, e.message
52
-
53
- e = assert_raises(MiniTest::Assertion) { assert_shortly_has(:table, ancestor: app.menu_bar_item, timeout: 0) }
54
- assert_match /to have descendent Table before a timeout occurred/, e.message
55
- end
56
-
57
- def test_refute_has_child
58
- assert_nil refute_has_child(app, :button)
59
- assert_nil refute_has_child(app, :window, title: 'Herp Derp')
60
-
61
- result = refute_has_child(app, :window) { |x| x.title == 'Herp Derp' }
62
- assert_nil result
63
- end
64
-
65
- def test_refute_has_child_raises_in_failure_cases
66
- e = assert_raises(MiniTest::Assertion) { refute_has_child app, :window }
67
- assert_match /NOT to have #{Regexp.escape(app.window.inspect)} as a child/, e.message
68
- end
69
-
70
- def test_refute_has_descendent
71
- slider = app.main_window.slider
72
-
73
- assert_nil refute_has_descendent(slider, :window)
74
- assert_nil refute_has_descendent(slider, :element, title: 'Rhubarb')
75
-
76
- result = refute_has_descendent slider, :element do |x|
77
- @got_called = true
78
- x.attributes.include?(:title) && x.title == 'Rhubarb'
79
- end
80
- assert_nil result
81
- assert @got_called
82
- end
83
-
84
- def test_refute_has_descendent_raises_in_failure_cases
85
- e = assert_raises(MiniTest::Assertion) { refute_has_descendent app, :window }
86
- assert_match /#{Regexp.escape(app.window.inspect)} as a descendent/, e.message
87
- end
88
-
89
- end