calabash-android 0.5.16.pre1 → 0.6.0.pre4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1bb7b1d479f70d02d21cb13ac79c342a4636d8a1
4
- data.tar.gz: a0054f26ac58558e5a93060ec6ba07819a522e16
3
+ metadata.gz: 43b1239ae3480cd7c7d91486030874b98bcc2458
4
+ data.tar.gz: e2720beceab3b24e451368c257cd54833d7da0fb
5
5
  SHA512:
6
- metadata.gz: 412afba1c956f1390cb7516125cbf4f56853bb0c153bd5c68215c70ba5d551e4a981f6899b380f7dc092532eb66c4c7f51ca6498591d627dcdc6010499d61017
7
- data.tar.gz: ebb6d1a2a0cdd7d9837c9ce19d931d3a716adfd6ccf9a0977c1710d18fd3319f267b96b1ec81a481f73676271c3f943695298e99ae8fda3954ca76f7803ed69e
6
+ metadata.gz: 1e6a8884a4a0253a8767d3c3669a1ec5fa359bcf3f9465c0daebbe22e137e776f15092f241ae67638117f00c2041b82bb94968abe211c6d657a0866a48c7aeb4
7
+ data.tar.gz: 1bfdbf7c4372c89d75aabc9c0aecca14d805bc56750636b6817518dfcf5cfb73c19dcb973b2306e2de37118c4fb15a513aa251a625f39cfeab9a3a833621ad0d
@@ -31,12 +31,13 @@ def calabash_build(app)
31
31
  FileUtils.mkdir_p File.dirname(test_server_file_name) unless File.exist? File.dirname(test_server_file_name)
32
32
 
33
33
  unsigned_test_apk = File.join(File.dirname(__FILE__), '..', 'lib/calabash-android/lib/TestServer.apk')
34
+ test_server_manifest = File.join(File.dirname(__FILE__), '..', 'lib', 'calabash-android', 'lib', 'AndroidManifest.xml')
34
35
 
35
36
  android_platform = Env.android_platform_path
36
37
  Dir.mktmpdir do |workspace_dir|
37
38
  Dir.chdir(workspace_dir) do
38
39
  FileUtils.cp(unsigned_test_apk, "TestServer.apk")
39
- FileUtils.cp(File.join(File.dirname(__FILE__), '..', 'test-server/AndroidManifest.xml'), "AndroidManifest.xml")
40
+ FileUtils.cp(test_server_manifest, "AndroidManifest.xml")
40
41
 
41
42
  unless system %Q{"#{RbConfig.ruby}" -pi.bak -e "gsub(/#targetPackage#/, '#{package_name(app)}')" AndroidManifest.xml}
42
43
  raise "Could not replace package name in manifest"
data/irbrc CHANGED
@@ -54,3 +54,20 @@ end
54
54
 
55
55
  extend Calabash::Android::Operations
56
56
 
