AXElements 0.7.5 → 0.7.6

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.
@@ -98,13 +98,13 @@ module Accessibility::Core
98
98
  def attribute name
99
99
  ptr = Pointer.new :id
100
100
  case code = AXUIElementCopyAttributeValue(self, name, ptr)
101
- when 0 then ptr.value.to_ruby
102
- when KAXErrorNoValue then nil
103
- when KAXErrorInvalidUIElement
101
+ when 0
102
+ ptr.value.to_ruby
103
+ when KAXErrorNoValue, KAXErrorAttributeUnsupported,
104
+ KAXErrorFailure, KAXErrorInvalidUIElement then
104
105
  name == KAXChildrenAttribute ? [] : nil
105
- when KAXErrorFailure
106
- name == KAXChildrenAttribute ? [] : handle_error(code, name)
107
- else handle_error code, name
106
+ else
107
+ handle_error code, name
108
108
  end
109
109
  end
110
110
 
@@ -177,10 +177,13 @@ module Accessibility::Core
177
177
  def size_of name
178
178
  ptr = Pointer.new :long_long
179
179
  case code = AXUIElementGetAttributeValueCount(self, name, ptr)
180
- when 0 then ptr.value
180
+ when 0
181
+ ptr.value
181
182
  when KAXErrorFailure, KAXErrorAttributeUnsupported,
182
- KAXErrorInvalidUIElement then 0
183
- else handle_error code, name
183
+ KAXErrorNoValue, KAXErrorInvalidUIElement
184
+ 0
185
+ else
186
+ handle_error code, name
184
187
  end
185
188
  end
186
189
 
@@ -196,9 +199,13 @@ module Accessibility::Core
196
199
  def writable? name
197
200
  ptr = Pointer.new :bool
198
201
  case code = AXUIElementIsAttributeSettable(self, name, ptr)
199
- when 0 then ptr.value
200
- when KAXErrorInvalidUIElement then false
201
- else handle_error code, name
202
+ when 0
203
+ ptr.value
204
+ when KAXErrorFailure, KAXErrorAttributeUnsupported,
205
+ KAXErrorNoValue, KAXErrorInvalidUIElement
206
+ false
207
+ else
208
+ handle_error code, name
202
209
  end
203
210
  end
204
211
 
@@ -223,8 +230,11 @@ module Accessibility::Core
223
230
  # @param [String] name an attribute constant
224
231
  def set name, value
225
232
  code = AXUIElementSetAttributeValue(self, name, value.to_ax)
226
- return value if code.zero?
227
- handle_error code, name, value
233
+ if code.zero?
234
+ value
235
+ else
236
+ handle_error code, name, value
237
+ end
228
238
  end
229
239
 
230
240
 
@@ -270,12 +280,15 @@ module Accessibility::Core
270
280
  # @param [String] attr an attribute constant
271
281
  # @param [Object] param
272
282
  def attribute name, for_parameter: param
273
- ptr = Pointer.new :id
274
- param = param.to_ax
275
- case code = AXUIElementCopyParameterizedAttributeValue(self,name,param,ptr)
276
- when 0 then ptr.value.to_ruby
277
- when KAXErrorNoValue, KAXErrorInvalidUIElement then nil
278
- else handle_error code, name, param
283
+ ptr = Pointer.new :id
284
+ case code = AXUIElementCopyParameterizedAttributeValue(self, name, param.to_ax, ptr)
285
+ when 0
286
+ ptr.value.to_ruby
287
+ when KAXErrorFailure, KAXErrorAttributeUnsupported,
288
+ KAXErrorNoValue, KAXErrorInvalidUIElement
289
+ nil
290
+ else
291
+ handle_error code, name, param
279
292
  end
280
293
  end
281
294
 
@@ -318,8 +331,11 @@ module Accessibility::Core
318
331
  # @return [Boolean]
319
332
  def perform action
320
333
  code = AXUIElementPerformAction(self, action)
321
- return true if code.zero?
322
- handle_error code, action
334
+ if code.zero?
335
+ true
336
+ else
337
+ handle_error code, action
338
+ end
323
339
  end
324
340
 
325
341
  ##
@@ -398,9 +414,14 @@ module Accessibility::Core
398
414
  def element_at point
399
415
  ptr = Pointer.new ELEMENT
400
416
  case code = AXUIElementCopyElementAtPosition(self, *point.to_point, ptr)
