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.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +39 -0
  3. data/LICENSE +204 -21
  4. data/README.md +36 -6
  5. data/VERSIONING.md +16 -0
  6. data/bin/calabash +95 -0
  7. data/lib/calabash.rb +185 -1
  8. data/lib/calabash/android.rb +64 -0
  9. data/lib/calabash/android/adb.rb +277 -0
  10. data/lib/calabash/android/application.rb +110 -0
  11. data/lib/calabash/android/build.rb +12 -0
  12. data/lib/calabash/android/build/application.rb +13 -0
  13. data/lib/calabash/android/build/build_error.rb +11 -0
  14. data/lib/calabash/android/build/builder.rb +119 -0
  15. data/lib/calabash/android/build/java_keystore.rb +177 -0
  16. data/lib/calabash/android/build/resigner.rb +56 -0
  17. data/lib/calabash/android/build/test_server.rb +27 -0
  18. data/lib/calabash/android/console_helpers.rb +44 -0
  19. data/lib/calabash/android/cucumber.rb +3 -0
  20. data/lib/calabash/android/device.rb +965 -0
  21. data/lib/calabash/android/environment.rb +470 -0
  22. data/lib/calabash/android/gestures.rb +369 -0
  23. data/lib/calabash/android/interactions.rb +45 -0
  24. data/lib/calabash/android/lib/.irbrc +55 -0
  25. data/lib/calabash/android/lib/AndroidManifest.xml +51 -0
  26. data/lib/calabash/android/lib/TestServer.apk +0 -0
  27. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5 +0 -0
  28. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie +0 -0
  29. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5 +0 -0
  30. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5-pie +0 -0
  31. data/lib/calabash/android/lib/calmd5/armeabi/calmd5 +0 -0
  32. data/lib/calabash/android/lib/calmd5/armeabi/calmd5-pie +0 -0
  33. data/lib/calabash/android/lib/calmd5/mips/calmd5 +0 -0
  34. data/lib/calabash/android/lib/calmd5/mips/calmd5-pie +0 -0
  35. data/lib/calabash/android/lib/calmd5/mips64/calmd5 +0 -0
  36. data/lib/calabash/android/lib/calmd5/mips64/calmd5-pie +0 -0
  37. data/lib/calabash/android/lib/calmd5/x86/calmd5 +0 -0
  38. data/lib/calabash/android/lib/calmd5/x86/calmd5-pie +0 -0
  39. data/lib/calabash/android/lib/calmd5/x86_64/calmd5 +0 -0
  40. data/lib/calabash/android/lib/calmd5/x86_64/calmd5-pie +0 -0
  41. data/lib/calabash/android/lib/screenshot_taker.jar +0 -0
  42. data/lib/calabash/android/life_cycle.rb +37 -0
  43. data/lib/calabash/android/orientation.rb +30 -0
  44. data/lib/calabash/android/physical_buttons.rb +39 -0
  45. data/lib/calabash/android/screenshot.rb +9 -0
  46. data/lib/calabash/android/scroll.rb +5 -0
  47. data/lib/calabash/android/server.rb +10 -0
  48. data/lib/calabash/android/text.rb +54 -0
  49. data/lib/calabash/application.rb +74 -0
  50. data/lib/calabash/cli.rb +12 -0
  51. data/lib/calabash/cli/build.rb +33 -0
  52. data/lib/calabash/cli/console.rb +90 -0
  53. data/lib/calabash/cli/generate.rb +110 -0
  54. data/lib/calabash/cli/helpers.rb +130 -0
  55. data/lib/calabash/cli/resign.rb +33 -0
  56. data/lib/calabash/cli/run.rb +99 -0
  57. data/lib/calabash/cli/setup_keystore.rb +39 -0
  58. data/lib/calabash/color.rb +32 -0
  59. data/lib/calabash/console_helpers.rb +90 -0
  60. data/lib/calabash/defaults.rb +56 -0
  61. data/lib/calabash/device.rb +401 -0
  62. data/lib/calabash/environment.rb +75 -0
  63. data/lib/calabash/gestures.rb +384 -0
  64. data/lib/calabash/http.rb +8 -0
  65. data/lib/calabash/http/error.rb +15 -0
  66. data/lib/calabash/http/request.rb +42 -0
  67. data/lib/calabash/http/retriable_client.rb +156 -0
  68. data/lib/calabash/interactions.rb +105 -0
  69. data/lib/calabash/ios.rb +37 -0
  70. data/lib/calabash/ios/application.rb +119 -0
  71. data/lib/calabash/ios/conditions.rb +79 -0
  72. data/lib/calabash/ios/console_helpers.rb +72 -0
  73. data/lib/calabash/ios/device.rb +24 -0
  74. data/lib/calabash/ios/device/device_implementation.rb +779 -0
  75. data/lib/calabash/ios/device/gestures_mixin.rb +167 -0
  76. data/lib/calabash/ios/device/keyboard_mixin.rb +133 -0
  77. data/lib/calabash/ios/device/physical_device_mixin.rb +266 -0
  78. data/lib/calabash/ios/device/rotation_mixin.rb +124 -0
  79. data/lib/calabash/ios/device/routes/backdoor_route_mixin.rb +86 -0
  80. data/lib/calabash/ios/device/routes/condition_route_mixin.rb +62 -0
  81. data/lib/calabash/ios/device/routes/error.rb +8 -0
  82. data/lib/calabash/ios/device/routes/handle_route_mixin.rb +102 -0
  83. data/lib/calabash/ios/device/routes/map_route_mixin.rb +38 -0
  84. data/lib/calabash/ios/device/routes/playback_route_mixin.rb +70 -0
  85. data/lib/calabash/ios/device/routes/response_parser.rb +48 -0
  86. data/lib/calabash/ios/device/routes/uia_route_mixin.rb +238 -0
  87. data/lib/calabash/ios/device/runtime_attributes.rb +184 -0
  88. data/lib/calabash/ios/device/status_bar_mixin.rb +17 -0
  89. data/lib/calabash/ios/device/text_mixin.rb +19 -0
  90. data/lib/calabash/ios/device/uia_keyboard_mixin.rb +188 -0
  91. data/lib/calabash/ios/device/uia_mixin.rb +12 -0
  92. data/lib/calabash/ios/environment.rb +41 -0
  93. data/lib/calabash/ios/interactions.rb +10 -0
  94. data/lib/calabash/ios/lib/.irbrc +55 -0
  95. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_ipad.base64 +2 -0
  96. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_iphone.base64 +2 -0
  97. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_ipad.base64 +2 -0
  98. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_iphone.base64 +2 -0
  99. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_ipad.base64 +2 -0
  100. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_iphone.base64 +2 -0
  101. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_ipad.base64 +2 -0
  102. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_iphone.base64 +2 -0
  103. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_ipad.base64 +2 -0
  104. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_iphone.base64 +2 -0
  105. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_ipad.base64 +2 -0
  106. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_iphone.base64 +2 -0
  107. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_ipad.base64 +2 -0
  108. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_iphone.base64 +2 -0
  109. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_ipad.base64 +2 -0
  110. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_iphone.base64 +2 -0
  111. data/lib/calabash/ios/orientation.rb +117 -0
  112. data/lib/calabash/ios/scroll.rb +504 -0
  113. data/lib/calabash/ios/server.rb +73 -0
  114. data/lib/calabash/ios/text.rb +248 -0
  115. data/lib/calabash/ios/uia.rb +24 -0
  116. data/lib/calabash/lib/skeleton/config/cucumber.yml +6 -0
  117. data/lib/calabash/lib/skeleton/features/sample.feature +5 -0
  118. data/lib/calabash/lib/skeleton/features/step_definitions/calabash_steps.rb +29 -0
  119. data/lib/calabash/lib/skeleton/features/support/env.rb +54 -0
  120. data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
  121. data/lib/calabash/life_cycle.rb +111 -0
  122. data/lib/calabash/location.rb +51 -0
  123. data/lib/calabash/logger.rb +87 -0
  124. data/lib/calabash/orientation.rb +84 -0
  125. data/lib/calabash/page.rb +35 -0
  126. data/lib/calabash/patch.rb +14 -0
  127. data/lib/calabash/patch/array.rb +16 -0
  128. data/lib/calabash/patch/run_loop.rb +90 -0
  129. data/lib/calabash/query.rb +160 -0
  130. data/lib/calabash/query_result.rb +85 -0
  131. data/lib/calabash/screenshot.rb +89 -0
  132. data/lib/calabash/server.rb +16 -0
  133. data/lib/calabash/text.rb +76 -0
  134. data/lib/calabash/utility.rb +58 -0
  135. data/lib/calabash/version.rb +3 -1
  136. data/lib/calabash/wait.rb +474 -0
  137. metadata +462 -24
