calabash 1.2.1 → 1.9.9.pre1
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/CONTRIBUTING.md +39 -0
- data/LICENSE +204 -21
- data/README.md +36 -6
- data/VERSIONING.md +16 -0
- data/bin/calabash +95 -0
- data/lib/calabash.rb +185 -1
- data/lib/calabash/android.rb +64 -0
- data/lib/calabash/android/adb.rb +277 -0
- data/lib/calabash/android/application.rb +110 -0
- data/lib/calabash/android/build.rb +12 -0
- data/lib/calabash/android/build/application.rb +13 -0
- data/lib/calabash/android/build/build_error.rb +11 -0
- data/lib/calabash/android/build/builder.rb +119 -0
- data/lib/calabash/android/build/java_keystore.rb +177 -0
- data/lib/calabash/android/build/resigner.rb +56 -0
- data/lib/calabash/android/build/test_server.rb +27 -0
- data/lib/calabash/android/console_helpers.rb +44 -0
- data/lib/calabash/android/cucumber.rb +3 -0
- data/lib/calabash/android/device.rb +965 -0
- data/lib/calabash/android/environment.rb +470 -0
- data/lib/calabash/android/gestures.rb +369 -0
- data/lib/calabash/android/interactions.rb +45 -0
- data/lib/calabash/android/lib/.irbrc +55 -0
- data/lib/calabash/android/lib/AndroidManifest.xml +51 -0
- data/lib/calabash/android/lib/TestServer.apk +0 -0
- data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/armeabi/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/armeabi/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/mips/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/mips/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/mips64/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/mips64/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/x86/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/x86/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/x86_64/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/x86_64/calmd5-pie +0 -0
- data/lib/calabash/android/lib/screenshot_taker.jar +0 -0
- data/lib/calabash/android/life_cycle.rb +37 -0
- data/lib/calabash/android/orientation.rb +30 -0
- data/lib/calabash/android/physical_buttons.rb +39 -0
- data/lib/calabash/android/screenshot.rb +9 -0
- data/lib/calabash/android/scroll.rb +5 -0
- data/lib/calabash/android/server.rb +10 -0
- data/lib/calabash/android/text.rb +54 -0
- data/lib/calabash/application.rb +74 -0
- data/lib/calabash/cli.rb +12 -0
- data/lib/calabash/cli/build.rb +33 -0
- data/lib/calabash/cli/console.rb +90 -0
- data/lib/calabash/cli/generate.rb +110 -0
- data/lib/calabash/cli/helpers.rb +130 -0
- data/lib/calabash/cli/resign.rb +33 -0
- data/lib/calabash/cli/run.rb +99 -0
- data/lib/calabash/cli/setup_keystore.rb +39 -0
- data/lib/calabash/color.rb +32 -0
- data/lib/calabash/console_helpers.rb +90 -0
- data/lib/calabash/defaults.rb +56 -0
- data/lib/calabash/device.rb +401 -0
- data/lib/calabash/environment.rb +75 -0
- data/lib/calabash/gestures.rb +384 -0
- data/lib/calabash/http.rb +8 -0
- data/lib/calabash/http/error.rb +15 -0
- data/lib/calabash/http/request.rb +42 -0
- data/lib/calabash/http/retriable_client.rb +156 -0
- data/lib/calabash/interactions.rb +105 -0
- data/lib/calabash/ios.rb +37 -0
- data/lib/calabash/ios/application.rb +119 -0
- data/lib/calabash/ios/conditions.rb +79 -0
- data/lib/calabash/ios/console_helpers.rb +72 -0
- data/lib/calabash/ios/device.rb +24 -0
- data/lib/calabash/ios/device/device_implementation.rb +779 -0
- data/lib/calabash/ios/device/gestures_mixin.rb +167 -0
- data/lib/calabash/ios/device/keyboard_mixin.rb +133 -0
- data/lib/calabash/ios/device/physical_device_mixin.rb +266 -0
- data/lib/calabash/ios/device/rotation_mixin.rb +124 -0
- data/lib/calabash/ios/device/routes/backdoor_route_mixin.rb +86 -0
- data/lib/calabash/ios/device/routes/condition_route_mixin.rb +62 -0
- data/lib/calabash/ios/device/routes/error.rb +8 -0
- data/lib/calabash/ios/device/routes/handle_route_mixin.rb +102 -0
- data/lib/calabash/ios/device/routes/map_route_mixin.rb +38 -0
- data/lib/calabash/ios/device/routes/playback_route_mixin.rb +70 -0
- data/lib/calabash/ios/device/routes/response_parser.rb +48 -0
- data/lib/calabash/ios/device/routes/uia_route_mixin.rb +238 -0
- data/lib/calabash/ios/device/runtime_attributes.rb +184 -0
- data/lib/calabash/ios/device/status_bar_mixin.rb +17 -0
- data/lib/calabash/ios/device/text_mixin.rb +19 -0
- data/lib/calabash/ios/device/uia_keyboard_mixin.rb +188 -0
- data/lib/calabash/ios/device/uia_mixin.rb +12 -0
- data/lib/calabash/ios/environment.rb +41 -0
- data/lib/calabash/ios/interactions.rb +10 -0
- data/lib/calabash/ios/lib/.irbrc +55 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_down_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_down_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_left_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_left_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_right_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_right_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_up_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_up_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_down_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_down_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_left_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_left_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_right_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_right_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_up_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_up_iphone.base64 +2 -0
- data/lib/calabash/ios/orientation.rb +117 -0
- data/lib/calabash/ios/scroll.rb +504 -0
- data/lib/calabash/ios/server.rb +73 -0
- data/lib/calabash/ios/text.rb +248 -0
- data/lib/calabash/ios/uia.rb +24 -0
- data/lib/calabash/lib/skeleton/config/cucumber.yml +6 -0
- data/lib/calabash/lib/skeleton/features/sample.feature +5 -0
- data/lib/calabash/lib/skeleton/features/step_definitions/calabash_steps.rb +29 -0
- data/lib/calabash/lib/skeleton/features/support/env.rb +54 -0
- data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
- data/lib/calabash/life_cycle.rb +111 -0
- data/lib/calabash/location.rb +51 -0
- data/lib/calabash/logger.rb +87 -0
- data/lib/calabash/orientation.rb +84 -0
- data/lib/calabash/page.rb +35 -0
- data/lib/calabash/patch.rb +14 -0
- data/lib/calabash/patch/array.rb +16 -0
- data/lib/calabash/patch/run_loop.rb +90 -0
- data/lib/calabash/query.rb +160 -0
- data/lib/calabash/query_result.rb +85 -0
- data/lib/calabash/screenshot.rb +89 -0
- data/lib/calabash/server.rb +16 -0
- data/lib/calabash/text.rb +76 -0
- data/lib/calabash/utility.rb +58 -0
- data/lib/calabash/version.rb +3 -1
- data/lib/calabash/wait.rb +474 -0
- metadata +462 -24
@@ -0,0 +1,160 @@
|
|
1
|
+
module Calabash
|
2
|
+
|
3
|
+
# A representation of a Calabash query.
|
4
|
+
# @todo Query needs more documentation.
|
5
|
+
# @todo Query needs some methods moved to private or doc'd private.
|
6
|
+
class Query
|
7
|
+
# @!visibility private
|
8
|
+
def self.web_query?(query_string)
|
9
|
+
# :no, :double or :single
|
10
|
+
in_quotes = :no
|
11
|
+
|
12
|
+
# Number of slashes before the current char
|
13
|
+
slash_count = 0
|
14
|
+
|
15
|
+
# If the query starts with css: or xpath:
|
16
|
+
# We could change the regex from /(\s|\'|\")css:/ to /(^|\s|\'|\")css:/
|
17
|
+
# and change if (query[i, indicator[:length]] =~ indicator[:regex]) == 0
|
18
|
+
# to if (query[0, i+indicator[:length]] =~ indicator[:regex]) == i
|
19
|
+
# (not working)
|
20
|
+
# to avoid having to do this check.
|
21
|
+
results = WEB_QUERY_INDICATORS.map do |indicator|
|
22
|
+
query_string =~ /^\s*#{indicator[:string]}/
|
23
|
+
end
|
24
|
+
|
25
|
+
if results.any?
|
26
|
+
return true
|
27
|
+
end
|
28
|
+
|
29
|
+
length = query_string.length
|
30
|
+
|
31
|
+
length.times do |i|
|
32
|
+
char = query_string[i]
|
33
|
+
|
34
|
+
if char == "\\"
|
35
|
+
slash_count += 1
|
36
|
+
next
|
37
|
+
end
|
38
|
+
|
39
|
+
if char == "'"
|
40
|
+
if slash_count == 0
|
41
|
+
if in_quotes == :no
|
42
|
+
in_quotes = :single
|
43
|
+
elsif in_quotes == :single
|
44
|
+
in_quotes = :no
|
45
|
+
end
|
46
|
+
end
|
47
|
+
elsif char == '"'
|
48
|
+
if slash_count == 0
|
49
|
+
if in_quotes == :no
|
50
|
+
in_quotes = :double
|
51
|
+
elsif in_quotes == :double
|
52
|
+
in_quotes = :no
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if slash_count == 0 && in_quotes == :no
|
58
|
+
WEB_QUERY_INDICATORS.each do |indicator|
|
59
|
+
if (query_string[i, indicator[:length]] =~ indicator[:regex]) == 0
|
60
|
+
return true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
slash_count = 0
|
66
|
+
end
|
67
|
+
|
68
|
+
false
|
69
|
+
end
|
70
|
+
|
71
|
+
# @!visibility private
|
72
|
+
def self.query_hash_to_string(hash)
|
73
|
+
result = hash.fetch(:class, '*')
|
74
|
+
|
75
|
+
if hash[:marked] && (hash[:id] || hash[:text])
|
76
|
+
raise 'Cannot use both marked and id/text'
|
77
|
+
end
|
78
|
+
|
79
|
+
if hash[:marked]
|
80
|
+
result = "#{result} marked:'#{Text.escape_single_quotes(hash[:marked])}'"
|
81
|
+
end
|
82
|
+
|
83
|
+
if hash[:id]
|
84
|
+
result = "#{result} id:'#{Text.escape_single_quotes(hash[:id])}'"
|
85
|
+
end
|
86
|
+
|
87
|
+
if hash[:text]
|
88
|
+
result = "#{result} text:'#{Text.escape_single_quotes(hash[:text])}'"
|
89
|
+
end
|
90
|
+
|
91
|
+
if hash[:index]
|
92
|
+
result = "#{result} index:#{hash[:index]}"
|
93
|
+
end
|
94
|
+
|
95
|
+
if hash[:css]
|
96
|
+
result = "#{result} css:'#{Text.escape_single_quotes(hash[:css])}'"
|
97
|
+
end
|
98
|
+
|
99
|
+
if hash[:xpath]
|
100
|
+
result = "#{result} xpath:'#{Text.escape_single_quotes(hash[:xpath])}'"
|
101
|
+
end
|
102
|
+
|
103
|
+
result
|
104
|
+
end
|
105
|
+
|
106
|
+
def initialize(query)
|
107
|
+
unless query.is_a?(Query) || query.is_a?(Hash) || query.is_a?(String)
|
108
|
+
raise ArgumentError, "Invalid argument for query: '#{query}' (#{query.class})"
|
109
|
+
end
|
110
|
+
|
111
|
+
@query = query.dup
|
112
|
+
|
113
|
+
freeze
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_s
|
117
|
+
if @query.is_a?(Query)
|
118
|
+
@query.to_s
|
119
|
+
elsif @query.is_a?(Hash)
|
120
|
+
Query.query_hash_to_string(@query)
|
121
|
+
else
|
122
|
+
@query.dup
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def inspect
|
127
|
+
"<Calabash::Query #{@query.inspect}>"
|
128
|
+
end
|
129
|
+
|
130
|
+
def web_query?
|
131
|
+
Query.web_query?(to_s)
|
132
|
+
end
|
133
|
+
|
134
|
+
WEB_QUERY_INDICATORS =
|
135
|
+
[
|
136
|
+
{
|
137
|
+
string: 'css:',
|
138
|
+
regex: /(\s|\'|\")css:/,
|
139
|
+
length: 5
|
140
|
+
},
|
141
|
+
{
|
142
|
+
string: 'xpath:',
|
143
|
+
regex: /(\s|\'|\")xpath:/,
|
144
|
+
length: 7
|
145
|
+
}
|
146
|
+
]
|
147
|
+
|
148
|
+
# @!visibility private
|
149
|
+
def self.valid_query?(query)
|
150
|
+
query.is_a?(String) || query.is_a?(Hash) || query.is_a?(Query)
|
151
|
+
end
|
152
|
+
|
153
|
+
# @!visibility private
|
154
|
+
def self.ensure_valid_query(query)
|
155
|
+
unless valid_query?(query)
|
156
|
+
raise ArgumentError, "invalid query '#{query}' (#{query.class})"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Calabash
|
2
|
+
# A QueryResult represents the returned value of a query.
|
3
|
+
# It is an immutable collection of matches or the result of applied methods.
|
4
|
+
# It will, unlike `Array`, raise an IndexError instead of returning nil if
|
5
|
+
# an entry outside bounds is accessed.
|
6
|
+
class QueryResult < Array
|
7
|
+
def self.create(result, query)
|
8
|
+
query_result = QueryResult.send(:new, query)
|
9
|
+
query_result.send(:initialize_copy, result)
|
10
|
+
recursive_freeze(query_result)
|
11
|
+
query_result
|
12
|
+
end
|
13
|
+
|
14
|
+
private_class_method :new
|
15
|
+
|
16
|
+
attr_reader :query
|
17
|
+
|
18
|
+
def initialize(query)
|
19
|
+
@query = Query.new(query)
|
20
|
+
end
|
21
|
+
|
22
|
+
def first(*several_variants)
|
23
|
+
ensure_in_bounds(0)
|
24
|
+
|
25
|
+
super(*several_variants)
|
26
|
+
end
|
27
|
+
|
28
|
+
def last(*several_variants)
|
29
|
+
ensure_in_bounds(-1)
|
30
|
+
|
31
|
+
super(*several_variants)
|
32
|
+
end
|
33
|
+
|
34
|
+
def [](index)
|
35
|
+
ensure_in_bounds(index)
|
36
|
+
|
37
|
+
super(index)
|
38
|
+
end
|
39
|
+
|
40
|
+
def at(index)
|
41
|
+
ensure_in_bounds(index)
|
42
|
+
|
43
|
+
super(index)
|
44
|
+
end
|
45
|
+
|
46
|
+
def fetch(*several_variants)
|
47
|
+
unless block_given? || several_variants.length > 1
|
48
|
+
ensure_in_bounds(several_variants.first)
|
49
|
+
end
|
50
|
+
|
51
|
+
super(*several_variants)
|
52
|
+
end
|
53
|
+
|
54
|
+
def ensure_in_bounds(index)
|
55
|
+
if empty?
|
56
|
+
raise IndexError, "Query result is empty"
|
57
|
+
end
|
58
|
+
|
59
|
+
if index > 0 && index >= length
|
60
|
+
raise IndexError, "Index out of bounds [index: #{index}, length: #{length}]"
|
61
|
+
end
|
62
|
+
|
63
|
+
if index < 0 && -index > length
|
64
|
+
raise IndexError, "Index out of bounds [index: #{index}, length: #{length}]"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.recursive_freeze(object)
|
69
|
+
if object.is_a?(Array)
|
70
|
+
object.each do |entry|
|
71
|
+
recursive_freeze(entry)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
if object.is_a?(Hash)
|
76
|
+
object.each do |key, value|
|
77
|
+
recursive_freeze(key)
|
78
|
+
recursive_freeze(value)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
object.freeze
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module Calabash
|
5
|
+
|
6
|
+
# A public API for taking screenshots.
|
7
|
+
module Screenshot
|
8
|
+
# @!visibility private
|
9
|
+
def self.screenshot_directory_prefix
|
10
|
+
@@screenshot_directory_prefix
|
11
|
+
end
|
12
|
+
|
13
|
+
# Set the screenshot directory prefix.
|
14
|
+
def self.screenshot_directory_prefix=(value)
|
15
|
+
if class_variable_defined?(:@@screenshots_taken) &&
|
16
|
+
@@screenshots_taken != 0
|
17
|
+
raise 'Cannot change the screenshot directory prefix after a screenshot has been taken'
|
18
|
+
end
|
19
|
+
|
20
|
+
@@screenshot_directory_prefix = value
|
21
|
+
end
|
22
|
+
|
23
|
+
# @!visibility private
|
24
|
+
self.screenshot_directory_prefix = 'test_run_'
|
25
|
+
|
26
|
+
# Takes a screenshot and saves it. The file is stored in the directory
|
27
|
+
# given by the ENV variable $CAL_SCREENSHOT_DIR, or by default in
|
28
|
+
# the relative directory 'screenshots'. The files are saved in a
|
29
|
+
# sub directory named test_run_n, where n is unique and incrementing for
|
30
|
+
# each new test run. The filename of the screenshot will be `name`.
|
31
|
+
# If `name` is not given (nil), the screenshot will be saved as
|
32
|
+
# screenshot_N, where N is the total amount of screenshots taken for the
|
33
|
+
# test run.
|
34
|
+
#
|
35
|
+
# @param [String] name Name of the screenshot.
|
36
|
+
# @return [String] Path to the screenshot
|
37
|
+
def screenshot(name=nil)
|
38
|
+
Device.default.screenshot(name)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Takes a screenshot and embeds it in the test report.
|
42
|
+
# @see Screenshot#screenshot
|
43
|
+
def screenshot_embed(name=nil)
|
44
|
+
path = screenshot(name)
|
45
|
+
embed(path, 'image/png', name || File.basename(path))
|
46
|
+
end
|
47
|
+
|
48
|
+
# @!visibility private
|
49
|
+
def self.obtain_screenshot_path!(name=nil)
|
50
|
+
@@screenshots_taken ||= 1
|
51
|
+
|
52
|
+
if name.nil?
|
53
|
+
name = "screenshot_#{@@screenshots_taken}.png"
|
54
|
+
end
|
55
|
+
|
56
|
+
name = "#{name}.png" if File.extname(name).empty?
|
57
|
+
|
58
|
+
@@screenshots_taken += 1
|
59
|
+
|
60
|
+
unless Dir.exist?(File.expand_path(screenshot_directory))
|
61
|
+
FileUtils.mkdir_p(File.expand_path(screenshot_directory))
|
62
|
+
end
|
63
|
+
|
64
|
+
File.join(screenshot_directory, name)
|
65
|
+
end
|
66
|
+
|
67
|
+
# @!visibility private
|
68
|
+
def self.screenshot_directory
|
69
|
+
@@screenshot_directory ||= new_screenshot_sub_directory
|
70
|
+
end
|
71
|
+
|
72
|
+
# @!visibility private
|
73
|
+
def self.new_screenshot_sub_directory
|
74
|
+
count = screenshot_directory_test_run_directories.count
|
75
|
+
File.join(Environment::SCREENSHOT_DIRECTORY,
|
76
|
+
"#{screenshot_directory_prefix}#{count+1}")
|
77
|
+
end
|
78
|
+
|
79
|
+
# @!visibility private
|
80
|
+
def self.screenshot_directory_test_run_directories
|
81
|
+
dir = File.expand_path(File.join(Environment::SCREENSHOT_DIRECTORY, '*'))
|
82
|
+
|
83
|
+
Dir.glob(dir).select do |file|
|
84
|
+
File.directory?(file) &&
|
85
|
+
File.basename(file) =~ /^#{screenshot_directory_prefix}\d+$/
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Calabash
|
2
|
+
|
3
|
+
# A representation of the Calabash test server.
|
4
|
+
class Server
|
5
|
+
attr_reader :endpoint
|
6
|
+
attr_reader :test_server_port
|
7
|
+
|
8
|
+
# @param [URI] endpoint The endpoint to reach the test server.
|
9
|
+
# @param [Integer] test_server_port The port bound to the test server
|
10
|
+
# running on the device. On iOS this is same as the endpoint port.
|
11
|
+
def initialize(endpoint, test_server_port = nil)
|
12
|
+
@endpoint = endpoint
|
13
|
+
@test_server_port = test_server_port || endpoint.port
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Calabash
|
2
|
+
|
3
|
+
# A public API for entering text.
|
4
|
+
module Text
|
5
|
+
# Enter `text` into the currently focused view.
|
6
|
+
#
|
7
|
+
# @param [String] text The text to type.
|
8
|
+
# @raise [RuntimeError] if the text cannot be typed.
|
9
|
+
def enter_text(text)
|
10
|
+
Device.default.enter_text(text)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Enter `text` into `query`.
|
14
|
+
# @see Calabash::Text#enter_text
|
15
|
+
#
|
16
|
+
# @param [String] text The text to type.
|
17
|
+
# @param query A query describing the view to enter text into.
|
18
|
+
def enter_text_in(query, text)
|
19
|
+
_enter_text_in(query, text)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Clears the text of the currently focused view.
|
23
|
+
def clear_text
|
24
|
+
_clear_text
|
25
|
+
end
|
26
|
+
|
27
|
+
# Clears the text `view`
|
28
|
+
# @see Calabash::Text#clear_text
|
29
|
+
#
|
30
|
+
# @param query A query describing the view to clear text in.
|
31
|
+
def clear_text_in(view)
|
32
|
+
_clear_text_in(view)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @todo add docs
|
36
|
+
def tap_current_keyboard_action_key
|
37
|
+
_tap_current_keyboard_action_key
|
38
|
+
end
|
39
|
+
|
40
|
+
# Escapes single quotes in `string`.
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# > escape_quotes("Let's get this done.")
|
44
|
+
# => "Let\\'s get this done."
|
45
|
+
# @param [String] string The string to escape.
|
46
|
+
# @return [String] A string with its single quotes properly escaped.
|
47
|
+
def escape_single_quotes(string)
|
48
|
+
Text.escape_single_quotes(string)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @!visibility private
|
52
|
+
def _enter_text_in(view, text)
|
53
|
+
abstract_method!
|
54
|
+
end
|
55
|
+
|
56
|
+
# @!visibility private
|
57
|
+
def _clear_text
|
58
|
+
abstract_method!
|
59
|
+
end
|
60
|
+
|
61
|
+
# @!visibility private
|
62
|
+
def _clear_text_in(view)
|
63
|
+
abstract_method!
|
64
|
+
end
|
65
|
+
|
66
|
+
# @!visibility private
|
67
|
+
def _tap_current_keyboard_action_key
|
68
|
+
abstract_method!
|
69
|
+
end
|
70
|
+
|
71
|
+
# @!visibility private
|
72
|
+
def self.escape_single_quotes(string)
|
73
|
+
string.gsub("'", "\\\\'")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Calabash
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
class AbstractMethodError < StandardError
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
module Utility
|
9
|
+
|
10
|
+
# @!visibility private
|
11
|
+
def abstract_method!
|
12
|
+
method_name = if Kernel.method_defined?(:caller_locations)
|
13
|
+
caller_locations.first.label
|
14
|
+
else
|
15
|
+
caller.first[/\`(.*)\'/, 1]
|
16
|
+
end
|
17
|
+
|
18
|
+
raise AbstractMethodError.new("Abstract method '#{method_name}'")
|
19
|
+
end
|
20
|
+
|
21
|
+
# @! visibility private
|
22
|
+
class RetryError < RuntimeError; end
|
23
|
+
|
24
|
+
# A convenience method for creating a percentage hash that that can be
|
25
|
+
# passed to gestures.
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# # These are equivalent.
|
29
|
+
# pan(percent(20, 50), percent(20, 100))
|
30
|
+
# pan({x: 20, y: 50}, {x: 20, y: 100})
|
31
|
+
#
|
32
|
+
# @param [Number] x The value of the x percent.
|
33
|
+
# @param [Number] y The value of the y percent.
|
34
|
+
# @return [Hash] Representing the given values.
|
35
|
+
def percent(x, y)
|
36
|
+
{x: x, y: y}
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method :pct, :percent
|
40
|
+
|
41
|
+
# A convenience method for creating a coordinate hash that that can be
|
42
|
+
# passed to gestures.
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# # These are equivalent.
|
46
|
+
# tap(query, offset: coordinate(20, 50))
|
47
|
+
# tap(query, offset: {x: 20, y: 50})
|
48
|
+
#
|
49
|
+
# @param [Number] x The value of the x.
|
50
|
+
# @param [Number] y The value of the y.
|
51
|
+
# @return [Hash] Representing the given values.
|
52
|
+
def coordinate(x, y)
|
53
|
+
{x: x, y: y}
|
54
|
+
end
|
55
|
+
|
56
|
+
alias_method :coord, :coordinate
|
57
|
+
end
|
58
|
+
end
|