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/.yardopts CHANGED
@@ -6,7 +6,7 @@
6
6
  --asset docs/images:images
7
7
  --readme README.markdown
8
8
  lib/**/*.rb
9
- ext/**/*.m
9
+ ext/**/*{.m,.c}
10
10
  -
11
11
  docs/Inspecting.markdown
12
12
  docs/Acting.markdown
@@ -17,4 +17,3 @@ docs/Debugging.markdown
17
17
  docs/NewBehaviour.markdown
18
18
  docs/AccessibilityTips.markdown
19
19
  docs/TestingExtensions.markdown
20
- LICENSE.txt
data/README.markdown CHANGED
@@ -9,58 +9,141 @@ GUI manipulation, whether it be finding controls on the screen,
9
9
  typing, clicking, or other ways in which a user can interact with the
10
10
  computer.
11
11
 
12
+
13
+ ## Demo
14
+
15
+ Perhaps you want to do something with the finder. This example opens a
16
+ new Finder window, finds Activity Monitor, and then opens the application
17
+ from a quick look window:
18
+
19
+ ```ruby
20
+ require 'rubygems'
21
+ require 'ax_elements'
22
+
23
+ finder = app_with_bundle_identifier 'com.apple.finder'
24
+ set_focus finder # bring to the front so you can see it happening
25
+
26
+ type "\\COMMAND+n"
27
+ sleep 1 # this is so you can see it happen in "slow motion"
28
+
29
+ window = finder.main_window
30
+ click window.outline.row(static_text: { value: 'Applications' })
31
+
32
+ utilities = window.row(text_field: { filename: 'Utilities' })
33
+ scroll_to utilities
34
+ double_click utilities
35
+
36
+ activity_monitor = window.text_field( filename: /Activity Monitor/ )
37
+ scroll_to activity_monitor
38
+ click activity_monitor
39
+ type " " # type a space, which should bring up quick look
40
+ sleep 1
41
+
42
+ click finder.quick_look.button(id: 'QLControlOpen')
43
+ ```
44
+
45
+ A simpler example would be changing the system volume by moving the
46
+ slider in the menu bar (unless you've hidden it):
47
+
48
+ ```ruby
49
+ require 'rubygems'
50
+ require 'ax_elements'
51
+
52
+ ui = app_with_bundle_id 'com.apple.systemuiserver'
53
+ volume = ui.menu_extra(description: 'system sound volume')
54
+
55
+ click volume
56
+ 15.times { decrement volume.slider }
57
+ 15.times { increment volume.slider }
58
+ ```
59
+
60
+
12
61
  ## Getting Setup
13
62
 
14
63
  You need to have the OS X developer tools installed in build and
15
64
  install AXElements (sorry). Go ahead and install the tools now if you
16
- haven't done that yet, I'll wait.
17
-
18
- Once, you have the developer tools, you should install MacRuby, the
19
- latest release should be sufficient, but nightly builds are usually
20
- safe as well. If you are on Snow Leopard, you will also need to
21
- install the
65
+ haven't done that yet, I'll wait. Once you have the developer tools,
66
+ you should install MacRuby, the latest nightly build is required. If you
67
+ are on Snow Leopard, you will also need to install the
22
68
  [Bridge Support Preview](http://www.macruby.org/blog/2010/10/08/bridgesupport-preview.html).
23
69
 
24
- At this point you should install development dependencies. You can do
25
- so with `bundler` if you have it, but it will be faster to use the
26
- `setup_dev` task that has been provided. Simply type the following in
27
- terminal:
70
+ Then you can install AXElements. You can install AXElements via
71
+ rubygems:
72
+
73
+ ```bash
74
+ gem install AXElements
75
+ ```
76
+
77
+ Or you can install from source:
28
78
 
29
- rake setup_dev
79
+ ```bash
80
+ cd ~/Documents # or where you want to put the AXElements code
81
+ git clone git://github.com/Marketcircle/AXElements
82
+ cd AXElements
83
+ rake install
84
+ ```
30
85
 
31
- __NOTE__: if you are not using RVM, then you should use `macrake`
32
- instead of `rake` for this command and anywhere else that you see
33
- `rake` in the documentation. Also, remember that if you are not using
34
- RVM with MacRuby but still have RVM installed then you will need to
35
- disable RVM like so:
86
+ AXElements has no gem dependencies, so you can try it out in `macirb` at
87
+ this point:
36
88
 
89
+ ```bash
90
+ rake console
91
+ ```
92
+
93
+ __NOTE__: If you are not using RVM, then you should use `macrake`
94
+ instead of `rake`, and do so for any other references to `rake` in the
95
+ documentation. You may also need to add `sudo` to your command when you
96
+ install the gem. Also, remember that if you are not using RVM with
97
+ MacRuby but still have RVM installed then you will need to disable RVM
98
+ like so:
99
+
100
+ ```bash
37
101
  rvm use system
102
+ ```
38
103
 
39
- Once you are setup, you can start looking through the tutorial
40
- documentation to show you how to use AXElements. The first tutorial is
41
- the {file:docs/Inspecting.markdown Inspecting tutorial}. The full list
42
- of topics include:
43
104
 
44
- * {file:docs/Inspecting.markdown Inspecting}
45
- * {file:docs/Acting.markdown Acting}
46
- * {file:docs/Searching.markdown Searching}
47
- * {file:docs/Notifications.markdown Notifications}
48
- * {file:docs/KeyboardEvents.markdown Keyboard}
49
- * {file:docs/Debugging.markdown Debugging}
50
- * {file:docs/NewBehaviour.markdown Adding Behaviour To AXElements}
51
- * {file:docs/AccessibilityTips.markdown Making Your Apps More Accessibile}
52
- * {file:docs/TestingExtensions.markdown Test Suite Extensions for RSpec, Minitest, etc.}
105
+ ## Getting Started
53
106
 
54
- ## Documentation
107
+ The
108
+ [documentation](http://rdoc.info/github/Marketcircle/AXElements/master/frames)
109
+ is the best place to get started, it includes tutorials to help you get
110
+ started as well the API documentation (API docs are broken right now due
111
+ to incompatabilities between MacRuby and YARD). The starting tutorial is the
112
+ [Inspecting Tutorial](docs/Inspecting.markdown).
55
113
 
56
- AXElements is documented using YARD, and includes a few tutorials in
57
- the `docs/` directory. If you do not want to generate the
58
- documentation yourself then you can go to
59
- [rdoc.info](http://rdoc.info/gems/AXElements/frames).
114
+ Documentation is hosted by rdoc.info, but you can also generate it yourself
115
+ using YARD. Documentation is stored in the `docs/` directory, but the
116
+ documentation includes a number of cross references and even some
117
+ pictures so you will lose a lot of the quality if you view them as
118
+ plain text.
60
119
 
61
120
  Though it is not required, you may want to read Apple's
62
121
  [Accessibility Overview](http://developer.apple.com/library/mac/#documentation/Accessibility/Conceptual/AccessibilityMacOSX/OSXAXModel/OSXAXmodel.html)
63
- as a primer on some the technical underpinnings of AXElements.
122
+ as a primer on some the rationale for the accessibility APIs as well
123
+ as the technical underpinnings of AXElements.
124
+
125
+
126
+ ## Development
127
+
128
+ Development of a stable release of AXElements is under way! The main
129
+ focus is an overall refactoring to create a more robust core, end user
130
+ features will become more consistent, and performance will
131
+ increase. Documentation will be overhauled and more examples will be
132
+ added. It will be magical, so we're code naming the next version
133
+ "Clefairy".
134
+
135
+ ![The Moon](https://github.com/Marketcircle/AXElements/raw/master/docs/images/next_version.png)
136
+
137
+ Proper releases to rubygems will be made as milestones are reached.
138
+
139
+ ### Road Map
140
+
141
+ There are still a bunch of things that could be done to improve
142
+ AXElements. Some of the higher level tasks are outlined in various
143
+ [Github Issues](http://github.com/Marketcircle/AXElements/issues).
144
+ Smaller items are peppered through the code base and marked with `@todo`
145
+ tags.
146
+
64
147
 
65
148
  ## Test Suite
66
149
 
@@ -68,18 +151,18 @@ Before starting development on your machine, you should run the test
68
151
  suite and make sure things are kosher. The nature of this library
69
152
  requires that the tests take over your computer while they run. The
70
153
  tests aren't programmed to do anything destructive, but if you
71
- interfere with them then something could go wrong.
72
-
73
- To run the tests you simply need to run the `test` task:
154
+ interfere with them then something could go wrong. To run the tests
155
+ you simply need to run the `test` task:
74
156
 
75
157
  rake test
76
158
 
77
- __NOTE__: there may be some tests are dependent on Accessibility
159
+ __NOTE__: There may be some tests are dependent on Accessibility
78
160
  features that are new in OS X Lion which will cause test failures on
79
161
  OS X Snow Leopard. If you have any issues then you should look at the
80
- output to find hints at what went wrong and/or log a bug. I will still
81
- support Snow Leopard as long as MacRuby does, but I do not have easy
82
- access to a Snow Leopard machine to verify that things still work.
162
+ output to find hints at what went wrong and/or log a bug. AXElements
163
+ will support Snow Leopard for as long as MacRuby does, but I do not
164
+ have easy access to a Snow Leopard machine to verify that things still
165
+ work.
83
166
 
84
167
  ### Benchmarks
85
168
 
@@ -89,46 +172,6 @@ disabled by default. In order to enable them you need to set the
89
172
 
90
173
  BENCH=1 rake test
91
174
 
92
- Benchmarks only exist for code that is known to be slow. I'm keeping
93
- tabs on slow code so that I be confident about getting depressed when
94
- it gets slower. Though, there is still room for improved performance
95
- as well.
96
-
97
- ## Road Map
98
-
99
- There are still a bunch of things that could be done to improve
100
- AXElements. The README only contains an idealized outline of some of
101
- the high-level items that should get done in the next couple of
102
- releases. Smaller items are peppered through the code base and marked
103
- with `@todo` tags.
104
-
105
- ### 0.7 (or maybe 1.0)
106
-
107
- - Pre-loading AX hierarchy and attribute cache from
108
- `/System/Library/Accessibility/AccessibilityDefinitions.plist`
109
- + Not available on Snow Leopard, so it will have to wait anyways
110
- + Probably inccurs too much overhead at boot time right now
111
- - Make a decision about NSArray#method_missing
112
- - Merge notifications with actions as they are commonly combined
113
- + But how?
114
- - Rewrite core module to handle errors more gracefully
115
- - Mouse module cleanup and regression testing
116
- - Test suite deduplication cleanup and better isolation
117
- - Performance tweaks
118
- - The OO abstraction leaks in a few places, code needs to be
119
- refactored without hurting performance too much
120
- - Test framework helpers
121
- + Minitest
122
- + RSpec
123
- - Thread Safety
124
- + Only if it becomes an issue, otherwise it might be better to
125
- forget thread safey to simplify and optimize existing code
126
-
127
- ### Future
128
-
129
- - Screenshot taking and diff'ing abilities for those rare cases when
130
- you need it
131
- - Address Book helpers, and other friends
132
175
 
133
176
  ## Contributing to AXElements
134
177
 
@@ -140,11 +183,32 @@ with `@todo` tags.
140
183
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
141
184
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
142
185
 
143
- ## Copyright
144
-
145
- Copyright (c) 2010-2011 Marketcircle Incorporated. All rights
146
- reserved.
147
186
 
148
- AXElements is available under the standard 3-clause BSD license. See
149
- {file:LICENSE.txt LICENSE.txt} for further details.
187
+ ## Copyright
150
188
 
189
+ Copyright (c) 2010-2012, Marketcircle Inc.
190
+ All rights reserved.
191
+
192
+ Redistribution and use in source and binary forms, with or without
193
+ modification, are permitted provided that the following conditions are met:
194
+
195
+ * Redistributions of source code must retain the above copyright
196
+ notice, this list of conditions and the following disclaimer.
197
+ * Redistributions in binary form must reproduce the above copyright
198
+ notice, this list of conditions and the following disclaimer in the
199
+ documentation and/or other materials provided with the distribution.
200
+ * Neither the name of Marketcircle Inc. nor the names of its
201
+ contributors may be used to endorse or promote products derived
202
+ from this software without specific prior written permission.
203
+
204
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
205
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
206
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
207
+ DISCLAIMED. IN NO EVENT SHALL Marketcircle Inc. BE LIABLE FOR ANY
208
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
209
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
210
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
211
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
212
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
213
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
214
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Rakefile CHANGED
@@ -1,109 +1,14 @@
1
1
  require 'rubygems'
2
2
 
3
- task :default => :gem
4
- task :clean => :clobber
5
-
6
- def safe_require path, name
7
- require path
8
- yield
9
- rescue LoadError => e
10
- $stderr.puts "It seems as though you do not have #{name} installed."
11
- command = ENV['RUBY_VERSION'] ? 'gem' : 'sudo macgem'
12
- $stderr.puts "You can install it by running `#{command} install #{name}`."
13
- end
14
-
15
-
16
- ## Documentation
17
-
18
- safe_require 'yard', 'yard' do
19
- YARD::Rake::YardocTask.new
20
- end
21
-
22
- desc 'Generate Graphviz object graph'
23
- task :garden => :yard do
24
- sh 'yard graph --full --dependencies --dot="-Tpng:quartz" -f docs/images/AX.dot'
25
- end
26
-
27
- ## Console
28
-
29
- desc 'Start up irb with AXElements loaded'
30
- task :console => :ext do
31
- irb = ENV['RUBY_VERSION'] ? 'irb' : 'macirb'
32
- sh "#{irb} -Ilib -Iext/key_coder -rubygems -rax_elements"
33
- end
34
-
35
- ## Compilation
36
-
37
- require 'rake/compiletask'
38
- Rake::CompileTask.new
39
-
40
- desc 'Compile C extensions'
41
- task :ext do
42
- Dir.chdir 'ext/key_coder' do
43
- break if File.exists?('key_coder.bundle') && File.mtime('key_coder.bundle') > File.mtime('key_coder.m')
44
- ruby 'extconf.rb'
45
- sh 'make'
46
- end
47
- end
3
+ task :default => :test
48
4
 
49
- desc 'Clean temporary files created by the C extension'
50
- task :clobber_ext do
51
- Dir.chdir 'ext/key_coder' do
52
- ['Makefile', 'key_coder.o', 'key_coder.bundle'].each do |file|
53
- $stdout.puts "rm ext/key_coder/#{file}"
54
- rm file
55
- end
56
- end
57
- end
5
+ desc 'Remove all generated files'
6
+ task :clean => :clobber
7
+ desc 'Remove all generated files'
58
8
  task :clobber => :clobber_ext
59
9
 
60
- ## Testing
61
-
62
- desc 'Open the fixture app'
63
- task :run_fixture => :fixture do
64
- sh 'open test/fixture/Release/AXElementsTester.app'
65
- end
66
-
67
- desc 'Build the test fixture'
68
- task :fixture do
69
- sh 'cd test/AXElementsTester && xcodebuild'
70
- end
71
-
72
- require 'rake/testtask'
73
- Rake::TestTask.new do |t|
74
- t.libs << 'test' << 'ext/key_coder'
75
- t.pattern = 'test/**/test_*.rb'
76
- t.ruby_opts = ['-rhelper']
77
- t.verbose = true
78
- end
79
- task :test => [:ext, :fixture]
80
-
81
- ## Gem Packaging
82
- require 'rubygems/dependency_installer'
83
- require 'rake/gempackagetask'
84
-
85
- spec = Gem::Specification.load('AXElements.gemspec')
86
-
87
- Rake::GemPackageTask.new(spec) { }
88
-
89
- # This only installs this gem, it does not take deps into consideration
90
- desc 'Build gem and install it'
91
- task :install => :gem do
92
- Gem::Installer.new("pkg/#{spec.file_name}").install
93
- end
94
-
95
- desc 'Install dependencies for a test node'
96
- task :setup_node do
97
- spec.runtime_dependencies.each do |dep|
98
- puts "Installing #{dep.name}"
99
- Gem::DependencyInstaller.new.install(dep.name, dep.requirement)
100
- end
101
- end
10
+ desc 'Compile C extensions'
11
+ task :ext => 'ext:key_coder'
102
12
 
103
- desc 'Install dependencies for development'
104
- task :setup_dev => :setup_node do
105
- spec.development_dependencies.each do |dep|
106
- puts "Installing #{dep.name}"
107
- Gem::DependencyInstaller.new.install(dep.name, dep.requirement)
108
- end
109
- end
13
+ desc 'Run all tests'
14
+ task :test => ['test:sanity', 'test:integration', 'test:cruby']
@@ -69,6 +69,13 @@ want to have turned into a dot graph; you will get a string back that
69
69
  you will then need to give to Graphviz in order to generate the visual
70
70
  graph.
71
71
 
72
+ File.open('graph.dot', 'w') do |file|
73
+ app = Accessibility.application_with_name 'Terminal'
74
+ file.write Accessibility.graph(app.window)
75
+ end
76
+ `dot graph.dot -Tpng > graph.png`
77
+ `open graph.png`
78
+
72
79
  ### Text Tree Won't Print?
73
80
 
74
81
  AXElements isn't perfect and it is possible that an edge case slipped
@@ -81,8 +88,8 @@ AXElements was that you could not search through the menu bar causing
81
88
  a text dump to fail in a very difficult to trace manner.
82
89
 
83
90
  In these cases you will need to use your deductive reasoning to figure
84
- out where the problem is coming from. Fortunately, AXElements has some
85
- tools to help you along the way.
91
+ out where the problem is coming from. Fortunately, I have provided
92
+ some tools to help you along the way.
86
93
 
87
94
  ## All The Way Up
88
95
 
@@ -1,57 +1,122 @@
1
1
  # Keyboard Events
2
2
 
3
- @todo Still a little bit to do in this doc
3
+ Keyboard events are a system provided by Apple that allows you to
4
+ simulate keyboard input. The API for this in the `ApplicationServices`
5
+ framework, but there is an analogue in the `Acessibility` APIs which
6
+ has the additional option of directing the input to a specific application.
4
7
 
5
- In some cases you cannot, or do not want to, set the value of a field
6
- directly by assigning to the accessibility object's value
7
- attribute. In these cases you can post keyboard events to an
8
- application object.
8
+ Using accessibility actions and setting attributes you can already
9
+ perform most of the interactions that would be possible with the
10
+ keyboard simulation. However, there are some things that you will need
11
+ to, or it will just make more sense to, simulate keyboard input. For
12
+ example, to make use of hot keys you would have to add extra actions
13
+ or attributes to a control in the application; that would be more
14
+ work, possibly prone to error, than simply simulating the hot key from
15
+ outside the application. In other situations you may specifically want
16
+ to test out keyboard navigation and so actions would not be a good
17
+ substitute. It may be that the APIs that AXElements provides for
18
+ typing just make more sense when writing tests or scripts.
9
19
 
10
- Other cases for using keyboard input simulation might include keyboard
11
- navigation or hotkey activation.
20
+ ## Typing with the DSL
12
21
 
13
- The DSL exposes Keyboard events through the `type` keyword. An example
14
- would look like this:
22
+ The {Accessibility::DSL} mix-in exposes keyboard events through the
23
+ `type` method. A simple example would look like this:
15
24
 
16
- ```ruby
17
- type "hello, world!", app
18
- ```
25
+ type "Hello, #{ENV['USER']}! How are you today?\n"
26
+
27
+ And watch your computer come to life! The `type` command takes an
28
+ additional optional parameter that we'll get to later. The first
29
+ parameter is just a string that you want AXElements to type out. How
30
+ to format the string should be obvious for the most part, but some
31
+ things like the command key and arrows might not be so obvious.
32
+
33
+ ## Formatting Strings
34
+
35
+ Letters and numbers should be written just as you would for any other
36
+ string. Any of the standard symbols can also be plainly added to a
37
+ string that you want to have typed. Here are some examples:
38
+
39
+ type "UPPER CASE LETTERS"
40
+ type "lower case letters"
41
+ type "1337 message @/\/|) 57|_||=|="
42
+ type "A proper sentence can be typed out (all at once)."
43
+
44
+ ### Regular Escape Sequences
45
+
46
+ Things like newlines and tabs should be formatted just like they would
47
+ in a regular string. That is, normal string escape sequences should
48
+ "just work" with AXElements. Here are some more examples:
49
+
50
+ type "Have a bad \b\b\b\b\b good day!"
51
+ type "First line.\nSecond line."
52
+ type "I \t like \t to \t use \t tabs \t a \t lot."
53
+ type "Explicit\sSpaces."
54
+
55
+ ### Custom Escape Sequences
56
+
57
+ Unfortunately, there is no built in escape sequence for deleting to
58
+ the right or pressing command keys like `F1`. AXElements defines some
59
+ extra escape sequences in order to easily represent the remaining
60
+ keys.
61
+
62
+ These custom escape sequences __shoud start with two `\` characters__,
63
+ as in this example:
64
+
65
+ type "\\F1"
66
+
67
+ A custom escape sequence __should terminate with a space or the end of
68
+ the string__, as in this example:
69
+
70
+ type "\\PAGEDOWN notice the space afterwards\\PAGEUP but not before"
71
+
72
+ The full list of supported custom escape sequences is listed in
73
+ {Accessibility::StringParser::CUSTOM}. Some escapes have an alias,
74
+ such as the right arrow key which can be escaped as `"\\RIGHT"` or as
75
+ `"\\->"`.
76
+
77
+ ### Hot Keys
78
+
79
+ To support pressing multiple keys at the same time (i.e. hot keys), you
80
+ must start with the custom escape sequence for the combination and
81
+ instead of ending with a space you should put a `+` character to chain
82
+ the next key. The entire sequence should be ended with a space or
83
+ nil. Some common examples are opening a file or quitting an
84
+ application:
85
+
86
+ type "\\COMMAND+o"
87
+ type "\\CONTROL+a Typing at the start of the line"
88
+ type "\\COMMAND+\\SHIFT+s"
89
+
90
+ You might also note that `CMD+SHIFT+s` could also be:
91
+
92
+ type "\\COMMAND+S"
93
+
94
+ Since a capital `S` will cause the shift key to be held down.
95
+
96
+ One caveat with hot keys is that you cannot use `"\\COMMAND+ "` to
97
+ represent command and space combination, you will need to use
98
+ `"\\COMMAND+\s"` instead.
99
+
100
+ ## Protips
19
101
 
20
102
  In order make sure that certain sequences of characters are properly
21
- transcribed to the screen you should be consistent about using double
22
- quotes, `"`, for literal strings. An escape sequence should begin
23
- `\\`.
24
-
25
- First the keyword `type`, and then the string you want to type
26
- out. Finally, there is a second argument, which is optional, that
27
- should be the application that you wish to send the keyboard input
28
- to; if you do not include the argument, then the input will go to the
29
- currently activate application.
30
-
31
- ## Behaviour
32
-
33
- The method is asynchronous. It appears to type information in at the
34
- keyboard repeat rate, but I have yet to check that out.
35
-
36
- ## Escape Sequences
37
-
38
- A number of custom escape sequences have been added in order to allow easy
39
- encoding of all key sequences/combinations.
40
-
41
- <table style="1px solid black">
42
- <tr><td>Key</td><td>Escape Sequence</td></tr>
43
- <tr><td>Delete Backwards (Backspace)</td><td>`\b`</td></tr>
44
- <tr><td>Enter</td><td>`\n` or `\r`</td></tr>
45
- <tr><td>Control</td><td>`\^`</td></tr>
46
- <tr><td>Command</td><td>`\C`</td></tr>
47
- <tr><td>Option/Alt</td><td>`\O`</td></tr>
48
- <tr><td>Tab</td><td>`\t`</td></tr>
49
- <tr><td>Escape</td><td>`\e`</td></tr>
50
- <tr><td>Space</td><td>` `</td></tr>
51
- <tr><td>Scroll To Top</td><td>`\x01`</td></tr>
52
- <tr><td>Scroll To Bottom</td><td>`\x04`</td></tr>
53
- <tr><td>Page Down</td><td>`\f`</td></tr>
54
- <tr><td>Left Arrow</td><td>`\\<->`</td></tr>
55
- <tr><td>Right Arrow</td><td>`\\->`</td></tr>
56
- <tr><td>Down Arrow</td><td>`\DOWN`</td></tr>
57
- </table>
103
+ escaped, it is recommended to simply always use double quoted
104
+ strings.
105
+
106
+ ### Posting To A Specific Application
107
+
108
+ The second argument to the `type` command can be an {AX::Application}
109
+ object. If you do not include the argument, the events will be posted
110
+ to the system, which usually means the application that currently is
111
+ active. Note that you cannot be more specific than the application
112
+ that you want to send the events to, within the application, the
113
+ control that has keyboard focus will receive the events.
114
+
115
+ ### Changing Typing Speed
116
+
117
+ You can set the typing speed at load time by setting the environment
118
+ variable `KEY_RATE`. See {Accessibility::Core::KEY\_RATE} for details on
119
+ possible values. An example of using it would be:
120
+
121
+ KEY_RATE=SLOW irb -rubygems -rax_elements
122
+ KEY_RATE=0.25 rspec gui_spec.rb
@@ -0,0 +1 @@
1
+ You can use ruby ranges, but there is one caveat, which is that negative ranges will have to be converted ahead of time by the programmer, but only if you are using Core directly. If you are using an AX::Element derived class then it will Just Work™.
Binary file
@@ -0,0 +1,22 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << ' -std=c99 -Wall -Werror -ObjC'
4
+ $LIBS << ' -framework Cocoa -framework Carbon -framework ApplicationServices'
5
+
6
+ if RUBY_ENGINE == 'macruby'
7
+ $CFLAGS << ' -fobjc-gc'
8
+ else
9
+ unless RbConfig::CONFIG["CC"].match /clang/
10
+ clang = `which clang`.chomp
11
+ if clang.empty?
12
+ $stdout.puts "Clang not installed. Cannot build C extension"
13
+ exit 1
14
+ else
15
+ RbConfig::MAKEFILE_CONFIG["CC"] = clang
16
+ RbConfig::MAKEFILE_CONFIG["CXX"] = clang
17
+ end
18
+ end
19
+ $CFLAGS << ' -DNOT_MACRUBY'
20
+ end
21
+
22
+ create_makefile('accessibility/key_coder')