appium_lib 0.3.3 → 0.3.4

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OWIwNjQ5MmY3YTQ0YTg1NTM4YzYwZTk4ZjlmMGEzNTI4NmNhMmM4NA==
4
+ YTA5MjVhYjAyZWEwMGM5NzQzYmI5OGRlZGU5NTkxMGM5YjY4ZDNmMw==
5
5
  data.tar.gz: !binary |-
6
- ZTRjMjNjZTQ2NzVhMzgwYTQ5MzNjMDFhNDc3MjVkYTA4NTM2YTBmNA==
6
+ YTg3MDQxYjBmZTEzZDhkNjYyODg2ZDIzYTY3YWRkMzVmMTc4NDFiZg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OWIyZGE2M2U3ZGQ1MjllMjQ3NDQ0N2ViNjA0ZmVlZmZhZjMxZmJhYjUyMzQy
10
- N2IyZGRjMDIxMTRmNzQxYzRhMWZlOGU1MDc1NDdlZjQ3Y2Q2NTc0YTllZDIx
11
- YzhiZDRmMGYyMTE1N2IyMWRhZDVjODdhN2E2ZTdlYWQ1MDYwYzk=
9
+ OGYyMzJlNGE1NWY3YWI4OWU1ZGY4Y2U2OWUzODljMzc2YzRjZDJlM2JhZTc2
10
+ OWU4Yzc3MmQzZGFiMjFiYjJmNjZmYTdkOWE3NzdlMjg5YjQwMDhlZGViNjMz
11
+ NjEwNzJlZGFkOGM3YTMzYWJlYjJkZWY3ZGQ1ZmUzOWY2MjA5NmM=
12
12
  data.tar.gz: !binary |-
13
- ODY1ZmRiM2RhMDdhMDFkYjZmMWM0NzllYWIxY2MxNmU5YjU2OWU2MTIwZDFm
14
- OWZkMTMxYTMxY2UzMWNkYzk4YTZjYWRkNTQ3MTUwOTMxNGMzMzFmYzdmZDkz
15
- YTIxYjA0MjlhNGE3MTc0NWNjODcyM2E1MzA1MDUwZTZjODYxZGE=
13
+ NTNjYmE5OTU1YzVlM2EwNjcxNzFiOTY5ZmVkYzZkY2JmMTc3YzA0MzUzZDUz
14
+ ODg2N2VmMjJkZTU4YjU2MGM4NzJhOTdjZGY2MDZkYjJhN2JhYjRhNmY5YzA5
15
+ ZTgwMjVlNmI1NzM2OGY0NjExMTdjZTdjODVlODFhZmQwM2M0ZmQ=
data/Rakefile CHANGED
@@ -90,7 +90,7 @@ end
90
90
 
91
91
  desc 'Install gem'
92
92
  task :install => [ :gem, :uninstall ] do
93
- sh "gem install --no-rdoc --no-ri #{repo_name}-#{version}.gem"
93
+ sh "gem install --no-rdoc --no-ri --local #{repo_name}-#{version}.gem"
94
94
  end
95
95
 
96
96
  desc 'Update release notes'
@@ -1,14 +1,14 @@
1
1
  # encoding: utf-8
2
2
 
3
- $last_driver = nil
3
+ $driver = nil
4
4
 
5
5
  # Invoke top level methods on last created Appium driver.
6
6
  def self.method_missing method, *args, &block
7
- raise "driver is nil. called #{method}" if $last_driver == nil
7
+ raise "driver is nil. called #{method}" if $driver == nil
8
8
 
9
- $last_driver.respond_to?(method) ?
10
- $last_driver.send( method, *args, &block ) :
11
- super
9
+ $driver.respond_to?(method) ?
10
+ $driver.send( method, *args, &block ) :
11
+ super
12
12
  end
13
13
 
14
14
  module Appium
@@ -1,10 +1,14 @@
1
1
  # encoding: utf-8
2
2
  module Appium::Android
3
- # Implement useful features for element.
4
- class Selenium::WebDriver::Element
5
- # Cross platform way of entering text into a textfield
6
- def type text
7
- self.send_keys text
3
+ # class_eval inside a method because class Selenium::WebDriver::Element
4
+ # will trigger as soon as the file is required. in contrast a method
5
+ # will trigger only when invoked.
6
+ def patch_webdriver_element
7
+ Selenium::WebDriver::Element.class_eval do
8
+ # Cross platform way of entering text into a textfield
9
+ def type text
10
+ self.send_keys text
11
+ end
12
+ end
8
13
  end
