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,15 @@
|
|
1
|
+
module Calabash
|
2
|
+
module HTTP
|
3
|
+
|
4
|
+
# Raised when there is a problem communicating with the Calabash test
|
5
|
+
# server.
|
6
|
+
class Error < StandardError
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
# Raised when there is a problem creating an HTTP request.
|
11
|
+
class RequestError < StandardError
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Calabash
|
2
|
+
module HTTP
|
3
|
+
|
4
|
+
# A representation of an HTTP request that can be passed passed to the HTTP
|
5
|
+
# client as an argument for `get` or `post`.
|
6
|
+
class Request
|
7
|
+
attr_reader :route, :params
|
8
|
+
|
9
|
+
def initialize(route, params={})
|
10
|
+
@route = route
|
11
|
+
@params = params
|
12
|
+
end
|
13
|
+
|
14
|
+
# Create a new Request from `route` and `parameters`.
|
15
|
+
#
|
16
|
+
# @param [String] route The http route for the new request.
|
17
|
+
# @param [Array, Hash] parameters An Array or Hash of parameters.
|
18
|
+
# @return [Request] A new Request for `route` with `parameters`.
|
19
|
+
# @raise [RequestError] Raises an error if the parameters cannot be
|
20
|
+
# converted to JSON
|
21
|
+
def self.request(route, parameters)
|
22
|
+
Request.new(route, Request.data(parameters))
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Converts `parameters` to JSON.
|
28
|
+
#
|
29
|
+
# @param [Array, Hash] parameters An Array or Hash of parameters.
|
30
|
+
# @return [String] A JSON formatted string that represents the parameters.
|
31
|
+
# @raise [RequestError] Raises an error if the parameters cannot be
|
32
|
+
# converted to JSON
|
33
|
+
def self.data(parameters)
|
34
|
+
begin
|
35
|
+
JSON.generate(parameters)
|
36
|
+
rescue *[TypeError, JSON::GeneratorError] => e
|
37
|
+
raise RequestError, "#{e}: could not generate JSON from '#{parameters}'"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'httpclient'
|
2
|
+
|
3
|
+
module Calabash
|
4
|
+
module HTTP
|
5
|
+
|
6
|
+
# An HTTP client that retries its connection on errors and can time out.
|
7
|
+
class RetriableClient
|
8
|
+
attr_reader :client
|
9
|
+
|
10
|
+
# @!visibility private
|
11
|
+
RETRY_ON =
|
12
|
+
[
|
13
|
+
# The connection, request, or response timed out
|
14
|
+
#HTTPClient::TimeoutError,
|
15
|
+
# The proxy could not connect to the server (Android)
|
16
|
+
# or the server is not running (iOS)
|
17
|
+
HTTPClient::KeepAliveDisconnected,
|
18
|
+
# No proxy has been set up (Android)
|
19
|
+
Errno::ECONNREFUSED,
|
20
|
+
# The server sent a partial response
|
21
|
+
#Errno::ECONNRESET,
|
22
|
+
# Client sent TCP reset (RST) before server has accepted the
|
23
|
+
# connection requested by client.
|
24
|
+
Errno::ECONNABORTED,
|
25
|
+
# The foreign function call call timed out
|
26
|
+
#Errno::ETIMEDOUT
|
27
|
+
]
|
28
|
+
|
29
|
+
# @!visibility private
|
30
|
+
HEADER =
|
31
|
+
{
|
32
|
+
'Content-Type' => 'application/json;charset=utf-8'
|
33
|
+
}
|
34
|
+
|
35
|
+
# Creates a new retriable client.
|
36
|
+
#
|
37
|
+
# This initializer takes multiple options. If the option is not
|
38
|
+
# documented, it should be considered _private_. You use undocumented
|
39
|
+
# options at your own risk.
|
40
|
+
#
|
41
|
+
# @param [Calabash::Server] server The server to make the HTTP request
|
42
|
+
# on.
|
43
|
+
# @param [Hash] options Control the retry, timeout, and interval.
|
44
|
+
# @option options [Number] :retries (5) How often to retry.
|
45
|
+
# @option options [Number] :timeout (5) How long to wait for a response
|
46
|
+
# before timing out.
|
47
|
+
# @option options [Number] :interval (0.5) How long to sleep between
|
48
|
+
# retries.
|
49
|
+
def initialize(server, options = {})
|
50
|
+
@client = options[:client] || ::HTTPClient.new
|
51
|
+
@server = server
|
52
|
+
@retries = options.fetch(:retries, 5)
|
53
|
+
@timeout = options.fetch(:timeout, 5)
|
54
|
+
@interval = options.fetch(:interval, 0.5)
|
55
|
+
@logger = options[:logger] || Calabash::Logger.new
|
56
|
+
@on_error = {}
|
57
|
+
end
|
58
|
+
|
59
|
+
def on_error(type, &block)
|
60
|
+
@on_error[type] = block
|
61
|
+
end
|
62
|
+
|
63
|
+
def change_server(new_server)
|
64
|
+
@server = new_server
|
65
|
+
end
|
66
|
+
|
67
|
+
# Make an HTTP get request.
|
68
|
+
#
|
69
|
+
# This method takes multiple options. If the option is not documented,
|
70
|
+
# it should be considered _private_. You use undocumented options at
|
71
|
+
# your own risk.
|
72
|
+
#
|
73
|
+
# @param [Calabash::HTTP::Request] request The request.
|
74
|
+
# @param [Hash] options Control the retry, timeout, and interval.
|
75
|
+
# @option options [Number] :retries (5) How often to retry.
|
76
|
+
# @option options [Number] :timeout (5) How long to wait for a response
|
77
|
+
# before timing out.
|
78
|
+
# @option options [Number] :interval (0.5) How long to sleep between
|
79
|
+
# retries.
|
80
|
+
def get(request, options={})
|
81
|
+
request(request, :get, options)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Make an HTTP post request.
|
85
|
+
#
|
86
|
+
# This method takes multiple options. If the option is not documented,
|
87
|
+
# it should be considered _private_. You use undocumented options at
|
88
|
+
# your own risk.
|
89
|
+
#
|
90
|
+
# @param [Calabash::HTTP::Request] request The request.
|
91
|
+
# @param [Hash] options Control the retry, timeout, and interval.
|
92
|
+
# @option options [Number] :retries (5) How often to retry.
|
93
|
+
# @option options [Number] :timeout (5) How long to wait for a response
|
94
|
+
# before timing out.
|
95
|
+
# @option options [Number] :interval (0.5) How long to sleep between
|
96
|
+
# retries.
|
97
|
+
def post(request, options={})
|
98
|
+
request(request, :post, options)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def request(request, request_method, options={})
|
104
|
+
retries = options.fetch(:retries, @retries)
|
105
|
+
timeout = options.fetch(:timeout, @timeout)
|
106
|
+
interval = options.fetch(:interval, @interval)
|
107
|
+
header = options.fetch(:header, HEADER)
|
108
|
+
|
109
|
+
@logger.log "Getting: #{@server.endpoint + request.route}"
|
110
|
+
|
111
|
+
start_time = Time.now
|
112
|
+
last_error = nil
|
113
|
+
|
114
|
+
client = @client.dup
|
115
|
+
client.receive_timeout = timeout
|
116
|
+
|
117
|
+
retries.times do |i|
|
118
|
+
first_try = i == 0
|
119
|
+
|
120
|
+
# Subtract the aggregate time we've spent thus far to make sure we're
|
121
|
+
# not exceeding the request timeout across retries.
|
122
|
+
time_diff = start_time + timeout - Time.now
|
123
|
+
|
124
|
+
if time_diff <= 0
|
125
|
+
raise HTTP::Error, 'Timeout exceeded'
|
126
|
+
end
|
127
|
+
|
128
|
+
client.receive_timeout = [time_diff, client.receive_timeout].min
|
129
|
+
|
130
|
+
begin
|
131
|
+
return client.send(request_method, @server.endpoint + request.route,
|
132
|
+
request.params, header)
|
133
|
+
rescue *RETRY_ON => e
|
134
|
+
@logger.log "Http error: #{e}"
|
135
|
+
|
136
|
+
if first_try
|
137
|
+
if @on_error[e.class]
|
138
|
+
@on_error[e.class].call(@server)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
last_error = e
|
143
|
+
sleep interval
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# We should raise helpful messages
|
148
|
+
if last_error.is_a?(HTTPClient::KeepAliveDisconnected)
|
149
|
+
raise HTTP::Error, "#{last_error}: It is likely your application has crashed"
|
150
|
+
end
|
151
|
+
|
152
|
+
raise HTTP::Error, last_error
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Calabash
|
2
|
+
module Interactions
|
3
|
+
# @todo Needs docs!
|
4
|
+
def query(query, *args)
|
5
|
+
Calabash::Device.default.map_route(Query.new(query), :query, *args)
|
6
|
+
end
|
7
|
+
|
8
|
+
# @todo Needs docs!
|
9
|
+
def flash(query)
|
10
|
+
Calabash::Device.default.map_route(Query.new(query), :flash)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Evaluate javascript in a Web View. On iOS, an implicit return is
|
14
|
+
# inserted, on Android an explicit return is needed.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# # iOS
|
18
|
+
# evaluate_javascript_in("UIWebView", "2+2")
|
19
|
+
# # Android
|
20
|
+
# evaluate_javascript_in("WebView", "return 2+2"
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# # iOS
|
24
|
+
# evaluate_javascript_in("WKWebView",
|
25
|
+
# "document.body.style.backgroundColor = 'red';")
|
26
|
+
#
|
27
|
+
# # Android
|
28
|
+
# evaluate_javascript_in("XWalkContent",
|
29
|
+
# "document.body.style.backgroundColor = 'red';")
|
30
|
+
#
|
31
|
+
# @note No error will be raised if the javascript given is invalid, or
|
32
|
+
# throws an exception.
|
33
|
+
#
|
34
|
+
# @param [String, Hash, Calabash::Query] query Query that matches the view
|
35
|
+
# @param [String] javascript The javascript to evaluate
|
36
|
+
#
|
37
|
+
# @raise ViewNotFoundError If no views are found matching `query`
|
38
|
+
def evaluate_javascript_in(query, javascript)
|
39
|
+
wait_for_view(query,
|
40
|
+
timeout: Calabash::Gestures::DEFAULT_GESTURE_WAIT_TIMEOUT)
|
41
|
+
|
42
|
+
_evaluate_javascript_in(query, javascript)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Invoke a method in your application.
|
46
|
+
#
|
47
|
+
# This is an escape hatch for calling an arbitrary hook inside
|
48
|
+
# (the test build) of your app. Commonly used to "go around" the UI for
|
49
|
+
# speed purposes or reset the app to a good known state.
|
50
|
+
#
|
51
|
+
# For iOS this method calls a method on the app's AppDelegate object.
|
52
|
+
#
|
53
|
+
# For Android this method tries to invoke a method on the current Activity
|
54
|
+
# instance. If the method is not defined in the current activity, Calabash
|
55
|
+
# tries to invoke the method on the current Application instance.
|
56
|
+
#
|
57
|
+
# @note The Android implementation accepts any number of arguments, of any
|
58
|
+
# type including null (Ruby nil). The iOS implementation does not accept
|
59
|
+
# more than one argument, of the type NSString (Ruby String) or
|
60
|
+
# NSDictionary (Ruby Hash).
|
61
|
+
#
|
62
|
+
#
|
63
|
+
# ### For iOS
|
64
|
+
#
|
65
|
+
# You must create a method on you app delegate of the form:
|
66
|
+
#
|
67
|
+
# - (NSString *) calabashBackdoor:(NSString *)aIgnorable;
|
68
|
+
#
|
69
|
+
# or if you want to pass parameters
|
70
|
+
#
|
71
|
+
# - (NSString *) calabashBackdoor:(NSDictionary *)params;
|
72
|
+
#
|
73
|
+
# ### For Android
|
74
|
+
#
|
75
|
+
# You must create a public method in your current Activity or Application.
|
76
|
+
#
|
77
|
+
# public <return type> calabashBackdoor(String param1, int param2)
|
78
|
+
#
|
79
|
+
# @example
|
80
|
+
# # iOS
|
81
|
+
# backdoor('calabashBackdoor:'', '')
|
82
|
+
#
|
83
|
+
# @example
|
84
|
+
# # iOS
|
85
|
+
# backdoor('calabashBackdoor:', {example:'param'})
|
86
|
+
#
|
87
|
+
# @example
|
88
|
+
# # Android
|
89
|
+
# backdoor('calabashBackdoor', 'first argument', 2)
|
90
|
+
#
|
91
|
+
# @param [String] name The selector/method name.
|
92
|
+
# @param [Object] *arguments A comma separated list of arguments to be
|
93
|
+
# passed to the backdoor selector/method.
|
94
|
+
# @return [Object] the result of performing the selector/method with the
|
95
|
+
# arguments (serialized)
|
96
|
+
def backdoor(name, *arguments)
|
97
|
+
Device.default.backdoor(name, *arguments)
|
98
|
+
end
|
99
|
+
|
100
|
+
# @!visibility private
|
101
|
+
def _evaluate_javascript_in(query, javascript)
|
102
|
+
abstract_method!
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/calabash/ios.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Calabash
|
2
|
+
# Contains the iOS implementations of the Calabash APIs.
|
3
|
+
module IOS
|
4
|
+
require 'calabash'
|
5
|
+
include Calabash
|
6
|
+
|
7
|
+
# @!visibility private
|
8
|
+
def self.extended(base)
|
9
|
+
Calabash.send(:extended, base)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @!visibility private
|
13
|
+
def self.included(base)
|
14
|
+
Calabash.send(:included, base)
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'calabash/ios/environment'
|
18
|
+
require 'calabash/ios/application'
|
19
|
+
require 'calabash/ios/device'
|
20
|
+
require 'calabash/ios/conditions'
|
21
|
+
require 'calabash/ios/interactions'
|
22
|
+
require 'calabash/ios/orientation'
|
23
|
+
require 'calabash/ios/server'
|
24
|
+
require 'calabash/ios/text'
|
25
|
+
require 'calabash/ios/console_helpers'
|
26
|
+
require 'calabash/ios/uia'
|
27
|
+
require 'calabash/ios/scroll'
|
28
|
+
|
29
|
+
include Calabash::IOS::Conditions
|
30
|
+
include Calabash::IOS::Orientation
|
31
|
+
include Calabash::IOS::Interactions
|
32
|
+
include Calabash::IOS::Text
|
33
|
+
include Calabash::IOS::UIA
|
34
|
+
include Calabash::IOS::Scroll
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Calabash
|
2
|
+
module IOS
|
3
|
+
|
4
|
+
# A class to represent an iOS application. An application can be a
|
5
|
+
# simulator bundle (.app) or a device binary (.ipa).
|
6
|
+
class Application < Calabash::Application
|
7
|
+
|
8
|
+
# The path to the application under test deduced by analysing the
|
9
|
+
# environment.
|
10
|
+
#
|
11
|
+
# You can control the default application path by setting the `CAL_APP`
|
12
|
+
# environment variable. This is the best way of ensuring Calabash
|
13
|
+
# can find your application.
|
14
|
+
#
|
15
|
+
# @todo We have a chicken and egg problem. If the device under test
|
16
|
+
# is a simulator, we have been analyzing the Xcode or Xamarin Studio
|
17
|
+
# project for the likely location of the .app. I think we still want
|
18
|
+
# to do this. The problem is that Xcode buries the .app in a
|
19
|
+
# DerivedData directory deep in the user's ~/Library/ and the correct
|
20
|
+
# directory path is very difficult to find. I overcome this problem
|
21
|
+
# with command-line build scripts that put the .app (or .ipa) in a
|
22
|
+
# directory local to my project. Others devs use Xcode Custom Build
|
23
|
+
# locations. I don't think we we want to branch here on whether or not
|
24
|
+
# the DEVICE_ID points to a simulator or physical device. This is
|
25
|
+
# wicked expensive.
|
26
|
+
def self.default_from_environment
|
27
|
+
application_path = Environment::APP_PATH
|
28
|
+
|
29
|
+
if application_path.nil?
|
30
|
+
raise 'No application path is set'
|
31
|
+
end
|
32
|
+
|
33
|
+
Application.new(application_path)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Create a new Application.
|
37
|
+
#
|
38
|
+
# @param [String] application_path The path to the ipa or app.
|
39
|
+
# @param [Hash] options Optional arguments.
|
40
|
+
# @option options [Calabash::Logger] :logger An optional logger. It is
|
41
|
+
# not recommended that you set this yourself.
|
42
|
+
# @return [Calabash::IOS::Application] A new application.
|
43
|
+
# @raise [RuntimeError] If the `application_path` does not indicate a
|
44
|
+
# file that exists.
|
45
|
+
# @raise [RuntimeError] If the `application_path` does not end with .ipa
|
46
|
+
# or .app.
|
47
|
+
def initialize(application_path, options = {})
|
48
|
+
super(application_path, options)
|
49
|
+
|
50
|
+
@simulator_bundle = File.extname(path) == '.app'
|
51
|
+
@device_binary = File.extname(path) == '.ipa'
|
52
|
+
|
53
|
+
unless @simulator_bundle || @device_binary
|
54
|
+
raise "Expected #{path} to be an .ipa or .app, but found '#{File.extname(path)}'"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return true if this application is for an iOS Simulator.
|
59
|
+
# @return [Boolean] Is this a .app?
|
60
|
+
def simulator_bundle?
|
61
|
+
@simulator_bundle
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return true if this application is for a physical iOS device.
|
65
|
+
# @return [Boolean] Is this a .ipa?
|
66
|
+
def device_binary?
|
67
|
+
@device_binary
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the sha1 of the directory or binary of this app's path.
|
71
|
+
# @return [String] A checksum.
|
72
|
+
def sha1
|
73
|
+
RunLoop::Directory.directory_digest(path)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Does this app have the same checksum as another app?
|
77
|
+
# @param [Calabash::IOS::Application] other The other app to compare to.
|
78
|
+
# @return [Boolean] Is the checksum the same for the two apps?
|
79
|
+
def same_sha1_as?(other)
|
80
|
+
sha1 == other.sha1
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# @!visibility private
|
86
|
+
def run_loop_ipa
|
87
|
+
@run_loop_ipa ||= lambda do
|
88
|
+
if device_binary?
|
89
|
+
RunLoop::Ipa.new(path)
|
90
|
+
else
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
end.call
|
94
|
+
end
|
95
|
+
|
96
|
+
# @!visibility private
|
97
|
+
def run_loop_app
|
98
|
+
@run_loop_app ||= lambda do
|
99
|
+
if simulator_bundle?
|
100
|
+
RunLoop::App.new(path)
|
101
|
+
else
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
end.call
|
105
|
+
end
|
106
|
+
|
107
|
+
# @!visibility private
|
108
|
+
def extract_identifier
|
109
|
+
if simulator_bundle?
|
110
|
+
run_loop_app.bundle_identifier
|
111
|
+
elsif device_binary?
|
112
|
+
run_loop_ipa.bundle_identifier
|
113
|
+
else
|
114
|
+
raise "Unknown app type '#{File.extname(path)}', cannot extract bundle identifier"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|