calabash-cucumber 0.16.4 → 0.17.0
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 +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
|
+
|