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.
@@ -24,4 +24,5 @@ Other changes:
24
24
  Old | New
25
25
  :--|:--
26
26
  `press_for_duration` | `long_press`
27
- `current_context=` | `set_context`
27
+ `current_context=` | `set_context`
28
+ `name` | `find`
@@ -1 +1,2 @@
1
- eval File.read('../Gemfile')
1
+ source 'https://rubygems.org'
2
+ gemspec path: File.expand_path('../../', __FILE__) # __dir__ fails on 1.9
@@ -1,3 +1,7 @@
1
1
  [caps]
2
2
  platformName = "ios"
3
- app = "./UICatalog.app"
3
+ app = "./UICatalog.app"
4
+
5
+ [appium_lib]
6
+ sauce_username = ""
7
+ sauce_access_key = ""
@@ -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 { wait(*wait_time) { raise NoMemoryError } }.must_raise Timeout::Error
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
- parser = @android_elements_parser ||= Nokogiri::XML::SAX::Parser.new(AndroidElements.new)
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 get_source
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
- pair = line.split(' ').last.gsub('}', '').split '/'
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
- doc = Nokogiri::XML(@driver.page_source) do |config|
110
- config.options = Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NONET
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.0.0' unless defined? ::Appium::VERSION
4
- DATE = '2014-05-14' unless defined? ::Appium::DATE
3
+ VERSION = '2.1.0' unless defined? ::Appium::VERSION
4
+ DATE = '2014-05-21' unless defined? ::Appium::DATE
5
5
  end
@@ -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(apk).start_driver
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
- puts "Debug is: #{@debug}"
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 window_number == -1
135
- # if the 0th window has no children, find the next window that does.
136
- target_window = source_window 0
137
- target_window = source_window 1 if target_window['children'].empty?
138
- get_page target_window, class_name
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
- get_page source_window(window_number || 0), class_name
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
@@ -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.0.0
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-14 00:00:00.000000000 Z
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: posix-spawn
94
+ name: nokogiri
95
95
  requirement: !ruby/object:Gem::Requirement
96
96
  requirements:
97
97
  - - "~>"
98
98
  - !ruby/object:Gem::Version
99
- version: '0.3'
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: '0.3'
110
- - - ">="
111
- - !ruby/object:Gem::Version
112
- version: 0.3.8
106
+ version: 1.6.1
113
107
  - !ruby/object:Gem::Dependency
114
- name: nokogiri
108
+ name: posix-spawn
115
109
  requirement: !ruby/object:Gem::Requirement
116
110
  requirements:
117
111
  - - "~>"
118
112
  - !ruby/object:Gem::Version
119
- version: 1.6.1
120
- type: :runtime
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: 1.6.1
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