appium_lib 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/android_tests/Gemfile +2 -1
- data/android_tests/api.apk +0 -0
- data/android_tests/appium.txt +7 -1
- data/android_tests/lib/android/specs/common/helper.rb +3 -1
- data/android_tests/lib/android/specs/common/web_context.rb +13 -0
- data/android_tests/lib/android/specs/driver.rb +4 -2
- data/appium_lib.gemspec +1 -1
- data/docs/android_docs.md +221 -150
- data/docs/ios_docs.md +208 -140
- data/docs/migration.md +2 -1
- data/ios_tests/Gemfile +2 -1
- data/ios_tests/appium.txt +5 -1
- data/ios_tests/lib/ios/specs/common/helper.rb +3 -1
- data/ios_tests/lib/ios/specs/common/web_context.rb +11 -0
- data/lib/appium_lib/android/helper.rb +15 -5
- data/lib/appium_lib/common/helper.rb +82 -5
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/driver.rb +6 -2
- data/lib/appium_lib/ios/helper.rb +17 -8
- data/release_notes.md +29 -0
- metadata +17 -15
data/docs/migration.md
CHANGED
data/ios_tests/Gemfile
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
gemspec path: File.expand_path('../../', __FILE__) # __dir__ fails on 1.9
|
data/ios_tests/appium.txt
CHANGED
@@ -31,6 +31,7 @@ must_not_raise is a no-op.
|
|
31
31
|
# regular rescue will not handle exceptions outside of StandardError hierarchy
|
32
32
|
# must rescue Exception explicitly to rescue everything
|
33
33
|
proc { wait(*wait_time) { raise NoMemoryError } }.must_raise Timeout::Error
|
34
|
+
proc { wait(0.2, 0.0) { raise NoMemoryError } }.must_raise Timeout::Error
|
34
35
|
end
|
35
36
|
|
36
37
|
t 'ignore' do
|
@@ -56,7 +57,8 @@ must_not_raise is a no-op.
|
|
56
57
|
|
57
58
|
# regular rescue will not handle exceptions outside of StandardError hierarchy
|
58
59
|
# must rescue Exception explicitly to rescue everything
|
59
|
-
proc {
|
60
|
+
proc { wait_true(*wait_time) { raise NoMemoryError } }.must_raise Timeout::Error
|
61
|
+
proc { wait_true(0.2, 0.0) { raise NoMemoryError } }.must_raise Timeout::Error
|
60
62
|
end
|
61
63
|
|
62
64
|
# t 'id' # id is for Selendroid
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Tests specifically for areas where the web_context differs in behaviour
|
2
|
+
describe 'the web context' do
|
3
|
+
|
4
|
+
t 'get_android_inspect' do
|
5
|
+
text('Web, Use of UIWebView').click
|
6
|
+
set_context 'WEBVIEW'
|
7
|
+
current_context.must_equal 'WEBVIEW_1'
|
8
|
+
sleep 1 #Give a chance to load
|
9
|
+
page.start_with?("\nhtml\n").must_equal true
|
10
|
+
end
|
11
|
+
end
|
@@ -86,17 +86,21 @@ module Appium
|
|
86
86
|
# if false (default) then all classes will be inspected
|
87
87
|
# @return [String]
|
88
88
|
def get_android_inspect class_name=false
|
89
|
-
|
90
|
-
|
89
|
+
source = get_source
|
90
|
+
if source.start_with? '<html>'
|
91
|
+
parser = @android_html_parser ||= Nokogiri::HTML::SAX::Parser.new(Common::HTMLElements.new)
|
92
|
+
else
|
93
|
+
parser = @android_webview_parser ||= Nokogiri::XML::SAX::Parser.new(AndroidElements.new)
|
94
|
+
end
|
91
95
|
parser.document.reset
|
92
96
|
parser.document.filter = class_name
|
93
|
-
parser.parse
|
94
|
-
|
97
|
+
parser.parse source
|
95
98
|
parser.document.result
|
96
99
|
end
|
97
100
|
|
98
101
|
# Intended for use with console.
|
99
102
|
# Inspects and prints the current page.
|
103
|
+
# Will return XHTML for Web contexts because of a quirk with Nokogiri.
|
100
104
|
# @option class [Symbol] the class name to filter on. case insensitive include match.
|
101
105
|
# if nil (default) then all classes will be inspected
|
102
106
|
# @return [void]
|
@@ -109,9 +113,15 @@ module Appium
|
|
109
113
|
# Lists package, activity, and adb shell am start -n value for current app.
|
110
114
|
# Works on local host only (not remote).
|
111
115
|
# noinspection RubyArgCount
|
116
|
+
# example line:
|
117
|
+
# "mFocusedApp=AppWindowToken{b1420058 token=Token{b128add0 ActivityRecord{b1264d10 u0 com.example.android.apis/.ApiDemos t23}}}"
|
112
118
|
def current_app
|
113
119
|
line = `adb shell dumpsys window windows`.each_line.grep(/mFocusedApp/).first.strip
|
114
|
-
|
120
|
+
|
121
|
+
match = line.match(/ ([^\/ ]+\/[^ ]+) /)
|
122
|
+
return nil unless match && match[1]
|
123
|
+
|
124
|
+
pair = match[1].split '/'
|
115
125
|
pkg = pair.first
|
116
126
|
act = pair.last
|
117
127
|
OpenStruct.new(line: line,
|
@@ -37,9 +37,14 @@ module Appium
|
|
37
37
|
until (
|
38
38
|
begin
|
39
39
|
result = block.call || true
|
40
|
+
rescue Errno::ECONNREFUSED => e
|
41
|
+
raise e
|
40
42
|
rescue Exception
|
41
|
-
end)
|
42
43
|
sleep interval
|
44
|
+
# sleep returns truthy value which breaks out of until
|
45
|
+
# must return false value
|
46
|
+
false
|
47
|
+
end)
|
43
48
|
end
|
44
49
|
end
|
45
50
|
result
|
@@ -68,9 +73,12 @@ module Appium
|
|
68
73
|
until (
|
69
74
|
begin
|
70
75
|
result = block.call
|
76
|
+
rescue Errno::ECONNREFUSED => e
|
77
|
+
raise e
|
71
78
|
rescue Exception
|
79
|
+
ensure
|
80
|
+
sleep interval unless result
|
72
81
|
end)
|
73
|
-
sleep interval
|
74
82
|
end
|
75
83
|
end
|
76
84
|
result
|
@@ -106,10 +114,18 @@ module Appium
|
|
106
114
|
# Prints xml of the current page
|
107
115
|
# @return [void]
|
108
116
|
def source
|
109
|
-
|
110
|
-
|
117
|
+
source = @driver.page_source
|
118
|
+
if source.start_with? '<html'
|
119
|
+
doc = Nokogiri::HTML(source) do |config|
|
120
|
+
config.options = Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NONET
|
121
|
+
end
|
122
|
+
puts doc.to_xhtml indent: 2
|
123
|
+
else
|
124
|
+
doc = Nokogiri::XML(source) do |config|
|
125
|
+
config.options = Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NONET
|
126
|
+
end
|
127
|
+
puts doc.to_xml indent: 2
|
111
128
|
end
|
112
|
-
puts doc.to_xml indent: 2
|
113
129
|
end
|
114
130
|
|
115
131
|
# Returns XML string for the current page
|
@@ -208,5 +224,66 @@ module Appium
|
|
208
224
|
lazy_load_strings
|
209
225
|
@strings_xml[id]
|
210
226
|
end
|
227
|
+
|
228
|
+
class HTMLElements < Nokogiri::XML::SAX::Document
|
229
|
+
def filter
|
230
|
+
@filter
|
231
|
+
end
|
232
|
+
|
233
|
+
# convert to string to support symbols
|
234
|
+
def filter= value
|
235
|
+
# nil and false disable the filter
|
236
|
+
return @filter = false unless value
|
237
|
+
@filter = value.to_s.downcase
|
238
|
+
end
|
239
|
+
|
240
|
+
def initialize
|
241
|
+
reset
|
242
|
+
@filter = false
|
243
|
+
end
|
244
|
+
|
245
|
+
def reset
|
246
|
+
@element_stack = []
|
247
|
+
@elements_in_order = []
|
248
|
+
@skip_element = false
|
249
|
+
end
|
250
|
+
|
251
|
+
def result
|
252
|
+
@elements_in_order.reduce('') do |r, e|
|
253
|
+
name = e.delete :name
|
254
|
+
attr_string = e.reduce('') do |string, attr|
|
255
|
+
string += " #{attr[0]}: #{attr[1]}\n"
|
256
|
+
end
|
257
|
+
|
258
|
+
unless attr_string.nil? || attr_string.empty?
|
259
|
+
r += "\n#{name}\n#{attr_string}"
|
260
|
+
end
|
261
|
+
r
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def start_element name, attrs = []
|
266
|
+
@skip_element = filter && !filter.include?(name.downcase)
|
267
|
+
unless @skip_element
|
268
|
+
element = {name: name}
|
269
|
+
attrs.each {|a| element[a[0]] = a[1]}
|
270
|
+
@element_stack.push element
|
271
|
+
@elements_in_order.push element
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def end_element name
|
276
|
+
return if filter && !filter.include?(name.downcase)
|
277
|
+
element_index = @element_stack.rindex {|e| e[:name] == name}
|
278
|
+
@element_stack.delete_at element_index
|
279
|
+
end
|
280
|
+
|
281
|
+
def characters(chars)
|
282
|
+
unless @skip_element
|
283
|
+
element = @element_stack.last
|
284
|
+
element[:text] = chars
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
211
288
|
end # module Common
|
212
289
|
end # module Appium
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Appium
|
2
2
|
# Version and Date are defined on the 'Appium' module, not 'Appium::Common'
|
3
|
-
VERSION = '2.
|
4
|
-
DATE = '2014-05-
|
3
|
+
VERSION = '2.1.0' unless defined? ::Appium::VERSION
|
4
|
+
DATE = '2014-05-21' unless defined? ::Appium::DATE
|
5
5
|
end
|
data/lib/appium_lib/driver.rb
CHANGED
@@ -226,7 +226,7 @@ module Appium
|
|
226
226
|
#
|
227
227
|
# # Start Android driver
|
228
228
|
# opts = { caps: { platformName: :android, app: '/path/to/my.apk' } }
|
229
|
-
# Appium::Driver.new(
|
229
|
+
# Appium::Driver.new(opts).start_driver
|
230
230
|
# ```
|
231
231
|
#
|
232
232
|
# @param opts [Object] A hash containing various options.
|
@@ -248,7 +248,9 @@ module Appium
|
|
248
248
|
@default_wait = appium_lib_opts.fetch :wait, 30
|
249
249
|
@last_waits = [@default_wait]
|
250
250
|
@sauce_username = appium_lib_opts.fetch :sauce_username, ENV['SAUCE_USERNAME']
|
251
|
+
@sauce_username = nil if @sauce_username.nil? || @sauce_username.empty?
|
251
252
|
@sauce_access_key = appium_lib_opts.fetch :sauce_access_key, ENV['SAUCE_ACCESS_KEY']
|
253
|
+
@sauce_access_key = nil if @sauce_access_key.nil? || @sauce_access_key.empty?
|
252
254
|
@port = appium_lib_opts.fetch :port, 4723
|
253
255
|
|
254
256
|
# Path to the .apk, .app or .app.zip.
|
@@ -279,9 +281,10 @@ module Appium
|
|
279
281
|
# enable debug patch
|
280
282
|
# !!'constant' == true
|
281
283
|
@debug = appium_lib_opts.fetch :debug, !!defined?(Pry)
|
282
|
-
|
284
|
+
|
283
285
|
if @debug
|
284
286
|
ap opts unless opts.empty?
|
287
|
+
puts "Debug is: #{@debug}"
|
285
288
|
puts "Device is: #{@device}"
|
286
289
|
patch_webdriver_bridge
|
287
290
|
end
|
@@ -419,6 +422,7 @@ module Appium
|
|
419
422
|
@client.timeout = 999999
|
420
423
|
|
421
424
|
begin
|
425
|
+
driver_quit
|
422
426
|
@driver = Selenium::WebDriver.for :remote, http_client: @client, desired_capabilities: @caps, url: server_url
|
423
427
|
# Load touch methods.
|
424
428
|
@driver.extend Selenium::WebDriver::DriverExtensions::HasTouchScreen
|
@@ -130,16 +130,25 @@ module Appium
|
|
130
130
|
window_number = -1
|
131
131
|
class_name = opts
|
132
132
|
end
|
133
|
-
|
134
|
-
if
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
133
|
+
# current_context may be nil which breaks start_with
|
134
|
+
if current_context && current_context.start_with?('WEBVIEW')
|
135
|
+
s = get_source
|
136
|
+
parser = @android_html_parser ||= Nokogiri::HTML::SAX::Parser.new(Common::HTMLElements.new)
|
137
|
+
parser.document.reset
|
138
|
+
parser.document.filter = class_name
|
139
|
+
parser.parse s
|
140
|
+
parser.document.result
|
139
141
|
else
|
140
|
-
|
142
|
+
if window_number == -1
|
143
|
+
# if the 0th window has no children, find the next window that does.
|
144
|
+
target_window = source_window 0
|
145
|
+
target_window = source_window 1 if target_window['children'].empty?
|
146
|
+
get_page target_window, class_name
|
147
|
+
else
|
148
|
+
get_page source_window(window_number || 0), class_name
|
149
|
+
end
|
150
|
+
nil
|
141
151
|
end
|
142
|
-
nil
|
143
152
|
end
|
144
153
|
|
145
154
|
# Gets the JSON source of window number
|
data/release_notes.md
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
#### v2.1.0 2014-05-21
|
2
|
+
|
3
|
+
- [f0db091](https://github.com/appium/ruby_lib/commit/f0db0910ea077e04329d3e0cafb434f829760abb) Release 2.1.0
|
4
|
+
- [189b99a](https://github.com/appium/ruby_lib/commit/189b99ab91625cc37414fe9aeb681949d4fd85be) Use io.appium.android.apis
|
5
|
+
- [5b1e3d8](https://github.com/appium/ruby_lib/commit/5b1e3d8b014137cdd8f5a4f8af5d7019983aab9a) Fix current_app on Android
|
6
|
+
- [aa6e93a](https://github.com/appium/ruby_lib/commit/aa6e93a0bb88ef31c596c5ac7352b159bc0ea53b) Fix wait
|
7
|
+
- [c590996](https://github.com/appium/ruby_lib/commit/c5909961be059d715200ba58943e1b56e2dd8843) Move posix-spawn to dev dependency
|
8
|
+
- [7a55892](https://github.com/appium/ruby_lib/commit/7a5589244db8f783f9a51b74809ff8fcb4354855) Fix typo
|
9
|
+
- [2a1c009](https://github.com/appium/ruby_lib/commit/2a1c0096db8a4e53ae09a8c556b51b513eacfa74) Merge pull request #197 from xrd/patch-1
|
10
|
+
- [9de20b7](https://github.com/appium/ruby_lib/commit/9de20b78f5dce29be874e727a027fd976703a0c1) Fix typo
|
11
|
+
- [b306378](https://github.com/appium/ruby_lib/commit/b306378a9d54223e2b446a004a2c5a63574a9143) Merge pull request #196 from DylanLacey/master
|
12
|
+
- [01dd97c](https://github.com/appium/ruby_lib/commit/01dd97ca63b6f8ff7ac65f170b8041241cad1271) Make wait and wait_true use the interval before it reexecutes
|
13
|
+
- [9a138bb](https://github.com/appium/ruby_lib/commit/9a138bb6e2d1b0d836d3940f5e4b7e84d1fc0e3c) Merge pull request #195 from DylanLacey/master
|
14
|
+
- [d85e292](https://github.com/appium/ruby_lib/commit/d85e292df723bcc9ff7227f8573581d44ef73c26) Don't continue to wait for crashed Appium server
|
15
|
+
- [107a90c](https://github.com/appium/ruby_lib/commit/107a90c9137ef4ee7f8b7598c25adddedbdb34d4) Use __FILE__ instead of __dir__
|
16
|
+
- [12d62bc](https://github.com/appium/ruby_lib/commit/12d62bcec3d8897089bd3045f564c0de271375bd) Merge pull request #194 from DylanLacey/master
|
17
|
+
- [bcc7865](https://github.com/appium/ruby_lib/commit/bcc7865db8f65f5439cd60a983d1c45b80b97eb8) Quit driver before creating a new one. Always.
|
18
|
+
- [a52f215](https://github.com/appium/ruby_lib/commit/a52f215fb2246b35e17636ed9114fc977ad97511) Fix android test
|
19
|
+
- [f43309c](https://github.com/appium/ruby_lib/commit/f43309ca716f5b140ef9370f4ebd4b45a500eb92) Fix #192
|
20
|
+
- [4a97ba1](https://github.com/appium/ruby_lib/commit/4a97ba12684c7e49e8251305c47b8a3443a9ef98) Set sauce to empty so tests run local #191
|
21
|
+
- [56d8a04](https://github.com/appium/ruby_lib/commit/56d8a04d8aa7e70f8e90a5e3cde79276bfb6158f) Fix #191
|
22
|
+
- [ea0fe8e](https://github.com/appium/ruby_lib/commit/ea0fe8e2a9570e984a41fa424a908398694660de) Set empty sauce ENV to nil
|
23
|
+
- [190f023](https://github.com/appium/ruby_lib/commit/190f0237fc94816e71e4327cbf8135913021688b) Update migration.md
|
24
|
+
- [28aa754](https://github.com/appium/ruby_lib/commit/28aa7546b321950d704ba091a91c424a3cc4ac04) Update migration.md
|
25
|
+
- [d9447a9](https://github.com/appium/ruby_lib/commit/d9447a97433b88afbc35c66264b1c67e175aef41) Merge pull request #190 from DylanLacey/xpath
|
26
|
+
- [ac9f5eb](https://github.com/appium/ruby_lib/commit/ac9f5ebecf3a0e603cafc8ad4befda86050fc6d1) Parse HTML as HTML, not XML.
|
27
|
+
- [a84163b](https://github.com/appium/ruby_lib/commit/a84163b113fb232068c9aa02bff61db8c11d374e) Output debug status only when enabled
|
28
|
+
|
29
|
+
|
1
30
|
#### v2.0.0 2014-05-14
|
2
31
|
|
3
32
|
- [2d7ab8b](https://github.com/appium/ruby_lib/commit/2d7ab8b6cc442f39f6171f8a27bc4923e4d4e2a4) Release 2.0.0
|
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: 2.
|
4
|
+
version: 2.1.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: 2014-05-
|
11
|
+
date: 2014-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: selenium-webdriver
|
@@ -91,39 +91,39 @@ dependencies:
|
|
91
91
|
- !ruby/object:Gem::Version
|
92
92
|
version: 0.0.4
|
93
93
|
- !ruby/object:Gem::Dependency
|
94
|
-
name:
|
94
|
+
name: nokogiri
|
95
95
|
requirement: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
97
|
- - "~>"
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version:
|
100
|
-
- - ">="
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: 0.3.8
|
99
|
+
version: 1.6.1
|
103
100
|
type: :runtime
|
104
101
|
prerelease: false
|
105
102
|
version_requirements: !ruby/object:Gem::Requirement
|
106
103
|
requirements:
|
107
104
|
- - "~>"
|
108
105
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
110
|
-
- - ">="
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
version: 0.3.8
|
106
|
+
version: 1.6.1
|
113
107
|
- !ruby/object:Gem::Dependency
|
114
|
-
name:
|
108
|
+
name: posix-spawn
|
115
109
|
requirement: !ruby/object:Gem::Requirement
|
116
110
|
requirements:
|
117
111
|
- - "~>"
|
118
112
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
120
|
-
|
113
|
+
version: '0.3'
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 0.3.8
|
117
|
+
type: :development
|
121
118
|
prerelease: false
|
122
119
|
version_requirements: !ruby/object:Gem::Requirement
|
123
120
|
requirements:
|
124
121
|
- - "~>"
|
125
122
|
- !ruby/object:Gem::Version
|
126
|
-
version:
|
123
|
+
version: '0.3'
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: 0.3.8
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
128
|
name: hashdiff
|
129
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -236,6 +236,7 @@ files:
|
|
236
236
|
- android_tests/lib/android/specs/common/helper.rb
|
237
237
|
- android_tests/lib/android/specs/common/patch.rb
|
238
238
|
- android_tests/lib/android/specs/common/version.rb
|
239
|
+
- android_tests/lib/android/specs/common/web_context.rb
|
239
240
|
- android_tests/lib/android/specs/driver.rb
|
240
241
|
- android_tests/lib/format.rb
|
241
242
|
- android_tests/lib/run.rb
|
@@ -302,6 +303,7 @@ files:
|
|
302
303
|
- ios_tests/lib/ios/specs/common/helper.rb
|
303
304
|
- ios_tests/lib/ios/specs/common/patch.rb
|
304
305
|
- ios_tests/lib/ios/specs/common/version.rb
|
306
|
+
- ios_tests/lib/ios/specs/common/web_context.rb
|
305
307
|
- ios_tests/lib/ios/specs/device/device.rb
|
306
308
|
- ios_tests/lib/ios/specs/device/multi_touch.rb
|
307
309
|
- ios_tests/lib/ios/specs/device/touch_actions.rb
|