57
+
58
+ def preferences
59
+ Calabash::Android::Preferences.new
60
+ end
61
+
62
+ def disable_usage_tracking
63
+ preferences.usage_tracking = "none"
64
+ puts "Calabash will not collect usage information."
65
+ "none"
66
+ end
67
+
68
+ def enable_usage_tracking(level="system_info")
69
+ preferences.usage_tracking = level
70
+ puts "Calabash will collect statistics using the '#{level}' rule."
71
+ level
72
+ end
73
+
@@ -0,0 +1,17 @@
1
+ module Calabash
2
+ module Android
3
+ # A module for managing the ~/.calabash directory.
4
+ module DotDir
5
+ def self.directory
6
+ home = Calabash::Android::Environment.user_home_directory
7
+ dir = File.join(home, ".calabash")
8
+ if !File.exist?(dir)
9
+ FileUtils.mkdir_p(dir)
10
+ end
11
+ dir
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+
@@ -0,0 +1,120 @@
1
+ module Calabash
2
+ module Android
3
+
4
+ # @!visibility private
5
+ class Environment
6
+
7
+ # @!visibility private
8
+ # Returns true if running on Windows
9
+ def self.windows?
10
+ RbConfig::CONFIG['host_os'][/mswin|mingw|cygwin/, 0] != nil
11
+ end
12
+
13
+ # @!visibility private
14
+ # Returns the user home directory
15
+ def self.user_home_directory
16
+ if self.xtc?
17
+ home = File.join("./", "tmp", "home")
18
+ FileUtils.mkdir_p(home)
19
+ home
20
+ else
21
+ if self.windows?
22
+ # http://stackoverflow.com/questions/4190930/cross-platform-means-of-getting-users-home-directory-in-ruby
23
+ home = ENV["HOME"] || ENV["USERPROFILE"]
24
+ else
25
+ require "etc"
26
+ home = Etc.getpwuid.dir
27
+ end
28
+
29
+ unless File.exist?(home)
30
+ home = File.join("./", "tmp", "home")
31
+ FileUtils.mkdir_p(home)
32
+ end
33
+
34
+ home
35
+ end
36
+ end
37
+
38
+ # @!visibility private
39
+ # Returns true if debugging is enabled.
40
+ def self.debug?
41
+ ENV['DEBUG'] == '1' ||
42
+ ARGV.include?("-v") ||
43
+ ARGV.include?("--verbose")
44
+ end
45
+
46
+ # @!visibility private
47
+ # Returns true if we are running on the XTC
48
+ def self.xtc?
49
+ ENV['XAMARIN_TEST_CLOUD'] == '1'
50
+ end
51
+
52
+ # @!visibility private
53
+ # Returns true if running in Jenkins CI
54
+ #
55
+ # Checks the value of JENKINS_HOME
56
+ def self.jenkins?
57
+ value = ENV["JENKINS_HOME"]
58
+ !!value && value != ''
59
+ end
60
+
61
+ # @!visibility private
62
+ # Returns true if running in Travis CI
63
+ #
64
+ # Checks the value of TRAVIS
65
+ def self.travis?
66
+ value = ENV["TRAVIS"]
67
+ !!value && value != ''
68
+ end
69
+
70
+ # @!visibility private
71
+ # Returns true if running in Circle CI
72
+ #
73
+ # Checks the value of CIRCLECI
74
+ def self.circle_ci?
75
+ value = ENV["CIRCLECI"]
76
+ !!value && value != ''
77
+ end
78
+
79
+ # @!visibility private
80
+ # Returns true if running in Teamcity
81
+ #
82
+ # Checks the value of TEAMCITY_PROJECT_NAME
83
+ def self.teamcity?
84
+ value = ENV["TEAMCITY_PROJECT_NAME"]
85
+ !!value && value != ''
86
+ end
87
+
88
+ # @!visibility private
89
+ # Returns true if running in Teamcity
90
+ #
91
+ # Checks the value of GITLAB_CI
92
+ def self.gitlab?
93
+ value = ENV["GITLAB_CI"]
94
+ !!value && value != ''
95
+ end
96
+
97
+ # @!visibility private
98
+ # Returns true if running in a CI environment
99
+ def self.ci?
100
+ [
101
+ self.ci_var_defined?,
102
+ self.travis?,
103
+ self.jenkins?,
104
+ self.circle_ci?,
105
+ self.teamcity?,
106
+ self.gitlab?
107
+ ].any?
108
+ end
109
+
110
+ private
111
+
112
+ # !@visibility private
113
+ def self.ci_var_defined?
114
+ value = ENV["CI"]
115
+ !!value && value != ''
116
+ end
117
+ end
118
+ end
119
+ end
120
+
@@ -0,0 +1,120 @@
1
+ module Calabash
2
+ module Android
3
+ module Logging
4
+ require "fileutils"
5
+
6
+ # These methods are not part of the API.
7
+ #
8
+ # They may change at any time.
9
+
10
+ # !@visibility private
11
+ # blue
12
+ def self.log_warn(msg)
13
+ puts self.blue(" WARN: #{msg}") if msg
14
+ end
15
+
16
+ # !@visibility private
17
+ # magenta
18
+ def self.log_debug(msg)
19
+ if Calabash::Android::Environment.debug?
20
+ puts self.magenta("DEBUG: #{msg}") if msg
21
+ end
22
+ end
23
+
24
+ # !@visibility private
25
+ # green
26
+ def self.log_info(msg)
27
+ puts self.green(" INFO: #{msg}") if msg
28
+ end
29
+
30
+ # !@visibility private
31
+ # red
32
+ def self.log_error(msg)
33
+ puts self.red("ERROR: #{msg}") if msg
34
+ end
35
+
36
+ # !@visibility private
37
+ def self.log_to_file(message)
38
+ timestamp = self.timestamp
39
+
40
+ begin
41
+ File.open(self.calabash_log_file, "a:UTF-8") do |file|
42
+ message.split($-0).each do |line|
43
+ file.write("#{timestamp} #{line}#{$-0}")
44
+ end
45
+ end
46
+ rescue => e
47
+ message =
48
+ %Q{Could not write:
49
+
50
+ #{message}
51
+
52
+ to calabash.log because:
53
+
54
+ #{e}
55
+ }
56
+ self.log_debug(message)
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ # @!visibility private
63
+ def self.colorize(string, color)
64
+ if Calabash::Android::Environment.windows?
65
+ string
66
+ elsif Calabash::Android::Environment.xtc?
67
+ string
68
+ else
69
+ "\033[#{color}m#{string}\033[0m"
70
+ end
71
+ end
72
+
73
+ # @!visibility private
74
+ def self.red(string)
75
+ colorize(string, 31)
76
+ end
77
+
78
+ # @!visibility private
79
+ def self.blue(string)
80
+ colorize(string, 34)
81
+ end
82
+
83
+ # @!visibility private
84
+ def self.magenta(string)
85
+ colorize(string, 35)
86
+ end
87
+
88
+ # @!visibility private
89
+ def self.cyan(string)
90
+ colorize(string, 36)
91
+ end
92
+
93
+ # @!visibility private
94
+ def self.green(string)
95
+ colorize(string, 32)
96
+ end
97
+
98
+ # @!visibility private
99
+ def self.timestamp
100
+ Time.now.strftime("%Y-%m-%d_%H-%M-%S")
101
+ end
102
+
103
+ # @!visibility private
104
+ def self.logs_directory
105
+ path = File.join(Calabash::Android::DotDir.directory, "logs")
106
+ FileUtils.mkdir_p(path)
107
+ path
108
+ end
109
+
110
+ # @!visibility private
111
+ def self.calabash_log_file
112
+ path = File.join(self.logs_directory, "calabash.log")
113
+ if !File.exist?(path)
114
+ FileUtils.touch(path)
115
+ end
116
+ path
117
+ end
118
+ end
119
+ end
120
+ end
@@ -15,6 +15,11 @@ require 'calabash-android/drag_helpers'
15
15
  require 'calabash-android/wait_helpers'
