AXElements 0.6.0beta2 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/.yardopts +1 -2
  2. data/README.markdown +152 -88
  3. data/Rakefile +8 -103
  4. data/docs/Debugging.markdown +9 -2
  5. data/docs/KeyboardEvents.markdown +114 -49
  6. data/docs/Setting.markdown +1 -0
  7. data/docs/images/next_version.png +0 -0
  8. data/ext/accessibility/key_coder/extconf.rb +22 -0
  9. data/ext/accessibility/key_coder/key_coder.c +113 -0
  10. data/lib/AXElements.rb +2 -0
  11. data/lib/accessibility/core.rb +897 -0
  12. data/lib/accessibility/debug.rb +168 -0
  13. data/lib/accessibility/dsl.rb +697 -0
  14. data/lib/accessibility/enumerators.rb +104 -0
  15. data/lib/accessibility/errors.rb +32 -0
  16. data/lib/accessibility/factory.rb +153 -0
  17. data/lib/accessibility/graph.rb +150 -0
  18. data/lib/{ax_elements/inspector.rb → accessibility/pp_inspector.rb} +39 -28
  19. data/lib/accessibility/qualifier.rb +158 -0
  20. data/lib/accessibility/string.rb +494 -0
  21. data/lib/accessibility/translator.rb +178 -0
  22. data/lib/accessibility/version.rb +7 -0
  23. data/lib/accessibility.rb +79 -0
  24. data/lib/ax/application.rb +234 -0
  25. data/lib/{ax_elements/elements → ax}/button.rb +2 -0
  26. data/lib/ax/element.rb +518 -0
  27. data/lib/{ax_elements/elements → ax}/radio_button.rb +2 -0
  28. data/lib/ax/row.rb +37 -0
  29. data/lib/{ax_elements/elements → ax}/static_text.rb +2 -0
  30. data/lib/ax/systemwide.rb +86 -0
  31. data/lib/ax_elements/awesome_print.rb +25 -0
  32. data/lib/ax_elements/exception_workaround.rb +8 -0
  33. data/lib/ax_elements/nsarray_compat.rb +64 -0
  34. data/lib/ax_elements/vendor/inflection_data.rb +65 -0
  35. data/lib/ax_elements/vendor/inflections.rb +172 -0
  36. data/lib/ax_elements/vendor/inflector.rb +306 -0
  37. data/lib/ax_elements.rb +14 -25
  38. data/lib/minitest/ax_elements.rb +112 -12
  39. data/lib/mouse.rb +72 -46
  40. data/lib/rspec/expectations/ax_elements.rb +133 -6
  41. data/rakelib/doc.rake +13 -0
  42. data/rakelib/ext.rake +61 -0
  43. data/rakelib/gem.rake +28 -0
  44. data/rakelib/test.rake +53 -0
  45. data/test/helper.rb +11 -97
  46. data/test/integration/accessibility/test_core.rb +18 -0
  47. data/test/integration/accessibility/test_debug.rb +44 -0
  48. data/test/integration/accessibility/test_dsl.rb +225 -0
  49. data/test/integration/accessibility/test_enumerators.rb +122 -0
  50. data/test/integration/accessibility/test_errors.rb +38 -0
  51. data/test/integration/accessibility/test_notifications.rb +22 -0
  52. data/test/integration/accessibility/test_qualifier.rb +148 -0
  53. data/test/integration/ax/test_application.rb +56 -0
  54. data/test/integration/ax/test_element.rb +46 -0
  55. data/test/integration/ax/test_row.rb +23 -0
  56. data/test/integration/ax_elements/test_nsarray_compat.rb +43 -0
  57. data/test/integration/minitest/test_ax_elements.rb +98 -0
  58. data/test/integration/rspec/expectations/test_ax_elements.rb +58 -0
  59. data/test/integration/test_mouse.rb +35 -0
  60. data/test/sanity/accessibility/test_core.rb +553 -0
  61. data/test/sanity/accessibility/test_debug.rb +63 -0
  62. data/test/sanity/accessibility/test_dsl.rb +75 -0
  63. data/test/sanity/accessibility/test_errors.rb +10 -0
  64. data/test/sanity/accessibility/test_factory.rb +88 -0
  65. data/test/sanity/accessibility/test_pp_inspector.rb +110 -0
  66. data/test/sanity/accessibility/test_qualifier.rb +13 -0
  67. data/test/sanity/accessibility/test_string.rb +238 -0
  68. data/test/sanity/accessibility/test_translator.rb +145 -0
  69. data/test/sanity/ax/test_application.rb +90 -0
  70. data/test/sanity/ax/test_element.rb +80 -0
  71. data/test/sanity/ax/test_systemwide.rb +66 -0
  72. data/test/sanity/ax_elements/test_nsarray_compat.rb +16 -0
  73. data/test/sanity/ax_elements/test_nsobject_inspect.rb +11 -0
  74. data/test/sanity/minitest/test_ax_elements.rb +15 -0
  75. data/test/sanity/rspec/expectations/test_ax_elements.rb +12 -0
  76. data/test/sanity/test_ax_elements.rb +10 -0
  77. data/test/sanity/test_mouse.rb +19 -0
  78. metadata +111 -93
  79. data/LICENSE.txt +0 -25
  80. data/ext/key_coder/extconf.rb +0 -6
  81. data/ext/key_coder/key_coder.m +0 -77
  82. data/lib/ax_elements/accessibility/enumerators.rb +0 -104
  83. data/lib/ax_elements/accessibility/graph.rb +0 -118
  84. data/lib/ax_elements/accessibility/language.rb +0 -347
  85. data/lib/ax_elements/accessibility/qualifier.rb +0 -73
  86. data/lib/ax_elements/accessibility.rb +0 -166
  87. data/lib/ax_elements/core.rb +0 -541
  88. data/lib/ax_elements/element.rb +0 -593
  89. data/lib/ax_elements/elements/application.rb +0 -88
  90. data/lib/ax_elements/elements/row.rb +0 -30
  91. data/lib/ax_elements/elements/systemwide.rb +0 -46
  92. data/lib/ax_elements/macruby_extensions.rb +0 -255
  93. data/lib/ax_elements/notification.rb +0 -37
  94. data/lib/ax_elements/version.rb +0 -9
  95. data/test/elements/test_application.rb +0 -72
  96. data/test/elements/test_row.rb +0 -27
  97. data/test/elements/test_systemwide.rb +0 -38
  98. data/test/test_accessibility.rb +0 -127
  99. data/test/test_blankness.rb +0 -26
  100. data/test/test_core.rb +0 -448
  101. data/test/test_element.rb +0 -939
  102. data/test/test_enumerators.rb +0 -81
  103. data/test/test_inspector.rb +0 -130
  104. data/test/test_language.rb +0 -157
  105. data/test/test_macruby_extensions.rb +0 -303
  106. data/test/test_mouse.rb +0 -5
  107. data/test/test_search_semantics.rb +0 -143