401
- when 0 then ptr.value
402
- when KAXErrorNoValue then nil
403
- else handle_error code, point, nil, nil
417
+ when 0
418
+ ptr.value
419
+ when KAXErrorNoValue
420
+ nil
421
+ when KAXErrorInvalidUIElement
422
+ system_wide.element_at point unless self == system_wide
423
+ else
424
+ handle_error code, point, nil, nil
404
425
  end
405
426
  end
406
427
 
@@ -453,9 +474,11 @@ module Accessibility::Core
453
474
  raise ArgumentError, 'A callback is required' unless block_given?
454
475
  ptr = Pointer.new OBSERVER
455
476
  callback = proc { |obsrvr, sender, notif, ctx| yield obsrvr, sender, notif }
456
- case code = AXObserverCreate(pid, callback, ptr)
457
- when 0 then ptr.value
458
- else handle_error code, callback
477
+ code = AXObserverCreate(pid, callback, ptr)
478
+ if code.zero?
479
+ ptr.value
480
+ else
481
+ handle_error code, callback
459
482
  end
460
483
  end
461
484
 
@@ -540,12 +563,14 @@ module Accessibility::Core
540
563
  # @return [Fixnum]
541
564
  def pid
542
565
  @pid ||= (
543
- ptr = Pointer.new :int
566
+ ptr = Pointer.new :int
544
567
  case code = AXUIElementGetPid(self, ptr)
545
- when 0 then ptr.value
568
+ when 0
569
+ ptr.value
546
570
  when KAXErrorInvalidUIElement
547
571
  self == system_wide ? 0 : handle_error(code)
548
- else handle_error code
572
+ else
573
+ handle_error code
549
574
  end
550
575
  )
551
576
  end
@@ -889,9 +914,3 @@ class CGPoint
889
914
  # @return [CGPoint]
890
915
  def to_point; self end
891
916
  end
892
-
893
- ##
894
- # Cached reference to the system wide object.
895
- #
896
- # @return [AXUIElementRef]
897
- SYSTEMWIDE = AXUIElementCreateSystemWide()
@@ -210,7 +210,7 @@ module Accessibility::DSL
210
210
  #
211
211
  # @param [AX::Element]
212
212
  def set_focus_to element
213
- element.set(:focused, true) if element.respond_to? :focused?
213
+ element.set(:focused, true) if element.respond_to? :focused
214
214
  end
215
215
  alias_method :set_focus, :set_focus_to
216
216
 
@@ -243,7 +243,7 @@ module Accessibility::DSL
243
243
  # @return [nil] do not rely on a return value
244
244
  def set element, change
245
245
  if element.respond_to? :focused
246
- if element.attribute_writable? :focused
246
+ if element.writable? :focused
247
247
  element.set :focused, true
248
248
  end
249
249
  end
@@ -66,16 +66,11 @@ module Accessibility::Factory
66
66
  # @param [AXUIElementRef]
67
67
  # @return [AX::Element]
68
68
  def process_element ref
69
- role = TRANSLATOR.unprefix ref.role
70
- attrs = ref.attributes
71
- klass = if attrs.include? KAXSubroleAttribute
72
- subrole = ref.subrole
73
- # Some objects claim to have a subrole but return nil
74
- if subrole
75
- class_for TRANSLATOR.unprefix(subrole), and: role
76
- else
77
- class_for role
78
- end
69
+ role = TRANSLATOR.unprefix ref.role
70
+
71
+ # Some objects claim to have a subrole but return nil
72
+ klass = if subrole = ref.subrole
73
+ class_for TRANSLATOR.unprefix(subrole), and: role
79
74
  else
80
75
  class_for role
81
76
  end
@@ -87,9 +82,9 @@ module Accessibility::Factory
87
82
  #
88
83
  # @return [Array]
89
84
  def process_array vals
90
- return vals if vals.empty?
91
- return vals if CFGetTypeID(vals.first) != REF_TYPE
92
- return vals.map { |val| process_element val }
85
+ (vals.empty? && vals) ||
86
+ (CFGetTypeID(vals.first) != REF_TYPE && vals) ||
87
+ vals.map { |val| process_element val }
93
88
  end
94
89
 
95
90
  ##
@@ -137,7 +132,7 @@ module Accessibility::Factory
137
132
 
138
133
  ##