9
- end
10
- end
14
+ end
@@ -20,12 +20,14 @@ module Appium::Common
20
20
 
21
21
  # Check every 0.5 seconds to see if block.call is true.
22
22
  # Give up after 30 seconds.
23
+ # @param max_wait [Integer] the maximum time in seconds to wait for
24
+ # @param interval [Float] the time in seconds to wait after calling the block
23
25
  # @param block [Block] the block to call
24
26
  # @return [Object] the result of block.call
25
- def wait &block
27
+ def wait max_wait=30, interval=0.5, &block
26
28
  # Rescue Timeout::Error: execution expired
27
29
  result = nil
28
- timeout(30) { until (result = begin; block.call; rescue; end) do; sleep 0.5 end }
30
+ timeout(max_wait) { until (result = begin; block.call; rescue; end) do; sleep interval end }
29
31
  result
30
32
  end
31
33
 
@@ -158,4 +160,4 @@ module Appium::Common
158
160
  def find_names name
159
161
  find_elements :name, name
160
162
  end
161
- end # module Appium::Common
163
+ end # module Appium::Common
@@ -52,11 +52,11 @@ require 'selenium/webdriver/remote/http/default'
52
52
  # Show http calls to the Selenium server.
53
53
  #
54
54
  # Invaluable for debugging.
55
- module Selenium::WebDriver::Remote
56
- class Bridge
55
+ def patch_webdriver_bridge
56
+ Selenium::WebDriver::Remote::Bridge.class_eval do
57
57
  # Code from lib/selenium/webdriver/remote/bridge.rb
58
58
  def raw_execute(command, opts = {}, command_hash = nil)
59
- verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
59
+ verb, path = Selenium::WebDriver::Remote::COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
60
60
  path = path.dup
61
61
 
62
62
  path[':session_id'] = @session_id if path.include?(':session_id')
@@ -75,12 +75,16 @@ module Selenium::WebDriver::Remote
75
75
  path_str = path.sub(path_match[0], '') unless path_match.nil?
76
76
 
77
77
  puts "#{verb} #{path_str}"
78
- puts command_hash.to_json unless command_hash.to_json == 'null'
78
+ unless command_hash.nil? || command_hash.length == 0
79
+ print_command = command_hash.clone
80
+ print_command.delete :args if print_command[:args] == []
81
+ ap print_command
82
+ end
79
83
  # puts "verb: #{verb}, path #{path}, command_hash #{command_hash.to_json}"
80
84
  http.call verb, path, command_hash
81
85
  end # def
82
86
  end # class
83
- end if defined? Pry # module Selenium::WebDriver::Remote
87
+ end # def
84
88
 
85
89
  # Print Appium's origValue error messages.
86
90
  class Selenium::WebDriver::Remote::Response
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
  module Appium
3
3
  # Version and Date are defined on the 'Appium' module, not 'Appium::Common'
4
- VERSION = '0.3.3' unless defined? ::Appium::VERSION
5
- DATE = '2013-04-27' unless defined? ::Appium::DATE
4
+ VERSION = '0.3.4' unless defined? ::Appium::VERSION
5
+ DATE = '2013-04-30' unless defined? ::Appium::DATE
6
6
  end
@@ -37,32 +37,42 @@ module Appium
37
37
  attr_reader :app_path, :app_name, :app_package, :app_activity,
38
38
  :app_wait_activity, :sauce_username, :sauce_access_key,
39
39
  :port, :os, :ios_js
40
- def initialize opts={}
40
+ def initialize options={}
41
+ # quit last driver
42
+ $driver.driver_quit if $driver
43
+
44
+ opts = {}
45
+ # convert to downcased symbols
46
+ options.each_pair { |k,v| opts[k.to_s.downcase.strip.intern] = v }
47
+
41
48
  opts = {} if opts.nil?
42
49
  # Path to the .apk, .app or .app.zip.
43
50
  # The path can be local or remote for Sauce.
44
- @app_path = opts.fetch 'APP_PATH', ENV['APP_PATH']
51
+ @app_path = opts.fetch :app_path, ENV['APP_PATH']
45
52
  raise 'APP_PATH must be set.' if @app_path.nil?
46
53
 
47
54
  # The name to use for the test run on Sauce.