data/test/helper.rb CHANGED
@@ -1,119 +1,33 @@
1
- require 'rubygems'
2
-
3
- require 'ax_elements'
4
- require 'stringio'
5
-
6
- # Accessibility.log.level = Logger::DEBUG
1
+ framework 'Cocoa'
7
2
 
8
3
  # We want to launch the test app and make sure it responds to
9
4
  # accessibility queries, but that is difficult, so we just sleep
10
- APP_BUNDLE_URL = NSURL.URLWithString File.expand_path './test/fixture/Release/AXElementsTester.app'
5
+ APP_BUNDLE_URL = NSURL.fileURLWithPath File.expand_path './test/fixture/Release/AXElementsTester.app'
6
+ APP_BUNDLE_IDENTIFIER = 'com.marketcircle.AXElementsTester'
11
7
 
12
- error = Pointer.new :id
8
+ error = Pointer.new :id
13
9
  TEST_APP = NSWorkspace.sharedWorkspace.launchApplicationAtURL APP_BUNDLE_URL,
14
10
  options: NSWorkspaceLaunchAsync,
15
11
  configuration: {},
16
12
  error: error
17
- if error[0]
18
- $stderr.puts 'You need to build AND run the fixture app before running tests'
19
- $stderr.puts 'Run `rake fixture`'
13
+ if TEST_APP.nil?
14
+ $stderr.puts 'You need to build AND run the fixture app once before running tests'
15
+ $stderr.puts 'Run `rake run_fixture` to initalize the fixture'
20
16
  exit 3
