AXElements 0.8.1 → 0.9.0

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 (62) hide show
  1. data/.yardopts +4 -0
  2. data/History.markdown +41 -0
  3. data/README.markdown +59 -62
  4. data/Rakefile +1 -1
  5. data/ext/accessibility/key_coder/extconf.rb +1 -1
  6. data/ext/accessibility/key_coder/key_coder.c +8 -5
  7. data/lib/accessibility/dsl.rb +261 -87
  8. data/lib/accessibility/enumerators.rb +14 -11
  9. data/lib/accessibility/errors.rb +4 -3
  10. data/lib/accessibility/factory.rb +159 -108
  11. data/lib/accessibility/graph.rb +13 -9
  12. data/lib/accessibility/{pp_inspector.rb → pretty_printer.rb} +4 -5
  13. data/lib/accessibility/qualifier.rb +23 -13
  14. data/lib/accessibility/string.rb +4 -4
  15. data/lib/accessibility/system_info.rb +230 -0
  16. data/lib/accessibility/translator.rb +38 -28
  17. data/lib/accessibility/version.rb +24 -2
  18. data/lib/accessibility.rb +25 -8
  19. data/lib/ax/application.rb +207 -77
  20. data/lib/ax/element.rb +62 -65
  21. data/lib/ax/menu.rb +5 -1
  22. data/lib/ax/row.rb +1 -1
  23. data/lib/ax/scroll_area.rb +7 -6
  24. data/lib/ax/systemwide.rb +38 -5
  25. data/lib/ax_elements/active_support_selections.rb +10 -0
  26. data/lib/ax_elements/mri.rb +57 -0
  27. data/lib/ax_elements/nsarray_compat.rb +97 -17
  28. data/lib/ax_elements.rb +9 -1
  29. data/rakelib/gem.rake +11 -11
  30. data/rakelib/test.rake +0 -9
  31. data/test/helper.rb +10 -18
  32. data/test/integration/accessibility/test_dsl.rb +52 -42
  33. data/test/integration/accessibility/test_enumerators.rb +0 -1
  34. data/test/integration/accessibility/test_graph.rb +1 -0
  35. data/test/integration/accessibility/test_qualifier.rb +2 -2
  36. data/test/integration/ax/test_application.rb +9 -2
  37. data/test/integration/ax/test_element.rb +41 -1
  38. data/test/sanity/accessibility/test_factory.rb +23 -56
  39. data/test/sanity/accessibility/{test_pp_inspector.rb → test_pretty_printer.rb} +9 -9
  40. data/test/sanity/accessibility/test_translator.rb +2 -5
  41. data/test/sanity/accessibility/test_version.rb +15 -0
  42. data/test/sanity/ax/test_application.rb +17 -2
  43. data/test/sanity/ax/test_element.rb +2 -2
  44. data/test/sanity/ax_elements/test_nsobject_inspect.rb +4 -2
  45. data/test/sanity/test_ax_elements.rb +1 -0
  46. metadata +69 -39
  47. data/lib/accessibility/core.rb +0 -973
  48. data/lib/accessibility/highlighter.rb +0 -86
  49. data/lib/ax_elements/vendor/inflection_data.rb +0 -66
  50. data/lib/ax_elements/vendor/inflections.rb +0 -172
  51. data/lib/ax_elements/vendor/inflector.rb +0 -306
  52. data/lib/minitest/ax_elements.rb +0 -175
  53. data/lib/mouse.rb +0 -223
  54. data/lib/rspec/expectations/ax_elements.rb +0 -234
  55. data/test/integration/accessibility/test_core.rb +0 -18
  56. data/test/integration/minitest/test_ax_elements.rb +0 -89
  57. data/test/integration/rspec/expectations/test_ax_elements.rb +0 -102
  58. data/test/sanity/accessibility/test_core.rb +0 -561
  59. data/test/sanity/accessibility/test_highlighter.rb +0 -56
  60. data/test/sanity/minitest/test_ax_elements.rb +0 -17
  61. data/test/sanity/rspec/expectations/test_ax_elements.rb +0 -15
  62. data/test/sanity/test_mouse.rb +0 -19
@@ -1,175 +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 [AX::Element]
20
- # @param [#to_s]
21
- # @param [Hash]
22
- # @return [AX::Element]
23
- def assert_has_child parent, kind, filters = {}, &block
24
- msg = message {
25
- child = ax_search_id kind, filters, block
26
- "Expected #{parent.inspect} to have #{child} as a child"
27
- }
28
- result = ax_check_children parent, kind, filters, block
29
- refute result.blank?, msg
30
- result
31
- end
32
-
33
- ##
34
- # Test that an element has a specifc descendent. For example, test
35
- # that a window contains a specific label. You can pass any filters
36
- # that you normally would during a search, including a block.
37
- #
38
- # @example
39
- #
40
- # assert_has_descendent window, :static_text, value: /Cake/
41
- #
42
- # @param [AX::Element]
43
- # @param [#to_s]
44
- # @param [Hash]
45
- # @return [AX::Element]
46
- def assert_has_descendent ancestor, kind, filters = {}, &block
47
- msg = message {
48
- descendent = ax_search_id kind, filters, block
49
- "Expected #{ancestor.inspect} to have #{descendent} as a descendent"
50
- }
51
- result = ax_check_descendent ancestor, kind, filters, block
52
- refute result.blank?, msg
53
- result
54
- end
55
- alias_method :assert_has_descendant, :assert_has_descendent
56
-
57
- ##
58
- # Test that an element will have a child/descendent soon. This method
59
- # will block until the element is found or a timeout occurs.
60
- #
61
- # This is a minitest front end to using {DSL#wait_for}, so any
62
- # parameters you would normally pass to that method will work here.
63
- # This also means that you must include either a `parent` key or an
64
- # `ancestor` key as one of the filters.
65
- #
66
- # @param [#to_s]
67
- # @param [Hash]
68
- # @yield An optional block to be used in the search qualifier
69
- def assert_shortly_has kind, filters = {}, &block
70
- # need to know if parent/ancestor now because wait_for eats some keys
71
- (ancest = filters[:ancestor]) || (parent = filters[:parent])
72
- msg = message {
73
- descend = ax_search_id kind, filters, block
74
- if ancest
75
- "Expected #{ancest.inspect} to have descendent #{descend} before a timeout occurred"
76
- else
77
- "Expected #{parent.inspect} to have child #{descend} before a timeout occurred"
78
- end
79
- }
80
- result = wait_for kind, filters, &block
81
- refute result.blank?, msg
82
- result
83
- end
84
-
85
- ##
86
- # Test that an element _does not_ have a specific child. For example,
87
- # test that a row is no longer in a table. You can pass any filters
88
- # that you normally would during a search, including a block.
89
- #
90
- # @example
91
- #
92
- # refute_has_child table, :row, id: 'MyRow'
93
- #
94
- # @param [AX::Element]
95
- # @param [#to_s]
96
- # @param [Hash]
97
- # @return [nil]
98
- def refute_has_child parent, kind, filters = {}, &block
99
- result = ax_check_children parent, kind, filters, block
100
- msg = message {
101
- "Expected #{parent.inspect} NOT to have #{result} as a child"
102
- }
103
- assert result.blank?, msg
104
- result
105
- end
106
-
107
- ##
108
- # Test that an element _does not_ have a specific descendent. For
109
- # example, test that a window does not contain a spinning progress
110
- # indicator anymore.
111
- #
112
- # @example
113
- #
114
- # refute_has_descendent window, :busy_indicator
115
- #
116
- # @param [AX::Element]
117
- # @param [#to_s]
118
- # @param [Hash]
119
- # @return [nil,Array()]
120
- def refute_has_descendent ancestor, kind, filters = {}, &block
121
- result = ax_check_descendent ancestor, kind, filters, block
122
- msg = message {
123
- "Expected #{ancestor.inspect} NOT to have #{result} as a descendent"
124
- }
125
- assert result.blank?, msg
126
- result
127
- end
128
- alias_method :refute_has_descendant, :refute_has_descendent
129
-
130
- ##
131
- # @todo Does having this assertion make sense? I've only added it
132
- # for the time being because OCD demands it.
133
- #
134
- # Test that an element will NOT have a child/descendent soon. This
135
- # method will block until the element is found or a timeout occurs.
136
- #
137
- # This is a minitest front end to using {DSL#wait_for}, so any
138
- # parameters you would normally pass to that method will work here.
139
- # This also means that you must include either a `parent` key or an
140
- # `ancestor` key as one of the filters.
141
- #
142
- # @param [#to_s]
143
- # @param [Hash]
144
- # @yield An optional block to be used in the search qualifier
145
- def refute_shortly_has kind, filters = {}, &block
146
- result = wait_for kind, filters, &block
147
- msg = message {
148
- if ancest = filters[:ancestor]
149
- "Expected #{ancest.inspect} NOT to have #{result.inspect} as a descendent"
150
- else
151
- parent = filters[:parent]
152
- "Expected #{parent.inspect} NOT to have #{result.inspect} as a child"
153
- end
154
- }
155
- assert result.blank?, msg
156
- result
157
- end
158
-
159
-
160
- private
161
-
162
- def ax_search_id kind, filters, block
163
- Accessibility::Qualifier.new(kind, filters, &block).describe
164
- end
165
-
166
- def ax_check_children parent, kind, filters, block
167
- q = Accessibility::Qualifier.new(kind, filters, &block)
168
- parent.children.find { |x| q.qualifies? x }
169
- end
170
-
171
- def ax_check_descendent ancestor, kind, filters, block
172
- ancestor.search(kind, filters, &block)
173
- end
174
-
175
- end
data/lib/mouse.rb DELETED
@@ -1,223 +0,0 @@
1
- framework 'ApplicationServices'
2
-
3
- ##
4
- # This is a first attempt at writing a wrapper around the CoreGraphics event
5
- # taps API provided by OS X. The module provides a simple Ruby interface to
6
- # performing mouse interactions such as moving and clicking.
7
- #
8
- # [Reference](http://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html).
9
- #
10
- # A rewrite is in the works, but in the mean time this code base still works
11
- # despite its warts.
12
- module Mouse
13
- extend self
14
-
15
- ##
16
- # Number of animation steps per second.
17
- #
18
- # @return [Number]
19
- FPS = 120
20
-
21
- ##
22
- # @note We keep the number as a rational to try and avoid rounding
23
- # error introduced by the floats, especially MacRuby floats.
24
- #
25
- # Smallest unit of time allowed for an animation step.
26
- #
27
- # @return [Number]
28
- QUANTUM = Rational(1, FPS)
29
-
30
- ##
31
- # Available constants for the type of units to use when scrolling.
32
- #
33
- # @return [Hash{Symbol=>Fixnum}]
34
- UNIT = {
35
- line: KCGScrollEventUnitLine,
36
- pixel: KCGScrollEventUnitPixel
37
- }
38
-
39
- ##
40
- # The coordinates of the mouse using the flipped coordinate system
41
- # (origin in top left).
42
- #
43
- # @return [CGPoint]
44
- def current_position
45
- CGEventGetLocation(CGEventCreate(nil))
46
- end
47
-
48
- ##
49
- # Move the mouse from the current position to the given point.
50
- #
51
- # @param [CGPoint]
52
- # @param [Float] duration animation duration, in seconds
53
- def move_to point, duration = 0.2
54
- animate KCGEventMouseMoved, KCGMouseButtonLeft, current_position, point, duration
55
- end
56
-
57
- ##
58
- # Click and drag from the current position to the given point.
59
- #
60
- # @param [CGPoint]
61
- # @param [Float] duration animation duration, in seconds
62
- def drag_to point, duration = 0.2
63
- post new_event(KCGEventLeftMouseDown, current_position, KCGMouseButtonLeft)
64
-
65
- animate KCGEventLeftMouseDragged, KCGMouseButtonLeft, current_position, point, duration
66
-
67
- post new_event(KCGEventLeftMouseUp, current_position, KCGMouseButtonLeft)
68
- end
69
-
70
- ##
71
- # @todo Need to double check to see if I introduce any inaccuracies.
72
- #
73
- # Scroll at the current position the given amount of units.
74
- #
75
- # Scrolling too much or too little in a period of time will cause the
76
- # animation to look weird, possibly causing the app to mess things up.
77
- #
78
- # @param [Fixnum] amount number of units to scroll; positive to scroll
79
- # up or negative to scroll down
80
- # @param [Float] duration animation duration, in seconds
81
- # @param [Symbol] units `:line` scrolls by line, `:pixel` scrolls by pixel
82
- def scroll amount, duration = 0.2, units = :line
83
- units = UNIT[units] || raise(ArgumentError, "#{units} is not a valid unit")
84
- steps = (FPS * duration).round
85
- current = 0.0
86
- steps.times do |step|
87
- done = (step+1).to_f / steps
88
- scroll = ((done - current)*amount).floor
89
- post new_scroll_event(units, 1, scroll)
90
- sleep QUANTUM
91
- current += scroll.to_f / amount
92
- end
93
- end
94
-
95
- ##
96
- # Perform a down click. You should follow this up with a call to
97
- # {#click_up} to finish the click.
98
- #
99
- # @param [CGPoint]
100
- def click_down point = current_position, duration = 12
101
- event = new_event KCGEventLeftMouseDown, point, KCGMouseButtonLeft
102
- post event
103
- sleep QUANTUM*duration
104
- end
105
-
106
- ##
107
- # Perform an up click. This should only be called after a call to
108
- # {#click_down} to finish the click event.
109
- #
110
- # @param [CGPoint]
111
- def click_up point = current_position
112
- event = new_event KCGEventLeftMouseUp, point, KCGMouseButtonLeft
113
- post event
114
- end
115
-
116
- ##
117
- # Standard secondary click. Default position is the current position.
118
- #
119
- # @param [CGPoint]
120
- def secondary_click point = current_position, duration = 12
121
- event = new_event KCGEventRightMouseDown, point, KCGMouseButtonRight
122
- post event
123
- sleep QUANTUM*duration
124
- set_type event, KCGEventRightMouseUp
125
- post event
126
- end
127
- alias_method :right_click, :secondary_click
128
-
129
- ##
130
- # A standard double click. Defaults to clicking at the current position.
131
- #
132
- # @param [CGPoint]
133
- def double_click point = current_position
134
- event = new_event KCGEventLeftMouseDown, point, KCGMouseButtonLeft
135
- post event
136
- set_type event, KCGEventLeftMouseUp
137
- post event
138
-
139
- CGEventSetIntegerValueField(event, KCGMouseEventClickState, 2)
140
- set_type event, KCGEventLeftMouseDown
141
- post event
142
- set_type event, KCGEventLeftMouseUp
143
- post event
144
- end
145
-
146
- ##
147
- # Click with an arbitrary mouse button, using numbers to represent
148
- # the mouse button. At the time of writing, the documented values are:
149
- #
150
- # - KCGMouseButtonLeft = 0
151
- # - KCGMouseButtonRight = 1
152
- # - KCGMouseButtonCenter = 2
153
- #
154
- # And the rest are not documented! Though they should be easy enough
155
- # to figure out. See the `CGMouseButton` enum in the reference
156
- # documentation for the most up to date list.
157
- #
158
- # @param [CGPoint]
159
- # @param [Number]
160
- def arbitrary_click point = current_position, button = KCGMouseButtonCenter, duration = 12
161
- event = new_event KCGEventOtherMouseDown, point, button
162
- post event
163
- sleep QUANTUM*duration
164
- set_type event, KCGEventOtherMouseUp
165
- post event
166
- end
167
- alias_method :other_click, :arbitrary_click
168
-
169
-
170
- private
171
-
172
- ##
173
- # Executes a mouse movement animation. It can be a simple cursor
174
- # move or a drag depending on what is passed to `type`.
175
- def animate type, button, from, to, duration
176
- current = current_position
177
- xstep = (to.x - current.x) / (FPS * duration)
178
- ystep = (to.y - current.y) / (FPS * duration)
179
- start = NSDate.date
180
-
181
- until close_enough?(current, to)
182
- remaining = to.x - current.x
183
- current.x += xstep.abs > remaining.abs ? remaining : xstep
184
-
185
- remaining = to.y - current.y
186
- current.y += ystep.abs > remaining.abs ? remaining : ystep
187
-
188
- post new_event(type, current, button)
189
-
190
- sleep QUANTUM
191
- break if NSDate.date.timeIntervalSinceDate(start) > 5.0
192
- current = current_position
193
- end
194
- end
195
-
196
- def close_enough? current, target
197
- x = current.x - target.x
198
- y = current.y - target.y
199
- delta = Math.sqrt((x**2) + (y**2))
200
- delta <= 1.0
201
- end
202
-
203
- def new_event event, position, button
204
- CGEventCreateMouseEvent(nil, event, position, button)
205
- end
206
-
207
- # @param [Fixnum] wheel which scroll wheel to use (value between 1-3)
208
- def new_scroll_event units, wheel, amount
209
- CGEventCreateScrollWheelEvent(nil, units, wheel, amount)
210
- end
211
-
212
- def post event
213
- CGEventPost(KCGHIDEventTap, event)
214
- end
215
-
216
- ##
217
- # Change the event type for an instance of an event. This is how you would
218
- # reuse a specific event. In most cases, reusing events is a necessity.
219
- def set_type event, state
220
- CGEventSetType(event, state)
221
- end
222
-
223
- 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 [#to_s]
23
- # @param [Hash]
24
- # @yield
25
- def initialize kind, filters, &block
26
- @kind, @filters, @block = kind, filters, block
27
- end
28
-
29
- # @param [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 [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 [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 [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 [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 [#to_s]
172
- # @param [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 [#to_s]
190
- # @param [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 [#to_s]
210
- # @param [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 [#to_s]
229
- # @param [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