calabash 1.2.1 → 1.9.9.pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|