21
17
  else
22
- sleep 3 # I haven't yet figured out a good way of knowing exactly
23
- # when the app is ready
18
+ sleep 2 # Instead of using high level features of AXElements that we are
19
+ # testing, I think it is just safer to sleep
24
20
  # Make sure the test app is closed when testing finishes
25
21
  at_exit do TEST_APP.terminate end
26
22
  end
27
23
 
28
24
 
29
- gem 'minitest'
30
- require 'minitest/autorun'
31
-
32
- # preprocessor powers, assemble!
33
- if ENV['BENCH']
34
- require 'minitest/benchmark'
35
- else
36
- require'minitest/pride'
37
- end
25
+ require 'test/runner'
38
26
 
39
27
 
40
28
  class MiniTest::Unit::TestCase
41
- # You may need this to help track down an issue if a test is crashing MacRuby
42
- # def self.test_order
43
- # :alpha
44
- # end
45
-
46
- def assert_instance_of_boolean value
47
- message = "Expected #{value.inspect} to be a boolean"
48
- assert value.is_a?(TrueClass) || value.is_a?(FalseClass), message
49
- end
50
-
51
- def self.bench_range
52
- bench_exp 10, 10_000
53
- end
54
- end
55
-
56
- ##
57
- # A mix in module to allow capture of logs
58
- module LoggingCapture
59
- def setup
60
- super
61
- @log_output = StringIO.new
62
- Accessibility.log = Logger.new @log_output
63
- end
64
- end
65
-
66
- module AXHelpers
67
- def pid_for name
68
- NSWorkspace.sharedWorkspace.runningApplications.find do |app|
69
- app.bundleIdentifier == name
70
- end.processIdentifier
71
- end
72
-
73
- # returns raw attribute
74
- def attribute_for element, attr
75
- ptr = Pointer.new :id
76
- AXUIElementCopyAttributeValue(element, attr, ptr)
77
- ptr[0]
78
- end
79
-
80
- def children_for element
81
- attribute_for element, KAXChildrenAttribute
82
- end
83
-
84
- def value_for element
85
- attribute_for element, KAXValueAttribute
86
- end
87
-
88
- def action_for element, action
89
- AXUIElementPerformAction(element, action)
90
- end
91
-
92
- # remember to wrap structs in an AXValueRef
93
- def set_attribute_for element, attr, value
94
- AXUIElementSetAttributeValue(element, attr, value)
95
- end
96
- end
97
-
98
- class TestAX < MiniTest::Unit::TestCase
99
- include AXHelpers
100
- extend AXHelpers
101
-
102
- APP_BUNDLE_IDENTIFIER = 'com.marketcircle.AXElementsTester'
29
+ # needs to be defined in the class, there is a TOPLEVEL::PID
103
30
  PID = pid_for APP_BUNDLE_IDENTIFIER
104
31
  REF = AXUIElementCreateApplication(PID)
105
-
106
- # execute the block with full logging turned on
107
- def with_logging level = Logger::DEBUG
108
- original_level = Accessibility.log.level
109
- Accessibility.log.level = level
110
- yield
111
- Accessibility.log.level = original_level
112
- end
113
32
  end
114
33
 