16
16
  require 'calabash-android/version'
17
17
  require 'calabash-android/env'
18
+ require 'calabash-android/environment'
19
+ require 'calabash-android/dot_dir'
20
+ require 'calabash-android/logging'
21
+ require 'calabash-android/store/preferences'
22
+ require 'calabash-android/usage_tracker'
18
23
  require 'retriable'
19
24
  require 'cucumber'
20
25
  require 'date'
@@ -702,6 +707,11 @@ module Calabash module Android
702
707
  end
703
708
 
704
709
  log("Client and server versions match (client: #{client_version}, server: #{server_version}). Proceeding...")
710
+
711
+ # What is Calabash tracking? Read this post for information
712
+ # No private data (like ip addresses) are collected
713
+ # https://github.com/calabash/calabash-android/issues/655
714
+ Calabash::Android::UsageTracker.new.post_usage_async
705
715
  end
706
716
 
707
717
  def shutdown_test_server
@@ -912,6 +922,8 @@ module Calabash module Android
912
922
  end
913
923
 
914
924
  def press_user_action_button(action_name=nil)
925
+ wait_for_keyboard
926
+
915
927
  if action_name.nil?
916
928
  perform_action("press_user_action_button")
917
929
  else
@@ -0,0 +1,211 @@
1
+ module Calabash
2
+ module Android
3
+
4
+ require "awesome_print"
5
+ require "json"
6
+ require "fileutils"
7
+ require "securerandom"
8
+
9
+ # Users preferences persisted across runs:
10
+ #
11
+ # ~/.calabash/preferences/preferences.json
12
+ class Preferences
13
+ def initialize
14
+ dot_dir = Calabash::Android::DotDir.directory
15
+ @path = File.join(dot_dir, "preferences", "preferences.json")
16
+ end
17
+
18
+ def to_s
19
+ $stdout.puts "Preferences:"
20
+ ap read
21
+ end
22
+
23
+ def inspect
24
+ to_s
25
+ end
26
+
27
+ # !@visibility private
28
+ def usage_tracking
29
+ preferences = read
30
+
31
+ unless valid_user_tracking_value?(preferences[:usage_tracking])
32
+ log_defaults_reset
33
+ preferences[:usage_tracking] = defaults[:usage_tracking]
34
+ write(preferences)
35
+ end
36
+
37
+ preferences[:usage_tracking]
38
+ end
39
+
40
+ # !@visibility private
41
+ def usage_tracking=(value)
42
+ if !valid_user_tracking_value?(value)
43
+ raise ArgumentError,
44
+ "Expected '#{value}' to be one of #{VALID_USAGE_TRACKING_VALUES.join(", ")}"
45
+ end
46
+
47
+ preferences = read
48
+ preferences[:usage_tracking] = value
49
+ write(preferences)
50
+ end
51
+
52
+ # !@visibility private
53
+ def user_id
54
+ preferences = read
55
+
56
+ unless valid_user_id?(preferences[:user_id])
57
+ preferences[:user_id] = SecureRandom.uuid
58
+ write(preferences)
59
+ end
60
+
61
+ preferences[:user_id]
62
+ end
63
+
64
+ # !@visibility private
65
+ def user_id=(value)
66
+ if !valid_user_id?(value)
67
+ raise ArgumentError,
68
+ "Expected '#{value}' to not be nil and not an empty string"
69
+ end
70
+
71
+ preferences = read
72
+ preferences[:user_id] = value
73
+ write(preferences)
74
+ end
75
+
76
+ private
77
+
78
+ # @!visibility private
79
+ def valid_user_tracking_value?(value)
80
+ VALID_USAGE_TRACKING_VALUES.include?(value)
81
+ end
82
+
83
+ # @!visibility private
84
+ def valid_user_id?(value)
85
+ !value.nil? && value != "" && value.is_a?(String)
86
+ end
87
+
88
+ # @!visibility private
89
+ #
90
+ # The preferences version
91
+ VERSION = "1.0"
92
+
93
+ # @!visibility private
94
+ #
95
+ # Ordered by permissiveness left to right ascending.
96
+ #
97
+ # "system_info" implies that "events" are also allowed.
98
+ VALID_USAGE_TRACKING_VALUES = ["none", "events", "system_info"]
99
+
100
+ # @!visibility private
101
+ def version
102
+ read[:version]
103
+ end
104
+
105
+ # @!visibility private
106
+ attr_reader :path
107
+
108
+ # @!visibility private
109
+ def ensure_preferences_dir
110
+ dir = File.dirname(@path)
111
+ unless File.exist?(dir)
112
+ FileUtils.mkdir_p(dir)
113
+ end
114
+ end
115
+
116
+ # @!visibility private
117
+ def defaults
118
+ {
119
+ :version => VERSION,
120
+ :usage_tracking => "system_info",
121
+ :user_id => SecureRandom.uuid
122
+ }
123
+ end
124
+
125
+ # @!visibility private
126
+ def write(hash)
127
+ if hash.nil?
128
+ raise ArgumentError, "Hash to write cannot be nil"
129
+ end
130
+
131
+ if !hash.is_a?(Hash)
132
+ raise ArgumentError, "Expected a Hash argument"
133
+ end
134
+
135
+ if hash.count == 0
136
+ raise ArgumentError, "Hash to write cannot be empty"
137
+ end
138
+
139
+ string = generate_json(hash)
140
+
141
+ ensure_preferences_dir
142
+
143
+ File.open(path, "w:UTF-8") do |file|
144
+ file.write(string)
145
+ end
146
+
147
+ true
148
+ end
149
+
150
+ # @!visibility private
151
+ def generate_json(hash)
152
+ begin
153
+ JSON.pretty_generate(hash)
154
+ rescue TypeError, JSON::UnparserError => _
155
+
156
+ log_defaults_reset
157
+
158
+ # Will always generate valid JSON
159
+ generate_json(defaults)
160
+ end
161
+ end
162
+
163
+ # @!visibility private
164
+ def read
165
+ if File.exist?(path)
166
+
167
+ string = File.read(path).force_encoding("UTF-8")
168
+
169
+ parse_json(string)
170
+ else
171
+ hash = defaults
172
+ write(hash)
173
+ hash
174
+ end
175
+ end
176
+
177
+ # @!visibility private
178
+ def parse_json(string)
179
+ begin
180
+ JSON.parse(string, {:symbolize_names => true})
181
+ rescue TypeError, JSON::ParserError => _
182
+
183
+ log_defaults_reset
184
+
185
+ hash = defaults
186
+ write(hash)
187
+ hash
188
+ end
189
+ end
190
+
191
+ # @!visibility private
192
+ def log_defaults_reset
193
+ $stderr.puts(
194
+ %q{An error occurred while accessing your user preferences.
195
+
196
+ We have reset the preferences to the default settings.
197
+
198
+ If this happens on a regular basis, please create a GitHub issue.
199
+
200
+ Your preferences control various Calabash behaviors. In particular, they tell
201
+ us how much usage information you are willing to share. If you have previously
202
+ turned off usage tracking, you will need to disable it again using the command
203
+ line tools or the irb.
204
+
205
+ We do not recommend that edit the preferences file by hand.
206
+ })
207
+ end
208
+ end
209
+ end
210
+ end
211
+
@@ -12,6 +12,7 @@ module Calabash
12
12
  end
