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.
- data/.yardopts +4 -0
- data/History.markdown +41 -0
- data/README.markdown +59 -62
- data/Rakefile +1 -1
- data/ext/accessibility/key_coder/extconf.rb +1 -1
- data/ext/accessibility/key_coder/key_coder.c +8 -5
- data/lib/accessibility/dsl.rb +261 -87
- data/lib/accessibility/enumerators.rb +14 -11
- data/lib/accessibility/errors.rb +4 -3
- data/lib/accessibility/factory.rb +159 -108
- data/lib/accessibility/graph.rb +13 -9
- data/lib/accessibility/{pp_inspector.rb → pretty_printer.rb} +4 -5
- data/lib/accessibility/qualifier.rb +23 -13
- data/lib/accessibility/string.rb +4 -4
- data/lib/accessibility/system_info.rb +230 -0
- data/lib/accessibility/translator.rb +38 -28
- data/lib/accessibility/version.rb +24 -2
- data/lib/accessibility.rb +25 -8
- data/lib/ax/application.rb +207 -77
- data/lib/ax/element.rb +62 -65
- data/lib/ax/menu.rb +5 -1
- data/lib/ax/row.rb +1 -1
- data/lib/ax/scroll_area.rb +7 -6
- data/lib/ax/systemwide.rb +38 -5
- data/lib/ax_elements/active_support_selections.rb +10 -0
- data/lib/ax_elements/mri.rb +57 -0
- data/lib/ax_elements/nsarray_compat.rb +97 -17
- data/lib/ax_elements.rb +9 -1
- data/rakelib/gem.rake +11 -11
- data/rakelib/test.rake +0 -9
- data/test/helper.rb +10 -18
- data/test/integration/accessibility/test_dsl.rb +52 -42
- data/test/integration/accessibility/test_enumerators.rb +0 -1
- data/test/integration/accessibility/test_graph.rb +1 -0
- data/test/integration/accessibility/test_qualifier.rb +2 -2
- data/test/integration/ax/test_application.rb +9 -2
- data/test/integration/ax/test_element.rb +41 -1
- data/test/sanity/accessibility/test_factory.rb +23 -56
- data/test/sanity/accessibility/{test_pp_inspector.rb → test_pretty_printer.rb} +9 -9
- data/test/sanity/accessibility/test_translator.rb +2 -5
- data/test/sanity/accessibility/test_version.rb +15 -0
- data/test/sanity/ax/test_application.rb +17 -2
- data/test/sanity/ax/test_element.rb +2 -2
- data/test/sanity/ax_elements/test_nsobject_inspect.rb +4 -2
- data/test/sanity/test_ax_elements.rb +1 -0
- metadata +69 -39
- data/lib/accessibility/core.rb +0 -973
- data/lib/accessibility/highlighter.rb +0 -86
- data/lib/ax_elements/vendor/inflection_data.rb +0 -66
- data/lib/ax_elements/vendor/inflections.rb +0 -172
- data/lib/ax_elements/vendor/inflector.rb +0 -306
- data/lib/minitest/ax_elements.rb +0 -175
- data/lib/mouse.rb +0 -223
- data/lib/rspec/expectations/ax_elements.rb +0 -234
- data/test/integration/accessibility/test_core.rb +0 -18
- data/test/integration/minitest/test_ax_elements.rb +0 -89
- data/test/integration/rspec/expectations/test_ax_elements.rb +0 -102
- data/test/sanity/accessibility/test_core.rb +0 -561
- data/test/sanity/accessibility/test_highlighter.rb +0 -56
- data/test/sanity/minitest/test_ax_elements.rb +0 -17
- data/test/sanity/rspec/expectations/test_ax_elements.rb +0 -15
- data/test/sanity/test_mouse.rb +0 -19
data/lib/ax/menu.rb
CHANGED
@@ -21,7 +21,7 @@ class AX::Menu < AX::Element
|
|
21
21
|
# menu.scroll_to menu.item(title: "Expensive Cake")
|
22
22
|
# end
|
23
23
|
#
|
24
|
-
# @param [AX::Element]
|
24
|
+
# @param [AX::Element] element
|
25
25
|
# @return [void]
|
26
26
|
def scroll_to element
|
27
27
|
Mouse.move_to self.to_point
|
@@ -58,6 +58,10 @@ class AX::Menu < AX::Element
|
|
58
58
|
# Search the menu for a `menu_item` that matches the given
|
59
59
|
# filters. The filters should be specified just as they would
|
60
60
|
# be when calling {#search}.
|
61
|
+
#
|
62
|
+
# @param [Hash] filters
|
63
|
+
# @yield Optional block used for search filtering
|
64
|
+
# @return [AX::Element]
|
61
65
|
def item filters = {}, &block
|
62
66
|
result = self.search :menu_item, filters, &block
|
63
67
|
return result unless result.blank?
|
data/lib/ax/row.rb
CHANGED
@@ -25,7 +25,7 @@ class AX::Row < AX::Element
|
|
25
25
|
# }
|
26
26
|
# puts "The average price is $ #{total / rows.size}"
|
27
27
|
#
|
28
|
-
# @param [Hash]
|
28
|
+
# @param [Hash] filters
|
29
29
|
# @return [AX::Element]
|
30
30
|
def child_in_column filters, &block
|
31
31
|
qualifier = Accessibility::Qualifier.new(:Column, filters, &block)
|
data/lib/ax/scroll_area.rb
CHANGED
@@ -17,17 +17,18 @@ class AX::ScrollArea < AX::Element
|
|
17
17
|
#
|
18
18
|
# scroll_area.scroll_to table.rows.last
|
19
19
|
#
|
20
|
-
# @param [AX::Element]
|
20
|
+
# @param element [AX::Element]
|
21
21
|
# @return [void]
|
22
22
|
def scroll_to element
|
23
23
|
return if NSContainsRect(self.bounds, element.bounds)
|
24
24
|
Mouse.move_to self.to_point
|
25
|
-
|
25
|
+
|
26
|
+
# calculate direction and velocity for scrolling
|
26
27
|
direction = element.position.y > self.position.y ? -5 : 5
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
|
29
|
+
Mouse.scroll direction until NSContainsRect(self.bounds, element.bounds)
|
30
|
+
|
31
|
+
spin 0.1
|
31
32
|
end
|
32
33
|
|
33
34
|
end
|
data/lib/ax/systemwide.rb
CHANGED
@@ -11,10 +11,37 @@ require 'accessibility/string'
|
|
11
11
|
class AX::SystemWide < AX::Element
|
12
12
|
include Accessibility::String
|
13
13
|
|
14
|
+
class << self
|
15
|
+
##
|
16
|
+
# Find and return the group that represents the desktop
|
17
|
+
#
|
18
|
+
# @return [AX::Group]
|
19
|
+
def desktop
|
20
|
+
AX::Application.finder.scroll_areas.first.groups.first
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# @note This currently does not include spotlight or the
|
25
|
+
# notification center as they interact oddly with
|
26
|
+
# accessibility APIs and how AXElements handle errors
|
27
|
+
#
|
28
|
+
# Find and return menu bar items for the system
|
29
|
+
#
|
30
|
+
# That is, menu bar items that do not belong to the current
|
31
|
+
# app, but that belong to the system, such as the clock or
|
32
|
+
# wi-fi menu.
|
33
|
+
#
|
34
|
+
# @return [AX::MenuBarItem]
|
35
|
+
def status_items
|
36
|
+
AX::Application.new('SystemUIServer').menu_bar.children
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
14
41
|
##
|
15
42
|
# Overridden since there is only one way to get the element ref.
|
16
43
|
def initialize
|
17
|
-
super
|
44
|
+
super Accessibility::Element.system_wide
|
18
45
|
end
|
19
46
|
|
20
47
|
##
|
@@ -27,6 +54,7 @@ class AX::SystemWide < AX::Element
|
|
27
54
|
# [Keyboarding documentation](http://github.com/Marketcircle/AXElements/wiki/Keyboarding)
|
28
55
|
# for more information on how to format strings.
|
29
56
|
#
|
57
|
+
# @param string [String]
|
30
58
|
# @return [Boolean]
|
31
59
|
def type string
|
32
60
|
@ref.post keyboard_events_for string
|
@@ -44,7 +72,7 @@ class AX::SystemWide < AX::Element
|
|
44
72
|
# drag_mouse_to point
|
45
73
|
# end
|
46
74
|
#
|
47
|
-
# @param [String]
|
75
|
+
# @param key [String]
|
48
76
|
# @return [Number,nil]
|
49
77
|
def hold_modifier key
|
50
78
|
code = EventGenerator::CUSTOM[key]
|
@@ -78,10 +106,10 @@ class AX::SystemWide < AX::Element
|
|
78
106
|
#
|
79
107
|
# `nil` will be returned if there was nothing at that point.
|
80
108
|
#
|
81
|
-
# @param [#to_point]
|
109
|
+
# @param point [#to_point]
|
82
110
|
# @return [AX::Element,nil]
|
83
111
|
def element_at point
|
84
|
-
|
112
|
+
@ref.element_at(point).to_ruby
|
85
113
|
end
|
86
114
|
|
87
115
|
##
|
@@ -89,10 +117,15 @@ class AX::SystemWide < AX::Element
|
|
89
117
|
# and looking up attributes incurs a lot of IPC calls and sometimes an
|
90
118
|
# app is slow to respond.
|
91
119
|
#
|
92
|
-
# @param [Number]
|
120
|
+
# @param seconds [Number]
|
93
121
|
# @return [Number]
|
94
122
|
def set_global_timeout seconds
|
95
123
|
@ref.set_timeout_to seconds
|
96
124
|
end
|
97
125
|
|
126
|
+
# (see AX::Application.frontmost_application)
|
127
|
+
def focused_application
|
128
|
+
AX::Application.frontmost_app
|
129
|
+
end
|
130
|
+
|
98
131
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# this is just a list of core extensions from Active Support
|
2
|
+
# that I would like to have loaded by default
|
3
|
+
|
4
|
+
require 'active_support/core_ext/numeric'
|
5
|
+
require 'active_support/core_ext/date/calculations'
|
6
|
+
require 'active_support/core_ext/date/conversions'
|
7
|
+
require 'active_support/core_ext/time/calculations'
|
8
|
+
require 'active_support/core_ext/time/conversions'
|
9
|
+
require 'active_support/core_ext/date_time/calculations'
|
10
|
+
require 'active_support/core_ext/date_time/conversions'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
unless on_macruby?
|
2
|
+
|
3
|
+
KAXChildrenAttribute = 'AXChildren'
|
4
|
+
KAXRoleAttribute = 'AXRole'
|
5
|
+
KAXSubroleAttribute = 'AXSubrole'
|
6
|
+
KAXIdentifierAttribute = 'AXIdentifier'
|
7
|
+
KAXWindowCreatedNotification = 'AXWindowCreated'
|
8
|
+
KAXMainWindowAttribute = 'AXMainWindow'
|
9
|
+
KAXFocusedAttribute = 'AXFocused'
|
10
|
+
KAXValueChangedNotification = 'AXValueChanged'
|
11
|
+
KAXTitleAttribute = 'AXTitle'
|
12
|
+
KAXURLAttribute = 'AXURL'
|
13
|
+
KAXTitleUIElementAttribute = 'AXTitleUIElement'
|
14
|
+
KAXPlaceholderValueAttribute = 'AXPlaceholderValue'
|
15
|
+
KAXWindowRole = 'AXWindow'
|
16
|
+
KAXCloseButtonSubrole = 'AXCloseButton'
|
17
|
+
KAXTrashDockItemSubrole = 'AXTrashDockItem'
|
18
|
+
KAXRTFForRangeParameterizedAttribute = 'AXRTFForRange'
|
19
|
+
KAXIsApplicationRunningAttribute = 'AXIsApplicationRunning'
|
20
|
+
KAXStringForRangeParameterizedAttribute = 'AXStringForRange'
|
21
|
+
|
22
|
+
unless defined? NSString
|
23
|
+
NSString = String
|
24
|
+
end
|
25
|
+
|
26
|
+
unless defined? NSDictionary
|
27
|
+
NSDictionary = Hash
|
28
|
+
end
|
29
|
+
|
30
|
+
unless defined? NSArray
|
31
|
+
NSArray = Array
|
32
|
+
end
|
33
|
+
|
34
|
+
unless defined? NSDate
|
35
|
+
NSDate = Time
|
36
|
+
end
|
37
|
+
|
38
|
+
class Symbol
|
39
|
+
|
40
|
+
def chomp suffix
|
41
|
+
to_s.chomp suffix
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
unless defined? KAXIdentifierAttribute
|
49
|
+
##
|
50
|
+
# Added for backwards compatability with Snow Leopard.
|
51
|
+
# This attribute is standard with Lion and newer. AXElements depends
|
52
|
+
# on it being defined.
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
KAXIdentifierAttribute = 'AXIdentifier'
|
56
|
+
end
|
57
|
+
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'ax/element'
|
2
2
|
require 'accessibility/translator'
|
3
|
+
require 'active_support/core_ext/array/access'
|
3
4
|
|
4
5
|
##
|
5
6
|
# An old hack on arrays that allows you to map a single method across
|
@@ -11,18 +12,6 @@ require 'accessibility/translator'
|
|
11
12
|
# on this and so I will just keep it around for backwards compatability.
|
12
13
|
module Accessibility::NSArrayCompat
|
13
14
|
|
14
|
-
##
|
15
|
-
# Equivalent to `#at(1)`
|
16
|
-
def second
|
17
|
-
at(1)
|
18
|
-
end
|
19
|
-
|
20
|
-
##
|
21
|
-
# Equivalent to `#at(2)`
|
22
|
-
def third
|
23
|
-
at(2)
|
24
|
-
end
|
25
|
-
|
26
15
|
##
|
27
16
|
# @note Debatably bad idea. Maintained for backwards compatibility.
|
28
17
|
#
|
@@ -40,11 +29,11 @@ module Accessibility::NSArrayCompat
|
|
40
29
|
# outline.rows.text_fields.values # all at once
|
41
30
|
#
|
42
31
|
def method_missing method, *args
|
43
|
-
smethod = TRANSLATOR.singularize(method.chomp('?'))
|
32
|
+
smethod = TRANSLATOR.singularize(method.to_s.chomp('?'))
|
44
33
|
map do |x|
|
45
|
-
if !x.kind_of?
|
46
|
-
elsif x.respond_to? method
|
47
|
-
else
|
34
|
+
if !x.kind_of?(AX::Element) then super
|
35
|
+
elsif x.respond_to? method then x.send method, *args
|
36
|
+
else x.send smethod, *args
|
48
37
|
end
|
49
38
|
end
|
50
39
|
end
|
@@ -58,8 +47,99 @@ module Accessibility::NSArrayCompat
|
|
58
47
|
|
59
48
|
end
|
60
49
|
|
50
|
+
unless defined? NSArray
|
51
|
+
NSArray = Array
|
52
|
+
end
|
61
53
|
|
62
|
-
|
54
|
+
##
|
55
|
+
# AXElements extensions for `NSArray`
|
63
56
|
class NSArray
|
64
57
|
include Accessibility::NSArrayCompat
|
58
|
+
|
59
|
+
if on_macruby?
|
60
|
+
|
61
|
+
##
|
62
|
+
# Returns the tail of the array from `position`
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
#
|
66
|
+
# [1, 2, 3, 4].from(0) # => [1, 2, 3, 4]
|
67
|
+
# [1, 2, 3, 4].from(2) # => [3, 4]
|
68
|
+
# [1, 2, 3, 4].from(10) # => []
|
69
|
+
# [].from(0) # => []
|
70
|
+
#
|
71
|
+
# @param position [Fixnum]
|
72
|
+
# @return [Array]
|
73
|
+
def from position
|
74
|
+
self[position, length] || []
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Returns the beginning of the array up to `position`
|
79
|
+
#
|
80
|
+
# [1, 2, 3, 4].to(0) # => [1]
|
81
|
+
# [1, 2, 3, 4].to(2) # => [1, 2, 3]
|
82
|
+
# [1, 2, 3, 4].to(10) # => [1, 2, 3, 4]
|
83
|
+
# [].to(0) # => []
|
84
|
+
#
|
85
|
+
# @param count [Fixnum]
|
86
|
+
# @return [Array]
|
87
|
+
def to count
|
88
|
+
take count + 1
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Equal to `self[1]`
|
93
|
+
def second
|
94
|
+
self[1]
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Equal to `self[2]`
|
99
|
+
def third
|
100
|
+
self[2]
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Equal to `self[3]`
|
105
|
+
def fourth
|
106
|
+
self[3]
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Equal to `self[4]`
|
111
|
+
def fifth
|
112
|
+
self[4]
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# Equal to `self[41]`
|
117
|
+
#
|
118
|
+
# Also known as accessing "the reddit".
|
119
|
+
def forty_two
|
120
|
+
self[41]
|
121
|
+
end
|
122
|
+
|
123
|
+
else
|
124
|
+
|
125
|
+
##
|
126
|
+
# Create a new array with the same contents as the given array
|
127
|
+
#
|
128
|
+
# @param ary [Array]
|
129
|
+
def self.arrayWithArray ary
|
130
|
+
ary.dup
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Create and return a new empty array
|
135
|
+
#
|
136
|
+
# @return [Array]
|
137
|
+
def self.array
|
138
|
+
[]
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
alias_method :the_reddit, :forty_two
|
144
|
+
|
65
145
|
end
|
data/lib/ax_elements.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
+
require 'ax_elements/active_support_selections'
|
2
|
+
require 'accessibility/bridge'
|
3
|
+
require 'ax_elements/mri' unless on_macruby?
|
4
|
+
|
1
5
|
# Mix the language methods into the TopLevel
|
2
6
|
require 'accessibility/dsl'
|
3
7
|
include Accessibility::DSL
|
4
8
|
|
9
|
+
require 'accessibility/system_info'
|
10
|
+
|
5
11
|
##
|
12
|
+
# @deprecated Please use {AX::Application.dock} instead
|
13
|
+
#
|
6
14
|
# The Mac OS X dock application.
|
7
15
|
#
|
8
16
|
# @return [AX::Application]
|
9
|
-
AX::DOCK = AX::Application.
|
17
|
+
AX::DOCK = AX::Application.dock
|
10
18
|
|
11
19
|
# Load explicitly defined elements that are optional
|
12
20
|
require 'ax/button'
|
data/rakelib/gem.rake
CHANGED
@@ -4,25 +4,25 @@ ax_elements = Gem::Specification.load('AXElements.gemspec')
|
|
4
4
|
Gem::PackageTask.new(ax_elements) { }
|
5
5
|
|
6
6
|
desc 'Build and install gem (not including deps)'
|
7
|
-
task :install => :gem do
|
7
|
+
task :install => [:gem, :setup] do
|
8
8
|
require 'rubygems/installer'
|
9
9
|
Gem::Installer.new("pkg/#{ax_elements.file_name}").install
|
10
10
|
end
|
11
11
|
|
12
|
-
desc 'Install dependencies for
|
13
|
-
task :
|
12
|
+
desc 'Install dependencies for running AXElements'
|
13
|
+
task :setup do
|
14
14
|
require 'rubygems/dependency_installer'
|
15
|
-
|
15
|
+
ax_elements.runtime_dependencies.each do |dep|
|
16
16
|
puts "Installing #{dep.name} (#{dep.requirement})"
|
17
17
|
Gem::DependencyInstaller.new.install(dep.name, dep.requirement)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
desc 'Install dependencies for development'
|
22
|
+
task :setup_dev => :setup do
|
23
|
+
require 'rubygems/dependency_installer'
|
24
|
+
(ax_elements.runtime_dependencies + ax_elements.development_dependencies).each do |dep|
|
25
|
+
puts "Installing #{dep.name} (#{dep.requirement})"
|
26
|
+
Gem::DependencyInstaller.new.install(dep.name, dep.requirement)
|
27
|
+
end
|
28
28
|
end
|
data/rakelib/test.rake
CHANGED
@@ -41,13 +41,4 @@ namespace :test do
|
|
41
41
|
t.pattern = "test/sanity/accessibility/test_string.rb"
|
42
42
|
end
|
43
43
|
task :string => :ext
|
44
|
-
|
45
|
-
desc 'Run tests under CRuby (where applicable)'
|
46
|
-
task :cruby do
|
47
|
-
if ENV['RUBY_VERSION'] # using rvm
|
48
|
-
puts sh 'rvm 1.9.3 do rake test:string'
|
49
|
-
else
|
50
|
-
sh 'rake test:string'
|
51
|
-
end
|
52
|
-
end
|
53
44
|
end
|
data/test/helper.rb
CHANGED
@@ -1,25 +1,18 @@
|
|
1
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'accessibility/core'
|
3
|
+
framework 'Cocoa' if on_macruby?
|
2
4
|
|
3
5
|
# We want to launch the test app and make sure it responds to
|
4
6
|
# accessibility queries, but that is difficult to know at what
|
5
7
|
# point it will start to respond, so we just sleep
|
6
|
-
|
8
|
+
APP_BUNDLE_PATH = File.expand_path './test/fixture/Release/AXElementsTester.app'
|
7
9
|
APP_BUNDLE_IDENTIFIER = 'com.marketcircle.AXElementsTester'
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
if TEST_APP.nil?
|
15
|
-
$stderr.puts 'You need to build AND run the fixture app once before running tests'
|
16
|
-
$stderr.puts 'Run `rake run_fixture` to initalize the fixture'
|
17
|
-
exit 3
|
18
|
-
else
|
19
|
-
sleep 2 # Instead of using high level features of AXElements that we are
|
20
|
-
# testing, I think it is just safer to sleep
|
21
|
-
# Make sure the test app is closed when testing finishes
|
22
|
-
at_exit do TEST_APP.terminate end
|
11
|
+
`open #{APP_BUNDLE_PATH}`
|
12
|
+
sleep 3
|
13
|
+
|
14
|
+
at_exit do
|
15
|
+
`killall AXElementsTester`
|
23
16
|
end
|
24
17
|
|
25
18
|
|
@@ -29,6 +22,5 @@ require 'test/runner'
|
|
29
22
|
class MiniTest::Unit::TestCase
|
30
23
|
# needs to be defined in the class, there is a TOPLEVEL::PID
|
31
24
|
PID = pid_for APP_BUNDLE_IDENTIFIER
|
32
|
-
REF =
|
25
|
+
REF = Accessibility::Element.application_for PID
|
33
26
|
end
|
34
|
-
|
@@ -14,8 +14,20 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
14
14
|
|
15
15
|
def text_area; @@text_area ||= app.main_window.text_area end
|
16
16
|
def pop_up; @@pop_up ||= app.main_window.pop_up end
|
17
|
-
def pref_window
|
18
|
-
|
17
|
+
def pref_window
|
18
|
+
app.children.find { |x|
|
19
|
+
if x.respond_to? :title
|
20
|
+
x.attribute(:title) == 'Preferences'
|
21
|
+
end
|
22
|
+
}
|
23
|
+
end
|
24
|
+
def spelling_window
|
25
|
+
app.children.find { |x|
|
26
|
+
if x.respond_to? :title
|
27
|
+
x.attribute(:title).to_s.match(/^Spelling/)
|
28
|
+
end
|
29
|
+
}
|
30
|
+
end
|
19
31
|
|
20
32
|
def try_typing string, expected = nil
|
21
33
|
expected = string unless expected
|
@@ -154,7 +166,8 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
154
166
|
|
155
167
|
def test_wait_for_invalidation_of_element
|
156
168
|
app.main_window.button(title: 'Yes').perform(:press)
|
157
|
-
|
169
|
+
Thread.new do
|
170
|
+
sleep 1
|
158
171
|
app.main_window.button(title: 'No').perform(:press)
|
159
172
|
end
|
160
173
|
|
@@ -163,7 +176,8 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
163
176
|
|
164
177
|
def test_wait_for_invalidation_of_wait_for
|
165
178
|
app.main_window.button(title: 'Yes').perform(:press)
|
166
|
-
|
179
|
+
Thread.new do
|
180
|
+
sleep 1
|
167
181
|
app.main_window.button(title: 'No').perform(:press)
|
168
182
|
end
|
169
183
|
|
@@ -187,48 +201,33 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
187
201
|
app.main_window.set :position, orig_window_position if orig_window_position
|
188
202
|
end
|
189
203
|
|
204
|
+
def test_right_click_with_block
|
205
|
+
area = app.main_window.web_area
|
206
|
+
|
207
|
+
got_called = false
|
208
|
+
dsl.right_click area do
|
209
|
+
got_called = true
|
210
|
+
end
|
211
|
+
assert got_called
|
212
|
+
ensure
|
213
|
+
dsl.click area
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_triple_click
|
217
|
+
dummy_text = 'Lorem ipsum dolor.' * 15
|
218
|
+
text_area.set :value, dummy_text
|
219
|
+
dsl.triple_click text_area
|
220
|
+
assert_equal dummy_text, text_area.selected_text
|
221
|
+
ensure
|
222
|
+
app.main_window.text_area.set :value, ''
|
223
|
+
end
|
224
|
+
|
190
225
|
def test_highlight
|
191
226
|
highlighter = dsl.highlight app.main_window, colour: NSColor.blueColor
|
192
227
|
assert_kind_of Accessibility::Highlighter, highlighter
|
193
|
-
assert_equal NSColor.blueColor, highlighter.
|
228
|
+
assert_equal NSColor.blueColor, highlighter.color
|
194
229
|
highlighter.stop
|
195
|
-
|
196
|
-
def highlight_test
|
197
|
-
@got_called = true
|
198
|
-
end
|
199
|
-
highlighter = dsl.highlight app.main_window, color: NSColor.greenColor, timeout: 0.1
|
200
|
-
NSNotificationCenter.defaultCenter.addObserver self,
|
201
|
-
selector: 'highlight_test',
|
202
|
-
name: NSWindowWillCloseNotification,
|
203
|
-
object: highlighter
|
204
|
-
sleep 0.1
|
205
|
-
assert @got_called
|
206
|
-
end
|
207
|
-
|
208
|
-
def test_dump_works_for_nested_tab_groups
|
209
|
-
output = dsl.subtree_for app.window.tab_group
|
210
|
-
|
211
|
-
expected = [
|
212
|
-
['AX::TabGroup', 0],
|
213
|
-
['AX::RadioButton', 1], ['AX::RadioButton', 1], ['AX::TabGroup', 1],
|
214
|
-
['AX::RadioButton', 2], ['AX::RadioButton', 2], ['AX::TabGroup', 2],
|
215
|
-
['AX::RadioButton', 3], ['AX::RadioButton', 3], ['AX::TabGroup', 3],
|
216
|
-
['AX::RadioButton', 4], ['AX::RadioButton', 4],
|
217
|
-
['AX::Group', 4],
|
218
|
-
['AX::TextField', 5], ['AX::StaticText', 6],
|
219
|
-
['AX::TextField' , 5], ['AX::StaticText', 6]
|
220
|
-
]
|
221
|
-
|
222
|
-
refute_empty output
|
223
|
-
output = output.split("\n")
|
224
|
-
|
225
|
-
until output.empty?
|
226
|
-
line = output.shift
|
227
|
-
klass, indents = expected.shift
|
228
|
-
assert_equal indents, line.match(/^\t*/).to_a.first.length, line
|
229
|
-
line.strip!
|
230
|
-
assert_match /^\#<#{klass}/, line
|
231
|
-
end
|
230
|
+
refute highlighter.visible?
|
232
231
|
end
|
233
232
|
|
234
233
|
def test_screenshot
|
@@ -332,4 +331,15 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
332
331
|
pop_up.menu_item.perform :cancel unless pop_up.children.empty?
|
333
332
|
end
|
334
333
|
|
334
|
+
def test_contextual_menu
|
335
|
+
Mouse.move_to app.window.web_area
|
336
|
+
menu = nil
|
337
|
+
dsl.right_click do
|
338
|
+
menu = dsl.contextual_menu
|
339
|
+
end
|
340
|
+
refute_nil menu, 'did not find the contextual menu'
|
341
|
+
refute_nil menu.item(title: 'Reload')
|
342
|
+
menu.perform :cancel
|
343
|
+
end
|
344
|
+
|
335
345
|
end
|
@@ -4,6 +4,7 @@ require 'accessibility/graph'
|
|
4
4
|
class TestAccessibilityGraph < MiniTest::Unit::TestCase
|
5
5
|
|
6
6
|
def test_generate
|
7
|
+
skip 'graphs are broken right now'
|
7
8
|
p = Accessibility::Graph.new(app.main_window).generate_png!
|
8
9
|
assert File.exists? p
|
9
10
|
assert_match /^PNG image/, `file --brief #{p}`
|
@@ -72,14 +72,14 @@ class TestAccessibilityQualifier < MiniTest::Unit::TestCase
|
|
72
72
|
|
73
73
|
def test_qualifies_based_on_param_attribute_value
|
74
74
|
e = app.attribute(:main_window).attribute(:title_ui_element)
|
75
|
-
q = qualifier(:StaticText, [:string_for_range,
|
75
|
+
q = qualifier(:StaticText, [:string_for_range, 0..1] => 'AX' )
|
76
76
|
assert q.qualifies? e
|
77
77
|
refute q.qualifies? list
|
78
78
|
end
|
79
79
|
|
80
80
|
def test_qualifies_based_on_param_attribute_regexp_match
|
81
81
|
e = app.attribute(:main_window).attribute(:title_ui_element)
|
82
|
-
q = qualifier(:StaticText, [:string_for_range,
|
82
|
+
q = qualifier(:StaticText, [:string_for_range, 0..1] => /AX/ )
|
83
83
|
assert q.qualifies? e
|
84
84
|
refute q.qualifies? items.sample
|
85
85
|
end
|
@@ -13,6 +13,13 @@ class TestAXApplication < MiniTest::Unit::TestCase
|
|
13
13
|
assert_equal app, AX::Application.new(running_app)
|
14
14
|
end
|
15
15
|
|
16
|
+
def test_initialize_causing_app_to_launch
|
17
|
+
app = AX::Application.new('com.apple.Grab')
|
18
|
+
assert_kind_of AX::Application, app
|
19
|
+
ensure
|
20
|
+
app.terminate if app
|
21
|
+
end
|
22
|
+
|
16
23
|
def test_can_set_focus_and_blur_app # lol, blur
|
17
24
|
assert app.set :focused, false
|
18
25
|
refute app.active?
|
@@ -25,7 +32,7 @@ class TestAXApplication < MiniTest::Unit::TestCase
|
|
25
32
|
assert app.attribute :focused?
|
26
33
|
|
27
34
|
ensure
|
28
|
-
running_app.activateWithOptions NSApplicationActivateIgnoringOtherApps
|
35
|
+
running_app.activateWithOptions NSRunningApplication::NSApplicationActivateIgnoringOtherApps
|
29
36
|
end
|
30
37
|
|
31
38
|
def test_can_hide_and_unhide_app
|
@@ -42,7 +49,7 @@ class TestAXApplication < MiniTest::Unit::TestCase
|
|
42
49
|
refute app.hidden?
|
43
50
|
|
44
51
|
ensure
|
45
|
-
running_app.activateWithOptions NSApplicationActivateIgnoringOtherApps
|
52
|
+
running_app.activateWithOptions NSRunningApplication::NSApplicationActivateIgnoringOtherApps
|
46
53
|
end
|
47
54
|
|
48
55
|
def test_set_calls_super
|