appium_lib 0.0.30 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Rakefile +15 -7
- data/appium_lib.gemspec +3 -3
- data/docs.md +7 -5
- data/lib/appium_lib.rb +34 -6
- data/lib/appium_lib/android/element/alert.rb +43 -0
- data/lib/appium_lib/android/element/generic.rb +94 -0
- data/lib/appium_lib/android/element/textfield.rb +43 -0
- data/lib/appium_lib/android/helper.rb +120 -0
- data/lib/appium_lib/android/patch.rb +10 -0
- data/lib/appium_lib/common/element/button.rb +83 -0
- data/lib/appium_lib/common/element/text.rb +44 -0
- data/lib/appium_lib/common/element/window.rb +9 -0
- data/lib/appium_lib/common/helper.rb +140 -0
- data/lib/appium_lib/common/patch.rb +83 -0
- data/lib/appium_lib/common/version.rb +6 -0
- data/lib/appium_lib/driver.rb +265 -0
- data/lib/appium_lib/ios/element/alert.rb +56 -0
- data/lib/appium_lib/ios/element/generic.rb +170 -0
- data/lib/appium_lib/ios/element/textfield.rb +90 -0
- data/lib/appium_lib/ios/helper.rb +103 -0
- data/lib/appium_lib/ios/patch.rb +15 -0
- data/readme.md +10 -3
- data/release_notes.md +8 -0
- metadata +19 -15
- data/lib/appium_lib/console.rb +0 -254
- data/lib/appium_lib/element/android/alert.rb +0 -45
- data/lib/appium_lib/element/android/generic.rb +0 -88
- data/lib/appium_lib/element/android/textfield.rb +0 -44
- data/lib/appium_lib/element/button.rb +0 -83
- data/lib/appium_lib/element/ios/alert.rb +0 -49
- data/lib/appium_lib/element/ios/generic.rb +0 -140
- data/lib/appium_lib/element/ios/textfield.rb +0 -93
- data/lib/appium_lib/element/text.rb +0 -43
- data/lib/appium_lib/element/window.rb +0 -12
- data/lib/appium_lib/helper.rb +0 -278
- data/lib/appium_lib/patch.rb +0 -90
- data/lib/appium_lib/version.rb +0 -4
data/release_notes.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
#### v0.0.30 2013-04-16
|
2
|
+
|
3
|
+
- [6d65a9c](https://github.com/appium/ruby_lib/commit/6d65a9c2895b1b66556b12fee4fc9649f558ede1) Release 0.0.30
|
4
|
+
- [5692f96](https://github.com/appium/ruby_lib/commit/5692f9604a09b6198f8ada7823d8f74858b8af88) Fix quote
|
5
|
+
- [ee17332](https://github.com/appium/ruby_lib/commit/ee173329758ea486d32d6887439de39a749ceba0) Use driver_quit
|
6
|
+
- [5a71419](https://github.com/appium/ruby_lib/commit/5a71419c931ab19f8ab2816e1e5ee35ff457b2a0) Update release notes
|
7
|
+
|
8
|
+
|
1
9
|
#### v0.0.29 2013-04-15
|
2
10
|
|
3
11
|
- [1c1e0ee](https://github.com/appium/ruby_lib/commit/1c1e0eeed8d636dc81d3b74612405722b1134071) Release 0.0.29
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appium_lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- code@bootstraponline.com
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: selenium-webdriver
|
@@ -66,19 +66,23 @@ files:
|
|
66
66
|
- appium_lib.gemspec
|
67
67
|
- docs.md
|
68
68
|
- lib/appium_lib.rb
|
69
|
-
- lib/appium_lib/
|
70
|
-
- lib/appium_lib/element/
|
71
|
-
- lib/appium_lib/element/
|
72
|
-
- lib/appium_lib/
|
73
|
-
- lib/appium_lib/
|
74
|
-
- lib/appium_lib/element/
|
75
|
-
- lib/appium_lib/element/
|
76
|
-
- lib/appium_lib/element/
|
77
|
-
- lib/appium_lib/
|
78
|
-
- lib/appium_lib/
|
79
|
-
- lib/appium_lib/
|
80
|
-
- lib/appium_lib/
|
81
|
-
- lib/appium_lib/
|
69
|
+
- lib/appium_lib/android/element/alert.rb
|
70
|
+
- lib/appium_lib/android/element/generic.rb
|
71
|
+
- lib/appium_lib/android/element/textfield.rb
|
72
|
+
- lib/appium_lib/android/helper.rb
|
73
|
+
- lib/appium_lib/android/patch.rb
|
74
|
+
- lib/appium_lib/common/element/button.rb
|
75
|
+
- lib/appium_lib/common/element/text.rb
|
76
|
+
- lib/appium_lib/common/element/window.rb
|
77
|
+
- lib/appium_lib/common/helper.rb
|
78
|
+
- lib/appium_lib/common/patch.rb
|
79
|
+
- lib/appium_lib/common/version.rb
|
80
|
+
- lib/appium_lib/driver.rb
|
81
|
+
- lib/appium_lib/ios/element/alert.rb
|
82
|
+
- lib/appium_lib/ios/element/generic.rb
|
83
|
+
- lib/appium_lib/ios/element/textfield.rb
|
84
|
+
- lib/appium_lib/ios/helper.rb
|
85
|
+
- lib/appium_lib/ios/patch.rb
|
82
86
|
- readme.md
|
83
87
|
- release_notes.md
|
84
88
|
homepage: https://github.com/appium/ruby_lib
|
data/lib/appium_lib/console.rb
DELETED
@@ -1,254 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
=begin
|
3
|
-
Run with:
|
4
|
-
pry -r ./console.rb
|
5
|
-
|
6
|
-
Based on simple_test.rb
|
7
|
-
https://github.com/appium/appium/blob/82995f47408530c80c3376f4e07a1f649d96ba22/sample-code/examples/ruby/simple_test.rb
|
8
|
-
https://github.com/appium/appium/blob/c58eeb66f2d6fa3b9a89d188a2e657cca7cb300f/LICENSE
|
9
|
-
=end
|
10
|
-
|
11
|
-
add_to_path __FILE__
|
12
|
-
add_to_path __FILE__, 'element'
|
13
|
-
|
14
|
-
require 'selenium-webdriver'
|
15
|
-
|
16
|
-
# Path to the .app or .app.zip.
|
17
|
-
# The path can be local or remote for Sauce.
|
18
|
-
APP_PATH = ENV['APP_PATH'] unless defined?(APP_PATH)
|
19
|
-
raise "APP_PATH must be set." if APP_PATH.nil?
|
20
|
-
|
21
|
-
# The name to use for the test run on Sauce.
|
22
|
-
APP_NAME = ENV['APP_NAME'] unless defined?(APP_NAME)
|
23
|
-
|
24
|
-
# Android app package
|
25
|
-
APP_PACKAGE = ENV['APP_PACKAGE'] unless defined?(APP_PACKAGE)
|
26
|
-
|
27
|
-
# Android app starting activity.
|
28
|
-
APP_ACTIVITY = ENV['APP_ACTIVITY'] unless defined?(APP_ACTIVITY)
|
29
|
-
|
30
|
-
# Android app waiting activity
|
31
|
-
APP_WAIT_ACTIVITY = ENV['APP_WAIT_ACTIVITY'] unless defined?(APP_WAIT_ACTIVITY)
|
32
|
-
|
33
|
-
# Sauce Username
|
34
|
-
SAUCE_USERNAME = ENV['SAUCE_USERNAME'] unless defined?(SAUCE_USERNAME)
|
35
|
-
|
36
|
-
# Sauce Key
|
37
|
-
SAUCE_ACCESS_KEY = ENV['SAUCE_ACCESS_KEY'] unless defined?(SAUCE_ACCESS_KEY)
|
38
|
-
|
39
|
-
PORT = ENV['PORT'] || 4723 unless defined?(PORT)
|
40
|
-
|
41
|
-
$os = nil
|
42
|
-
|
43
|
-
if $os.nil?
|
44
|
-
$os = :ios
|
45
|
-
$os = :android if APP_PATH.end_with?('.apk') || APP_PATH.end_with?('.apk.zip')
|
46
|
-
end
|
47
|
-
|
48
|
-
puts "OS is: #{$os}" if defined?(Pry)
|
49
|
-
|
50
|
-
if $os == :android
|
51
|
-
raise "APP_PACKAGE must be set." if APP_PACKAGE.nil?
|
52
|
-
raise "APP_ACTIVITY must be set." if APP_ACTIVITY.nil?
|
53
|
-
end
|
54
|
-
|
55
|
-
# ruby_console files load depending on OS
|
56
|
-
require 'helper'
|
57
|
-
require 'button'
|
58
|
-
require 'text'
|
59
|
-
require 'window'
|
60
|
-
require 'patch'
|
61
|
-
|
62
|
-
# Android combines secure and textfield.
|
63
|
-
# iOS differentiates between secure and textfield.
|
64
|
-
# combine secure & textfield on iOS to match Android behavior.
|
65
|
-
if $os == :ios
|
66
|
-
require 'ios/textfield'
|
67
|
-
require 'ios/alert'
|
68
|
-
require 'ios/generic'
|
69
|
-
else
|
70
|
-
require 'android/textfield'
|
71
|
-
require 'android/alert'
|
72
|
-
require 'android/generic'
|
73
|
-
end
|
74
|
-
|
75
|
-
# WebDriver capabilities. Must be valid for Sauce to work.
|
76
|
-
# https://github.com/jlipps/appium/blob/master/app/android.js
|
77
|
-
def android_capabilities
|
78
|
-
{
|
79
|
-
browserName: 'Android',
|
80
|
-
platform: 'LINUX',
|
81
|
-
version: '4.1',
|
82
|
-
device: 'Android',
|
83
|
-
name: APP_NAME || 'Ruby Console Android Appium',
|
84
|
-
app: absolute_app_path,
|
85
|
-
:'app-package' => APP_PACKAGE,
|
86
|
-
:'app-activity' => APP_ACTIVITY,
|
87
|
-
:'app-wait-activity' => APP_WAIT_ACTIVITY
|
88
|
-
}
|
89
|
-
end
|
90
|
-
|
91
|
-
# WebDriver capabilities. Must be valid for Sauce to work.
|
92
|
-
def ios_capabilities
|
93
|
-
{
|
94
|
-
browserName: 'iOS 6.0',
|
95
|
-
platform: 'Mac 10.8',
|
96
|
-
version: '6.0',
|
97
|
-
device: 'iPhone Simulator',
|
98
|
-
name: APP_NAME || 'Ruby Console iOS Appium',
|
99
|
-
app: absolute_app_path
|
100
|
-
}
|
101
|
-
end
|
102
|
-
|
103
|
-
def capabilities
|
104
|
-
$os == :ios ? ios_capabilities : android_capabilities
|
105
|
-
end
|
106
|
-
|
107
|
-
# Converts environment variable APP_PATH to an absolute path.
|
108
|
-
# @return [String] APP_PATH as an absolute path
|
109
|
-
def absolute_app_path
|
110
|
-
raise 'APP_PATH environment variable not set!' if APP_PATH.nil?
|
111
|
-
return APP_PATH if APP_PATH.match(/^http/) # public URL for Sauce
|
112
|
-
if APP_PATH.match(/^\//) # absolute file path
|
113
|
-
raise "App doesn't exist. #{APP_PATH}" unless File.exist? APP_PATH
|
114
|
-
return APP_PATH
|
115
|
-
end
|
116
|
-
file = File.join(File.dirname(__FILE__), APP_PATH)
|
117
|
-
raise "App doesn't exist #{file}" unless File.exist? file
|
118
|
-
file
|
119
|
-
end
|
120
|
-
|
121
|
-
# Get the server url for sauce or local based on env vars.
|
122
|
-
# @return [String] the server url
|
123
|
-
def server_url
|
124
|
-
if !SAUCE_USERNAME.nil? && !SAUCE_ACCESS_KEY.nil?
|
125
|
-
"http://#{SAUCE_USERNAME}:#{SAUCE_ACCESS_KEY}@ondemand.saucelabs.com:80/wd/hub"
|
126
|
-
else
|
127
|
-
"http://127.0.0.1:#{PORT}/wd/hub"
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# Quits the driver
|
132
|
-
# @return [void]
|
133
|
-
def driver_quit
|
134
|
-
# rescue NoSuchDriverError
|
135
|
-
begin; $driver.quit unless $driver.nil?; rescue; end
|
136
|
-
end
|
137
|
-
|
138
|
-
# Creates a new global driver and quits the old one if it exists.
|
139
|
-
# @return [Selenium::WebDriver] the new global driver
|
140
|
-
def start_driver wait=30
|
141
|
-
@client = @client || Selenium::WebDriver::Remote::Http::Default.new
|
142
|
-
@client.timeout = 999999
|
143
|
-
|
144
|
-
$default_wait = wait
|
145
|
-
|
146
|
-
# If the driver already exists, quit before creating a new driver.
|
147
|
-
driver_quit
|
148
|
-
|
149
|
-
begin
|
150
|
-
$driver = Selenium::WebDriver.for(:remote, http_client: @client, desired_capabilities: capabilities, url: server_url)
|
151
|
-
rescue Errno::ECONNREFUSED
|
152
|
-
puts 'ERROR: Unable to connect to Appium. Is the server running?'
|
153
|
-
exit
|
154
|
-
end
|
155
|
-
|
156
|
-
# Set timeout to a large number so that Appium doesn't quit
|
157
|
-
# when no commands are entered after 60 seconds.
|
158
|
-
$driver.execute_script 'mobile: setCommandTimeout', timeout: 9999
|
159
|
-
|
160
|
-
# Set implicit wait by default unless we're using Pry.
|
161
|
-
$driver.manage.timeouts.implicit_wait = $default_wait unless defined?(Pry)
|
162
|
-
|
163
|
-
$driver
|
164
|
-
end
|
165
|
-
|
166
|
-
# Set implicit wait to zero.
|
167
|
-
def no_wait
|
168
|
-
$driver.manage.timeouts.implicit_wait = 0
|
169
|
-
end
|
170
|
-
|
171
|
-
# Set implicit wait to timeout, defaults to 30.
|
172
|
-
# @param timeout [Integer] the timeout in seconds
|
173
|
-
# @return [void]
|
174
|
-
def set_wait timeout=$default_wait
|
175
|
-
$driver.manage.timeouts.implicit_wait = timeout
|
176
|
-
end
|
177
|
-
|
178
|
-
# Returns the default client side wait.
|
179
|
-
# This value is independent of what the server is using
|
180
|
-
# @return [Integer]
|
181
|
-
def get_wait
|
182
|
-
$default_wait
|
183
|
-
end
|
184
|
-
|
185
|
-
# Returns existance of element.
|
186
|
-
#
|
187
|
-
# Example:
|
188
|
-
#
|
189
|
-
# exists { button('sign in') } ? puts('true') : puts('false')
|
190
|
-
#
|
191
|
-
# @return [Boolean]
|
192
|
-
def exists &search_block
|
193
|
-
pre_check = 0
|
194
|
-
post_check = $default_wait
|
195
|
-
|
196
|
-
set_wait pre_check # set wait to zero
|
197
|
-
|
198
|
-
# the element exists unless an error is raised.
|
199
|
-
exists = true
|
200
|
-
|
201
|
-
begin
|
202
|
-
search_block.call # search for element
|
203
|
-
rescue
|
204
|
-
exists = false # error means it's not there
|
205
|
-
end
|
206
|
-
|
207
|
-
# restore wait
|
208
|
-
set_wait post_check
|
209
|
-
|
210
|
-
return exists
|
211
|
-
end
|
212
|
-
|
213
|
-
# The same as $driver.execute_script
|
214
|
-
# @return [Object] the object returned by execute_script
|
215
|
-
def execute_script script, *args
|
216
|
-
$driver.execute_script script, *args
|
217
|
-
end
|
218
|
-
|
219
|
-
# Helper method for mobile gestures
|
220
|
-
#
|
221
|
-
# https://github.com/appium/appium/wiki/Automating-mobile-gestures
|
222
|
-
#
|
223
|
-
# $driver.execute_script 'mobile: swipe', endX: 100, endY: 100, duration: 0.01
|
224
|
-
#
|
225
|
-
# becomes
|
226
|
-
#
|
227
|
-
# mobile :swipe, endX: 100, endY: 100, duration: 0.01
|
228
|
-
def mobile method, *args
|
229
|
-
raise "Method must not be nil" if method.nil?
|
230
|
-
raise "Method must have .to_s" unless method.respond_to? :to_s
|
231
|
-
$driver.execute_script "mobile: #{method.to_s}", *args
|
232
|
-
end
|
233
|
-
|
234
|
-
# Calls $driver.find_elements
|
235
|
-
def find_elements *args
|
236
|
-
$driver.find_elements *args
|
237
|
-
end
|
238
|
-
|
239
|
-
# Calls $driver.find_elements
|
240
|
-
def find_element *args
|
241
|
-
$driver.find_element *args
|
242
|
-
end
|
243
|
-
|
244
|
-
# Quit the driver and Pry.
|
245
|
-
# quit and exit are reserved by Pry.
|
246
|
-
def x
|
247
|
-
driver_quit
|
248
|
-
exit # exit pry
|
249
|
-
end
|
250
|
-
|
251
|
-
# Paging in Pry is annoying :q required to exit.
|
252
|
-
# With pager disabled, the output is similar to IRB
|
253
|
-
# Only set if Pry is defined.
|
254
|
-
Pry.config.pager = false if defined?(Pry)
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
if $os == :android
|
3
|
-
|
4
|
-
# Tap the alert button identified by value.
|
5
|
-
# @param value [Integer, String] either an integer index of the button or the button's name
|
6
|
-
# @return [void]
|
7
|
-
def alert_click value
|
8
|
-
button(value).click
|
9
|
-
end
|
10
|
-
|
11
|
-
# Get the alert message text.
|
12
|
-
# @return [String]
|
13
|
-
def alert_text
|
14
|
-
get_page
|
15
|
-
end
|
16
|
-
|
17
|
-
# Accept the alert.
|
18
|
-
# The last button is considered "accept."
|
19
|
-
# @return [void]
|
20
|
-
def alert_accept
|
21
|
-
last_button.click
|
22
|
-
end
|
23
|
-
|
24
|
-
# Get the text of the alert's accept button.
|
25
|
-
# The last button is considered "accept."
|
26
|
-
# @return [String]
|
27
|
-
def alert_accept_text
|
28
|
-
last_button.text
|
29
|
-
end
|
30
|
-
|
31
|
-
# Dismiss the alert.
|
32
|
-
# The first button is considered "dismiss."
|
33
|
-
# @return [void]
|
34
|
-
def alert_dismiss
|
35
|
-
first_button.click
|
36
|
-
end
|
37
|
-
|
38
|
-
# Get the text of the alert's dismiss button.
|
39
|
-
# The first button is considered "dismiss."
|
40
|
-
# @return [String]
|
41
|
-
def alert_dismiss_text
|
42
|
-
first_button.text
|
43
|
-
end
|
44
|
-
|
45
|
-
end # if $os == :android
|
@@ -1,88 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
if $os == :android
|
3
|
-
=begin
|
4
|
-
name, names, text, text should match substring and case insensitive.
|
5
|
-
|
6
|
-
In Android //* is used to find partial case insensitive text matches.
|
7
|
-
//* is not currently implemented in iOS.
|
8
|
-
|
9
|
-
find_element :name by default uses a partial case insensitive match.
|
10
|
-
On iOS the default is an exact name match.
|
11
|
-
=end
|
12
|
-
|
13
|
-
=begin
|
14
|
-
// iOS version
|
15
|
-
// https://github.com/appium/ruby_lib/blob/37bb4e90b29e5adb4438b287b6387a504c94b5c4/lib/appium_lib/element/ios/generic.rb#L23
|
16
|
-
var search = "name contains[c] '#{text}' || label contains[c] '#{text}' || value contains[c] '#{text}'";
|
17
|
-
var a = w.secureTextFields().firstWithPredicate(search);
|
18
|
-
if ( isNil(a) ) {
|
19
|
-
a = w.textFields().firstWithPredicate(search);
|
20
|
-
if ( isNil(a) ) {
|
21
|
-
a = w.buttons().firstWithPredicate(search);
|
22
|
-
if ( isNil(a) ) {
|
23
|
-
a = w.elements().firstWithPredicate(search);
|
24
|
-
}
|
25
|
-
}
|
26
|
-
}
|
27
|
-
|
28
|
-
Android considers both a textfield and a secure textfield to be "EditText".
|
29
|
-
Name (the content desc) is searched first and then we search for value (text).
|
30
|
-
There's no label in Android.
|
31
|
-
|
32
|
-
Android buttons have different class names (android.widget.Button, android.widget.ImageButton)
|
33
|
-
so we consider the element a button if the class name contains the word button.
|
34
|
-
|
35
|
-
After looking for textfields and buttons, then we search all elements. Find will return
|
36
|
-
the first element that matches.
|
37
|
-
=end
|
38
|
-
def find val
|
39
|
-
# s.className('android.widget.EditText').descriptionContains(value);
|
40
|
-
args = [ [4, 'android.widget.EditText'], [7, val] ],
|
41
|
-
# s.className('android.widget.EditText').textContains(value);
|
42
|
-
[ [4, 'android.widget.EditText'], [3, val] ],
|
43
|
-
# s.classNameMatches('(?i).*button.*').descriptionContains(value);
|
44
|
-
[ [26, '(?i).*button.*'], [7, val] ],
|
45
|
-
# s.classNameMatches('(?i).*button.*').textContains(value);
|
46
|
-
[ [26, '(?i).*button.*'], [3, val] ],
|
47
|
-
# s.descriptionContains(value);
|
48
|
-
[ [7, val] ],
|
49
|
-
# s.textContains(value);
|
50
|
-
[ [3, val] ]
|
51
|
-
mobile :find, args
|
52
|
-
end
|
53
|
-
|
54
|
-
# Return the first element matching text.
|
55
|
-
# @param text [String] the text to search for
|
56
|
-
# @return [Element] the first matching element
|
57
|
-
def text text
|
58
|
-
# TODO: Use XPath index once it's implemented
|
59
|
-
# https://github.com/appium/appium/issues/295
|
60
|
-
texts(text).first
|
61
|
-
end
|
62
|
-
|
63
|
-
# Return all elements matching text.
|
64
|
-
# @param text [String] the text to search for
|
65
|
-
# @return [Array<Element>] all matching elements
|
66
|
-
def texts text
|
67
|
-
$driver.find_elements :xpath, "//*[contains(@text, '#{text}')]"
|
68
|
-
end
|
69
|
-
|
70
|
-
# Return the first element matching name.
|
71
|
-
# on Android name is content description
|
72
|
-
# on iOS name is the accessibility label or the text.
|
73
|
-
# @param name [String] the name to search for
|
74
|
-
# @return [Element] the first matching element
|
75
|
-
def name name
|
76
|
-
$driver.find_element :name, name
|
77
|
-
end
|
78
|
-
|
79
|
-
# Return all elements matching name.
|
80
|
-
# on Android name is content description
|
81
|
-
# on iOS name is the accessibility label or the text.
|
82
|
-
# @param name [String] the name to search for
|
83
|
-
# @return [Array<Element>] all matching elements
|
84
|
-
def names name
|
85
|
-
$driver.find_elements :name, name
|
86
|
-
end
|
87
|
-
|
88
|
-
end # if $os == :android
|