115
- ##
116
- # Just pretend that you didnt' see this hack
117
- class AX::Element
118
- attr_reader :ref
119
- end
@@ -0,0 +1,18 @@
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
@@ -0,0 +1,44 @@
1
+ require 'test/integration/helper'
2
+
3
+ class TestAccessibilityDebug < MiniTest::Unit::TestCase
4
+
5
+ def app
6
+ @app ||= AX::Application.new PID
7
+ end
8
+
9
+ def test_path_returns_correct_elements_in_correct_order
10
+ list = Accessibility::Debug.path(app.window.close_button)
11
+ assert_equal 3, list.size
12
+ assert_instance_of AX::CloseButton, list.first
13
+ assert_instance_of AX::StandardWindow, list.second
14
+ assert_instance_of AX::Application, list.third
15
+ end
16
+
17
+ def test_dump_works_for_nested_tab_groups
18
+ element = app.window.tab_group
19
+ output = Accessibility::Debug.subtree_for element
20
+
21
+ expected = [
22
+ ['AX::TabGroup', 0],
23
+ ['AX::RadioButton', 1], ['AX::RadioButton', 1], ['AX::TabGroup', 1],
24
+ ['AX::RadioButton', 2], ['AX::RadioButton', 2], ['AX::TabGroup', 2],
25
+ ['AX::RadioButton', 3], ['AX::RadioButton', 3], ['AX::TabGroup', 3],
26
+ ['AX::RadioButton', 4], ['AX::RadioButton', 4],
27
+ ['AX::Group', 4],
28
+ ['AX::TextField', 5], ['AX::StaticText', 6],
29
+ ['AX::TextField' , 5], ['AX::StaticText', 6]
30
+ ]
31
+
32
+ refute_empty output
33
+ output = output.split("\n")
34
+
35
+ until output.empty?
36
+ line = output.shift
37
+ klass, indents = expected.shift
38
+ assert_equal indents, line.match(/^\t*/).to_a.first.length, line
39
+ line.strip!
40
+ assert_match /^\#<#{klass}/, line
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,225 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'test/integration/helper'
3
+
4
+ class TestAccessibilityDSL < MiniTest::Unit::TestCase
5
+
6
+ # LSP FTW
7
+ class DSL
8
+ include Accessibility::DSL
9
+ end
10
+
11
+ def dsl
12
+ @dsl ||= DSL.new
13
+ end
14
+
15
+ def app
16
+ @@app ||= AX::Application.new REF
17
+ end
18
+
19
+ def text_area
20
+ @@text_area ||= app.main_window.text_area
21
+ end
22
+
23
+ def pref_window
24
+ app.children.find { |x|
25
+ x.attributes.include?(:title) && x.title == 'Preferences'
26
+ }
27
+ end
28
+
29
+ def spelling_window
30
+ app.children.find { |x|
31
+ x.attributes.include?(:title) && x.title.match(/^Spelling/)
32
+ }
33
+ end
34
+
35
+ def try_typing string, expected = nil
36
+ expected = string unless expected
37
+ text_area.set :focused, true
38
+ dsl.type string
39
+ assert_equal expected, text_area.value
40
+ ensure # reset for next test
41
+ dsl.type "\\COMMAND+a \b"
42
+ end
43
+
44
+ def test_dsl_is_mixed_into_toplevel
45
+ assert_includes Object.new.class.ancestors, Accessibility::DSL
46
+ end
47
+
48
+ def test_application_with_bundle_id
49
+ assert_equal app, dsl.app_with_bundle_identifier(APP_BUNDLE_IDENTIFIER)
50
+ assert_equal app, dsl.app_with_bundle_id(APP_BUNDLE_IDENTIFIER)
51
+ assert_equal app, dsl.launch(APP_BUNDLE_IDENTIFIER)
52
+ end
53
+
54
+ def test_application_with_name
55
+ assert_equal app, dsl.app_with_name('AXElementsTester')
56
+ end
57
+
58
+ def test_application_with_pid
59
+ assert_equal app, dsl.app_with_pid(PID)
60
+ end
61
+
62
+ def test_typing_human_string
63
+ try_typing "A sentence, with punctuation and num8ers. LOL!\tA 'quoted' string--then some @#*$."
64
+ end
65
+
66
+ def test_typing_backspaces
67
+ try_typing "The cake is a lie!\b\b\b\bgift!", 'The cake is a gift!'
68
+ end
69
+
70
+ def test_typing_hotkeys
71
+ try_typing ", world!\\CONTROL+a Hello", 'Hello, world!'
72
+ try_typing "MacRuby\\OPTION+2", 'MacRuby™'
73
+ end
74
+
75
+ def test_typing_command_keys
76
+ try_typing "Hai.\\<- \\<- \b", "Hi."
77
+ end
78
+
79
+ def test_typing_ruby_escapes
80
+ try_typing "First.\nSecond."
81
+ end
82
+
83
+ def test_select_menu_item_string
84
+ assert_nil pref_window
85
+ dsl.select_menu_item app, app.title, 'Preferences…'
86
+ window = dsl.wait_for :window, parent: app, title: 'Preferences'
87
+ refute_nil window
88
+ ensure
89
+ window.close_button.perform :press if window
90
+ end
91
+
92
+ def test_select_menu_item_regexp
93
+ assert_nil spelling_window
94
+ dsl.select_menu_item app, /Edit/, /Spelling/, /show spelling/i
95
+ window = dsl.wait_for :floating_window, parent: app
96
+ refute_nil window
97
+ ensure
98
+ window.close_button.perform :press if window
99
+ end
100
+
101
+ def test_select_menu_item_raises_if_cannot_find_item
102
+ assert_raises Accessibility::SearchFailure do
103
+ dsl.select_menu_item app, 'File', 'NonExistantMenuItem'
104
+ end
105
+ # @todo verify that menu is closed
106
+ end
107
+
108
+ def test_select_menu_item_provides_proper_debug_info
109
+ e = assert_raises Accessibility::SearchFailure do
110
+ dsl.select_menu_item app, 'Format', 'Front'
111
+ end
112
+ assert_match /MenuItem/, e.message
113
+ end
114
+
115
+ def test_wait_for_obeys_timeout_option
116
+ # loop sleeps for 0.2, so we have to wait at least that long
117
+ start = Time.now
118
+ dsl.wait_for :strawberry_rhubarb, parent: AX::DOCK, timeout: 0.2
119
+ assert_in_delta Time.now, start, 0.3
120
+ end
121
+
122
+ def test_wait_for_parent_only_looks_at_children
123
+ result = dsl.wait_for :trash_dock_item, parent: AX::DOCK, timeout: 0.5
124
+ assert_nil result
125
+
126
+ result = dsl.wait_for :trash_dock_item, parent: AX::DOCK.list
127
+ assert_equal AX::DOCK.list.trash_dock_item, result
128
+
129
+ result = dsl.wait_for :button, parent: app.main_window, title: 'Yes'
130
+ assert_equal 'Yes', result.title
131
+ end
132
+
133
+ def test_wait_for_ancestor_searches
134
+ result = dsl.wait_for :trash_dock_item, ancestor: AX::DOCK
135
+ assert_equal AX::DOCK.list.trash_dock_item, result
136
+
137
+ result = dsl.wait_for :nothing, ancestor: AX::DOCK, timeout: 0.5
138
+ assert_nil result
139
+
140
+ result = dsl.wait_for :text_field, ancestor: app.main_window, value: 'AXIsNyan'
141
+ assert_equal 'AXIsNyan', result.value
142
+ end
143
+
144
+ def test_system_wide
145
+ assert_instance_of AX::SystemWide, dsl.system_wide
146
+ end
147
+
148
+ def test_element_under_mouse
149
+ [
150
+ app.main_window.close_button,
151
+ app.main_window.value_indicator
152
+ ].each do |element|
153
+ dsl.move_mouse_to element
154
+ assert_equal element, dsl.element_under_mouse
155
+ end
156
+ end
157
+
158
+ def test_element_at_point_for_app
159
+ [
160
+ app.main_window.minimize_button,
161
+ app.main_window.increment_arrow
162
+ ].each do |element|
163
+ assert_equal element, dsl.element_at_point(element, for: app)
164
+ end
165
+ end
166
+
167
+ # @todo We aren't being very thorough here
168
+ def test_element_at_point
169
+ [
170
+ app.main_window.minimize_button,
171
+ app.main_window.increment_arrow
172
+ ].each do |element|
173
+ assert_equal element, dsl.element_at_point(element)
174
+ end
175
+ end
176
+
177
+ def test_show_about_window
178
+ dialog = dsl.show_about_window_for app
179
+ assert_instance_of AX::Dialog, dialog
180
+ assert_equal 'AXElementsTester icon', dialog.image.description
181
+ ensure
182
+ dialog.close_button.perform :press if dialog
183
+ end
184
+
185
+ def test_show_prefs_for_app
186
+ prefs = dsl.show_preferences_window_for app
187
+ assert_kind_of AX::Window, prefs
188
+ assert_equal 'Preferences', prefs.title
189
+ ensure
190
+ prefs.close_button.perform :press if prefs
191
+ end
192
+
193
+ def test_scroll_to
194
+ table = app.main_window.table
195
+ ['AXIsNyan', 'AXSubrole'].each do |attr|
196
+ text = table.text_field(value: attr)
197
+ dsl.scroll_to text
198
+ assert NSContainsRect(table.bounds, text.bounds)
199
+ end
200
+ end
201
+
202
+ def test_scroll_menu_to
203
+ pop_up = app.main_window.pop_up_button
204
+
205
+ pop_up.perform :press
206
+ expected = pop_up.menu_item(title: '49')
207
+ dsl.scroll_menu_to expected
208
+ assert_equal expected, element_under_mouse
209
+ dsl.click
210
+ assert_equal '49', pop_up.value
211
+
212
+ pop_up.perform :press
213
+ expected = pop_up.menu_item(title: 'Togusa')
214
+ dsl.scroll_menu_to expected
215
+ assert_equal expected, element_under_mouse
216
+ dsl.click
217
+ assert_equal 'Togusa', pop_up.value
218
+
219
+ ensure
220
+ unless pop_up.children.empty?
221
+ pop_up.menu_item.perform :cancel
222
+ end if pop_up
223
+ end
224
+
225
+ end
@@ -0,0 +1,122 @@
1
+ require 'test/integration/helper'
2
+
3
+ class TestAccessibilityEnumeratorsBreadthFirst < MiniTest::Unit::TestCase
4
+
5
+ def app
6
+ @@app ||= AX::Application.new REF
7
+ end
8
+
9
+ def test_each_iterates_in_correct_order
10
+ tab_group = app.main_window.children.find { |x| x.class == AX::TabGroup }
11
+ enum = Accessibility::Enumerators::BreadthFirst.new(tab_group)
12
+ actual = enum.map &:class
13
+ expected = [
14
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
15
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
16
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
17
+ AX::RadioButton, AX::RadioButton, AX::Group,
18
+ AX::TextField, AX::TextField,
19
+ AX::StaticText, AX::StaticText
20
+ ]
21
+ assert_equal expected, actual
22
+ end
23
+
24
+ def test_first_element_is_first_child # not the root
25
+ enum = Accessibility::Enumerators::BreadthFirst.new app
26
+ def enum.first
27
+ each { |x| return x }
28
+ end
29
+ assert_instance_of AX::StandardWindow, enum.first
30
+ end
31
+
32
+ # this was a big performance issue, so we should make sure it
33
+ # doesn't happen again
34
+ def test_find_returns_immediately_after_finding
35
+ tree = Accessibility::Enumerators::BreadthFirst.new app
36
+ cache = []
37
+ tree.find do |element|
38
+ cache << element.class
39
+ element.class == AX::StandardWindow
40
+ end
41
+ assert_equal 1, cache.size
42
+ end
43
+
44
+ def bench_each
45
+ skip 'TODO'
46
+ end
47
+
48
+ def bench_find
49
+ skip 'TODO'
50
+ end
51
+
52
+ end
53
+
54
+
55
+ class TestAccessibilityEnumeratorsDepthFirst < MiniTest::Unit::TestCase
56
+ include Accessibility::Core
57
+
58
+ def app
59
+ @@app ||= AX::Application.new REF
60
+ end
61
+
62
+ def test_each_iterates_in_correct_order
63
+ tab_group = app.main_window.children.find { |x| x.class == AX::TabGroup }
64
+ enum = Accessibility::Enumerators::DepthFirst.new tab_group
65
+ actual = enum.map &:class
66
+ expected = [
67
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
68
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
69
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
70
+ AX::RadioButton, AX::RadioButton, AX::Group,
71
+ AX::TextField, AX::StaticText,
72
+ AX::TextField, AX::StaticText
73
+ ]
74
+ assert_equal expected, actual
75
+ end
76
+
77
+ # since we have a different implementation, we should also verify order here...
78
+ def test_each_with_level_in_correct_order
79
+ tab_group = app.main_window.children.find { |x| x.class == AX::TabGroup }
80
+ enum = Accessibility::Enumerators::DepthFirst.new tab_group
81
+ actual = []
82
+ enum.each_with_level do |x,_| actual << x.class end
83
+ expected = [
84
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
85
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
86
+ AX::RadioButton, AX::RadioButton, AX::TabGroup,
87
+ AX::RadioButton, AX::RadioButton, AX::Group,
88
+ AX::TextField, AX::StaticText,
89
+ AX::TextField, AX::StaticText
90
+ ]
91
+ assert_equal expected, actual
92
+ end
93
+
94
+ def test_each_with_level_has_correct_height
95
+ enum = Accessibility::Enumerators::DepthFirst.new app.main_window
96
+ actual = []
97
+ enum.each_with_level do |element, level|
98
+ actual << [element.class, level]
99
+ end
100
+
101
+ assert_includes actual, [AX::Slider, 1]
102
+ assert_includes actual, [AX::CloseButton, 1]
103
+ assert_includes actual, [AX::ZoomButton, 1]
104
+ assert_includes actual, [AX::MinimizeButton, 1]
105
+ assert_includes actual, [AX::SearchField, 1]
106
+ assert_includes actual, [AX::CheckBox, 1]
107
+ assert_includes actual, [AX::WebArea, 2]
108
+ assert_includes actual, [AX::Table, 2]
109
+ assert_includes actual, [AX::ScrollBar, 2]
110
+ assert_includes actual, [AX::SortButton, 4]
111
+ end
112
+
113
+ def bench_each
114
+ skip 'TODO'
115
+ end
116
+
117
+ def bench_each_with_level
118
+ skip 'TODO'
119
+ end
120
+
121
+ end
122
+
@@ -0,0 +1,38 @@
1
+ require 'test/integration/helper'
2
+
3
+ class TestAccessibilityErrors < MiniTest::Unit::TestCase
4
+
5
+ def test_search_failure_shows_arguments
6
+ e = Accessibility::SearchFailure.new(AX::DOCK, :list, {herp: :derp})
7
+ def e.backtrace; []; end
8
+ assert_match /Could not find `List\(herp: :derp\)`/, e.message
9
+ assert_match /as a child of AX::Application/, e.message
10
+ assert_match /Element Path:\n\t\#<AX::Application/, e.message
11
+
12
+ e = Accessibility::SearchFailure.new(AX::DOCK, :list, {})
13
+ def e.backtrace; []; end
14
+ assert_match /Could not find `List`/, e.message
15
+
16
+ e = Accessibility::SearchFailure.new(AX::DOCK, :list, nil)
17
+ def e.backtrace; []; end
18
+ assert_match /Could not find `List`/, e.message
19
+ end
20
+
21
+ def test_search_failure_shows_element_path
22
+ l = AX::DOCK.children.first
23
+ e = Accessibility::SearchFailure.new(l, :trash_dock_item, nil)
24
+ def e.backtrace; []; end
25
+ assert_match /AX::Application/, e.message
26
+ assert_match /AX::List/, e.message
27
+ end
28
+
29
+ def test_search_failure_includes_subtree_in_debug_mode
30
+ assert Accessibility::Debug.on?, 'Someone turned debugging off'
31
+ l = AX::DOCK.children.first
32
+ e = Accessibility::SearchFailure.new(l, :trash_dock_item, nil)
33
+ def e.backtrace; []; end
34
+ assert_match /Subtree:/, e.message
35
+ assert_match subtree_for(l), e.message
36
+ end
37
+
38
+ end
@@ -0,0 +1,22 @@
1
+ class TestAccessibilityNotifications < MiniTest::Unit::TestCase
2
+
3
+ def test_custom_notifications
4
+ end
5
+
6
+
7
+ def test_standard_notifications
8
+ end
9
+
10
+
11
+ def test_notifications_from_the_app
12
+ end
13
+
14
+
15
+ def test_notification_filtering
16
+ # I can reject based on block return value
17
+ end
18
+
19
+ def test_notification_callbacks_get_correct_arguments
20
+ end
21
+
22
+ end