AXElements 1.0.0.alpha11 → 1.0.0.beta

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.
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