calabash-cucumber 0.16.4 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/calabash-ios-generate.rb +61 -10
- data/dylibs/libCalabashDyn.dylib +0 -0
- data/dylibs/libCalabashDynSim.dylib +0 -0
- data/features-skeleton/sample.feature +7 -0
- data/features-skeleton/steps/sample_steps.rb +45 -0
- data/features-skeleton/support/01_launch.rb +31 -33
- data/features-skeleton/support/dry_run.rb +2 -0
- data/features-skeleton/support/env.rb +1 -0
- data/features-skeleton/support/patches/cucumber.rb +15 -0
- data/lib/calabash-cucumber.rb +4 -0
- data/lib/calabash-cucumber/actions/instruments_actions.rb +0 -5
- data/lib/calabash-cucumber/actions/playback_actions.rb +1 -6
- data/lib/calabash-cucumber/connection_helpers.rb +50 -1
- data/lib/calabash-cucumber/core.rb +94 -72
- data/lib/calabash-cucumber/dot_dir.rb +18 -0
- data/lib/calabash-cucumber/launch/simulator_launcher.rb +35 -3
- data/lib/calabash-cucumber/launcher.rb +46 -99
- data/lib/calabash-cucumber/logging.rb +79 -0
- data/lib/calabash-cucumber/playback_helpers.rb +2 -2
- data/lib/calabash-cucumber/store/preferences.rb +223 -0
- data/lib/calabash-cucumber/uia.rb +0 -43
- data/lib/calabash-cucumber/usage_tracker.rb +192 -0
- data/lib/calabash-cucumber/version.rb +2 -2
- data/lib/calabash-cucumber/wait_helpers.rb +32 -0
- data/scripts/.irbrc +19 -4
- data/staticlib/calabash.framework.zip +0 -0
- data/staticlib/libFrankCalabash.a +0 -0
- metadata +31 -19
- data/features-skeleton/my_first.feature +0 -12
- data/features-skeleton/step_definitions/calabash_steps.rb +0 -1
- data/features-skeleton/step_definitions/my_first_steps.rb +0 -4
- data/features-skeleton/support/02_pre_stop_hooks.rb +0 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
module Calabash
|
2
|
+
module Cucumber
|
3
|
+
# A module for managing the ~/.calabash directory.
|
4
|
+
module DotDir
|
5
|
+
require "run_loop"
|
6
|
+
|
7
|
+
def self.directory
|
8
|
+
home = RunLoop::Environment.user_home_directory
|
9
|
+
dir = File.join(home, ".calabash")
|
10
|
+
if !File.exist?(dir)
|
11
|
+
FileUtils.mkdir_p(dir)
|
12
|
+
end
|
13
|
+
dir
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -34,6 +34,10 @@ module Calabash
|
|
34
34
|
# The file path to the default Xcode DerivedData directory.
|
35
35
|
DERIVED_DATA = File.expand_path('~/Library/Developer/Xcode/DerivedData')
|
36
36
|
|
37
|
+
# @!visibility private]
|
38
|
+
# The file path to the default Xcode preferences plist.
|
39
|
+
XCODE_PREFS = File.expand_path('~/Library/Preferences/com.apple.dt.Xcode.plist')
|
40
|
+
|
37
41
|
# @!visibility private
|
38
42
|
# REGEX for finding application Info.plist.
|
39
43
|
DEFAULT_DERIVED_DATA_INFO = File.expand_path("#{DERIVED_DATA}/*/info.plist")
|
@@ -161,6 +165,33 @@ module Calabash
|
|
161
165
|
end
|
162
166
|
end
|
163
167
|
|
168
|
+
# @!visibility private
|
169
|
+
# Returns the absolute build path to the project directory.
|
170
|
+
#
|
171
|
+
# @return [String] absolute path to the projects build directory
|
172
|
+
def build_output_dir_for_project
|
173
|
+
xcode_temp_prefs = File.join(project_dir, '.cal_xcode_prefs')
|
174
|
+
FileUtils.cp(XCODE_PREFS, xcode_temp_prefs)
|
175
|
+
`plutil -convert xml1 "#{xcode_temp_prefs}"`
|
176
|
+
|
177
|
+
plist = CFPropertyList::List.new(:file => xcode_temp_prefs)
|
178
|
+
hash = CFPropertyList.native_types(plist.value)
|
179
|
+
|
180
|
+
if hash.has_key?('IDESharedBuildFolderName')
|
181
|
+
build_folder_name = hash['IDESharedBuildFolderName']
|
182
|
+
output_dir = "#{DERIVED_DATA}/#{build_folder_name}/Products"
|
183
|
+
elsif hash.has_key?('IDECustomBuildProductsPath')
|
184
|
+
products_path = hash['IDECustomBuildProductsPath']
|
185
|
+
File.join(project_dir, products_path)
|
186
|
+
else
|
187
|
+
output_dir = derived_data_dir_for_project
|
188
|
+
end
|
189
|
+
|
190
|
+
FileUtils.rm(xcode_temp_prefs)
|
191
|
+
|
192
|
+
output_dir
|
193
|
+
end
|
194
|
+
|
164
195
|
# @!visibility private
|
165
196
|
# Returns the absolute path to the project directory.
|
166
197
|
#
|
@@ -220,12 +251,13 @@ module Calabash
|
|
220
251
|
puts('-'*37)
|
221
252
|
end
|
222
253
|
else
|
223
|
-
|
224
|
-
sim_dirs = Dir.glob(File.join(
|
254
|
+
bo_dir = build_output_dir_for_project
|
255
|
+
sim_dirs = Dir.glob(File.join(bo_dir, '*-iphonesimulator', '*.app'))
|
256
|
+
|
225
257
|
if sim_dirs.empty?
|
226
258
|
msg = ['Unable to auto detect APP_BUNDLE_PATH.']
|
227
259
|
msg << 'Have you built your app for simulator?'
|
228
|
-
msg << "Searched dir: #{
|
260
|
+
msg << "Searched dir: #{bo_dir}"
|
229
261
|
msg << 'Please build your app from Xcode'
|
230
262
|
msg << 'You should build the -cal target.'
|
231
263
|
msg << ''
|
@@ -8,6 +8,7 @@ require 'run_loop'
|
|
8
8
|
require 'cfpropertylist'
|
9
9
|
require 'calabash-cucumber/utils/logging'
|
10
10
|
require 'calabash/dylibs'
|
11
|
+
require "calabash-cucumber/usage_tracker"
|
11
12
|
|
12
13
|
# Used to launch apps for testing in iOS Simulator or on iOS Devices. By default
|
13
14
|
# it uses Apple's `instruments` process to launch your app, but has legacy support
|
@@ -56,6 +57,7 @@ class Calabash::Cucumber::Launcher
|
|
56
57
|
attr_accessor :launch_args
|
57
58
|
attr_accessor :simulator_launcher
|
58
59
|
attr_reader :xcode
|
60
|
+
attr_reader :usage_tracker
|
59
61
|
|
60
62
|
# @!visibility private
|
61
63
|
# Generated when calabash cannot launch the app.
|
@@ -81,6 +83,10 @@ class Calabash::Cucumber::Launcher
|
|
81
83
|
@xcode ||= RunLoop::Xcode.new
|
82
84
|
end
|
83
85
|
|
86
|
+
def usage_tracker
|
87
|
+
@usage_tracker ||= Calabash::Cucumber::UsageTracker.new
|
88
|
+
end
|
89
|
+
|
84
90
|
# @!visibility private
|
85
91
|
def initialize
|
86
92
|
@simulator_launcher = Calabash::Cucumber::SimulatorLauncher.new
|
@@ -147,12 +153,15 @@ class Calabash::Cucumber::Launcher
|
|
147
153
|
self.run_loop = run_loop
|
148
154
|
major = self.device.ios_major_version
|
149
155
|
if major.to_i >= 7 && self.actions.is_a?(Calabash::Cucumber::PlaybackActions)
|
150
|
-
puts
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
+
puts %Q{
|
157
|
+
|
158
|
+
WARNING
|
159
|
+
|
160
|
+
Connected to simulator that was not launched by Calabash.
|
161
|
+
|
162
|
+
Queries will work, but gestures will not.
|
163
|
+
|
164
|
+
}
|
156
165
|
end
|
157
166
|
self
|
158
167
|
end
|
@@ -267,56 +276,24 @@ class Calabash::Cucumber::Launcher
|
|
267
276
|
# `:all` is passed, then the sandboxes for all sdks will be deleted.
|
268
277
|
# @option opts [String] :path (nil) path to the application bundle
|
269
278
|
def reset_app_sandbox(opts={})
|
279
|
+
calabash_warn(%Q{
|
280
|
+
Starting in Calabash 0.17.0, this method does nothing.
|
270
281
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
end
|
275
|
-
|
276
|
-
default_opts = {:sdk => nil, :path => nil}
|
277
|
-
merged_opts = default_opts.merge opts
|
282
|
+
You can still control whether or not your app's sandbox is
|
283
|
+
reset between Scenarios using RESET_BETWEEN_SCENARIOS=1 or
|
284
|
+
by passing :reset => true as a launch option.
|
278
285
|
|
279
|
-
|
280
|
-
|
286
|
+
options = {
|
287
|
+
:reset => true
|
288
|
+
}
|
281
289
|
|
282
|
-
|
283
|
-
default_sim = RunLoop::Core.default_simulator(xcode)
|
284
|
-
name_or_udid = merged_opts[:udid] || ENV['DEVICE_TARGET'] || default_sim
|
290
|
+
launcher.relaunch(options)
|
285
291
|
|
286
|
-
|
287
|
-
[name_or_udid == sim.instruments_identifier(xcode),
|
288
|
-
name_or_udid == sim.udid,
|
289
|
-
name_or_udid == sim.name].any?
|
290
|
-
end
|
292
|
+
Please do not ignore this message.
|
291
293
|
|
292
|
-
|
293
|
-
raise "Could not find a simulator that matches '#{name_or_udid}'"
|
294
|
-
end
|
295
|
-
|
296
|
-
sim_control.reset_sim_content_and_settings({:sim_udid => target_simulator.udid})
|
297
|
-
else
|
298
|
-
sdk ||= merged_opts[:sdk] || sdk_version || self.simulator_launcher.sdk_detector.latest_sdk_version
|
299
|
-
path ||= merged_opts[:path] || self.simulator_launcher.app_bundle_or_raise(app_path)
|
294
|
+
Remove direct calls to reset_app_sandbox.
|
300
295
|
|
301
|
-
|
302
|
-
|
303
|
-
directories_for_sdk_prefix(sdk).each do |sdk_dir|
|
304
|
-
app_dir = File.expand_path("#{sdk_dir}/Applications")
|
305
|
-
next unless File.exists?(app_dir)
|
306
|
-
|
307
|
-
bundle = `find "#{app_dir}" -type d -depth 2 -name "#{app}" | head -n 1`
|
308
|
-
|
309
|
-
next if bundle.empty? # Assuming we're already clean
|
310
|
-
|
311
|
-
if debug_logging?
|
312
|
-
puts "Reset app state for #{bundle}"
|
313
|
-
end
|
314
|
-
sandbox = File.dirname(bundle)
|
315
|
-
['Library', 'Documents', 'tmp'].each do |content_dir|
|
316
|
-
FileUtils.rm_rf(File.join(sandbox, content_dir))
|
317
|
-
end
|
318
|
-
end
|
319
|
-
end
|
296
|
+
})
|
320
297
|
end
|
321
298
|
|
322
299
|
# Erases the contents and setting for every available simulator.
|
@@ -503,36 +480,27 @@ class Calabash::Cucumber::Launcher
|
|
503
480
|
end
|
504
481
|
end
|
505
482
|
|
506
|
-
# Launches your app on the connected device or simulator.
|
507
|
-
# `relaunch` does a lot of error detection and handling to reliably start the app and test. Instruments (particularly the cli)
|
508
|
-
# has stability issues which we workaround by restarting the simulator process and checking that UIAutomation is correctly
|
509
|
-
# attaching.
|
483
|
+
# Launches your app on the connected device or simulator.
|
510
484
|
#
|
511
|
-
#
|
512
|
-
#
|
485
|
+
# `relaunch` does a lot of error detection and handling to reliably start the
|
486
|
+
# app and test. Instruments (particularly the cli) has stability issues which
|
487
|
+
# we workaround by restarting the simulator process and checking that
|
488
|
+
# UIAutomation is correctly attaching to your application.
|
513
489
|
#
|
514
|
-
#
|
490
|
+
# Use the `args` parameter to to control:
|
515
491
|
#
|
516
|
-
#
|
517
|
-
#
|
518
|
-
# -
|
519
|
-
# - `BUNDLE_ID` used with `DEVICE_TARGET=device` to specify which app to launch on device
|
520
|
-
# - `DEBUG` - set to "1" to obtain debug info (typically used to debug launching, UIAutomation and other issues)
|
521
|
-
# - `DEBUG_HTTP` - set to "1" to show raw HTTP traffic
|
492
|
+
# * `:app` - which app to launch.
|
493
|
+
# * `:device_target` - simulator or device to target.
|
494
|
+
# * `:reset_app_sandbox - reset he app's data (sandbox) before testing
|
522
495
|
#
|
496
|
+
# and many other behaviors.
|
523
497
|
#
|
524
|
-
#
|
525
|
-
#
|
526
|
-
#
|
527
|
-
#
|
528
|
-
# @
|
529
|
-
# @option args {String} :bundle_id if launching on device, specify this or env `BUNDLE_ID` to be the bundle identifier
|
530
|
-
# of the application to launch
|
531
|
-
# @option args {Hash} :privacy_settings preset privacy settings for the, e.g., `{:photos => {:allow => true}}`.
|
532
|
-
# See {KNOWN_PRIVACY_SETTINGS}
|
498
|
+
# Many of these behaviors can be be controlled by environment variables. The
|
499
|
+
# most important environment variables are `APP`, `DEVICE_TARGET`, and
|
500
|
+
# `DEVICE_ENDPOINT`.
|
501
|
+
#
|
502
|
+
# @param {Hash} args optional arguments to control the how the app is launched
|
533
503
|
def relaunch(args={})
|
534
|
-
#TODO stopping is currently broken, but this works anyway because instruments stop the process before relaunching
|
535
|
-
RunLoop.stop(run_loop) if run_loop
|
536
504
|
|
537
505
|
# @todo Don't overwrite the _args_ parameter!
|
538
506
|
args = default_launch_args.merge(args)
|
@@ -577,34 +545,11 @@ class Calabash::Cucumber::Launcher
|
|
577
545
|
|
578
546
|
args[:device] ||= detect_device_from_args(args)
|
579
547
|
|
580
|
-
if simulator_target?(args) and args[:reset]
|
581
|
-
# attempt to find the sdk version from the :device_target
|
582
|
-
sdk = sdk_version_for_simulator_target(args)
|
583
|
-
|
584
|
-
# *** LEGACY SUPPORT ***
|
585
|
-
# If DEVICE_TARGET has not been set and is not a device UDID, then
|
586
|
-
# :device_target will be 'simulator'. In that case, we cannot know what
|
587
|
-
# SDK version of the app sandbox we should reset. The user _might_ give
|
588
|
-
# us a hint with SDK_VERSION, but we want to deprecate that variable ASAP.
|
589
|
-
#
|
590
|
-
# If passed a nil SDK arg, reset_app_sandbox will reset the _latest_ SDK.
|
591
|
-
# This is not good, because this is probably _not_ the SDK that should be
|
592
|
-
# reset. Our only option is to reset every sandbox for all SDKs by
|
593
|
-
# passing :sdk => :all to reset_app_sandbox.
|
594
|
-
if sdk.nil? and args[:device_target] == 'simulator'
|
595
|
-
sdk = :all
|
596
|
-
end
|
597
|
-
reset_app_sandbox({:sdk => sdk,
|
598
|
-
:path => args[:app],
|
599
|
-
:udid => args[:udid],
|
600
|
-
:sim_control => args[:sim_control]})
|
601
|
-
end
|
602
|
-
|
603
548
|
if args[:privacy_settings]
|
604
549
|
if simulator_target?(args)
|
605
550
|
update_privacy_settings(args[:bundle_id], args[:privacy_settings])
|
606
551
|
else
|
607
|
-
#Not supported on device
|
552
|
+
# Not supported on device
|
608
553
|
puts 'Warning: :privacy_settings not supported on device'
|
609
554
|
end
|
610
555
|
end
|
@@ -649,6 +594,8 @@ class Calabash::Cucumber::Launcher
|
|
649
594
|
check_server_gem_compatibility
|
650
595
|
end
|
651
596
|
end
|
597
|
+
|
598
|
+
usage_tracker.post_usage_async
|
652
599
|
end
|
653
600
|
|
654
601
|
# @!visibility private
|
@@ -1083,7 +1030,7 @@ class Calabash::Cucumber::Launcher
|
|
1083
1030
|
msgs = [
|
1084
1031
|
'The server version is not compatible with gem version.',
|
1085
1032
|
'Please update your server.',
|
1086
|
-
'https://github.com/calabash/calabash-ios/wiki/
|
1033
|
+
'https://github.com/calabash/calabash-ios/wiki/Updating-your-Calabash-iOS-version',
|
1087
1034
|
" gem version: '#{gem_version}'",
|
1088
1035
|
"min server version: '#{min_server_version}'",
|
1089
1036
|
" server version: '#{server_version}'"]
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Calabash
|
2
|
+
module Cucumber
|
3
|
+
require "run_loop"
|
4
|
+
|
5
|
+
# These methods are not part of the API.
|
6
|
+
#
|
7
|
+
# They may change at any time.
|
8
|
+
|
9
|
+
# !@visibility private
|
10
|
+
# blue
|
11
|
+
def self.log_warn(msg)
|
12
|
+
puts self.blue(" WARN: #{msg}") if msg
|
13
|
+
end
|
14
|
+
|
15
|
+
# !@visibility private
|
16
|
+
# magenta
|
17
|
+
def self.log_debug(msg)
|
18
|
+
if RunLoop::Environment.debug?
|
19
|
+
puts self.magenta("DEBUG: #{msg}") if msg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# !@visibility private
|
24
|
+
# green
|
25
|
+
def self.log_info(msg)
|
26
|
+
puts self.green(" INFO: #{msg}") if msg
|
27
|
+
end
|
28
|
+
|
29
|
+
# !@visibility private
|
30
|
+
# red
|
31
|
+
def self.log_error(msg)
|
32
|
+
puts self.red("ERROR: #{msg}") if msg
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# @!visibility private
|
38
|
+
def self.windows_env?
|
39
|
+
RbConfig::CONFIG["host_os"] =~ /mswin|mingw|cygwin/
|
40
|
+
end
|
41
|
+
|
42
|
+
# @!visibility private
|
43
|
+
def self.colorize(string, color)
|
44
|
+
if self.windows_env?
|
45
|
+
string
|
46
|
+
elsif RunLoop::Environment.xtc?
|
47
|
+
string
|
48
|
+
else
|
49
|
+
"\033[#{color}m#{string}\033[0m"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @!visibility private
|
54
|
+
def self.red(string)
|
55
|
+
colorize(string, 31)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @!visibility private
|
59
|
+
def self.blue(string)
|
60
|
+
colorize(string, 34)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @!visibility private
|
64
|
+
def self.magenta(string)
|
65
|
+
colorize(string, 35)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @!visibility private
|
69
|
+
def self.cyan(string)
|
70
|
+
colorize(string, 36)
|
71
|
+
end
|
72
|
+
|
73
|
+
# @!visibility private
|
74
|
+
def self.green(string)
|
75
|
+
colorize(string, 32)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
@@ -75,7 +75,7 @@ module Calabash
|
|
75
75
|
Most likely you have updated your calabash-cucumber client
|
76
76
|
but not your server. Please follow closely:
|
77
77
|
|
78
|
-
https://github.com/calabash/calabash-ios/wiki/
|
78
|
+
https://github.com/calabash/calabash-ios/wiki/Updating-your-Calabash-iOS-version
|
79
79
|
|
80
80
|
If you are running version 0.9.120+ then please report this message as a bug.
|
81
81
|
EOF
|
@@ -194,7 +194,7 @@ EOF
|
|
194
194
|
Most likely you have updated your calabash-cucumber client
|
195
195
|
but not your server. Please follow closely:
|
196
196
|
|
197
|
-
https://github.com/calabash/calabash-ios/wiki/
|
197
|
+
https://github.com/calabash/calabash-ios/wiki/Updating-your-Calabash-iOS-version
|
198
198
|
|
199
199
|
If you are running version 0.9.120+ then please report this message as a bug.
|
200
200
|
EOF
|
@@ -0,0 +1,223 @@
|
|
1
|
+
module Calabash
|
2
|
+
module Cucumber
|
3
|
+
|
4
|
+
require "fileutils"
|
5
|
+
require "securerandom"
|
6
|
+
|
7
|
+
# Users preferences persisted across runs:
|
8
|
+
#
|
9
|
+
# ~/.calabash/preferences/preferences.json
|
10
|
+
class Preferences
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
dot_dir = Calabash::Cucumber::DotDir.directory
|
14
|
+
@path = File.join(dot_dir, "preferences", "preferences.json")
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
puts "Preferences:"
|
19
|
+
ap read
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
# !@visibility private
|
27
|
+
def usage_tracking
|
28
|
+
preferences = read
|
29
|
+
|
30
|
+
unless valid_user_tracking_value?(preferences[:usage_tracking])
|
31
|
+
log_defaults_reset
|
32
|
+
preferences[:usage_tracking] = defaults[:usage_tracking]
|
33
|
+
write(preferences)
|
34
|
+
end
|
35
|
+
|
36
|
+
preferences[:usage_tracking]
|
37
|
+
end
|
38
|
+
|
39
|
+
# !@visibility private
|
40
|
+
def usage_tracking=(value)
|
41
|
+
if !valid_user_tracking_value?(value)
|
42
|
+
raise ArgumentError,
|
43
|
+
"Expected '#{value}' to be one of #{VALID_USAGE_TRACKING_VALUES.join(", ")}"
|
44
|
+
end
|
45
|
+
|
46
|
+
preferences = read
|
47
|
+
preferences[:usage_tracking] = value
|
48
|
+
write(preferences)
|
49
|
+
end
|
50
|
+
|
51
|
+
# !@visibility private
|
52
|
+
def user_id
|
53
|
+
preferences = read
|
54
|
+
|
55
|
+
unless valid_user_id?(preferences[:user_id])
|
56
|
+
preferences[:user_id] = SecureRandom.uuid
|
57
|
+
write(preferences)
|
58
|
+
end
|
59
|
+
|
60
|
+
preferences[:user_id]
|
61
|
+
end
|
62
|
+
|
63
|
+
# !@visibility private
|
64
|
+
def user_id=(value)
|
65
|
+
if !valid_user_id?(value)
|
66
|
+
raise ArgumentError,
|
67
|
+
"Expected '#{value}' to not be nil and not an empty string"
|
68
|
+
end
|
69
|
+
|
70
|
+
preferences = read
|
71
|
+
preferences[:user_id] = value
|
72
|
+
write(preferences)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# @!visibility private
|
78
|
+
def valid_user_tracking_value?(value)
|
79
|
+
VALID_USAGE_TRACKING_VALUES.include?(value)
|
80
|
+
end
|
81
|
+
|
82
|
+
# @!visibility private
|
83
|
+
def valid_user_id?(value)
|
84
|
+
!value.nil? && value != "" && value.is_a?(String)
|
85
|
+
end
|
86
|
+
|
87
|
+
# @!visibility private
|
88
|
+
#
|
89
|
+
# The preferences version
|
90
|
+
VERSION = "1.0"
|
91
|
+
|
92
|
+
# @!visibility private
|
93
|
+
#
|
94
|
+
# Ordered by permissiveness left to right ascending.
|
95
|
+
#
|
96
|
+
# "system_info" implies that "events" are also allowed.
|
97
|
+
VALID_USAGE_TRACKING_VALUES = ["none", "events", "system_info"]
|
98
|
+
|
99
|
+
# @!visibility private
|
100
|
+
def version
|
101
|
+
read[:version]
|
102
|
+
end
|
103
|
+
|
104
|
+
# @!visibility private
|
105
|
+
attr_reader :path
|
106
|
+
|
107
|
+
# @!visibility private
|
108
|
+
def ensure_preferences_dir
|
109
|
+
dir = File.dirname(@path)
|
110
|
+
unless File.exist?(dir)
|
111
|
+
FileUtils.mkdir_p(dir)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# @!visibility private
|
116
|
+
def defaults
|
117
|
+
{
|
118
|
+
:version => VERSION,
|
119
|
+
:usage_tracking => "system_info",
|
120
|
+
:user_id => SecureRandom.uuid
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
# @!visibility private
|
125
|
+
def write(hash)
|
126
|
+
if hash.nil?
|
127
|
+
raise ArgumentError, "Hash to write cannot be nil"
|
128
|
+
end
|
129
|
+
|
130
|
+
if !hash.is_a?(Hash)
|
131
|
+
raise ArgumentError, "Expected a Hash argument"
|
132
|
+
end
|
133
|
+
|
134
|
+
if hash.count == 0
|
135
|
+
raise ArgumentError, "Hash to write cannot be empty"
|
136
|
+
end
|
137
|
+
|
138
|
+
string = generate_json(hash)
|
139
|
+
|
140
|
+
ensure_preferences_dir
|
141
|
+
|
142
|
+
File.open(path, "w:UTF-8") do |file|
|
143
|
+
file.write(string)
|
144
|
+
end
|
145
|
+
|
146
|
+
true
|
147
|
+
end
|
148
|
+
|
149
|
+
# @!visibility private
|
150
|
+
def generate_json(hash)
|
151
|
+
begin
|
152
|
+
JSON.pretty_generate(hash)
|
153
|
+
rescue TypeError, JSON::UnparserError => e
|
154
|
+
write_to_log(
|
155
|
+
%Q{Error generating JSON from:
|
156
|
+
hash: #{hash}
|
157
|
+
error: #{e}
|
158
|
+
})
|
159
|
+
log_defaults_reset
|
160
|
+
|
161
|
+
# Will always generate valid JSON
|
162
|
+
generate_json(defaults)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# @!visibility private
|
167
|
+
def read
|
168
|
+
if File.exist?(path)
|
169
|
+
|
170
|
+
string = File.read(path).force_encoding("UTF-8")
|
171
|
+
|
172
|
+
parse_json(string)
|
173
|
+
else
|
174
|
+
hash = defaults
|
175
|
+
write(hash)
|
176
|
+
hash
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# @!visibility private
|
181
|
+
def parse_json(string)
|
182
|
+
begin
|
183
|
+
JSON.parse(string, {:symbolize_names => true})
|
184
|
+
rescue TypeError, JSON::ParserError => e
|
185
|
+
write_to_log(
|
186
|
+
%Q{Error parsing JSON from:
|
187
|
+
string: #{string}
|
188
|
+
error: #{e}
|
189
|
+
})
|
190
|
+
log_defaults_reset
|
191
|
+
|
192
|
+
hash = defaults
|
193
|
+
write(hash)
|
194
|
+
hash
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# @!visibility private
|
199
|
+
def write_to_log(error_message)
|
200
|
+
# TODO write to a log file?
|
201
|
+
end
|
202
|
+
|
203
|
+
# @!visibility private
|
204
|
+
def log_defaults_reset
|
205
|
+
Calabash::Cucumber.log_warn(
|
206
|
+
%q{An error occurred while accessing your user preferences.
|
207
|
+
|
208
|
+
We have reset the preferences to the default settings.
|
209
|
+
|
210
|
+
If this happens on a regular basis, please create a GitHub issue.
|
211
|
+
|
212
|
+
Your preferences control various Calabash behaviors. In particular, they tell
|
213
|
+
us how much usage information you are willing to share. If you have previously
|
214
|
+
turned off usage tracking, you will need to disable it again using the command
|
215
|
+
line tools or the irb.
|
216
|
+
|
217
|
+
We do not recommend that edit the preferences file by hand.
|
218
|
+
})
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|