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.
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,167 @@
1
+ module Calabash
2
+ module IOS
3
+ # @!visibility private
4
+ #
5
+ # Gestures should wait for the views involved before performing the
6
+ # gesture.
7
+ #
8
+ # 1. Wait for the view or views.
9
+ # 2. Find the absolute coordinates of the gesture.
10
+ # 3. Pass the coordinates to the Calabash UIA offset API.
11
+ # 4. Return the views involved in the gesture as QueryResults.
12
+ #
13
+ # @todo Needs unit tests.
14
+ module GesturesMixin
15
+
16
+ def _tap(query, options={})
17
+ view_to_touch = _gesture_waiter.wait_for_view(query, options)
18
+
19
+ offset = uia_center_of_view(view_to_touch)
20
+
21
+ uia_serialize_and_call(:tapOffset, offset, options)
22
+
23
+ Calabash::QueryResult.create([view_to_touch], query)
24
+ end
25
+
26
+ def _double_tap(query, options={})
27
+ view_to_touch = _gesture_waiter.wait_for_view(query, options)
28
+
29
+ offset = uia_center_of_view(view_to_touch)
30
+
31
+ uia_serialize_and_call(:doubleTapOffset, offset, options)
32
+
33
+ Calabash::QueryResult.create([view_to_touch], query)
34
+ end
35
+
36
+ def _long_press(query, options={})
37
+
38
+ begin
39
+ _expect_valid_duration(options)
40
+ rescue ArgumentError => e
41
+ raise ArgumentError e
42
+ end
43
+
44
+ view_to_touch = _gesture_waiter.wait_for_view(query, options)
45
+
46
+ offset = uia_center_of_view(view_to_touch)
47
+
48
+ uia_serialize_and_call(:touchHoldOffset, options[:duration], offset)
49
+
50
+ Calabash::QueryResult.create([view_to_touch], query)
51
+ end
52
+
53
+ def _pan_between(query_from, query_to, options={})
54
+
55
+ begin
56
+ _expect_valid_duration(options)
57
+ rescue ArgumentError => e
58
+ raise ArgumentError e
59
+ end
60
+
61
+ from_view = _gesture_waiter.wait_for_view(query_from, options)
62
+ to_view = _gesture_waiter.wait_for_view(query_to, options)
63
+
64
+ from_offset = uia_center_of_view(from_view)
65
+ to_offset = uia_center_of_view(to_view)
66
+
67
+ uia_serialize_and_call(:panOffset, from_offset, to_offset, options)
68
+
69
+ {
70
+ :from => Calabash::QueryResult.create([from_view], query_from),
71
+ :to => Calabash::QueryResult.create([to_view], query_to)
72
+ }
73
+ end
74
+
75
+ # The default to and from for the pan_* methods are not good for iOS.
76
+ #
77
+ # * from: {x: 90, y: 50}
78
+ # * to: {x: 10, y: 50}
79
+ #
80
+ # If the view has a UINavigationBar or UITabBar, the defaults will
81
+ # cause vertical gestures to start and/or end on one of these bars.
82
+ #
83
+ # dragInsideWithOptions broke in iOS 7, so the condition should really be
84
+ # `Device.default.simulator? && !Device.ios6?`, but I haven't checked on
85
+ # iOS 9 yet, so I will leave the condition out.
86
+ def _pan(query, from, to, options={})
87
+ if Device.default.simulator?
88
+ message = [
89
+ "Apple's UIAutomation `dragInsideWithOptions` API is broken for iOS > 7",
90
+ 'If you are trying to scroll on a UITableView or UICollectionView, try using the scroll_* methods'
91
+ ].join("\n")
92
+
93
+ raise message
94
+ end
95
+
96
+ begin
97
+ _expect_valid_duration(options)
98
+ rescue ArgumentError => e
99
+ raise ArgumentError e
100
+ end
101
+
102
+ view_to_pan = _gesture_waiter.wait_for_view(query, options)
103
+
104
+ rect = view_to_pan['rect']
105
+
106
+ from_x = rect['width'] * (from[:x]/100.0)
107
+ from_y = rect['height'] * (from[:y]/100.0)
108
+ from_offset = percent(from_x, from_y)
109
+
110
+ to_x = rect['width'] * (to[:x]/100.0)
111
+ to_y = rect['height'] * (to[:y]/100.0)
112
+ to_offset = percent(to_x, to_y)
113
+
114
+ uia_serialize_and_call(:panOffset, from_offset, to_offset)
115
+
116
+ Calabash::QueryResult.create([view_to_pan], query)
117
+ end
118
+
119
+ private
120
+
121
+ # !@visibility private
122
+ #
123
+ # Unlike the Calabash Android server, the iOS server does not wait
124
+ # before gestures, so the client must do the waiting. The _gesture_waiter
125
+ # allows access to query, wait, etc. without having to include all of
126
+ # Calabash in this module.
127
+ #
128
+ # @todo Replace with waiting on the iOS Server
129
+ def _gesture_waiter
130
+ lambda do |reference_to_self|
131
+ Class.new do
132
+ # world_for_device will return a copy of the module Calabash::IOS,
133
+ # which has redefined Calabash.default_device to reference this
134
+ # device. We should not keep a reference to gesture_waiter
135
+ # because of this, as the user might change a constant or class
136
+ # variable in Calabash.
137
+ include reference_to_self.send(:world_for_device)
138
+
139
+ define_method(:query) do |query, *args|
140
+ reference_to_self.map_route(query, :query, *args)
141
+ end
142
+
143
+ def to_s
144
+ '#<Calabash::IOS::GestureWaiter>'
145
+ end
146
+
147
+ def inspect
148
+ to_s
149
+ end
150
+ end.new
151
+ end.call(self)
152
+ end
153
+
154
+ def _expect_valid_duration(options)
155
+ duration = options[:duration].to_f
156
+ if duration < 0.5 || duration > 60
157
+ message = [
158
+ "Expected :duration 0.5 <= '#{duration}' <= 60",
159
+ 'On iOS, gesture durations must be between 0.5 and 60 seconds.',
160
+ 'This is a limitation enforced by the UIAutomation API.'
161
+ ].join("\n")
162
+ raise ArgumentError, message
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,133 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # @!visibility private
5
+ module KeyboardMixin
6
+
7
+ # Returns true if a docked keyboard is visible.
8
+ #
9
+ # A docked keyboard is pinned to the bottom of the view.
10
+ #
11
+ # Keyboards on the iPhone and iPod are docked.
12
+ def docked_keyboard_visible?
13
+ query_result = query_for_keyboard
14
+ return false if query_result.empty?
15
+
16
+ return true if device_family_iphone?
17
+
18
+ # iPad
19
+ rect = query_result.first['rect']
20
+ orientation = status_bar_orientation.to_sym
21
+ case orientation
22
+ when :left then
23
+ rect['center_x'] == 592 && rect['center_y'] == 512
24
+ when :right then
25
+ rect['center_x'] == 176 && rect['center_y'] == 512
26
+ when :up then
27
+ rect['center_x'] == 384 && rect['center_y'] == 132
28
+ when :down then
29
+ rect['center_x'] == 384 && rect['center_y'] == 892
30
+ else
31
+ false
32
+ end
33
+ end
34
+
35
+ # Returns true if an undocked keyboard is visible.
36
+ #
37
+ # A undocked keyboard is floats in the middle of the view.
38
+ #
39
+ # Only iPad keyboards can be undocked.
40
+ def undocked_keyboard_visible?
41
+ return false if device_family_iphone?
42
+
43
+ return false if query_for_keyboard.empty?
44
+
45
+ not docked_keyboard_visible?
46
+ end
47
+
48
+ # Returns true if a split keyboard is visible.
49
+ #
50
+ # A split keyboard is floats in the middle of the view and is split to
51
+ # allow faster thumb typing
52
+ #
53
+ # Only iPad keyboards can be split.
54
+ def split_keyboard_visible?
55
+ return false if device_family_iphone?
56
+ query_for_keyboard_keys.count > 0 && query_for_keyboard.empty?
57
+ end
58
+
59
+ # Returns true if there is a visible keyboard.
60
+ def keyboard_visible?
61
+ docked_keyboard_visible? || undocked_keyboard_visible? || split_keyboard_visible?
62
+ end
63
+
64
+ # Returns the the text in the first responder.
65
+ #
66
+ # The first responder will be the UITextField or UITextView instance
67
+ # that is associated with the visible keyboard.
68
+ #
69
+ # Returns empty string if no textField or textView elements are found to be
70
+ # the first responder. Otherwise, it will return the text in the
71
+ # UITextField or UITextField that is associated with the keyboard.
72
+ def text_from_keyboard_first_responder
73
+ raise 'There must be a visible keyboard.' unless keyboard_visible?
74
+
75
+ text = ''
76
+ ['textField', 'textView'].each do |ui_class|
77
+ text = query_for_text_of_first_responder(ui_class)
78
+ if text.nil?
79
+ text = ''
80
+ else
81
+ break
82
+ end
83
+ end
84
+ text
85
+ end
86
+
87
+ private
88
+
89
+ # @!visibility private
90
+ # Returns a query string for detecting a keyboard.
91
+ KEYBOARD_QUERY = "view:'UIKBKeyplaneView'"
92
+ KEYBOARD_KEY_QUERY = "view:'UIKBKeyView'"
93
+
94
+ def device_family_iphone?
95
+ family = device_family
96
+ family == 'iPhone'
97
+ end
98
+
99
+ # Unlike the Calabash Android server, the iOS server does not wait
100
+ # before gestures. We need to do this in the client for now.
101
+ # @todo Replace with waiting on the iOS Server
102
+ def keyboard_waiter
103
+ @keyboard_waiter ||= lambda do |reference_to_self|
104
+ Class.new do
105
+ include Calabash::Wait
106
+ define_method(:query) do |query, *args|
107
+ reference_to_self.map_route(query, :query, *args)
108
+ end
109
+ end.new
110
+ end.call(self)
111
+ end
112
+
113
+ def query_for_keyboard
114
+ keyboard_waiter.query(KEYBOARD_QUERY)
115
+ end
116
+
117
+ # When the split keyboard is showing, KEYBOARD_QUERY will return no
118
+ # results. UIKBKeyView are the individual key views on the keyboard.
119
+ def query_for_keyboard_keys
120
+ keyboard_waiter.query(KEYBOARD_KEY_QUERY)
121
+ end
122
+
123
+ def query_for_text_of_first_responder(query)
124
+ result = keyboard_waiter.query("#{query} isFirstResponder:1", :text)
125
+ if result.empty?
126
+ nil
127
+ else
128
+ result.first
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,266 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # @!visibility private
5
+ # A mixin for IOS::Device that provides methods that users can override
6
+ # to use a third-party tool like `ideviceinstaller` or `ios-deploy` to
7
+ # manage apps on physical devices.
8
+ #
9
+ #
10
+ # Calabash cannot manage apps on physical devices. There are third-party
11
+ # tools you can use to manage apps on devices. Two popular tools are
12
+ # ideviceinstaller and ios-deploy. Both can be installed using homebrew.
13
+ #
14
+ # To integrate these tools, Calabash provides several methods for you to
15
+ # override in your project. In your `features/support/` directory, you
16
+ # can patch Calabash::IOS::Device with your own implementation of these
17
+ # methods. The five methods to override are:
18
+ #
19
+ # 1. app_installed_on_physical_device?
20
+ # 2. install_app_on_physical_device
21
+ # 3. ensure_app_installed_on_physical_device
22
+ # 4. clear_app_data_on_physical_device
23
+ # 5. uninstall_app_on_physical_device
24
+ #
25
+ #
26
+ # ```
27
+ # # features/support/ideviceinstaller.rb
28
+ #
29
+ # require 'fileutils'
30
+ # class Calabash::IOS::Device
31
+ #
32
+ # def app_installed_on_physical_device?(application, device_udid)
33
+ # out = `/usr/local/bin/ideviceinstaller --udid #{device_udid} --list-apps`
34
+ # out.split(/\s/).include? application.identifier
35
+ # end
36
+ #
37
+ # def install_app_on_physical_device(application, device_udid)
38
+ #
39
+ # if app_installed_on_physical_device?(application, device_udid)
40
+ # uninstall_app_on_physical_device(application, device_udid)
41
+ # end
42
+ #
43
+ # args =
44
+ # [
45
+ # '--udid', device_udid,
46
+ # '--install', application.path
47
+ # ]
48
+ #
49
+ # log = FileUtils.touch('./ideviceinstaller.log')
50
+ # system('/usr/local/bin/ideviceinstaller', *args, {:out => log})
51
+ #
52
+ # exit_code = $?
53
+ # unless exit_code == 0
54
+ # raise "Could not install the app (#{exit_code}). See #{File.expand_path(log)}"
55
+ # end
56
+ # true
57
+ # end
58
+ #
59
+ # def uninstall_app_on_physical_device(application, device_udid)
60
+ #
61
+ # if app_installed_on_physical_device?(application, device_udid)
62
+ #
63
+ # args =
64
+ # [
65
+ # '--udid', device_udid,
66
+ # '--uninstall', application.identifier
67
+ # ]
68
+ #
69
+ # log = FileUtils.touch('./ideviceinstaller.log')
70
+ # system('/usr/local/bin/ideviceinstaller', *args, {:out => log})
71
+ #
72
+ # exit_code = $?
73
+ # unless exit_code == 0
74
+ # raise "Could not uninstall the app (#{exit_code}). See #{File.expand_path(log)}"
75
+ # end
76
+ # end
77
+ # true
78
+ # end
79
+ #
80
+ # def ensure_app_installed_on_physical_device(application, device_udid)
81
+ # unless app_installed_on_physical_device?(application, device_udid)
82
+ # install_app_on_physical_device(application, device_udid)
83
+ # end
84
+ # true
85
+ # end
86
+ #
87
+ # # The only way to clear the data is to uninstall the app.
88
+ # def clear_app_data_on_physical_device(application, device_udid)
89
+ # if app_installed_on_physical_device?(application, device_udid)
90
+ # install_app_on_physical_device(application, device_udid)
91
+ # end
92
+ # true
93
+ # end
94
+ # end
95
+ # ```
96
+ #
97
+ # For a real-world example of a ruby wrapper around the ideviceinstaller
98
+ # command-line tool, see https://github.com/calabash/ios-smoke-test-app.
99
+ #
100
+ # @see #app_installed_on_physical_device?
101
+ # @see #install_app_on_physical_device
102
+ # @see #ensure_app_installed_on_physical_device
103
+ # @see #clear_app_data_on_physical_device
104
+ # @see #uninstall_app_on_physical_device
105
+ #
106
+ # @see http://brew.sh/
107
+ # @see https://github.com/libimobiledevice/ideviceinstaller
108
+ # @see https://github.com/phonegap/ios-deploy
109
+ # @see https://github.com/calabash/ios-smoke-test-app/blob/master/CalSmokeApp/features/support/ideviceinstaller.rb
110
+ # @see https://github.com/blueboxsecurity/idevice
111
+ #
112
+ # For an real-world example of a ruby wrapper around the ideviceinstaller
113
+ # tool, see /blob/master/CalSmokeApp/features/support/ideviceinstaller.rb
114
+ module PhysicalDeviceMixin
115
+
116
+ # Install an app on physical device. To fit into Calabash's app lifecycle
117
+ # model, implementations of this method must follow these rules:
118
+ #
119
+ # 1. If the app is installed, uninstall it, and then install it.
120
+ # 2. If the app cannot be uninstalled or installed, raise a StandardError.
121
+ #
122
+ # param [Calabash::IOS::Application] application The application to
123
+ # to install. The important methods on application are `path` and
124
+ # `identifier`.
125
+ # @param [String] device_udid The identifier of the device to install the
126
+ # application on.
127
+ #
128
+ # @return [Boolean] If the app was installed ont the device.
129
+ #
130
+ # @raise [Calabash::AbstractMethodError] If this method is not implemented
131
+ # by the user.
132
+ def install_app_on_physical_device(application, device_udid)
133
+ logger.log('To install an ipa on a physical device, you must extend', :info)
134
+ logger.log('Calabash::IOS::Device and implement the #install_app_on_physical_device', :info)
135
+ logger.log('method that using a third-party tool to interact with physical devices.', :info)
136
+ logger.log('For an example of an implementation using ideviceinstaller, see:', :info)
137
+ logger.log('https://github.com/calabash/ios-smoke-test-app.', :info)
138
+ raise Calabash::AbstractMethodError,
139
+ 'Device install_app_on_physical_device must be implemented by you.'
140
+ end
141
+
142
+ # Ensures that `application` is installed on a physical device. To fit
143
+ # into Calabash's app lifecycle model, implementations of this method must
144
+ # follow these rules:
145
+ #
146
+ # 1. If the app is not installed, install it.
147
+ # 2. If the app is installed, return true
148
+ # 3. If the app cannot be installed, raise a StandardError.
149
+ #
150
+ # @param [Calabash::IOS::Application] application The application to
151
+ # to install. The important methods on application are `path` and
152
+ # `identifier`.
153
+ # @param [String] device_udid The identifier of the device to install the
154
+ # application on.
155
+ #
156
+ # @return [Boolean] If the app is installed on the physical_device.
157
+ #
158
+ # @raise [Calabash::AbstractMethodError] If this method is not implemented
159
+ # by the user.
160
+ def ensure_app_installed_on_physical_device(application, device_udid)
161
+ logger.log('To check if an app installed on a physical device, you must extend', :info)
162
+ logger.log('Calabash::IOS::Device and implement the #ensure_app_installed_on_device', :info)
163
+ logger.log('method that using a third-party tool to interact with physical devices.', :info)
164
+ logger.log('For an example of an implementation using ideviceinstaller, see:', :info)
165
+ logger.log('https://github.com/calabash/ios-smoke-test-app.', :info)
166
+ raise Calabash::AbstractMethodError,
167
+ 'Device ensure_app_installed_on_device must be implemented by you.'
168
+ end
169
+
170
+ # Clears the application's data from a physical device. To fit into
171
+ # Calabash's app lifecycle model, implementations of this method must
172
+ # follow these rules:
173
+ #
174
+ # 1. The data in the applications sandbox must be reset to a good known
175
+ # state. What that means for your application is up to you to
176
+ # decide. Generally, this means you should remove _all_ files from
177
+ # the application's sandbox.
178
+ # 2. If the data has been reset, return true.
179
+ # 3. If the app data cannot be cleared, raise a StandardError.
180
+ #
181
+ # Some kinds of user data are very difficult to clear. For example,
182
+ # values stored in NSUserDefaults are not removed when an app is
183
+ # uninstalled. The same is true for values stored in the Keychain.
184
+ #
185
+ # You might need to add logic in your Cucumber Before hooks to clear
186
+ # such data.
187
+ #
188
+ # @param [Calabash::IOS::Application] application The application to
189
+ # to install. The important methods on application are `path` and
190
+ # `identifier`.
191
+ # @param [String] device_udid The identifier of the device to install the
192
+ # application on.
193
+ #
194
+ # @return [Boolean] Return true if the application data was cleared.
195
+ #
196
+ # @raise [Calabash::AbstractMethodError] If this method is not implemented
197
+ # by the user.
198
+ def clear_app_data_on_physical_device(application, device_udid)
199
+ logger.log('To clear app data on a physical device, you must extend', :info)
200
+ logger.log('Calabash::IOS::Device and implement the #clear_app_data_on_physical_device', :info)
201
+ logger.log('method using a third-party tool to interact with physical devices.', :info)
202
+ logger.log('For an example of an implementation using ideviceinstaller, see:', :info)
203
+ logger.log('https://github.com/calabash/ios-smoke-test-app.', :info)
204
+ raise Calabash::AbstractMethodError,
205
+ 'Device clear_app_data_on_physical_device must be implemented by you.'
206
+ end
207
+
208
+ # Returns true if the application is installed on a physical device. To
209
+ # fit into Calabash's app lifecycle model, implementations of this method
210
+ # must follow these rules:
211
+ #
212
+ # 1. If the app is installed, this method must return true.
213
+ # 2. If the app is not installed, this method must return false.
214
+ # 3. If the state of the app on the device cannot be determined, raise
215
+ # a RuntimeError.
216
+ #
217
+ # @param [Calabash::IOS::Application] application The application to
218
+ # to install. The important methods on application are `path` and
219
+ # `identifier`.
220
+ # @param [String] device_udid The identifier of the device to install the
221
+ # application on.
222
+ #
223
+ # @return [Boolean] Return true if the application is installed on the
224
+ # device.
225
+ #
226
+ # @raise [Calabash::AbstractMethodError] If this method is not implemented
227
+ # by the user.
228
+ def app_installed_on_physical_device?(application, device_udid)
229
+ logger.log('To determine if an app is installed on a physical device, you must extend', :info)
230
+ logger.log('Calabash::IOS::Device and implement the #app_installed_on_physical_device', :info)
231
+ logger.log('method using a third-party tool to interact with physical devices.', :info)
232
+ logger.log('For an example of an implementation using ideviceinstaller, see:', :info)
233
+ logger.log('https://github.com/calabash/ios-smoke-test-app.', :info)
234
+ raise Calabash::AbstractMethodError,
235
+ 'Device app_installed_on_physical_device? must be implemented by you.'
236
+ end
237
+
238
+ # Uninstalls an application from a physical device. To fit into Calabash's
239
+ # app lifecycle model, implementations of this method must follow these
240
+ # rules:
241
+ #
242
+ # 1. Return true if the app was uninstalled.
243
+ # 2. Raise an error if the app cannot be uninstalled.
244
+ #
245
+ # @param [Calabash::IOS::Application] application The application to
246
+ # to install. The important methods on application are `path` and
247
+ # `identifier`.
248
+ # @param [String] device_udid The identifier of the device to install the
249
+ # application on.
250
+ #
251
+ # @return [Boolean] Return true if the application was uninstalled.
252
+ #
253
+ # @raise [Calabash::AbstractMethodError] If this method is not implemented
254
+ # by the user.
255
+ def uninstall_app_on_physical_device(application, device_udid)
256
+ logger.log('To uninstall an ipa on a physical device, you must extend', :info)
257
+ logger.log('Calabash::IOS::Device and implement the #uninstall_app_on_physical_device', :info)
258
+ logger.log('method that using a third-party tool to interact with physical devices.', :info)
259
+ logger.log('For an example of an implementation using ideviceinstaller, see:', :info)
260
+ logger.log('https://github.com/calabash/ios-smoke-test-app.', :info)
261
+ raise Calabash::AbstractMethodError,
262
+ 'Device uninstall_app_on_physical_device must be implemented by you.'
263
+ end
264
+ end
265
+ end
266
+ end