48
- @app_name = opts.fetch 'APP_NAME', ENV['APP_NAME']
55
+ @app_name = opts.fetch :app_name, ENV['APP_NAME']
56
+
57
+ # If key or env is defined, use selendroid else nil
58
+ @selendroid = opts.key?(:selendroid) || ENV['SELENDROID'] ? 'selendroid' : nil
49
59
 
50
60
  # Android app package
51
- @app_package = opts.fetch 'APP_PACKAGE', ENV['APP_PACKAGE']
61
+ @app_package = opts.fetch :app_package, ENV['APP_PACKAGE']
52
62
 
53
63
  # Android app starting activity.
54
- @app_activity = opts.fetch 'APP_ACTIVITY', ENV['APP_ACTIVITY']
64
+ @app_activity = opts.fetch :app_activity, ENV['APP_ACTIVITY']
55
65
 
56
66
  # Android app waiting activity
57
- @app_wait_activity = opts.fetch 'APP_WAIT_ACTIVITY', ENV['APP_WAIT_ACTIVITY']
67
+ @app_wait_activity = opts.fetch :app_wait_activity, ENV['APP_WAIT_ACTIVITY']
58
68
 
59
69
  # Sauce Username
60
- @sauce_username = opts.fetch'SAUCE_USERNAME', ENV['SAUCE_USERNAME']
70
+ @sauce_username = opts.fetch :sauce_username, ENV['SAUCE_USERNAME']
61
71
 
62
72
  # Sauce Key
63
- @sauce_access_key = opts.fetch 'SAUCE_ACCESS_KEY', ENV['SAUCE_ACCESS_KEY']
73
+ @sauce_access_key = opts.fetch :sauce_access_key, ENV['SAUCE_ACCESS_KEY']
64
74
 
65
- @port = opts.fetch 'PORT', ENV['PORT'] || 4723
75
+ @port = opts.fetch :port, ENV['PORT'] || 4723
66
76
 
67
77
  @os = :ios
68
78
  @os = :android if @app_path.end_with?('.apk') || @app_path.end_with?('.apk.zip')
@@ -81,18 +91,24 @@ module Appium
81
91
  extend Appium::Ios
82
92
  end
83
93
 
94
+ # apply os specific patches
95
+ patch_webdriver_element
96
+
97
+ # enable debug patch
98
+ patch_webdriver_bridge if opts.fetch :debug, defined?(Pry)
99
+
84
100
  # Save global reference to last created Appium driver for top level methods.
85
- $last_driver = self
101
+ $driver = self
86
102
 
87
103
  # Promote exactly once the first time the driver is created.
88
104
  # Subsequent drivers do not trigger promotion.
89
105
  unless @@loaded
90
106
  @@loaded = true
91
107
  # Promote Appium driver methods to Object instance methods.
92
- $last_driver.public_methods(false).each do | m |
108
+ $driver.public_methods(false).each do | m |
93
109
  Object.class_eval do
94
110
  define_method m do | *args, &block |
95
- $last_driver.send m, *args, &block
111
+ $driver.send m, *args, &block
96
112
  end
97
113
  end
98
114
  end
@@ -106,7 +122,7 @@ module Appium
106
122
  browserName: 'Android',
107
123
  platform: 'LINUX',
108
124
  version: '4.1',
109
- device: 'Android',
125
+ device: @selendroid || 'Android',
110
126
  name: @app_name || 'Ruby Console Android Appium',
111
127
  app: absolute_app_path,
112
128
  :'app-package' => @app_package,
@@ -31,22 +31,35 @@ module Appium::Ios
31
31
  # execute_script 'au.mainApp.getNameContains("sign")'
32
32
  # execute_script 'au.mainApp.getNameContains("zzz")'
33
33
  # must check .isVisible or a hidden element may be returned.
34
- # .tap() will error on invisible elements.
34
+ # .tap() may error on invisible elements.
35
+ # if there are no visible elements though, then it's useful
36
+ # to .tap() on an invisible element.
35
37
  <<-JS
