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/ios/device.rb
CHANGED
@@ -18,6 +18,7 @@ module Calabash
|
|
18
18
|
require 'calabash/ios/device/uia_keyboard_mixin'
|
19
19
|
require 'calabash/ios/device/text_mixin'
|
20
20
|
require 'calabash/ios/device/uia_mixin'
|
21
|
+
require 'calabash/ios/device/ipad_1x_2x_mixin'
|
21
22
|
require 'calabash/ios/device/device_implementation'
|
22
23
|
|
23
24
|
end
|
@@ -19,7 +19,7 @@ module Calabash
|
|
19
19
|
include Calabash::IOS::UIAKeyboardMixin
|
20
20
|
include Calabash::IOS::TextMixin
|
21
21
|
include Calabash::IOS::UIAMixin
|
22
|
-
|
22
|
+
include Calabash::IOS::IPadMixin
|
23
23
|
include Calabash::IOS::GesturesMixin
|
24
24
|
|
25
25
|
attr_reader :run_loop
|
@@ -78,7 +78,7 @@ module Calabash
|
|
78
78
|
identifier = Environment::DEVICE_IDENTIFIER
|
79
79
|
|
80
80
|
if identifier.nil?
|
81
|
-
connected_devices = RunLoop::
|
81
|
+
connected_devices = RunLoop::Instruments.new.physical_devices
|
82
82
|
if connected_devices.empty?
|
83
83
|
raise 'There are no physical devices connected.'
|
84
84
|
elsif connected_devices.count > 1
|
@@ -339,6 +339,10 @@ module Calabash
|
|
339
339
|
else
|
340
340
|
raise "Invalid application #{application} for iOS platform."
|
341
341
|
end
|
342
|
+
|
343
|
+
# @todo Get the language code from the server!
|
344
|
+
ensure_ipad_emulation_1x
|
345
|
+
|
342
346
|
{
|
343
347
|
:device => self,
|
344
348
|
:application => application,
|
@@ -367,7 +371,7 @@ module Calabash
|
|
367
371
|
|
368
372
|
expect_app_installed_on_simulator(bridge)
|
369
373
|
|
370
|
-
installed_app = Calabash::IOS::Application.new(bridge.
|
374
|
+
installed_app = Calabash::IOS::Application.new(bridge.send(:installed_app_bundle_dir))
|
371
375
|
expect_matching_sha1s(installed_app, application)
|
372
376
|
end
|
373
377
|
|
@@ -468,7 +472,7 @@ module Calabash
|
|
468
472
|
bridge = run_loop_bridge(@run_loop_device, application)
|
469
473
|
|
470
474
|
if bridge.app_is_installed?
|
471
|
-
installed_app = Calabash::IOS::Application.new(bridge.
|
475
|
+
installed_app = Calabash::IOS::Application.new(bridge.send(:installed_app_bundle_dir))
|
472
476
|
|
473
477
|
if installed_app.same_sha1_as?(application)
|
474
478
|
true
|
@@ -571,9 +575,9 @@ module Calabash
|
|
571
575
|
# @!visibility private
|
572
576
|
def uninstall_app_on_simulator(application, run_loop_device, bridge)
|
573
577
|
begin
|
574
|
-
bridge.
|
578
|
+
bridge.uninstall_app_and_sandbox
|
575
579
|
true
|
576
|
-
rescue e
|
580
|
+
rescue => e
|
577
581
|
raise "Could not uninstall #{application.identifier} on #{run_loop_device}: #{e}"
|
578
582
|
end
|
579
583
|
end
|
@@ -599,10 +603,11 @@ module Calabash
|
|
599
603
|
end
|
600
604
|
|
601
605
|
# @!visibility private
|
602
|
-
# Do not memoize this. The
|
606
|
+
# Do not memoize this. The CoreSimulator initializer does a bunch of work to
|
603
607
|
# prepare the environment for simctl actions.
|
604
608
|
def run_loop_bridge(run_loop_simulator_device, application)
|
605
|
-
RunLoop::
|
609
|
+
run_loop_app = RunLoop::App.new(application.path)
|
610
|
+
RunLoop::CoreSimulator.new(run_loop_simulator_device, run_loop_app)
|
606
611
|
end
|
607
612
|
|
608
613
|
# @!visibility private
|
@@ -615,7 +620,7 @@ module Calabash
|
|
615
620
|
bridge = run_loop_bridge
|
616
621
|
end
|
617
622
|
|
618
|
-
bridge.
|
623
|
+
bridge.uninstall_app_and_sandbox
|
619
624
|
bridge.install
|
620
625
|
rescue StandardError => e
|
621
626
|
raise "Could not install #{application} on #{run_loop_device}: #{e}"
|
@@ -635,8 +640,8 @@ module Calabash
|
|
635
640
|
# @!visibility private
|
636
641
|
# Very expensive!
|
637
642
|
def Device.fetch_matching_physical_device(udid_or_name)
|
638
|
-
|
639
|
-
|
643
|
+
instruments = RunLoop::Instruments.new
|
644
|
+
instruments.physical_devices.detect do |device|
|
640
645
|
device.name == udid_or_name ||
|
641
646
|
device.udid == udid_or_name
|
642
647
|
end
|
@@ -0,0 +1,253 @@
|
|
1
|
+
module Calabash
|
2
|
+
module IOS
|
3
|
+
# @!visibility private
|
4
|
+
# Contains methods for interacting with the iPad.
|
5
|
+
module IPadMixin
|
6
|
+
|
7
|
+
# @!visibility private
|
8
|
+
# Provides methods to interact with the 1x and 2x buttons that appear
|
9
|
+
# when an iPhone-only app is emulated on an iPad. Calabash cannot
|
10
|
+
# interact with these apps in 2x mode because the touch coordinates
|
11
|
+
# cannot be reliably translated from normal iPhone dimensions to the
|
12
|
+
# emulated dimensions.
|
13
|
+
#
|
14
|
+
# On iOS < 7, an app _remembered_ its last 1x/2x scale so when it
|
15
|
+
# reopened the previous scale would be the same as when it closed. This
|
16
|
+
# meant you could manually set the scale once to 1x and never have to
|
17
|
+
# interact with the scale button again.
|
18
|
+
#
|
19
|
+
# On iOS > 7, the default behavior is that all emulated apps open at 2x
|
20
|
+
# regardless of their previous scale.
|
21
|
+
#
|
22
|
+
# @note In order to use this class, you must allow Calabash to launch
|
23
|
+
# your app with instruments.
|
24
|
+
class Emulation
|
25
|
+
|
26
|
+
# @!visibility private
|
27
|
+
#
|
28
|
+
# Maintainers: when adding a localization, please notice that
|
29
|
+
# the keys and values are semantically reversed.
|
30
|
+
#
|
31
|
+
# you should read the hash as:
|
32
|
+
#
|
33
|
+
# ```
|
34
|
+
# :emulated_1x <= what button is showing when the app is emulated at 2X?
|
35
|
+
# :emulated_2x <= what button is showing when the app is emulated at 1X?
|
36
|
+
# ```
|
37
|
+
#
|
38
|
+
# @todo Once we have localizations wired up, we can use these keys
|
39
|
+
#
|
40
|
+
# These pull requests describe how to find a key/value pairs from the
|
41
|
+
# on-disk accessibility bundles for _keyboards_ but we can use the same
|
42
|
+
# strategy to look up the Zoom button localizations.
|
43
|
+
#
|
44
|
+
# * https://github.com/calabash/run_loop/pull/197
|
45
|
+
# * https://github.com/calabash/calabash-ios-server/pull/221
|
46
|
+
#
|
47
|
+
#
|
48
|
+
# fullscreen.zoom => 2x => 'Switch to full screen mode'
|
49
|
+
# normal.zoom => 1x => 'Switch to normal mode'
|
50
|
+
#
|
51
|
+
# # We will still need query windows.
|
52
|
+
# uia("UIATarget.localTarget().frontMostApp().windows()[2].elements()[0].label()")
|
53
|
+
IPAD_1X_2X_BUTTON_LABELS = {
|
54
|
+
:en => {:emulated_1x => '2X',
|
55
|
+
:emulated_2x => '1X'}
|
56
|
+
}
|
57
|
+
|
58
|
+
# @!visibility private
|
59
|
+
# @!attribute [r] scale
|
60
|
+
# The current 1X or 2X scale represented as a Symbol.
|
61
|
+
#
|
62
|
+
# @return [Symbol] Returns this emulation's scale. Will be one of
|
63
|
+
# `{:emulated_1x | :emulated_2x}`.
|
64
|
+
attr_reader :scale
|
65
|
+
|
66
|
+
# @!visibility private
|
67
|
+
# @!attribute [r] lang_code
|
68
|
+
# The Apple compatible language code for determining the accessibility
|
69
|
+
# label of the 1X and 2X buttons.
|
70
|
+
#
|
71
|
+
# @return [Symbol] Returns the language code of this emulation.
|
72
|
+
attr_reader :lang_code
|
73
|
+
|
74
|
+
# @!visibility private
|
75
|
+
# @!attribute [r] device
|
76
|
+
# A handle on the default device.
|
77
|
+
attr_reader :device
|
78
|
+
|
79
|
+
# @!visibility private
|
80
|
+
# A private instance variable for storing this emulation's 1X/2X button
|
81
|
+
# names. The value will be set at runtime based on the language code
|
82
|
+
# that is passed the initializer.
|
83
|
+
@button_names_hash = nil
|
84
|
+
|
85
|
+
# @!visibility private
|
86
|
+
# Creates a new Emulation.
|
87
|
+
# @param [Symbol] lang_code an Apple compatible language code
|
88
|
+
# @return [Emulation] Returns an emulation that is ready for action!
|
89
|
+
def initialize (device, lang_code=:en)
|
90
|
+
@button_names_hash = IPAD_1X_2X_BUTTON_LABELS[lang_code]
|
91
|
+
if @button_names_hash.nil?
|
92
|
+
raise "could not find 1X/2X buttons for language code '#{lang_code}'"
|
93
|
+
end
|
94
|
+
|
95
|
+
@device = device
|
96
|
+
@lang_code = lang_code
|
97
|
+
@scale = _internal_ipad_emulation_scale
|
98
|
+
end
|
99
|
+
|
100
|
+
# @!visibility private
|
101
|
+
def tap_ipad_scale_button
|
102
|
+
key = @scale
|
103
|
+
name = @button_names_hash[key]
|
104
|
+
|
105
|
+
query_args =
|
106
|
+
[
|
107
|
+
[
|
108
|
+
:view, {:marked => "#{name}"}
|
109
|
+
]
|
110
|
+
]
|
111
|
+
|
112
|
+
device.uia_query_then_make_javascript_calls(:queryElWindows, query_args, :tap)
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
# @!visibility private
|
118
|
+
def _internal_ipad_emulation_scale
|
119
|
+
hash = @button_names_hash
|
120
|
+
val = nil
|
121
|
+
hash.values.each do |button_name|
|
122
|
+
query_args =
|
123
|
+
[
|
124
|
+
:view, {:marked => button_name}
|
125
|
+
]
|
126
|
+
|
127
|
+
button_exists = device.uia_serialize_and_call(:queryElWindows,
|
128
|
+
query_args)
|
129
|
+
if button_exists
|
130
|
+
result = device.uia_query_then_make_javascript_calls(:queryElWindows,
|
131
|
+
[query_args],
|
132
|
+
:name)
|
133
|
+
if result == button_name
|
134
|
+
val = button_name
|
135
|
+
break
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if val.nil?
|
141
|
+
raise "Could not find iPad scale button with '#{hash.values}'"
|
142
|
+
end
|
143
|
+
|
144
|
+
if val == hash[:emulated_1x]
|
145
|
+
:emulated_1x
|
146
|
+
elsif val == hash[:emulated_2x]
|
147
|
+
:emulated_2x
|
148
|
+
else
|
149
|
+
raise "Unrecognized emulation scale '#{val}'"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# @!visibility private
|
155
|
+
# Ensures that iPhone apps emulated on an iPad are displayed at scale.
|
156
|
+
#
|
157
|
+
# @note It is recommended that clients call this `ensure_ipad_emulation_1x`
|
158
|
+
# instead of this method.
|
159
|
+
#
|
160
|
+
# @note If this is not an iPhone app emulated on an iPad, then calling
|
161
|
+
# this method has no effect.
|
162
|
+
#
|
163
|
+
# @note In order to use this method, you must allow Calabash to launch
|
164
|
+
# your app with instruments.
|
165
|
+
#
|
166
|
+
# Starting in iOS 7, iPhone apps emulated on the iPad always launch at 2x.
|
167
|
+
# calabash cannot currently interact with such apps in 2x mode (trust us,
|
168
|
+
# we've tried).
|
169
|
+
#
|
170
|
+
# @see #ensure_ipad_emulation_1x
|
171
|
+
#
|
172
|
+
# @param [Symbol] scale the desired scale - must be `:emulated_1x` or
|
173
|
+
# `:emulated_2x`
|
174
|
+
#
|
175
|
+
# @param [Hash] opts optional arguments to control the interaction with
|
176
|
+
# the 1X/2X buttons
|
177
|
+
#
|
178
|
+
# @option opts [Symbol] :lang_code (:en) an Apple compatible
|
179
|
+
# language code
|
180
|
+
# @option opts [Symbol] :wait_after_touch (0.4) how long to
|
181
|
+
# wait _after_ the scale button is touched
|
182
|
+
#
|
183
|
+
# @return [void]
|
184
|
+
#
|
185
|
+
# @raise [RuntimeError] If the app was not launched with instruments.
|
186
|
+
# @raise [RuntimeError] If an invalid `scale` is passed.
|
187
|
+
# @raise [RuntimeError] If an unknown language code is passed.
|
188
|
+
# @raise [RuntimeError] If the scale button cannot be touched.
|
189
|
+
def ensure_ipad_emulation_scale(scale, opts={})
|
190
|
+
return unless iphone_app_emulated_on_ipad?
|
191
|
+
|
192
|
+
allowed = [:emulated_1x, :emulated_2x]
|
193
|
+
unless allowed.include?(scale)
|
194
|
+
raise "Scale '#{scale}' is not one of '#{allowed}' allowed args"
|
195
|
+
end
|
196
|
+
|
197
|
+
default_opts = {:lang_code => :en,
|
198
|
+
:wait_after_touch => 0.4}
|
199
|
+
merged_opts = default_opts.merge(opts)
|
200
|
+
|
201
|
+
obj = Emulation.new(self, merged_opts[:lang_code])
|
202
|
+
|
203
|
+
actual_scale = obj.scale
|
204
|
+
|
205
|
+
if actual_scale != scale
|
206
|
+
obj.tap_ipad_scale_button
|
207
|
+
end
|
208
|
+
|
209
|
+
sleep(merged_opts[:wait_after_touch])
|
210
|
+
end
|
211
|
+
|
212
|
+
# @!visibility private
|
213
|
+
# Ensures that iPhone apps emulated on an iPad are displayed at `1X`.
|
214
|
+
#
|
215
|
+
# @note If this is not an iPhone app emulated on an iPad, then calling
|
216
|
+
# this method has no effect.
|
217
|
+
#
|
218
|
+
# @note In order to use this method, you must allow Calabash to launch
|
219
|
+
# your app with instruments.
|
220
|
+
#
|
221
|
+
# Starting in iOS 7, iPhone apps emulated on the iPad always launch at 2x.
|
222
|
+
# calabash cannot currently interact with such apps in 2x mode (trust us,
|
223
|
+
# we've tried).
|
224
|
+
#
|
225
|
+
# @param [Hash] opts optional arguments to control the interaction with
|
226
|
+
# the 1X/2X buttons
|
227
|
+
#
|
228
|
+
# @option opts [Symbol] :lang_code (:en) an Apple compatible
|
229
|
+
# language code
|
230
|
+
# @option opts [Symbol] :wait_after_touch (0.4) how long to
|
231
|
+
# wait _after_ the scale button is touched
|
232
|
+
#
|
233
|
+
# @return [void]
|
234
|
+
#
|
235
|
+
# @raise [RuntimeError] If the app was not launched with instruments.
|
236
|
+
# @raise [RuntimeError] If an unknown language code is passed.
|
237
|
+
# @raise [RuntimeError] If the scale button cannot be touched.
|
238
|
+
def ensure_ipad_emulation_1x(opts={})
|
239
|
+
ensure_ipad_emulation_scale(:emulated_1x, opts)
|
240
|
+
end
|
241
|
+
|
242
|
+
private
|
243
|
+
# @!visibility private
|
244
|
+
# Ensures iPhone apps running on an iPad are emulated at 2X
|
245
|
+
#
|
246
|
+
# You should never need to call this function - Calabash cannot interact
|
247
|
+
# with iPhone apps emulated on the iPad in 2x mode.
|
248
|
+
def _ensure_ipad_emulation_2x(opts={})
|
249
|
+
ensure_ipad_emulation_scale(:emulated_2x, opts)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
@@ -110,6 +110,7 @@ module Calabash
|
|
110
110
|
end.call(self)
|
111
111
|
end
|
112
112
|
|
113
|
+
# @!visibility private
|
113
114
|
def query_for_keyboard
|
114
115
|
keyboard_waiter.query(KEYBOARD_QUERY)
|
115
116
|
end
|
@@ -120,6 +121,7 @@ module Calabash
|
|
120
121
|
keyboard_waiter.query(KEYBOARD_KEY_QUERY)
|
121
122
|
end
|
122
123
|
|
124
|
+
# @!visibility private
|
123
125
|
def query_for_text_of_first_responder(query)
|
124
126
|
result = keyboard_waiter.query("#{query} isFirstResponder:1", :text)
|
125
127
|
if result.empty?
|
@@ -9,6 +9,7 @@ module Calabash
|
|
9
9
|
require 'run_loop'
|
10
10
|
require 'edn'
|
11
11
|
|
12
|
+
# @!visibility private
|
12
13
|
def uia_route(command)
|
13
14
|
unless run_loop
|
14
15
|
if defined?(IRB)
|
@@ -49,6 +50,49 @@ module Calabash
|
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
53
|
+
# @!visibility private
|
54
|
+
def uia_serialize_and_call(uia_command, *query_args)
|
55
|
+
command = uia_serialize_command(uia_command, *query_args)
|
56
|
+
result = uia_route(command)
|
57
|
+
result.first
|
58
|
+
end
|
59
|
+
|
60
|
+
# @!visibility private
|
61
|
+
# @todo Extract argument consing and unit test
|
62
|
+
def uia_query_then_make_javascript_calls(uia_command, query_parts, *javascript_parts)
|
63
|
+
if javascript_parts.empty?
|
64
|
+
uia_serialize_and_call(uia_command, *query_parts)
|
65
|
+
else
|
66
|
+
javascript_command = uia_serialize_command(uia_command, *query_parts)
|
67
|
+
|
68
|
+
javascript_args = []
|
69
|
+
javascript_parts.each do |invocation|
|
70
|
+
javascript_args << case invocation
|
71
|
+
when Symbol
|
72
|
+
"#{invocation}()"
|
73
|
+
when Hash
|
74
|
+
method = invocation.keys.first
|
75
|
+
method_args = invocation[method]
|
76
|
+
|
77
|
+
if method_args.is_a?(Array)
|
78
|
+
serialized_args = (method_args.map &:to_json).join(',')
|
79
|
+
else
|
80
|
+
serialized_args = method_args.to_json
|
81
|
+
end
|
82
|
+
|
83
|
+
"#{method}(#{serialized_args})"
|
84
|
+
else
|
85
|
+
raise Calabash::IOS::RouteError,
|
86
|
+
"Invalid invocation spec #{invocation}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
command = "#{javascript_command}.#{javascript_args.join('.')}"
|
90
|
+
|
91
|
+
result = uia_route(command)
|
92
|
+
result.first
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
52
96
|
private
|
53
97
|
|
54
98
|
UIA_STRATEGIES = [:preferences, :host, :shared_element]
|
@@ -159,12 +203,6 @@ module Calabash
|
|
159
203
|
end
|
160
204
|
end
|
161
205
|
|
162
|
-
def uia_serialize_and_call(uia_command, *query_args)
|
163
|
-
command = uia_serialize_command(uia_command, *query_args)
|
164
|
-
result = uia_route(command)
|
165
|
-
result.first
|
166
|
-
end
|
167
|
-
|
168
206
|
# @todo Verify this is the correct way to escape '\n in string
|
169
207
|
def uia_escape_string(string)
|
170
208
|
Calabash::Text.escape_single_quotes(string).gsub("\n", "\\\\n")
|