motion-accessibility 1.1.1 → 2.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.
- checksums.yaml +4 -4
- data/README.md +76 -0
- data/lib/motion-accessibility-console/object.rb +16 -0
- data/lib/motion-accessibility-console.rb +8 -0
- data/lib/project/constants.rb +10 -1
- data/lib/project/motion-accessibility-console/browser.rb +111 -0
- data/lib/project/motion-accessibility-console/touch.rb +104 -0
- data/lib/project/motion-accessibility-console/tree.rb +149 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a8b8a68fde38c107500ee9ba7391df3cf22d7a6
|
4
|
+
data.tar.gz: e979abc551392f9dede8c3dbf88199f70b1c34ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b97f12b278ea3522bd242c8ee9c94bcae1f67cbf5e17ba4ff87839ccd2997bc73164f3524e879b574ef6e770b42e849524276efd0399d1a85334a9104e960479
|
7
|
+
data.tar.gz: 356842305034eb08ce3a4f49aebd4166e7c9156069295d636c9371f43c237143d6a148016e2bf2579dc2fb356bb93ffdf2f31ad370d3fbdc2f16b81b14ff0e26
|
data/README.md
CHANGED
@@ -23,6 +23,82 @@ Or install it yourself as:
|
|
23
23
|
$ gem install motion-accessibility
|
24
24
|
|
25
25
|
## Usage
|
26
|
+
### The Motion-Accessibility Console
|
27
|
+
|
28
|
+
The motion-accessibility console gives you a way to interact with a running application through a purely textual interface. This works well for blind developers and command line users.
|
29
|
+
|
30
|
+
#### Enabling the Console
|
31
|
+
|
32
|
+
To enable the console, you can do one of two things. If you would just like to try it, type `include Accessibility::Console` at a REPL prompt. If you would like to use it in your application, add `require motion-accessibility-console` to your Rakefile. You have to do this even if you use bundler.
|
33
|
+
|
34
|
+
#### `browse` or `b`
|
35
|
+
|
36
|
+
The `browse` or `b` command lets you examine the view hierarchy in a speech-friendly way. This lets you see all the relevant views displayed in your running application. It will detect if the screen has changed and refresh itself automatically.
|
37
|
+
|
38
|
+
The following examples come from the sample app included with motion-accessibility.
|
39
|
+
|
40
|
+
```
|
41
|
+
(main)> browse
|
42
|
+
Browsing UIWindow
|
43
|
+
1 UILabel Hello!
|
44
|
+
2 Touchable UITextField
|
45
|
+
3 Touchable UIRoundedRectButton Update
|
46
|
+
4 UINavigationBar
|
47
|
+
5 UITabBar with 2 subviews
|
48
|
+
=> nil
|
49
|
+
```
|
50
|
+
|
51
|
+
If a view has subviews, you can browse that view.
|
52
|
+
|
53
|
+
```
|
54
|
+
(main)> b 5
|
55
|
+
Browsing UITabBar
|
56
|
+
0 Superview UIWindow
|
57
|
+
1 Touchable UITabBarButton Test App
|
58
|
+
2 Touchable UITabBarButton Table
|
59
|
+
=> nil
|
60
|
+
```
|
61
|
+
|
62
|
+
You can refresh the browser by passing the `:refresh` or `:top` keyword.
|
63
|
+
|
64
|
+
You may pass the `:scroll` keyword to scroll a UIScrollView or descendants, such as a UITableView. This still has some minor issues .
|
65
|
+
|
66
|
+
#### `view` or `v`
|
67
|
+
|
68
|
+
The `view` or `v` command simply returns the current view. If you have just browsed a view, it will return that. Otherwise, you may specify the view you wish to browse. Note that for all the commands, you may either use its number or accessibility label.
|
69
|
+
|
70
|
+
```
|
71
|
+
(main)> v 1
|
72
|
+
=> #<UITabBarButton:0x9380560>
|
73
|
+
```
|
74
|
+
|
75
|
+
#### `touch`
|
76
|
+
The `touch` command lets you interact with the various controls. It works on all standard UIControls. `touch` can accept an argument depending on the type of control. For example, you can pass a UITextField a string to set its value.
|
77
|
+
|
78
|
+
```
|
79
|
+
(main)> touch 2,"motion-accessibility rocks!"
|
80
|
+
Browsing UIWindow
|
81
|
+
1 UILabel Hello!
|
82
|
+
2 Touchable UITextField motion-accessibility rocks!
|
83
|
+
3 Touchable UIRoundedRectButton Update
|
84
|
+
4 UINavigationBar
|
85
|
+
5 UITabBar with 2 subviews
|
86
|
+
=> nil
|
87
|
+
```
|
88
|
+
|
89
|
+
UIButtons can take a UIControlEvent, but default to `UIControlEventTouchUpInside`. Note here the use of an accessibility label to reference the view.
|
90
|
+
|
91
|
+
```
|
92
|
+
(main)> touch "update"
|
93
|
+
Browsing UIWindow
|
94
|
+
1 UILabel motion-accessibility rocks!
|
95
|
+
2 Touchable UITextField motion-accessibility rocks!
|
96
|
+
3 Touchable UIRoundedRectButton Update
|
97
|
+
4 UINavigationBar
|
98
|
+
5 UITabBar with 2 subviews
|
99
|
+
=> nil
|
100
|
+
```
|
101
|
+
|
26
102
|
### The Accessibility Inspector
|
27
103
|
|
28
104
|
You can easily see the state of any of the following attributes and methods by using the accessibility inspector. Just call the `inspect_accessibility` method on any object.
|
@@ -0,0 +1,8 @@
|
|
1
|
+
unless defined?(Motion::Project::Config)
|
2
|
+
raise "The motion-accessibility browser must be required within a RubyMotion project Rakefile."
|
3
|
+
end
|
4
|
+
|
5
|
+
lib_dir_path = File.dirname(File.expand_path(__FILE__))
|
6
|
+
Motion::Project::App.setup do |app|
|
7
|
+
app.files.unshift(Dir.glob(File.join(lib_dir_path, "motion-accessibility-console/**/*.rb")))
|
8
|
+
end
|
data/lib/project/constants.rb
CHANGED
@@ -187,7 +187,16 @@ attributes.member?(attribute)
|
|
187
187
|
end
|
188
188
|
|
189
189
|
Touchable_Types = ["UITextField", "UIButton", "UIPickerView", "UIDatePicker",
|
190
|
-
"UISegmentedControl", "UISlider", "UIStepper", "UISwitch"
|
190
|
+
"UISegmentedControl", "UISlider", "UIStepper", "UISwitch",
|
191
|
+
"UITableViewCell", "UITabBarButton","UINavigationItemButtonView"]
|
192
|
+
|
193
|
+
Ignored_Views = ["UIView", "UILayoutContainerView", "UITransitionView", "UINavigationTransitionView", "UIViewControllerWrapperView", "UITableViewCellContentView", "UINavigationItemView", "UITableViewWrapperView"]
|
194
|
+
|
195
|
+
Ignored_ImageViews = ["UINavigationBar", "UITabBar", "UITableView"]
|
196
|
+
|
197
|
+
Reverse_Views = ["UITableView", "UINavigationBar", "UITabBar"]
|
198
|
+
|
199
|
+
View_Names = {"UINavigationItemButtonView" => "Back Button"}
|
191
200
|
|
192
201
|
private
|
193
202
|
def compile_attributes
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Accessibility
|
2
|
+
module Console
|
3
|
+
|
4
|
+
$browser_path=[]
|
5
|
+
Update_Delay=1.0
|
6
|
+
|
7
|
+
def self.touchable_type(view)
|
8
|
+
control=view.class
|
9
|
+
until A11y::Touchable_Types.member?(control.to_s)||control.nil?
|
10
|
+
control=control.superclass
|
11
|
+
end
|
12
|
+
control
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.scrollable_view?(view)
|
16
|
+
control=view.class
|
17
|
+
until control==UIScrollView||control.nil?
|
18
|
+
control=control.superclass
|
19
|
+
end
|
20
|
+
control==UIScrollView
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.init(view=nil)
|
24
|
+
view=UIApplication.sharedApplication.keyWindow if view.nil?
|
25
|
+
$browser_tree=A11y::Console::Tree.build(view)
|
26
|
+
$browser_path<<$browser_tree if $browser_path.empty?
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.display_views
|
31
|
+
$browser_current=$browser_tree unless $browser_current
|
32
|
+
puts "Browsing "+$browser_current.display_view
|
33
|
+
$browser_current.browsable_nodes.each_with_index do |node, index|
|
34
|
+
next if node.nil?
|
35
|
+
output=node.display_view( index)
|
36
|
+
puts output unless output.nil?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.start_refreshing
|
41
|
+
if !A11y::Data[:refresh]&&RUBYMOTION_ENV!='test'
|
42
|
+
NSTimer.scheduledTimerWithTimeInterval(Update_Delay, target: self, selector: 'refresh', userInfo: nil, repeats: true)
|
43
|
+
A11y::Data[:refresh]=true
|
44
|
+
self.init
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.browse(request=nil)
|
49
|
+
self.init unless $browser_current
|
50
|
+
self.start_refreshing
|
51
|
+
request=0 if request==:back
|
52
|
+
if request.nil?
|
53
|
+
elsif request==:top||request==:refresh
|
54
|
+
self.init
|
55
|
+
$browser_current=$browser_tree
|
56
|
+
$browser_path.clear
|
57
|
+
elsif request==0
|
58
|
+
raise "You cannot go back any further" if $browser_path.length<2
|
59
|
+
$browser_path.pop
|
60
|
+
$browser_current=$browser_path.last
|
61
|
+
self.init unless A11y::Data[:refresh]
|
62
|
+
elsif request==:scroll
|
63
|
+
raise "This view cannot scroll" unless A11y::Console.scrollable_view?($browser_current.view)
|
64
|
+
below=CGRect.new([0, $browser_current.view.size.height], $browser_current.view.size)
|
65
|
+
$browser_current.view.scrollRectToVisible(below, animated: false)
|
66
|
+
else
|
67
|
+
self.init unless $browser_tree
|
68
|
+
$browser_current=$browser_tree unless $browser_current
|
69
|
+
found=$browser_current.find(request)
|
70
|
+
if found
|
71
|
+
if found.subviews.empty?
|
72
|
+
$browser_cursor=found
|
73
|
+
return found.view.inspect_a11y
|
74
|
+
end
|
75
|
+
self.init unless A11y::Data[:refresh]
|
76
|
+
$browser_current=found
|
77
|
+
$browser_path<<found
|
78
|
+
end
|
79
|
+
end
|
80
|
+
$browser_cursor=$browser_current
|
81
|
+
self.display_views
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.refresh
|
86
|
+
self.init
|
87
|
+
$before=$browser_tree.copy unless $before
|
88
|
+
unless $browser_tree==$before
|
89
|
+
puts "The screen has changed."
|
90
|
+
self.browse :top
|
91
|
+
puts "(Main)> "
|
92
|
+
end
|
93
|
+
$before=$browser_tree.copy
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.view(request=nil)
|
97
|
+
self.init unless A11y::Data[:refresh]
|
98
|
+
$browser_current=$browser_tree unless $browser_current
|
99
|
+
$browser_cursor=$browser_tree unless $browser_cursor
|
100
|
+
return $browser_cursor.view unless request
|
101
|
+
result=$browser_current.find(request)
|
102
|
+
raise "Unknown view" unless result
|
103
|
+
$browser_cursor=result
|
104
|
+
result.view
|
105
|
+
end
|
106
|
+
|
107
|
+
alias :b :browse
|
108
|
+
alias :v :view
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Accessibility
|
2
|
+
module Console
|
3
|
+
|
4
|
+
def self.touch(view, arg=nil, options={})
|
5
|
+
self.start_refreshing
|
6
|
+
$browser_current=$browser_tree unless $browser_current
|
7
|
+
unless RUBYMOTION_ENV=='test'
|
8
|
+
found=$browser_current.find(view)
|
9
|
+
raise "Could not find the view" unless found
|
10
|
+
view=found.view
|
11
|
+
end
|
12
|
+
control=A11y::Console.touchable_type(view)
|
13
|
+
raise "I don't know how to touch a #{view.class}" if control.nil?
|
14
|
+
if found
|
15
|
+
sv=options[:superview]||found.superview.view
|
16
|
+
else
|
17
|
+
sv=options[:superview]
|
18
|
+
end
|
19
|
+
case control.to_s
|
20
|
+
when "UIButton"
|
21
|
+
arg||=UIControlEventTouchUpInside
|
22
|
+
view.sendActionsForControlEvents(arg)
|
23
|
+
when "UITabBarButton"
|
24
|
+
arg||=UIControlEventTouchUpInside
|
25
|
+
view.sendActionsForControlEvents(arg)
|
26
|
+
when "UITextField"
|
27
|
+
view.text=arg
|
28
|
+
when "UIPickerView"
|
29
|
+
self.touch_pickerview(view, arg)
|
30
|
+
when "UIDatePicker"
|
31
|
+
view.date=arg
|
32
|
+
when "UISegmentedControl"
|
33
|
+
self.touch_segmented(view, arg)
|
34
|
+
when "UISlider"
|
35
|
+
view.value=arg
|
36
|
+
when "UIStepper"
|
37
|
+
view.value=arg
|
38
|
+
when "UISwitch"
|
39
|
+
arg||=!view.arg
|
40
|
+
view.on=arg
|
41
|
+
when "UITableViewCell"
|
42
|
+
raise "Could not get the UITableView" unless sv.kind_of?(UITableView)
|
43
|
+
index=options[:index]||sv.indexPathForCell(view)
|
44
|
+
raise "Could not get the index" unless index
|
45
|
+
sv.delegate.tableView(self, didSelectRowAtIndexPath: index)
|
46
|
+
when "UINavigationItemButtonView"
|
47
|
+
view.superview.delegate.popViewControllerAnimated(true)
|
48
|
+
else
|
49
|
+
raise "I don't know what to do with a #{control}"
|
50
|
+
end
|
51
|
+
self.browse unless RUBYMOTION_ENV=='test'
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.touch_pickerview(view, arg)
|
55
|
+
raise "You must pass a hash with the row and component keywords" unless arg.kind_of?(Hash)&&arg[:row]&&arg[:component]
|
56
|
+
arg[:animated]||=false
|
57
|
+
if arg[:row].kind_of?(String)
|
58
|
+
results=[]
|
59
|
+
view.numberOfRowsInComponent(arg[:component]).times do |row_index|
|
60
|
+
title=view.delegate.pickerView(view, titleForRow: row_index, forComponent: arg[:component])
|
61
|
+
if title.casecmp(arg[:row])==0
|
62
|
+
results=[row_index]
|
63
|
+
break
|
64
|
+
end
|
65
|
+
if title=~Regexp.new(arg[:row],true)
|
66
|
+
results<<row_index
|
67
|
+
end
|
68
|
+
end
|
69
|
+
raise "Unknown value" if results.empty?
|
70
|
+
raise "That could refer to more than one value." if results.length>1
|
71
|
+
view.selectRow(results.first, inComponent: arg[:component], animated: false)
|
72
|
+
elsif arg[:row].kind_of?(Fixnum)
|
73
|
+
view.selectRow(arg[:row], inComponent: arg[:component], animated: arg[:animated])
|
74
|
+
else
|
75
|
+
raise "Unknown row #{arg[:row]}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.touch_segmented(view, arg)
|
80
|
+
if arg.kind_of?(Fixnum)
|
81
|
+
view.selectedSegmentIndex=arg
|
82
|
+
elsif arg.kind_of?(String)
|
83
|
+
results=[]
|
84
|
+
view.numberOfSegments.times do |index|
|
85
|
+
title=view.titleForSegmentAtIndex(index)
|
86
|
+
if title.casecmp(arg)==0
|
87
|
+
results=[index]
|
88
|
+
break
|
89
|
+
end
|
90
|
+
if title=~Regexp.new(arg,true)
|
91
|
+
results<<index
|
92
|
+
end
|
93
|
+
end
|
94
|
+
raise "Unknown segment" if results.empty?
|
95
|
+
raise "That could refer to more than one segment" if results.length>1
|
96
|
+
view.selectedSegmentIndex=results.first
|
97
|
+
else
|
98
|
+
raise "Invalid segment"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module Accessibility
|
2
|
+
module Console
|
3
|
+
class Tree
|
4
|
+
|
5
|
+
attr_accessor :view, :subviews, :superview
|
6
|
+
|
7
|
+
def initialize(options={})
|
8
|
+
@view=options[:view]
|
9
|
+
@subviews=options[:subviews]||[]
|
10
|
+
@superview=options[:superview]
|
11
|
+
end
|
12
|
+
|
13
|
+
def copy
|
14
|
+
other=A11y::Console::Tree.new
|
15
|
+
other.superview=self.superview if superview
|
16
|
+
other.view=self.view if view
|
17
|
+
self.subviews.each {|subview| other.subviews<<subview.clone}
|
18
|
+
other
|
19
|
+
end
|
20
|
+
|
21
|
+
def ==(other)
|
22
|
+
return false unless self.superview.view==other.superview.view
|
23
|
+
return false unless self.view==other.view
|
24
|
+
return false unless self.subviews.size==other.subviews.size
|
25
|
+
self.subviews.each_index {|index| return false unless self.subviews[index]==other.subviews[index]}
|
26
|
+
return true
|
27
|
+
end
|
28
|
+
|
29
|
+
def browsable_nodes
|
30
|
+
nodes=[@superview]
|
31
|
+
if @subviews
|
32
|
+
if A11y::Reverse_Views.member?(@view.class.to_s)
|
33
|
+
nodes+=@subviews.reverse
|
34
|
+
else
|
35
|
+
nodes+=@subviews
|
36
|
+
end
|
37
|
+
end
|
38
|
+
nodes
|
39
|
+
end
|
40
|
+
|
41
|
+
def inspect
|
42
|
+
nodes=@subviews.collect {|tree| tree.inspect}
|
43
|
+
return @view.class.to_s if @subviews.empty?
|
44
|
+
result="[#{@view.class}"
|
45
|
+
result+=" #{nodes.join(" ")}" unless nodes.empty?
|
46
|
+
result+="]"
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
def display_view(index=nil)
|
51
|
+
display=Array.new
|
52
|
+
control=@view.class.to_s
|
53
|
+
control=nil if A11y::View_Names[control]
|
54
|
+
control="Superview #{control}" if index==0
|
55
|
+
if @view.class==UITableViewCell
|
56
|
+
label=@view.subviews.first
|
57
|
+
while label&&!label.kind_of?(UILabel)
|
58
|
+
label=label.subviews.first
|
59
|
+
end
|
60
|
+
raise "Could not find the UITableViewCell's label" unless label.kind_of?(UILabel)
|
61
|
+
name=label.text
|
62
|
+
elsif @view.class==UITextField
|
63
|
+
name=@view.text
|
64
|
+
else
|
65
|
+
name=A11y::View_Names[@view.class.to_s]||@view.accessibility_value||@view.accessibility_label if @view.accessibility_element?||view.superclass==UIControl
|
66
|
+
end
|
67
|
+
display<<index.to_s
|
68
|
+
display<<"Touchable" if A11y::Console.touchable_type(@view)
|
69
|
+
display<<control if control
|
70
|
+
display<<name if name
|
71
|
+
if index
|
72
|
+
if index>0 and not(@subviews.empty?)
|
73
|
+
indicator="with #{@subviews.length} subview"
|
74
|
+
indicator+="s" if @subviews.length>1
|
75
|
+
end
|
76
|
+
display<<indicator
|
77
|
+
end
|
78
|
+
display.join(" ")
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.accessible_view?(view)
|
82
|
+
return view.accessibility_element?||view.accessibility_label||view.accessibility_value||view.accessibility_traits
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.ignore_view?(view)
|
86
|
+
return true if view.subviews.empty?&&!self.accessible_view?(view)
|
87
|
+
if view.superview
|
88
|
+
sv=view.superview
|
89
|
+
while sv&&self.ignore_view?(sv)
|
90
|
+
sv=sv.superview
|
91
|
+
end
|
92
|
+
return true if A11y::Console.touchable_type(sv)
|
93
|
+
return true if view.class==UIImageView&&A11y::Ignored_ImageViews.member?(sv.class.to_s)
|
94
|
+
end
|
95
|
+
class_name=view.class.to_s
|
96
|
+
return true if class_name=~/^_/
|
97
|
+
A11y::Ignored_Views.member?(class_name)
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.build(view=nil, superview=nil)
|
101
|
+
tree=self.new
|
102
|
+
view=UIApplication.sharedApplication.keyWindow if view.nil?
|
103
|
+
subviews=[]
|
104
|
+
view.subviews.each do |subview|
|
105
|
+
subview_tree=self.build(subview, tree)
|
106
|
+
if self.ignore_view?(subview)
|
107
|
+
subview_tree.subviews.each {|v| v.superview=tree}
|
108
|
+
subviews=subviews+subview_tree.subviews
|
109
|
+
else
|
110
|
+
subviews<<subview_tree
|
111
|
+
end
|
112
|
+
end
|
113
|
+
tree.view=view
|
114
|
+
tree.subviews=subviews
|
115
|
+
tree.superview=superview
|
116
|
+
tree
|
117
|
+
end
|
118
|
+
|
119
|
+
def find(request)
|
120
|
+
found=nil
|
121
|
+
if request.kind_of?(Fixnum)
|
122
|
+
raise "Invalid number" unless request>=0&&request<browsable_nodes.length
|
123
|
+
found=browsable_nodes[request]
|
124
|
+
elsif request.kind_of?(String)
|
125
|
+
results=[]
|
126
|
+
browsable_nodes.each do |node|
|
127
|
+
next if node.nil?
|
128
|
+
next unless node.view.accessibility_label
|
129
|
+
pattern=Regexp.new(request,true)
|
130
|
+
compare=node.view.accessibility_label=~pattern
|
131
|
+
next if compare.nil?
|
132
|
+
if node.view.accessibility_label.downcase==request.downcase
|
133
|
+
return node
|
134
|
+
else
|
135
|
+
results<<node
|
136
|
+
end
|
137
|
+
end
|
138
|
+
raise "\"#{request}\" could refer to more than one view." if results.length>1
|
139
|
+
found=results.first
|
140
|
+
else
|
141
|
+
raise "Unknown request: #{request}: #{request.class}" unless request.respond_to?(:superview)
|
142
|
+
found=request
|
143
|
+
end
|
144
|
+
found
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: motion-accessibility
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: '2.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Austin Seraphin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -32,10 +32,15 @@ extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
34
|
- README.md
|
35
|
+
- lib/motion-accessibility-console/object.rb
|
36
|
+
- lib/motion-accessibility-console.rb
|
35
37
|
- lib/motion-accessibility.rb
|
36
38
|
- lib/project/constants.rb
|
37
39
|
- lib/project/element.rb
|
38
40
|
- lib/project/inspector.rb
|
41
|
+
- lib/project/motion-accessibility-console/browser.rb
|
42
|
+
- lib/project/motion-accessibility-console/touch.rb
|
43
|
+
- lib/project/motion-accessibility-console/tree.rb
|
39
44
|
- lib/project/object.rb
|
40
45
|
- lib/project/picker.rb
|
41
46
|
- lib/project/status.rb
|
@@ -59,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
64
|
version: '0'
|
60
65
|
requirements: []
|
61
66
|
rubyforge_project:
|
62
|
-
rubygems_version: 2.0.
|
67
|
+
rubygems_version: 2.0.6
|
63
68
|
signing_key:
|
64
69
|
specification_version: 4
|
65
70
|
summary: This gem provides easy ruby-like wrappers around the protocols which interact
|