36
38
  UIAElement.prototype.getNameContains = function(targetName) {
37
39
  var target = UIATarget.localTarget();
38
40
  target.pushTimeout(0);
39
- var search = "(name contains[c] '" + targetName + "' || label contains[c] '" + targetName + "') && visible == 1";
41
+ var search = "name contains[c] '" + targetName + "' || label contains[c] '" + targetName + "'";
42
+ var result = {};
43
+ result.type = function() { return 'UIAElementNil'; };
44
+ result.isVisible = function() { return -1; };
45
+
40
46
  var searchElements = function(element) {
41
47
  var children = element.elements();
42
- var result = children.firstWithPredicate(search);
43
- if (result.type() !== 'UIAElementNil' && result.isVisible() === 1) {
44
- return result;
48
+ var results = children.withPredicate(search);
49
+
50
+ for (var resIdx = 0, resLen = results.length; resIdx < resLen; resIdx++) {
51
+ var tmp = results[resIdx];
52
+ if (tmp.type() !== 'UIAElementNil') {
53
+ result = tmp;
54
+ if (tmp.isVisible() === 1) {
55
+ return tmp;
56
+ }
57
+ }
45
58
  }
46
59
 
47
60
  for ( var a = 0, len = children.length; a < len; a++) {
48
- result = searchElements(children[a]);
49
- if (result.type() !== 'UIAElementNil') {
61
+ searchElements(children[a]);
62
+ if (result.type() !== 'UIAElementNil' && result.isVisible() === 1) {
50
63
  return result;
51
64
  }
52
65
  }
@@ -63,6 +76,7 @@ module Appium::Ios
63
76
  };
64
77
  }
65
78
 
79
+ console.log("Match is visible? " + result.isVisible())
66
80
  return {
67
81
  status: 0,
68
82
  value: {ELEMENT: au.getId(result)}
@@ -1,15 +1,19 @@
1
1
  # encoding: utf-8
2
2
  module Appium::Ios
3
- # Implement useful features for element.
4
- class Selenium::WebDriver::Element
5
- # Cross platform way of entering text into a textfield
6
- def type text
7
- # enter text then tap window to hide the keyboard.
8
- js = %Q(
9
- au.getElement('#{self.ref}').setValue('#{text}');
10
- au.lookup('window')[0].tap()
11
- )
12
- @driver.execute_script js
3
+ # class_eval inside a method because class Selenium::WebDriver::Element
4
+ # will trigger as soon as the file is required. in contrast a method
5
+ # will trigger only when invoked.
6
+ def patch_webdriver_element
7
+ Selenium::WebDriver::Element.class_eval do
8
+ # Cross platform way of entering text into a textfield
9
+ def type text
10
+ # enter text then tap window to hide the keyboard.
11
+ js = <<-JS
12
+ au.getElement('#{self.ref}').setValue('#{text}');
13
+ au.lookup('window')[0].tap();
14
+ JS
15
+ @driver.execute_script js
16
+ end
13
17
  end
14
18
  end
15
19
  end
data/readme.md CHANGED
@@ -8,6 +8,10 @@ Helper methods for writing cross platform (iPad, iPhone, Android) tests in Ruby
8
8
 
9
9
  Make sure you're using Ruby 1.9.3+ with upgraded rubygems and bundler.
10
10
 
11
+ #### Start appium server
12
+
13
+ `node server.js -V --fast-reset --without-delay`
14
+
11
15
  #### Install / Upgrade
12
16
 
13
17
  Update rubygems and bundler.
@@ -1,3 +1,12 @@
1
+ #### v0.3.3 2013-04-27
2
+
3
+ - [b0ca37c](https://github.com/appium/ruby_lib/commit/b0ca37cfe47318f029e1f2ad498a5c08338016d7) Release 0.3.3
4
+ - [e7f55d9](https://github.com/appium/ruby_lib/commit/e7f55d92181660ea188a5123e6e4f447389c8d6d) Add driver method
5
+ - [6d381fe](https://github.com/appium/ruby_lib/commit/6d381fe029bd9a5c11aa4d1a322d6afb603c6434) Update readme.md
6
+ - [07da208](https://github.com/appium/ruby_lib/commit/07da208973ea4de64ec9605ef5dd38884771e8c6) Add troubleshooting steps
7
+ - [7df8ddc](https://github.com/appium/ruby_lib/commit/7df8ddcd0edb294abaddd2424f0f6b45f086fb53) Update release notes
8
+
9
+
1
10
  #### v0.3.2 2013-04-26
2
11
 
3
12
  - [eee6632](https://github.com/appium/ruby_lib/commit/eee6632251c40c8b2d6be9a361f429d7c89762f8) Release 0.3.2
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.3.3
4
+ version: 0.3.4
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-27 00:00:00.000000000 Z
11
+ date: 2013-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: selenium-webdriver