139
134
  # Create a new class in the {AX} namesapce that has the given
140
- # `superklass` as the superclass..
135
+ # `superklass` as the superclass.
141
136
  #
142
137
  # @param [#to_s] name
143
138
  # @param [#to_s] superklass
@@ -18,7 +18,6 @@ module Accessibility::PPInspector
18
18
  #
19
19
  # @return [String]
20
20
  def pp_identifier
21
- # @todo Break this method up into chunks
22
21
  # @note use, or lack of use, of #inspect is intentional for visual effect
23
22
 
24
23
  if attributes.include? :value
@@ -1,6 +1,6 @@
1
1
  module Accessibility
2
2
  # @return [String]
3
- VERSION = '0.7.5'
3
+ VERSION = '0.7.6'
4
4
 
5
5
  # @return [String]
6
6
  CODE_NAME = 'Clefairy'
@@ -9,6 +9,13 @@ require 'accessibility/string'
9
9
  class AX::Application < AX::Element
10
10
  include Accessibility::String
11
11
 
12
+ ##
13
+ # @private
14
+ # Cached reference to the system wide object.
15
+ #
16
+ # @return [AXUIElementRef]
17
+ SYSTEMWIDE = AXUIElementCreateSystemWide()
18
+
12
19
  ##
13
20
  # Overridden so that we can also cache the `NSRunningApplication`
14
21
  # instance for this object.
@@ -81,7 +88,7 @@ class AX::Application < AX::Element
81
88
  # Overridden to handle the {Accessibility::Language#set_focus} case.
82
89
  #
83
90
  # (see AX::Element#set:to:)
84
- def set attr, to: value
91
+ def set attr, value
85
92
  case attr
86
93
  when :focused
87
94
  perform(value ? :unhide : :hide)
data/lib/ax/element.rb CHANGED
@@ -17,6 +17,7 @@ class AX::Element
17
17
  include Accessibility::PPInspector
18
18
  include Accessibility::Factory
19
19
 
20
+
20
21
  # @param [AXUIElementRef]
21
22
  def initialize ref
22
23
  @ref = ref
@@ -34,7 +35,7 @@ class AX::Element
34
35
  #
35
36
  # @return [Array<Symbol>]
36
37
  def attributes
37
- @attributes ||= TRANSLATOR.rubyize @ref.attributes
38
+ @attrs ||= TRANSLATOR.rubyize @ref.attributes
38
39
  end
39
40
 
40
41
  ##
@@ -49,14 +50,15 @@ class AX::Element
49
50
  #
50
51
  # @param [#to_sym]
51
52
  def attribute name
52
- if rattr = lookup(name, @ref.attributes)
53
+ if rattr = TRANSLATOR.lookup(name, @ref.attributes)
53
54
  process @ref.attribute(rattr)
54
55
  end
55
56
  end
56
57
 
57
58
  ##
58
- # Needed to override inherited `NSObject#description`. If you want a
59
- # description of the object then you should use {#inspect} instead.
59
+ # Needed to override inherited `NSObject#description` as some
60
+ # elements have a `description` attribute. If you want a description
61
+ # of the object then you should use {#inspect} instead.
60
62
  def description
61
63
  attribute :description
62
64
  end
@@ -75,7 +77,7 @@ class AX::Element
75
77
  # @param [#to_sym]
76
78
  # @return [Number]
77
79
  def size_of attr
78
- if rattr = lookup(attr, @ref.attributes)
80
+ if rattr = TRANSLATOR.lookup(attr, @ref.attributes)
79
81
  @ref.size_of rattr
80
82
  else
81
83
  0
@@ -105,7 +107,7 @@ class AX::Element
105
107
  #
106
108
  # @param [#to_sym]
107
109
  def writable? attr
108
- if rattr = lookup(attr, @ref.attributes)
110
+ if rattr = TRANSLATOR.lookup(attr, @ref.attributes)
109
111
  @ref.writable? rattr
110
112
  else
111
113
  false
@@ -127,9 +129,7 @@ class AX::Element
127
129
  raise NoMethodError, "#{attr} is read-only for #{inspect}"
128
130
  end
129
131
  value = value.relative_to(@ref.value.size) if value.kind_of? Range
130
- rattr = lookup(attr, @ref.attributes)
131
- @ref.set rattr, value
132
- value
132
+ @ref.set TRANSLATOR.lookup(attr, @ref.attributes), value
133
133
  end