13
13
 
14
14
  def keyboard_enter_text(text, options = {})
15
+ wait_for_keyboard
15
16
  perform_action('keyboard_enter_text', text)
16
17
  end
17
18
 
@@ -19,36 +20,62 @@ module Calabash
19
20
  keyboard_enter_text(character[0,1], options)
20
21
  end
21
22
 
23
+ # Appends `text` into the first view matching `uiquery`.
22
24
  def enter_text(uiquery, text, options = {})
23
25
  tap_when_element_exists(uiquery, options)
24
26
  sleep 0.5
27
+ set_selection(-1, -1)
25
28
  keyboard_enter_text(text, options)
26
29
  end
27
30
 
28
31
  def clear_text_in(query_string, options={})
29
- unless query_string.nil?
30
- touch(query_string, options)
31
- sleep 0.5
32
- end
33
-
32
+ touch(query_string, options)
33
+ sleep 0.5
34
34
  clear_text(options)
35
35
  end
36
36
 
37
+ # Clears the text of the currently focused view.
37
38
  def clear_text(options={})
38
- if options.is_a?(String)
39
- puts "Warning: The method clear_text now clears the text in the currently focused view. Use clear_text_in instead"
40
- puts "Notice that clear_text_in only clears the text of the first element matching the given query, not all."
41
- puts "Use query(query, setText: '') to replicate the old behaviour"
39
+ set_selection(-1, -1)
40
+ perform_action("delete_surrounding_text", -1, 0)
41
+ end
42
+
43
+ def escape_quotes(str)
44
+ str.gsub("'", "\\\\'")
45
+ end
42
46
 
