calabash 2.0.0.pre1 → 2.0.0.prelegacy2
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/README.md +1 -38
- data/lib/calabash.rb +18 -5
- data/lib/calabash/android.rb +3 -0
- data/lib/calabash/android/adb.rb +25 -1
- data/lib/calabash/android/application.rb +14 -3
- data/lib/calabash/android/build/builder.rb +15 -2
- data/lib/calabash/android/build/java_keystore.rb +10 -0
- data/lib/calabash/android/build/resigner.rb +4 -0
- data/lib/calabash/android/build/test_server.rb +2 -0
- data/lib/calabash/android/defaults.rb +1 -0
- data/lib/calabash/android/device.rb +42 -1
- data/lib/calabash/android/environment.rb +10 -0
- data/lib/calabash/android/interactions.rb +2 -0
- data/lib/calabash/android/legacy.rb +149 -0
- data/lib/calabash/android/lib/TestServer.apk +0 -0
- data/lib/calabash/android/life_cycle.rb +1 -0
- data/lib/calabash/android/physical_buttons.rb +8 -0
- data/lib/calabash/android/screenshot.rb +1 -0
- data/lib/calabash/android/scroll.rb +110 -0
- data/lib/calabash/android/server.rb +3 -1
- data/lib/calabash/android/text.rb +6 -0
- data/lib/calabash/application.rb +29 -0
- data/lib/calabash/cli/build.rb +15 -1
- data/lib/calabash/cli/console.rb +9 -5
- data/lib/calabash/cli/generate.rb +3 -0
- data/lib/calabash/cli/helpers.rb +7 -1
- data/lib/calabash/cli/resign.rb +1 -0
- data/lib/calabash/cli/run.rb +10 -6
- data/lib/calabash/cli/setup_keystore.rb +2 -0
- data/lib/calabash/color.rb +7 -0
- data/lib/calabash/defaults.rb +1 -0
- data/lib/calabash/device.rb +7 -0
- data/lib/calabash/environment.rb +1 -0
- data/lib/calabash/http/retriable_client.rb +2 -0
- data/lib/calabash/interactions.rb +1 -0
- data/lib/calabash/ios.rb +2 -0
- data/lib/calabash/ios/application.rb +8 -1
- data/lib/calabash/ios/conditions.rb +3 -0
- data/lib/calabash/ios/date_picker.rb +412 -0
- data/lib/calabash/ios/defaults.rb +1 -0
- data/lib/calabash/ios/device.rb +1 -0
- data/lib/calabash/ios/device/device_implementation.rb +16 -11
- data/lib/calabash/ios/device/ipad_1x_2x_mixin.rb +253 -0
- data/lib/calabash/ios/device/keyboard_mixin.rb +2 -0
- data/lib/calabash/ios/device/rotation_mixin.rb +1 -0
- data/lib/calabash/ios/device/routes/condition_route_mixin.rb +1 -0
- data/lib/calabash/ios/device/routes/map_route_mixin.rb +1 -0
- data/lib/calabash/ios/device/routes/response_parser.rb +1 -0
- data/lib/calabash/ios/device/routes/uia_route_mixin.rb +44 -6
- data/lib/calabash/ios/device/text_mixin.rb +2 -0
- data/lib/calabash/ios/device/uia_keyboard_mixin.rb +9 -0
- data/lib/calabash/ios/device/uia_mixin.rb +1 -0
- data/lib/calabash/ios/interactions.rb +30 -1
- data/lib/calabash/ios/runtime.rb +8 -0
- data/lib/calabash/ios/text.rb +5 -45
- data/lib/calabash/legacy.rb +7 -0
- data/lib/calabash/lib/skeleton/config/cucumber.yml +1 -3
- data/lib/calabash/lib/skeleton/features/support/env.rb +15 -1
- data/lib/calabash/life_cycle.rb +19 -2
- data/lib/calabash/location.rb +2 -0
- data/lib/calabash/page.rb +13 -0
- data/lib/calabash/patch.rb +1 -0
- data/lib/calabash/query_result.rb +4 -0
- data/lib/calabash/text.rb +53 -0
- data/lib/calabash/utility.rb +4 -4
- data/lib/calabash/version.rb +1 -1
- data/lib/calabash/wait.rb +4 -0
- metadata +119 -115
data/lib/calabash/cli/console.rb
CHANGED
@@ -3,6 +3,7 @@ module Calabash
|
|
3
3
|
module CLI
|
4
4
|
# @!visibility private
|
5
5
|
module Console
|
6
|
+
# @!visibility private
|
6
7
|
def parse_console_arguments!
|
7
8
|
application = @arguments.shift
|
8
9
|
|
@@ -22,12 +23,14 @@ module Calabash
|
|
22
23
|
when '.apk'
|
23
24
|
set_platform!(:android)
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
unless Environment::TEST_SERVER_PATH
|
27
|
+
# Create the test server if it does not exist
|
28
|
+
test_server = Android::Build::TestServer.new(application_path)
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
30
|
+
unless test_server.exists?
|
31
|
+
Logger.info('Test server does not exist. Creating test server.')
|
32
|
+
Calabash::Android::Build::Builder.new(application_path).build
|
33
|
+
end
|
31
34
|
end
|
32
35
|
|
33
36
|
enter_console(application_path)
|
@@ -45,6 +48,7 @@ module Calabash
|
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
51
|
+
# @!visibility private
|
48
52
|
def enter_console(application_path)
|
49
53
|
irbrc_path = Environment::IRBRC
|
50
54
|
|
@@ -5,6 +5,7 @@ module Calabash
|
|
5
5
|
module CLI
|
6
6
|
# @!visibility private
|
7
7
|
module Generate
|
8
|
+
# @!visibility private
|
8
9
|
def parse_generate_arguments!
|
9
10
|
if File.exist?('features')
|
10
11
|
puts "A features directory already exists. Please remove this to continue."
|
@@ -70,10 +71,12 @@ module Calabash
|
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
74
|
+
# @!visibility private
|
73
75
|
def file(file)
|
74
76
|
File.join(Calabash::Environment::SKELETON_DIR_PATH, file)
|
75
77
|
end
|
76
78
|
|
79
|
+
# @!visibility private
|
77
80
|
def msg(title, &block)
|
78
81
|
puts "\n" + "-"*10 + title + "-"*10
|
79
82
|
block.call
|
data/lib/calabash/cli/helpers.rb
CHANGED
@@ -3,6 +3,7 @@ module Calabash
|
|
3
3
|
module CLI
|
4
4
|
# @!visibility private
|
5
5
|
module Helpers
|
6
|
+
# @!visibility private
|
6
7
|
HELP = {
|
7
8
|
help: 'help',
|
8
9
|
generate: 'generate',
|
@@ -14,6 +15,7 @@ module Calabash
|
|
14
15
|
build: 'build <apk>'
|
15
16
|
}
|
16
17
|
|
18
|
+
# @!visibility private
|
17
19
|
def key_for_command(command)
|
18
20
|
HELP.each do |key, value|
|
19
21
|
if value.split(' ').first == command
|
@@ -24,6 +26,7 @@ module Calabash
|
|
24
26
|
nil
|
25
27
|
end
|
26
28
|
|
29
|
+
# @!visibility private
|
27
30
|
def print_usage_for(key, output=STDOUT)
|
28
31
|
if key.nil? || HELP[key].nil?
|
29
32
|
output.write <<EOF
|
@@ -37,6 +40,7 @@ EOF
|
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
43
|
+
# @!visibility private
|
40
44
|
def print_usage(output=STDOUT)
|
41
45
|
output.write <<EOF
|
42
46
|
Usage: calabash [options] <command-name> [command specific options]
|
@@ -64,7 +68,7 @@ EOF
|
|
64
68
|
#{HELP[:resign]}
|
65
69
|
resigns the app with the currently configured keystore.
|
66
70
|
|
67
|
-
#{HELP[:build]}
|
71
|
+
#{HELP[:build]} [-o <output_file>]
|
68
72
|
builds the test server that will be used when testing the app.
|
69
73
|
|
70
74
|
iOS specific commands
|
@@ -101,11 +105,13 @@ EOF
|
|
101
105
|
EOF
|
102
106
|
end
|
103
107
|
|
108
|
+
# @!visibility private
|
104
109
|
def help
|
105
110
|
file_name = File.join(File.dirname(__FILE__), '..', 'doc', 'calabash_help.txt')
|
106
111
|
system("less \"#{file_name}\"")
|
107
112
|
end
|
108
113
|
|
114
|
+
# @!visibility private
|
109
115
|
def fail(reason, command=nil)
|
110
116
|
STDERR.write("#{reason}\n")
|
111
117
|
|
data/lib/calabash/cli/resign.rb
CHANGED
data/lib/calabash/cli/run.rb
CHANGED
@@ -3,6 +3,7 @@ module Calabash
|
|
3
3
|
module CLI
|
4
4
|
# @!visibility private
|
5
5
|
module Run
|
6
|
+
# @!visibility private
|
6
7
|
def parse_run_arguments!
|
7
8
|
first_argument = @arguments.first # Do not remove the entry from the arguments yet - it might be a cucumber arg
|
8
9
|
|
@@ -30,12 +31,14 @@ module Calabash
|
|
30
31
|
when '.apk'
|
31
32
|
set_platform!(:android)
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
unless Environment::TEST_SERVER_PATH
|
35
|
+
# Create the test server if it does not exist
|
36
|
+
test_server = Android::Build::TestServer.new(application_path)
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
unless test_server.exists?
|
39
|
+
Logger.info('Test server does not exist. Creating test server.')
|
40
|
+
Calabash::Android::Build::Builder.new(application_path).build
|
41
|
+
end
|
39
42
|
end
|
40
43
|
|
41
44
|
run(application_path, @arguments)
|
@@ -54,6 +57,7 @@ module Calabash
|
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
60
|
+
# @!visibility private
|
57
61
|
def run(application_path, cucumber_arguments)
|
58
62
|
cucumber_environment = {}
|
59
63
|
cucumber_environment['CAL_DEBUG'] = Environment::DEBUG ? '1' : '0'
|
@@ -88,7 +92,7 @@ module Calabash
|
|
88
92
|
end
|
89
93
|
end
|
90
94
|
|
91
|
-
arguments = ['-S', 'cucumber',
|
95
|
+
arguments = ['-S', 'cucumber', *cucumber_arguments]
|
92
96
|
|
93
97
|
Logger.debug("Starting Ruby with arguments: #{arguments.join(', ')} and environment #{cucumber_environment.to_s}")
|
94
98
|
|
@@ -6,6 +6,7 @@ module Calabash
|
|
6
6
|
module CLI
|
7
7
|
# @!visibility private
|
8
8
|
module SetupKeystore
|
9
|
+
# @!visibility private
|
9
10
|
def parse_setup_keystore_arguments!
|
10
11
|
set_platform!(:android)
|
11
12
|
|
@@ -25,6 +26,7 @@ module Calabash
|
|
25
26
|
puts "Saved your settings to '#{Android::Build::JavaKeystore::CALABASH_KEYSTORE_SETTINGS_FILENAME}'. You can edit the settings manually or run this setup script again"
|
26
27
|
end
|
27
28
|
|
29
|
+
# @!visibility private
|
28
30
|
def prompt(message, secure = false)
|
29
31
|
puts message
|
30
32
|
|
data/lib/calabash/color.rb
CHANGED
@@ -1,30 +1,37 @@
|
|
1
1
|
module Calabash
|
2
2
|
# @!visibility private
|
3
3
|
module Color
|
4
|
+
# @!visibility private
|
4
5
|
def self.colorize(string, color)
|
5
6
|
"\e[#{color}m#{string}\e[0m"
|
6
7
|
end
|
7
8
|
|
9
|
+
# @!visibility private
|
8
10
|
def self.red(string)
|
9
11
|
colorize(string, 31)
|
10
12
|
end
|
11
13
|
|
14
|
+
# @!visibility private
|
12
15
|
def self.green(string)
|
13
16
|
colorize(string, 32)
|
14
17
|
end
|
15
18
|
|
19
|
+
# @!visibility private
|
16
20
|
def self.yellow(string)
|
17
21
|
colorize(string, 33)
|
18
22
|
end
|
19
23
|
|
24
|
+
# @!visibility private
|
20
25
|
def self.blue(string)
|
21
26
|
colorize(string, 34)
|
22
27
|
end
|
23
28
|
|
29
|
+
# @!visibility private
|
24
30
|
def self.magenta(string)
|
25
31
|
colorize(string, 35)
|
26
32
|
end
|
27
33
|
|
34
|
+
# @!visibility private
|
28
35
|
def self.cyan(string)
|
29
36
|
colorize(string, 36)
|
30
37
|
end
|
data/lib/calabash/defaults.rb
CHANGED
data/lib/calabash/device.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
module Calabash
|
2
|
+
# A model of the device under test. Can be a physical Android or iOS device,
|
3
|
+
# an Android emulator, or an iOS simulator.
|
2
4
|
class Device
|
3
5
|
include Utility
|
4
6
|
|
@@ -251,6 +253,11 @@ module Calabash
|
|
251
253
|
abstract_method!
|
252
254
|
end
|
253
255
|
|
256
|
+
# @!visibility private
|
257
|
+
def keyboard_visible?
|
258
|
+
abstract_method!
|
259
|
+
end
|
260
|
+
|
254
261
|
private
|
255
262
|
|
256
263
|
# @!visibility private
|
data/lib/calabash/environment.rb
CHANGED
data/lib/calabash/ios.rb
CHANGED
@@ -31,6 +31,7 @@ module Calabash
|
|
31
31
|
require 'calabash/ios/runtime'
|
32
32
|
require 'calabash/ios/gestures'
|
33
33
|
require 'calabash/ios/slider'
|
34
|
+
require 'calabash/ios/date_picker'
|
34
35
|
|
35
36
|
include Calabash::IOS::Conditions
|
36
37
|
include Calabash::IOS::Orientation
|
@@ -41,6 +42,7 @@ module Calabash
|
|
41
42
|
include Calabash::IOS::Runtime
|
42
43
|
include Calabash::IOS::Gestures
|
43
44
|
include Calabash::IOS::Slider
|
45
|
+
include Calabash::IOS::DatePicker
|
44
46
|
|
45
47
|
end
|
46
48
|
end
|
@@ -27,7 +27,7 @@ module Calabash
|
|
27
27
|
application_path = Environment::APP_PATH
|
28
28
|
|
29
29
|
if application_path.nil?
|
30
|
-
raise 'No application path is set'
|
30
|
+
raise 'No application path is set. Specify application with environment variable CAL_APP'
|
31
31
|
end
|
32
32
|
|
33
33
|
Application.new(application_path)
|
@@ -67,6 +67,13 @@ module Calabash
|
|
67
67
|
@device_binary
|
68
68
|
end
|
69
69
|
|
70
|
+
# Is this application an iOS application
|
71
|
+
#
|
72
|
+
# @return [Boolean] Always returns true
|
73
|
+
def ios_application?
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
70
77
|
# Returns the sha1 of the directory or binary of this app's path.
|
71
78
|
# @return [String] A checksum.
|
72
79
|
def sha1
|
@@ -0,0 +1,412 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Calabash
|
4
|
+
module IOS
|
5
|
+
|
6
|
+
# A collection of methods for interacting with UIDatePicker.
|
7
|
+
module DatePicker
|
8
|
+
|
9
|
+
# The API has been tested in various time zones and tested
|
10
|
+
# once while crossing the international date line (on a boat).
|
11
|
+
# With that said, the API makes some assumptions about locales
|
12
|
+
# and time zones. It is possible to customize the ruby date
|
13
|
+
# format and Objective-C date format to get the behavior you
|
14
|
+
# need. You will need to monkey patch the following methods:
|
15
|
+
#
|
16
|
+
# * date_picker_ruby_date_format
|
17
|
+
# * date_picker_objc_date_format
|
18
|
+
#
|
19
|
+
# Before going down this path, we recommend that you ask for
|
20
|
+
# advice on the Calabash support channels.
|
21
|
+
|
22
|
+
# @!visibility private
|
23
|
+
# Provided for monkey patching, but not part of the public API.
|
24
|
+
def date_picker_ruby_date_format
|
25
|
+
RUBY_DATE_AND_TIME_FMT
|
26
|
+
end
|
27
|
+
|
28
|
+
# @!visibility private
|
29
|
+
# Provided for monkey patching, but not part of the public API.
|
30
|
+
def date_picker_objc_date_format
|
31
|
+
OBJC_DATE_AND_TIME_FMT
|
32
|
+
end
|
33
|
+
|
34
|
+
# @!visibility private
|
35
|
+
# Returns the picker mode of the first UIDatePicker match by `query`.
|
36
|
+
#
|
37
|
+
# @see #time_mode?
|
38
|
+
# @see #date_mode?
|
39
|
+
# @see #date_and_time_mode?
|
40
|
+
# @see #countdown_mode?
|
41
|
+
#
|
42
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
43
|
+
# to find UIDatePickers.
|
44
|
+
# @return [String] Returns the picker mode which will be one of
|
45
|
+
# `{'0', '1', '2', '3'}`
|
46
|
+
# @raise [RuntimeError] If no picker can be found.
|
47
|
+
# @raise [RuntimeError] If an unknown mode is returned.
|
48
|
+
# @raise [RuntimeError] If first view matched by query does not responde
|
49
|
+
# to 'datePickerMode'.
|
50
|
+
def date_picker_mode(query)
|
51
|
+
Query.ensure_valid_query(query)
|
52
|
+
|
53
|
+
message = "Timed out waiting for picker with #{query}"
|
54
|
+
mode = nil
|
55
|
+
|
56
|
+
wait_for(message) do
|
57
|
+
result = query(query, :datePickerMode)
|
58
|
+
if result.empty?
|
59
|
+
false
|
60
|
+
else
|
61
|
+
mode = result.first
|
62
|
+
if [0, 1, 2, 3].include?(mode)
|
63
|
+
mode
|
64
|
+
else
|
65
|
+
if mode == '*****'
|
66
|
+
raise RuntimeError,
|
67
|
+
"Query #{query} matched a view that does not respond 'datePickerMode'"
|
68
|
+
else
|
69
|
+
raise RuntimeError,
|
70
|
+
"Query #{query} returned an unknown mode '#{mode}' for 'datePickerMode'"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Is the date picker in time mode?
|
78
|
+
#
|
79
|
+
# @see #time_mode?
|
80
|
+
# @see #date_mode?
|
81
|
+
# @see #date_and_time_mode?
|
82
|
+
# @see #countdown_mode?
|
83
|
+
#
|
84
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
85
|
+
# to find UIDatePickers.
|
86
|
+
#
|
87
|
+
# @return [Boolean] True if the picker is in time mode.
|
88
|
+
#
|
89
|
+
# @raise [RuntimeError] If no picker can be found.
|
90
|
+
# @raise [RuntimeError] If an unknown mode is returned.
|
91
|
+
# @raise [RuntimeError] If first view matched by query does not responde
|
92
|
+
# to 'datePickerMode'.
|
93
|
+
def time_mode?(query)
|
94
|
+
date_picker_mode(query) == UI_DATE_PICKER_MODE_TIME
|
95
|
+
end
|
96
|
+
|
97
|
+
# Is the date picker in date mode?
|
98
|
+
#
|
99
|
+
# @see #time_mode?
|
100
|
+
# @see #date_mode?
|
101
|
+
# @see #date_and_time_mode?
|
102
|
+
# @see #countdown_mode?
|
103
|
+
#
|
104
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
105
|
+
# to find UIDatePickers.
|
106
|
+
#
|
107
|
+
# @return [Boolean] True if the picker is in date mode.
|
108
|
+
#
|
109
|
+
# @raise [RuntimeError] If no picker can be found.
|
110
|
+
# @raise [RuntimeError] If an unknown mode is returned.
|
111
|
+
# @raise [RuntimeError] If first view matched by query does not responde
|
112
|
+
# to 'datePickerMode'.
|
113
|
+
def date_mode?(query)
|
114
|
+
date_picker_mode(query) == UI_DATE_PICKER_MODE_DATE
|
115
|
+
end
|
116
|
+
|
117
|
+
# Is the date picker in date and time mode?
|
118
|
+
#
|
119
|
+
# @see #time_mode?
|
120
|
+
# @see #date_mode?
|
121
|
+
# @see #date_and_time_mode?
|
122
|
+
# @see #countdown_mode?
|
123
|
+
#
|
124
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
125
|
+
# to find UIDatePickers.
|
126
|
+
#
|
127
|
+
# @return [Boolean] True if the picker is in date and time mode.
|
128
|
+
#
|
129
|
+
# @raise [RuntimeError] If no picker can be found.
|
130
|
+
# @raise [RuntimeError] If an unknown mode is returned.
|
131
|
+
# @raise [RuntimeError] If first view matched by query does not responde
|
132
|
+
# to 'datePickerMode'.
|
133
|
+
def date_and_time_mode?(query)
|
134
|
+
date_picker_mode(query) == UI_DATE_PICKER_MODE_DATE_AND_TIME
|
135
|
+
end
|
136
|
+
|
137
|
+
# Is the date picker in countdown mode?
|
138
|
+
#
|
139
|
+
# @see #time_mode?
|
140
|
+
# @see #date_mode?
|
141
|
+
# @see #date_and_time_mode?
|
142
|
+
# @see #countdown_mode?
|
143
|
+
#
|
144
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
145
|
+
# to find UIDatePickers.
|
146
|
+
#
|
147
|
+
# @return [Boolean] True if the picker is in countdown mode.
|
148
|
+
#
|
149
|
+
# @raise [RuntimeError] If no picker can be found.
|
150
|
+
# @raise [RuntimeError] If an unknown mode is returned.
|
151
|
+
# @raise [RuntimeError] If first view matched by query does not responde
|
152
|
+
# to 'datePickerMode'.
|
153
|
+
def countdown_mode?(query)
|
154
|
+
date_picker_mode(query) == UI_DATE_PICKER_MODE_COUNT_DOWN_TIMER
|
155
|
+
end
|
156
|
+
|
157
|
+
# The maximum date for a picker. If there is no maximum date, this
|
158
|
+
# method returns nil.
|
159
|
+
#
|
160
|
+
# @note
|
161
|
+
# From the Apple docs:
|
162
|
+
# `The property is an NSDate object or nil (the default)`.
|
163
|
+
#
|
164
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
165
|
+
# to find UIDatePickers.
|
166
|
+
#
|
167
|
+
# @return [DateTime] The maximum date on the picker or nil if no maximum
|
168
|
+
# exists
|
169
|
+
#
|
170
|
+
# @raise [RuntimeError] If the picker is in countdown mode.
|
171
|
+
# @raise [RuntimeError] If no picker can be found.
|
172
|
+
# @raise [RuntimeError] If the date returned by the server cannot be
|
173
|
+
# converted to a DateTime object.
|
174
|
+
def maximum_date_time_from_picker(query)
|
175
|
+
Query.ensure_valid_query(query)
|
176
|
+
|
177
|
+
wait_for_view(query)
|
178
|
+
|
179
|
+
if countdown_mode?(query)
|
180
|
+
fail('Countdown pickers do not have a maximum date.')
|
181
|
+
end
|
182
|
+
|
183
|
+
result = query(query, :maximumDate)
|
184
|
+
|
185
|
+
if result.empty?
|
186
|
+
fail("Expected '#{query}' to return a visible UIDatePicker")
|
187
|
+
else
|
188
|
+
if result.first.nil?
|
189
|
+
nil
|
190
|
+
else
|
191
|
+
date_str = result.first
|
192
|
+
begin
|
193
|
+
date_time = DateTime.parse(date_str)
|
194
|
+
rescue TypeError, ArgumentError => _
|
195
|
+
raise RuntimeError,
|
196
|
+
"Could not convert string '#{date_str}' into a valid DateTime object"
|
197
|
+
end
|
198
|
+
date_time
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# The minimum date for a picker. If there is no minimum date, this
|
204
|
+
# method returns nil.
|
205
|
+
#
|
206
|
+
# @note
|
207
|
+
# From the Apple docs:
|
208
|
+
# `The property is an NSDate object or nil (the default)`.
|
209
|
+
#
|
210
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
211
|
+
# to find UIDatePickers.
|
212
|
+
#
|
213
|
+
# @return [DateTime] The minimum date on the picker or nil if no minimum
|
214
|
+
# exists
|
215
|
+
#
|
216
|
+
# @raise [RuntimeError] If the picker is in countdown mode.
|
217
|
+
# @raise [RuntimeError] If no picker can be found.
|
218
|
+
# @raise [RuntimeError] If the date returned by the server cannot be
|
219
|
+
# converted to a DateTime object.
|
220
|
+
def minimum_date_time_from_picker(query)
|
221
|
+
Query.ensure_valid_query(query)
|
222
|
+
|
223
|
+
wait_for_view(query)
|
224
|
+
|
225
|
+
if countdown_mode?(query)
|
226
|
+
fail('Countdown pickers do not have a minimum date.')
|
227
|
+
end
|
228
|
+
|
229
|
+
result = query(query, :minimumDate)
|
230
|
+
|
231
|
+
if result.empty?
|
232
|
+
fail("Expected '#{query}' to return a visible UIDatePicker")
|
233
|
+
else
|
234
|
+
if result.first.nil?
|
235
|
+
nil
|
236
|
+
else
|
237
|
+
date_str = result.first
|
238
|
+
begin
|
239
|
+
date_time = DateTime.parse(date_str)
|
240
|
+
rescue TypeError, ArgumentError => _
|
241
|
+
raise RuntimeError,
|
242
|
+
"Could not convert string '#{date_str}' into a valid DateTime object"
|
243
|
+
end
|
244
|
+
date_time
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
# Returns the date and time from the picker as DateTime object.
|
250
|
+
#
|
251
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
252
|
+
# to find UIDatePickers.
|
253
|
+
#
|
254
|
+
# @return [DateTime] The date on the picker
|
255
|
+
#
|
256
|
+
# @raise [RuntimeError] If the picker is in countdown mode.
|
257
|
+
# @raise [RuntimeError] If no picker can be found.
|
258
|
+
# @raise [RuntimeError] If the date returned by the server cannot be
|
259
|
+
# converted to a DateTime object.
|
260
|
+
def date_time_from_picker(query)
|
261
|
+
Query.ensure_valid_query(query)
|
262
|
+
|
263
|
+
wait_for_view(query)
|
264
|
+
|
265
|
+
if countdown_mode?(query)
|
266
|
+
fail('This method is available for pickers in countdown mode.')
|
267
|
+
end
|
268
|
+
|
269
|
+
result = query(query, :date)
|
270
|
+
|
271
|
+
if result.empty?
|
272
|
+
fail("Expected '#{query}' to return a visible UIDatePicker")
|
273
|
+
else
|
274
|
+
if result.first.nil?
|
275
|
+
nil
|
276
|
+
else
|
277
|
+
date_str = result.first
|
278
|
+
date_time = DateTime.parse(date_str)
|
279
|
+
if date_time.nil?
|
280
|
+
raise RuntimeError,
|
281
|
+
"Could not convert string '#{date_str}' into a valid DateTime object"
|
282
|
+
end
|
283
|
+
date_time
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
# Sets the date and time on the _first_ UIDatePicker matched by
|
289
|
+
# `query`.
|
290
|
+
#
|
291
|
+
# This method is not valid for UIDatePickers in _countdown_ mode.
|
292
|
+
#
|
293
|
+
# @param [DateTime] date_time The date and time you want to change to.
|
294
|
+
#
|
295
|
+
# @raise [RuntimeError] If `query` does match exactly one picker.
|
296
|
+
# @raise [RuntimeError] If `query` matches a picker in countdown mode.
|
297
|
+
# @raise [RuntimeError] If the target date is greater than the picker's
|
298
|
+
# maximum date.
|
299
|
+
# @raise [RuntimeError] If the target date is less than the picker's
|
300
|
+
# minimum date
|
301
|
+
# @raise [ArgumentError] If the target date is not a DateTime instance.
|
302
|
+
def picker_set_date_time(date_time)
|
303
|
+
picker_set_date_time_in("UIDatePicker index:0", date_time)
|
304
|
+
end
|
305
|
+
|
306
|
+
# Sets the date and time on the _first_ UIDatePicker matched by
|
307
|
+
# `query`.
|
308
|
+
#
|
309
|
+
# This method is not valid for UIDatePickers in _countdown_ mode.
|
310
|
+
#
|
311
|
+
# An error will be raised if more than on view is matched by `query`.
|
312
|
+
#
|
313
|
+
# To avoid matching more than one UIPickerView or subclass:
|
314
|
+
# * Make the query more specific: "UIPickerView marked:'alarm'"
|
315
|
+
# * Use the index language feature: "UIPickerView index:0"
|
316
|
+
# * Query by custom class: "view:'MyPickerView'"
|
317
|
+
#
|
318
|
+
# @param [String, Hash, Calabash::Query] query A query that can be used
|
319
|
+
# to find UIDatePickers.
|
320
|
+
# @param [DateTime] date_time The date and time you want to change to.
|
321
|
+
#
|
322
|
+
# @raise [RuntimeError] If `query` does match exactly one picker.
|
323
|
+
# @raise [RuntimeError] If `query` matches a picker in countdown mode.
|
324
|
+
# @raise [RuntimeError] If the target date is greater than the picker's
|
325
|
+
# maximum date.
|
326
|
+
# @raise [RuntimeError] If the target date is less than the picker's
|
327
|
+
# minimum date
|
328
|
+
# @raise [ArgumentError] If the target date is not a DateTime instance.
|
329
|
+
def picker_set_date_time_in(query, date_time)
|
330
|
+
unless date_time.is_a?(DateTime)
|
331
|
+
raise ArgumentError,
|
332
|
+
"Date time argument '#{date_time}' must be a DateTime but found '#{date_time.class}'"
|
333
|
+
end
|
334
|
+
|
335
|
+
Query.ensure_valid_query(query)
|
336
|
+
|
337
|
+
message = "Timed out waiting for UIDatePicker with '#{query}'"
|
338
|
+
|
339
|
+
wait_for(message) do
|
340
|
+
result = query(query)
|
341
|
+
if result.length > 1
|
342
|
+
fail("Query '#{query}' matched more than on UIDatePicker")
|
343
|
+
else
|
344
|
+
!result.empty?
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
if countdown_mode?(query)
|
349
|
+
message =
|
350
|
+
[
|
351
|
+
"Query '#{query}' matched a picker in countdown mode.",
|
352
|
+
'Setting the date or time on a countdown picker is not supported'
|
353
|
+
].join("\n")
|
354
|
+
fail(message)
|
355
|
+
end
|
356
|
+
|
357
|
+
minimum_date = minimum_date_time_from_picker(query)
|
358
|
+
if !minimum_date.nil? && minimum_date > date_time
|
359
|
+
message = [
|
360
|
+
"Cannot set the date on the picker matched by '#{query}'",
|
361
|
+
"Picker minimum date: '#{minimum_date}'",
|
362
|
+
" Date to change to: '#{date_time}'",
|
363
|
+
"Target date comes before the minimum date."].join("\n")
|
364
|
+
fail(message)
|
365
|
+
end
|
366
|
+
|
367
|
+
maximum_date = maximum_date_time_from_picker(query)
|
368
|
+
if !maximum_date.nil? && maximum_date < date_time
|
369
|
+
message = [
|
370
|
+
"Cannot set the date on the picker matched by '#{query}'",
|
371
|
+
"Picker maximum date: '#{maximum_date}'",
|
372
|
+
" Date to change to: '#{date_time}'",
|
373
|
+
"Target date comes after the maximum date."].join("\n")
|
374
|
+
fail(message)
|
375
|
+
end
|
376
|
+
|
377
|
+
ruby_format = date_picker_ruby_date_format
|
378
|
+
objc_format = date_picker_objc_date_format
|
379
|
+
target_date_string = date_time.strftime(ruby_format).squeeze(' ').strip
|
380
|
+
|
381
|
+
Device.default.map_route(query,
|
382
|
+
:changeDatePickerDate,
|
383
|
+
target_date_string,
|
384
|
+
objc_format,
|
385
|
+
# notify targets
|
386
|
+
true,
|
387
|
+
# animate
|
388
|
+
true)
|
389
|
+
end
|
390
|
+
|
391
|
+
private
|
392
|
+
|
393
|
+
# @!visibility private
|
394
|
+
OBJC_DATE_AND_TIME_FMT = 'yyyy_MM_dd_HH_mm'
|
395
|
+
|
396
|
+
# @!visibility private
|
397
|
+
RUBY_DATE_AND_TIME_FMT = '%Y_%m_%d_%H_%M'
|
398
|
+
|
399
|
+
# UIDatePicker modes
|
400
|
+
|
401
|
+
# @!visibility private
|
402
|
+
UI_DATE_PICKER_MODE_TIME = 0
|
403
|
+
# @!visibility private
|
404
|
+
UI_DATE_PICKER_MODE_DATE = 1
|
405
|
+
# @!visibility private
|
406
|
+
UI_DATE_PICKER_MODE_DATE_AND_TIME = 2
|
407
|
+
# @!visibility private
|
408
|
+
UI_DATE_PICKER_MODE_COUNT_DOWN_TIMER = 3
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|