@@ -0,0 +1,124 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # !@visibility private
5
+ module RotationMixin
6
+
7
+ def rotate(direction)
8
+ # If we are in the console, we want to be able to rotate without
9
+ # calling start_app. However, if the Device in the console has not
10
+ # connected with the server, the runtime attributes will not be
11
+ # available. It *might* make sense for the console to do this.
12
+ if defined?(IRB)
13
+ wait_for_server_to_start({:timeout => 1})
14
+ end
15
+
16
+ family = device_family
17
+
18
+ current_orientation = status_bar_orientation.to_sym
19
+ recording_name = nil
20
+ case direction
21
+ when :left
22
+ if current_orientation == :down
23
+ recording_name = 'left_home_down'
24
+ elsif current_orientation == :right
25
+ recording_name = 'left_home_right'
26
+ elsif current_orientation == :left
27
+ recording_name = 'left_home_left'
28
+ elsif current_orientation == :up
29
+ recording_name = 'left_home_up'
30
+ end
31
+ when :right
32
+ if current_orientation == :down
33
+ recording_name = 'right_home_down'
34
+ elsif current_orientation == :left
35
+ recording_name = 'right_home_left'
36
+ elsif current_orientation == :right
37
+ recording_name = 'right_home_right'
38
+ elsif current_orientation == :up
39
+ recording_name = 'right_home_up'
40
+ end
41
+ else
42
+ # Caller should have guarded us against this case.
43
+ raise ArgumentError, "Expected '#{direction}' to be :left or :right"
44
+ end
45
+
46
+ if family == 'iPad'
47
+ form_factor = 'ipad'
48
+ else
49
+ form_factor = 'iphone'
50
+ end
51
+
52
+ if recording_name.nil?
53
+ raise "Could not rotate device in direction '#{direction}' " \
54
+ "with orientation '#{current_orientation}'"
55
+ end
56
+
57
+ recording_name = "rotate_#{recording_name}"
58
+ playback_route(recording_name, form_factor)
59
+ end
60
+
61
+ # !@visibility private
62
+ # Caller must pass position one of these positions down, left, right, up
63
+ def rotate_home_button_to(position)
64
+
65
+ valid_positions = ['down', 'left', 'right', 'up']
66
+ unless valid_positions.include?(position)
67
+ raise ArgumentError,
68
+ "Expected '#{position}' to be on of #{valid_positions.join(', ')}"
69
+ end
70
+
71
+ # If we are in the console, we want to be able to rotate without
72
+ # calling start_app. However, if the Device in the console has not
73
+ # connected with the server, the runtime attributes will not be
74
+ # available. It *might* make sense for the console to do this.
75
+ if defined?(IRB)
76
+ wait_for_server_to_start({:timeout => 1})
77
+ end
78
+
79
+ orientation = status_bar_orientation
80
+
81
+ if orientation == position
82
+ return orientation
83
+ end
84
+
85
+ family = device_family
86
+
87
+ if family == 'iPad'
88
+ form_factor = 'ipad'
89
+ else
90
+ form_factor = 'iphone'
91
+ end
92
+
93
+ ROTATION_CANDIDATES.each do |recording_name|
94
+ playback_route(recording_name, form_factor)
95
+
96
+ # Wait for rotation animation.
97
+ timeout = 1.0
98
+ condition_route('NONE_ANIMATING', timeout, '*')
99
+
100
+ orientation = status_bar_orientation
101
+ if orientation == position
102
+ return orientation
103
+ end
104
+ end
105
+
106
+ orientation
107
+ end
108
+
109
+ private
110
+
111
+ ROTATION_CANDIDATES =
112
+ [
113
+ 'rotate_left_home_down',
114
+ 'rotate_left_home_left',
115
+ 'rotate_left_home_right',
116
+ 'rotate_left_home_up',
117
+ 'rotate_right_home_down',
118
+ 'rotate_right_home_left',
119
+ 'rotate_right_home_right',
120
+ 'rotate_right_home_up'
121
+ ]
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,86 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # @!visibility private
5
+ class BackdoorError < StandardError; end
6
+
7
+ # @!visibility private
8
+ module Routes
9
+ # @!visibility private
10
+ module BackdoorRouteMixin
11
+
12
+
13
+ # @!visibility private
14
+ def backdoor(selector_name, *arguments)
15
+ request = make_backdoor_request(selector_name, arguments)
16
+ response = route_post_request(request)
17
+ handle_backdoor_response(selector_name, arguments, response)
18
+ end
19
+
20
+ private
21
+
22
+ def make_backdoor_parameters(selector_name, arguments)
23
+ if arguments.length > 1
24
+ message = 'Calabash iOS does not support backdoor selectors with ' \
25
+ "more than one argument. Received #{arguments}"
26
+ raise ArgumentError, message
27
+ end
28
+
29
+ if arguments.length < 1
30
+ message = 'Calabash iOS does not support backdoor selectors with no arguments.'
31
+ raise ArgumentError, message
32
+ end
33
+
34
+ unless selector_name.end_with?(':')
35
+ messages =
36
+ [
37
+ "Selector '#{selector_name}' is missing a trailing ':'",
38
+ 'Valid backdoor selectors must take one argument.',
39
+ '',
40
+ 'http://developer.xamarin.com/guides/testcloud/calabash/working-with/backdoors/#backdoor_in_iOS',
41
+ ''
42
+ ]
43
+ raise ArgumentError, messages.join("\n")
44
+ end
45
+
46
+ {
47
+ :selector => selector_name,
48
+ :arg => arguments.first
49
+ }
50
+ end
51
+
52
+ def make_backdoor_request(selector_name, arguments)
53
+ parameters = make_backdoor_parameters(selector_name, arguments)
54
+ begin
55
+ Calabash::HTTP::Request.request('backdoor', parameters)
56
+ rescue => e
57
+ raise RouteError, e
58
+ end
59
+ end
60
+
61
+ def handle_backdoor_response(selector_name, arguments, response)
62
+ hash = parse_response_body(response)
63
+
64
+ outcome = hash['outcome']
65
+
66
+ case outcome
67
+ when 'FAILURE'
68
+ message = "Calling backdoor '#{selector_name}' with arguments '#{arguments}'" \
69
+ "failed because:\n\n#{hash['reason']}\n#{hash['details']}"
70
+ raise Calabash::IOS::RouteError, message
71
+ when 'SUCCESS'
72
+ # Legacy API: will be removed in iOS Server > 0.14.3
73
+ if hash.has_key?('results')
74
+ return hash['results']
75
+ else
76
+ return hash['result']
77
+ end
78
+ else
79
+ raise RouteError, "Server responded with an invalid outcome: '#{hash['outcome']}'"
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+
@@ -0,0 +1,62 @@
1
+ module Calabash
2
+ module IOS
3
+ # @!visibility private
4
+ module Routes
5
+ # @!visibility private
6
+ module ConditionRouteMixin
7
+
8
+ def condition_route(condition, timeout, query)
9
+ request = make_condition_request(condition, timeout, query)
10
+ response = route_post_request(request)
11
+ handle_condition_response(response)
12
+ end
13
+
14
+ private
15
+
16
+ # server
17
+ # key default description
18
+ # :condition required
19
+ # :timeout optional * how long to wait
20
+ # :duration optional 0.2 time after which condition can be considered met
21
+ # :frequency optional 0.2 how often to check condition
22
+ # :query ! n/a apply condition to matched views
23
+ #
24
+ # * => 6.0 for none animating and 30.0 for network indicator
25
+ # ! => query is required for none animating!
26
+ #
27
+ # The :duration and :frequency are not part of the public API.
28
+ def make_condition_parameters(condition, timeout, query)
29
+ {
30
+ :condition => condition,
31
+ :timeout => timeout,
32
+ :query => query
33
+ }
34
+ end
35
+
36
+ def make_condition_request(condition, timeout, query)
37
+ parameters = make_condition_parameters(condition, timeout, query)
38
+ begin
39
+ Calabash::HTTP::Request.request('condition', parameters)
40
+ rescue => e
41
+ raise Calabash::IOS::RouteError, e
42
+ end
43
+ end
44
+
45
+ def handle_condition_response(response)
46
+ hash = parse_response_body(response)
47
+
48
+ outcome = hash['outcome']
49
+
50
+ case outcome
51
+ when 'FAILURE'
52
+ false
53
+ when 'SUCCESS'
54
+ true
55
+ else
56
+ nil
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,8 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # Raised when there is a problem handling an HTTP route.
5
+ class RouteError < StandardError; end
6
+
7
+ end
8
+ end
@@ -0,0 +1,102 @@
1
+ module Calabash
2
+ module IOS
3
+ # @!visibility private
4
+ module Routes
5
+ # @!visibility private
6
+ module HandleRouteMixin
7
+
8
+ private
9
+
10
+ def route_post_request(request)
11
+ begin
12
+ http_client.post(request)
13
+ rescue => e
14
+ raise Calabash::IOS::RouteError, e
15
+ end
16
+ end
17
+
18
+ def route_handle_response(response, query)
19
+ hash = parse_response_body(response)
20
+
21
+ outcome = hash['outcome']
22
+
23
+ case outcome
24
+ when 'FAILURE'
25
+ route_failure(hash, query)
26
+ when 'SUCCESS'
27
+ route_success(hash, query)
28
+ else
29
+ raise Calabash::IOS::RouteError, "Server responded with an invalid outcome: '#{hash['outcome']}'"
30
+ end
31
+ end
32
+
33
+ def route_failure(hash, query)
34
+
35
+ fetch_value = lambda do |key|
36
+ value = hash[key]
37
+ if value.nil? || value.empty?
38
+ 'unknown'
39
+ else
40
+ value
41
+ end
42
+ end
43
+
44
+ reason = fetch_value.call('reason')
45
+ details = fetch_value.call('details')
46
+ raise Calabash::IOS::RouteError, "Map failed reason: '#{reason}' details: '#{details}' for query '#{query}'"
47
+ end
48
+
49
+ # TODO: handle invalid results
50
+ #
51
+ # So far, cases like this have been handled individually.
52
+ #
53
+ # Briar tests the 0.x behavior for every map call.
54
+ #
55
+ # These are the docs from 0.x assert_map_results
56
+ #
57
+ # # Asserts the result of a calabash `map` call and raises an error with
58
+ # # `msg` if no valid results are found.
59
+ # #
60
+ # # Casual gem users should never need to call this method; this is a
61
+ # # convenience method for gem maintainers.
62
+ # #
63
+ # # Raises an error if `map_results`:
64
+ # #
65
+ # # is an empty list #=> []
66
+ # # contains a '<VOID>' string #=> [ "<VOID>" ]
67
+ # # contains '*****' string #=> [ "*****" ]
68
+ # # contains a single nil #=> [ nil ]
69
+ # #
70
+ # # When evaluating whether a `map` call is successful it is important to
71
+ # # note that sometimes a <tt>[ nil ]</tt> or <tt>[nil, <val>, nil]</tt> is
72
+ # # a valid result.
73
+ # #
74
+ # # Consider a controller with 3 labels:
75
+ # #
76
+ # # label @ index 0 has text "foo"
77
+ # # label @ index 1 has text nil (the [label text] => nil)
78
+ # # label @ index 2 has text "bar"
79
+ # #
80
+ # # map('label', :text) => ['foo', nil, 'bar']
81
+ # # map('label index:1', :text) => [nil]
82
+ # #
83
+ # # In other cases, <tt>[ nil ]</tt> should be treated as an invalid result
84
+ # #
85
+ # # # invalid
86
+ # # > mark = 'mark does not exist'
87
+ # # > map('tableView', :scrollToRowWithMark, mark, args) => [ nil ]
88
+ # #
89
+ # # Here a <tt>[ nil ]</tt> should be considered invalid because the
90
+ # # the operation could not be performed because there is not row that
91
+ # # matches `mark`
92
+ def route_success(hash, query)
93
+ if query.nil?
94
+ hash['results']
95
+ else
96
+ Calabash::QueryResult.create(hash['results'], query)
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,38 @@
1
+ module Calabash
2
+ module IOS
3
+ # @!visibility private
4
+ module Routes
5
+ # @!visibility private
6
+ module MapRouteMixin
7
+
8
+ def map_route(query, method_name, *method_args)
9
+ request = make_map_request(query, method_name, *method_args)
10
+ response = route_post_request(request)
11
+ route_handle_response(response, query)
12
+ end
13
+
14
+ private
15
+
16
+ def make_map_parameters(query, method_name, *method_args)
17
+ {
18
+ :operation =>
19
+ {
20
+ :method_name => method_name,
21
+ :arguments => method_args
22
+ },
23
+ :query => query
24
+ }
25
+ end
26
+
27
+ def make_map_request(query, method_name, *method_args)
28
+ parameters = make_map_parameters(query, method_name, *method_args)
29
+ begin
30
+ Calabash::HTTP::Request.request('map', parameters)
31
+ rescue => e
32
+ raise Calabash::IOS::RouteError, e
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,70 @@
1
+ module Calabash
2
+ module IOS
3
+ module Routes
4
+
5
+ # !@visibility private
6
+ module PlaybackRouteMixin
7
+
8
+ # This is a Legacy API and is only used to support rotations.
9
+ #
10
+ # form_factor is iphone | ipad
11
+ #
12
+ # **NOTE** If we revive this API, move the call to
13
+ # recalibrate_after_rotation closer to the actually implementation of
14
+ # rotate; it is (probably?) not necessary for all recordings.
15
+ def playback_route(recording_name, form_factor)
16
+ request = make_playback_request(recording_name, form_factor)
17
+ response = route_post_request(request)
18
+ result = playback_route_handle_response(response)
19
+
20
+ # The first query after a rotation will have incorrect coordinates!
21
+ # We have to make a uia query to force an update.
22
+ recalibrate_after_rotation
23
+ result
24
+ end
25
+
26
+ private
27
+
28
+ PLAYBACK_DIR = File.expand_path(File.join(File.dirname(__FILE__),
29
+ '..', '..', 'lib', 'recordings'))
30
+
31
+ def path_to_recording(basename, form_factor)
32
+ name = "#{basename}_#{form_factor}.base64"
33
+ File.join(PLAYBACK_DIR, name)
34
+ end
35
+
36
+ def read_recording(path)
37
+ unless File.exist?(path)
38
+ raise "Expected file '#{path}' to exist. Can't load recording."
39
+ end
40
+
41
+ File.read(path)
42
+ end
43
+
44
+ def make_playback_parameters(data)
45
+ %Q|{"events":"#{data}"}|
46
+ end
47
+
48
+ def make_playback_request(recording_basename, form_factor)
49
+ path = path_to_recording(recording_basename, form_factor)
50
+ data = read_recording(path)
51
+ to_post = make_playback_parameters(data)
52
+ Calabash::HTTP::Request.new('play', to_post)
53
+ end
54
+
55
+ def playback_route_handle_response(response)
56
+ hash = parse_response_body(response)
57
+ if hash['outcome'] == 'SUCCESS'
58
+ hash['results']
59
+ else
60
+ raise "Playback failed because:\n#{hash['reason']}\n#{hash['details']}"
61
+ end
62
+ end
63
+
64
+ def recalibrate_after_rotation
65
+ uia_serialize_and_call(:query, 'window')
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end