134
134
 
135
135
 
@@ -146,7 +146,7 @@ class AX::Element
146
146
  #
147
147
  # @return [Array<Symbol>]
148
148
  def parameterized_attributes
149
- TRANSLATOR.rubyize @ref.parameterized_attributes
149
+ @param_attrs ||= TRANSLATOR.rubyize @ref.parameterized_attributes
150
150
  end
151
151
 
152
152
  ##
@@ -158,7 +158,7 @@ class AX::Element
158
158
  #
159
159
  # @param [#to_sym]
160
160
  def attribute attr, for_parameter: param
161
- if rattr = lookup(attr, @ref.parameterized_attributes)
161
+ if rattr = TRANSLATOR.lookup(attr, @ref.parameterized_attributes)
162
162
  param = param.relative_to(@ref.value.size) if value.kind_of? Range
163
163
  process @ref.attribute(rattr, for_parameter: param)
164
164
  end
@@ -178,7 +178,7 @@ class AX::Element
178
178
  #
179
179
  # @return [Array<Symbol>]
180
180
  def actions
181
- TRANSLATOR.rubyize @ref.actions
181
+ @actions ||= TRANSLATOR.rubyize @ref.actions
182
182
  end
183
183
 
184
184
  ##
@@ -191,12 +191,13 @@ class AX::Element
191
191
  #
192
192
  # @example
193
193
  #
194
- # button.perform :press # => true
194
+ # button.perform :press # => true
195
+ # button.perform :make_pie # => false
195
196
  #
196
197
  # @param [#to_sym]
197
198
  # @return [Boolean] true if successful
198
199
  def perform action
199
- if raction = lookup(action, @ref.actions)
200
+ if raction = TRANSLATOR.lookup(action, @ref.actions)
200
201
  @ref.perform raction
201
202
  else
202
203
  false
@@ -226,7 +227,7 @@ class AX::Element
226
227
  tree = Accessibility::Enumerators::BreadthFirst.new(self)
227
228
 
228
229
  if TRANSLATOR.singularize(kind) == kind
229
- tree.find { |element| qualifier.qualifies? element }
230
+ tree.find { |element| qualifier.qualifies? element }
230
231
  else
231
232
  tree.find_all { |element| qualifier.qualifies? element }
232
233
  end
@@ -300,16 +301,18 @@ class AX::Element
300
301
  if method[-1] == EQUALS
301
302
  return set(method.chomp(EQUALS), args.first)
302
303
 
303
- elsif attr = lookup(method, @ref.attributes)
304
- return process @ref.attribute(attr)
304
+ elsif attributes.include? method
305
+ return attribute method
305
306
 
306
- elsif attr = lookup(method, @ref.parameterized_attributes)
307
- return process @ref.attribute(attr, for_parameter: args.first)
307
+ elsif parameterized_attributes.include? method
308
+ return attribute method, for_parameter: args.first
308
309
 
309
- elsif @ref.attributes.include? KAXChildrenAttribute
310
- result = search method, *args, &block
311
- return result unless result.blank?
312
- raise Accessibility::SearchFailure.new(self, method, args.first)
310
+ elsif attributes.include? :children
311
+ if (result = search method, *args, &block).blank?
312
+ raise Accessibility::SearchFailure.new(self, method, args.first)
313
+ else
314
+ return result
315
+ end
313
316
 
314
317
  else
315
318
  super
@@ -416,8 +419,8 @@ class AX::Element
416
419
  # Overriden to respond properly with regards to dynamic attribute
417
420
  # lookups, but will return false for potential implicit searches.
418
421
  def respond_to? name
419
- lookup(name.chomp(EQUALS), @ref.attributes) ||
420
- lookup(name, @ref.parameterized_attributes) ||
422
+ attributes.include?(name) ||
423
+ parameterized_attributes.include?(name) ||
421
424
  super
422
425
  end
423
426
 
@@ -486,11 +489,6 @@ class AX::Element
486
489
  # @return [String]
487
490
  EQUALS = '='
488
491
 
489
- def lookup key, values
490
- value = TRANSLATOR.lookup key, values
491
- return value if values.include? value
492
- end
493
-
494
492
  def notif_callback_for
495
493
  # we are ignoring the context pointer since this is OO
496
494
  Proc.new do |observer, sender, notif, _|