43
- clear_text_in(options)
47
+ # Sets the selection of the currently focused view.
48
+ #
49
+ # @param [Integer] selection_start The start of the selection, can be
50
+ # negative to begin counting from the end of the string.
51
+ # @param [Integer] selection_end The end of the selection, can be
52
+ # negative to begin counting from the end of the string.
53
+ def set_selection(selection_start, selection_end)
54
+ perform_action("set_selection", selection_start, selection_end)
55
+ end
56
+
57
+ def keyboard_visible?
58
+ input_method = `#{default_device.adb_command} shell dumpsys input_method`.force_encoding('UTF-8')
59
+ shown = input_method.each_line.grep(/mInputShown\s*=\s*(.*)/){$1}.first.chomp
60
+
61
+ if shown == "true"
62
+ true
63
+ elsif shown == "false"
64
+ false
44
65
  else
45
- perform_action('clear_text')
66
+ raise "Could not detect keyboard visibility. '#{shown}'"
46
67
  end
47
68
  end
48
69
 
49
- def escape_quotes(str)
50
- str.gsub("'", "\\\\'")
70
+ def wait_for_keyboard(opt={})
71
+ params = opt.clone
72
+ params[:timeout_message] ||= "Timed out waiting for the keyboard to appear"
73
+ params[:timeout] ||= 5
74
+
75
+ wait_for(params) do
76
+ keyboard_visible?
77
+ end
51
78
  end
52
79
  end
53
80
  end
54
- end
81
+ end