@@ -59,6 +59,22 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
59
59
  assert_equal app, dsl.app_with_pid(PID)
60
60
  end
61
61
 
62
+ def test_set_focus_to
63
+ assert dsl.set_focus_to app
64
+ assert dsl.set_focus app
65
+ assert dsl.set_focus_to app.main_window.search_field
66
+ assert dsl.set_focus app.main_window.search_field
67
+ end
68
+
69
+ def test_set
70
+ expected = 'Octocat is not Hello Kitty!'
71
+ field = app.main_window.search_field
72
+ dsl.set field, expected
73
+ assert_equal expected, field.value
74
+ ensure
75
+ field.set :value, '' if field
76
+ end
77
+
62
78
  def test_typing_human_string
63
79
  try_typing "A sentence, with punctuation and num8ers. LOL!\tA 'quoted' string--then some @#*$."
64
80
  end
@@ -17,12 +17,12 @@ class TestAXApplication < MiniTest::Unit::TestCase
17
17
  end
18
18
 
19
19
  def test_can_set_focus_and_blur_app # lol, blur
20
- assert app.set :focused, to: false
20
+ assert app.set :focused, false
21
21
  refute app.active?
22
22
  refute app.attribute :focused
23
23
  refute app.attribute :focused?
24
24
 
25
- assert app.set :focused, to: true
25
+ assert app.set :focused, true
26
26
  assert app.active?
27
27
  assert app.attribute :focused
28
28
  assert app.attribute :focused?
@@ -32,10 +32,10 @@ class TestAXApplication < MiniTest::Unit::TestCase
32
32
  end
33
33
 
34
34
  def test_can_hide_and_unhide_app
35
- assert app.set :hidden, to: true
35
+ assert app.set :hidden, true
36
36
  assert app.hidden?
37
37
 
38
- assert app.set :hidden, to: false
38
+ assert app.set :hidden, false
39
39
  refute app.hidden?
40
40
 
41
41
  assert app.perform :hide
@@ -48,6 +48,10 @@ class TestAXApplication < MiniTest::Unit::TestCase
48
48
  running_app.activateWithOptions NSApplicationActivateIgnoringOtherApps
49
49
  end
50
50
 
51
+ def test_set_calls_super
52
+ assert app.set(:enhanced_user_interface, true)
53
+ end
54
+
51
55
  def test_element_at_point
52
56
  button = app.main_window.close_button
53
57
  assert_equal button, app.element_at_point(button)
@@ -39,8 +39,4 @@ class TestAXElement < MiniTest::Unit::TestCase
39
39
  box.set :value, '' if box
40
40
  end
41
41
 
42
- # @todo test setting selected text
43
- # def test_setting
44
- # end
45
-
46
42
  end
@@ -70,7 +70,7 @@ class TestAccessibilityCore < MiniTest::Unit::TestCase
70
70
  assert_equal 10..19, window.attribute("AXPie" )
71
71
  end
72
72
 
73
- def test_attribute_is_nil_when_no_value
73
+ def test_attribute_when_no_value
74
74
  assert_nil window.attribute(KAXGrowAreaAttribute)
75
75
  end
76
76
 
@@ -79,8 +79,8 @@ class TestAccessibilityCore < MiniTest::Unit::TestCase
79
79
  assert_empty invalid_ref.attribute(KAXChildrenAttribute)
80
80
  end
81
81
 
82
- def test_attribute_handles_errors
83
- assert_raises(ArgumentError) { REF.attribute 'MADEUPATTRIBUTE' }
82
+ def test_attribute_when_not_supported_attribute
83
+ assert_nil REF.attribute('MADEUPATTRIBUTE')
84
84
  end
85
85
 
86
86
  def test_role
@@ -120,8 +120,8 @@ class TestAccessibilityCore < MiniTest::Unit::TestCase
120
120
  refute invalid_ref.writable? KAXRoleAttribute
121
121
  end
122
122
 
123
- def test_writable_handles_errors
124
- assert_raises(ArgumentError) { REF.writable? 'FAKE' }
123
+ def test_writable_false_for_bad_attributes
124
+ refute REF.writable? 'FAKE'
125
125
  end
126
126
 
127
127
  def test_set_number
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: AXElements
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.7.5
5
+ version: 0.7.6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Mark Rada
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-04 00:00:00 Z
12
+ date: 2012-04-06 00:00:00 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest