calabash 1.9.9.pre3 → 2.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -0
  3. data/bin/calabash +45 -36
  4. data/lib/calabash/android/build/builder.rb +1 -1
  5. data/lib/calabash/android/build/resigner.rb +19 -1
  6. data/lib/calabash/android/device.rb +13 -2
  7. data/lib/calabash/android/interactions.rb +104 -3
  8. data/lib/calabash/android/lib/TestServer.apk +0 -0
  9. data/lib/calabash/android/life_cycle.rb +5 -4
  10. data/lib/calabash/android/physical_buttons.rb +4 -1
  11. data/lib/calabash/android/scroll.rb +5 -0
  12. data/lib/calabash/android/text.rb +10 -25
  13. data/lib/calabash/android.rb +3 -0
  14. data/lib/calabash/cli/generate.rb +2 -0
  15. data/lib/calabash/console_helpers.rb +4 -2
  16. data/lib/calabash/device.rb +1 -9
  17. data/lib/calabash/environment.rb +4 -0
  18. data/lib/calabash/gestures.rb +159 -66
  19. data/lib/calabash/http/retriable_client.rb +1 -1
  20. data/lib/calabash/interactions.rb +67 -5
  21. data/lib/calabash/ios/conditions.rb +0 -1
  22. data/lib/calabash/ios/device/device_implementation.rb +17 -5
  23. data/lib/calabash/ios/device/gestures_mixin.rb +202 -48
  24. data/lib/calabash/ios/device/rotation_mixin.rb +10 -8
  25. data/lib/calabash/ios/device/routes/handle_route_mixin.rb +5 -1
  26. data/lib/calabash/ios/device/runtime_attributes.rb +4 -5
  27. data/lib/calabash/ios/gestures.rb +82 -8
  28. data/lib/calabash/ios/orientation.rb +21 -21
  29. data/lib/calabash/ios/runtime.rb +146 -2
  30. data/lib/calabash/ios/slider.rb +70 -0
  31. data/lib/calabash/ios/text.rb +6 -2
  32. data/lib/calabash/ios/uia.rb +24 -2
  33. data/lib/calabash/ios.rb +2 -0
  34. data/lib/calabash/lib/skeleton/features/support/dry_run.rb +8 -0
  35. data/lib/calabash/life_cycle.rb +59 -30
  36. data/lib/calabash/location.rb +0 -1
  37. data/lib/calabash/orientation.rb +0 -1
  38. data/lib/calabash/page.rb +38 -5
  39. data/lib/calabash/patch/array.rb +7 -7
  40. data/lib/calabash/query.rb +17 -2
  41. data/lib/calabash/query_result.rb +10 -0
  42. data/lib/calabash/screenshot.rb +28 -8
  43. data/lib/calabash/text.rb +52 -8
  44. data/lib/calabash/utility.rb +3 -3
  45. data/lib/calabash/version.rb +1 -1
  46. data/lib/calabash/wait.rb +33 -11
  47. data/lib/calabash.rb +124 -13
  48. metadata +114 -111
@@ -4,6 +4,7 @@ module Calabash
4
4
  # It will, unlike `Array`, raise an IndexError instead of returning nil if
5
5
  # an entry outside bounds is accessed.
6
6
  class QueryResult < Array
7
+ # @!visibility private
7
8
  def self.create(result, query)
8
9
  query_result = QueryResult.send(:new, query)
9
10
  query_result.send(:initialize_copy, result)
@@ -13,36 +14,43 @@ module Calabash
13
14
 
14
15
  private_class_method :new
15
16
 
17
+ # @!visibility private
16
18
  attr_reader :query
17
19
 
20
+ # @!visibility private
18
21
  def initialize(query)
19
22
  @query = Query.new(query)
20
23
  end
21
24
 
25
+ # @!visibility private
22
26
  def first(*several_variants)
23
27
  ensure_in_bounds(0)
24
28
 
25
29
  super(*several_variants)
26
30
  end
27
31
 
32
+ # @!visibility private
28
33
  def last(*several_variants)
29
34
  ensure_in_bounds(-1)
30
35
 
31
36
  super(*several_variants)
32
37
  end
33
38
 
39
+ # @!visibility private
34
40
  def [](index)
35
41
  ensure_in_bounds(index)
36
42
 
37
43
  super(index)
38
44
  end
39
45
 
46
+ # @!visibility private
40
47
  def at(index)
41
48
  ensure_in_bounds(index)
42
49
 
43
50
  super(index)
44
51
  end
45
52
 
53
+ # @!visibility private
46
54
  def fetch(*several_variants)
47
55
  unless block_given? || several_variants.length > 1
48
56
  ensure_in_bounds(several_variants.first)
@@ -51,6 +59,7 @@ module Calabash
51
59
  super(*several_variants)
52
60
  end
53
61
 
62
+ # @!visibility private
54
63
  def ensure_in_bounds(index)
55
64
  if empty?
56
65
  raise IndexError, "Query result is empty"
@@ -65,6 +74,7 @@ module Calabash
65
74
  end
66
75
  end
67
76
 
77
+ # @!visibility private
68
78
  def self.recursive_freeze(object)
69
79
  if object.is_a?(Array)
70
80
  object.each do |entry|
@@ -4,7 +4,6 @@ require 'pathname'
4
4
  module Calabash
5
5
 
6
6
  # A public API for taking screenshots.
7
- # @!visibility private
8
7
  module Screenshot
9
8
  # @!visibility private
10
9
  def self.screenshot_directory_prefix
@@ -12,6 +11,7 @@ module Calabash
12
11
  end
13
12
 
14
13
  # Set the screenshot directory prefix.
14
+ # @!visibility private
15
15
  def self.screenshot_directory_prefix=(value)
16
16
  if class_variable_defined?(:@@screenshots_taken) &&
17
17
  @@screenshots_taken != 0
@@ -24,22 +24,36 @@ module Calabash
24
24
  # @!visibility private
25
25
  self.screenshot_directory_prefix = 'test_run_'
26
26
 
27
- # Takes a screenshot and saves it. The file is stored in the directory
28
- # given by the ENV variable $CAL_SCREENSHOT_DIR, or by default in
29
- # the relative directory 'screenshots'. The files are saved in a
27
+ # Takes a screenshot and saves it.
28
+ #
29
+ # If `name` is a relative path or a file name, then the file is stored in
30
+ # the directory specified by the ENV variable CAL_SCREENSHOT_DIR, or by
31
+ # default in the relative directory 'screenshots'. The files are saved in a
30
32
  # sub directory named test_run_n, where n is unique and incrementing for
31
33
  # each new test run. The filename of the screenshot will be `name`.
32
34
  # If `name` is not given (nil), the screenshot will be saved as
33
35
  # screenshot_N, where N is the total amount of screenshots taken for the
34
36
  # test run.
35
37
  #
38
+ # If the name given is an absolute path, then Calabash will save the
39
+ # screenshot to the absolute directory given.
40
+ #
41
+ # If the name given starts with ./ (e.g. `screenshot('./foo.png')`) then
42
+ # the filename will be saved relative to the current working directory.
43
+ #
44
+ # If the file specified by `name` has no extension then the filename will
45
+ # default to name + '.png'.
46
+ #
47
+ # If the directories specified do not exist, Calabash will create them.
48
+ #
36
49
  # @param [String] name Name of the screenshot.
37
50
  # @return [String] Path to the screenshot
38
51
  def screenshot(name=nil)
39
52
  Device.default.screenshot(name)
40
53
  end
41
54
 
42
- # Takes a screenshot and embeds it in the test report.
55
+ # Takes a screenshot and embeds it in the test report. This method is only
56
+ # available/useful when running in the context of cucumber.
43
57
  # @see Screenshot#screenshot
44
58
  def screenshot_embed(name=nil)
45
59
  path = screenshot(name)
@@ -58,11 +72,17 @@ module Calabash
58
72
 
59
73
  @@screenshots_taken += 1
60
74
 
61
- unless Dir.exist?(File.expand_path(screenshot_directory))
62
- FileUtils.mkdir_p(File.expand_path(screenshot_directory))
75
+ if name.start_with?('./')
76
+ name = File.join(Dir.pwd, "#{name[2..-1]}")
77
+ end
78
+
79
+ file_name = File.expand_path(name, screenshot_directory)
80
+
81
+ unless Dir.exist?(File.dirname(file_name))
82
+ FileUtils.mkdir_p(File.dirname(file_name))
63
83
  end
64
84
 
65
- File.join(screenshot_directory, name)
85
+ file_name
66
86
  end
67
87
 
68
88
  # @!visibility private
data/lib/calabash/text.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  module Calabash
2
2
 
3
3
  # A public API for entering text.
4
- # @!visibility private
5
4
  module Text
6
5
  # Enter `text` into the currently focused view.
7
6
  #
@@ -15,7 +14,8 @@ module Calabash
15
14
  # @see Calabash::Text#enter_text
16
15
  #
17
16
  # @param [String] text The text to type.
18
- # @param query A query describing the view to enter text into.
17
+ # @param [String, Hash, Calabash::Query] query A query describing the view
18
+ # to enter text into.
19
19
  def enter_text_in(query, text)
20
20
  _enter_text_in(query, text)
21
21
  end
@@ -28,21 +28,65 @@ module Calabash
28
28
  # Clears the text `view`
29
29
  # @see Calabash::Text#clear_text
30
30
  #
31
- # @param query A query describing the view to clear text in.
31
+ # @param [String, Hash, Calabash::Query] query A query describing the view
32
+ # to clear text in.
32
33
  def clear_text_in(query)
33
34
  _clear_text_in(query)
34
35
  end
35
36
 
36
- # @todo add docs
37
- def tap_current_keyboard_action_key
38
- _tap_current_keyboard_action_key
37
+ # Taps the keyboard action key. On iOS there is only one action key, which
38
+ # is the blue coloured key on the standard keyboard. On Android, there can
39
+ # be multiple actions keys available depending on the keyboard, but one key
40
+ # is often replacing the enter key, becoming the default action key. The
41
+ # view in focus on Android asks to keyboard to show one action key, but the
42
+ # keyboard might not adhere to this.
43
+ #
44
+ # On iOS some examples include:
45
+ # * Return
46
+ # * Next
47
+ # * Go
48
+ # * Join
49
+ # * Search
50
+ #
51
+ # On Android some examples include:
52
+ # * Search
53
+ # * Next
54
+ # * Previous
55
+ #
56
+ # See http://developer.android.com/reference/android/view/inputmethod/EditorInfo.html
57
+ #
58
+ # @example
59
+ # tap_keyboard_action_key(:search)
60
+ # tap_keyboard_action_key(:send)
61
+ # tap_keyboard_action_key(:next)
62
+ # tap_keyboard_action_key(:previous)
63
+ #
64
+ # Notice that, for Android, Calabash does not ensure that this particular action key is
65
+ # actually available on the current keyboard.
66
+ #
67
+ # Not all keyboards have an action key. For example, on iOS, numeric keyboards
68
+ # do not have an action key. On Android, if no action key is set for the
69
+ # view, the enter key is pressed instead.
70
+ #
71
+ # @param [Symbol] action_key The action key to press. This is only
72
+ # used for Android.
73
+ # @raise [ArgumentError] If action_key if set for iOS.
74
+ def tap_keyboard_action_key(action_key = nil)
75
+ _tap_keyboard_action_key(action_key)
76
+ true
39
77
  end
40
78
 
41
79
  # Escapes single quotes in `string`.
42
80
  #
43
81
  # @example
44
- # > escape_quotes("Let's get this done.")
82
+ # escape_single_quotes("Let's get this done.")
45
83
  # => "Let\\'s get this done."
84
+ #
85
+ # @example
86
+ # query("* text:'#{escape_single_quotes("Let's go")}'")
87
+ # # Equivalent to
88
+ # query("* text:'Let\\'s go'")
89
+ #
46
90
  # @param [String] string The string to escape.
47
91
  # @return [String] A string with its single quotes properly escaped.
48
92
  def escape_single_quotes(string)
@@ -70,7 +114,7 @@ module Calabash
70
114
  end
71
115
 
72
116
  # @!visibility private
73
- def _tap_current_keyboard_action_key
117
+ def _tap_keyboard_action_key(action_key)
74
118
  abstract_method!
75
119
  end
76
120
 
@@ -5,7 +5,6 @@ module Calabash
5
5
 
6
6
  end
7
7
 
8
- # @!visibility private
9
8
  module Utility
10
9
 
11
10
  # @!visibility private
@@ -27,8 +26,8 @@ module Calabash
27
26
  #
28
27
  # @example
29
28
  # # These are equivalent.
30
- # pan(percent(20, 50), percent(20, 100))
31
- # pan({x: 20, y: 50}, {x: 20, y: 100})
29
+ # pan("*", percent(20, 50), percent(20, 100))
30
+ # pan("*", {x: 20, y: 50}, {x: 20, y: 100})
32
31
  #
33
32
  # @param [Number] x The value of the x percent.
34
33
  # @param [Number] y The value of the y percent.
@@ -50,6 +49,7 @@ module Calabash
50
49
  # @param [Number] x The value of the x.
51
50
  # @param [Number] y The value of the y.
52
51
  # @return [Hash] Representing the given values.
52
+ # @!visibility private
53
53
  def coordinate(x, y)
54
54
  {x: x, y: y}
55
55
  end
@@ -1,5 +1,5 @@
1
1
  module Calabash
2
2
 
3
3
  # @!visibility private
4
- VERSION = '1.9.9.pre3'
4
+ VERSION = '2.0.0.pre1'
5
5
  end
data/lib/calabash/wait.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  module Calabash
2
2
 
3
3
  # A public API for waiting for things to happen.
4
- # @!visibility private
5
4
  module Wait
6
5
  # @!visibility private
7
6
  class TimeoutError < RuntimeError
@@ -141,9 +140,15 @@ module Calabash
141
140
 
142
141
  # Waits for `query` to match one or more views.
143
142
  #
144
- # @param [String] query Query to match view
143
+ # @example
144
+ # wait_for_view({marked: 'mark'})
145
+ #
146
+ # @example
147
+ # text = wait_for_view("myview")['text']
148
+ #
149
+ # @param [String, Hash, Calabash::Query] query Query to match view
145
150
  # @see Calabash::Wait#with_timeout for options
146
- # @return [Object] The first view matching `query`.
151
+ # @return [Hash] The first view matching `query`.
147
152
  def wait_for_view(query, options={})
148
153
  if query.nil?
149
154
  raise ArgumentError, 'Query cannot be nil'
@@ -169,7 +174,9 @@ module Calabash
169
174
 
170
175
  # Waits for all `queries` to simultaneously match at least one view.
171
176
  #
172
- # @param [Array<String>, String] queries List of queries or a query.
177
+ # @param [String, Hash, Calabash::Query] queries List of queries or a
178
+ # query.
179
+ #
173
180
  # @see Calabash::Wait#with_timeout for options
174
181
  # @return [void] The return value for this method is undefined.
175
182
  def wait_for_views(*queries, **options)
@@ -200,7 +207,7 @@ module Calabash
200
207
 
201
208
  # Waits for `query` not to match any views
202
209
  #
203
- # @param [String] query Query to match view
210
+ # @param [String, Hash, Calabash::Query] query Query to match view
204
211
  # @see Calabash::Wait#with_timeout for options
205
212
  def wait_for_no_view(query, options={})
206
213
  if query.nil?
@@ -226,7 +233,9 @@ module Calabash
226
233
 
227
234
  # Waits for all `queries` to simultaneously match no views
228
235
  #
229
- # @param [Array<String>, String] queries List of queries or a query.
236
+ # @param [String, Hash, Calabash::Query] queries List of queries or a
237
+ # query.
238
+ #
230
239
  # @see Calabash::Wait#with_timeout for options
231
240
  def wait_for_no_views(*queries, **options)
232
241
  if queries.nil? || queries.any?(&:nil?)
@@ -252,7 +261,7 @@ module Calabash
252
261
 
253
262
  # Does the given `query` match at least one view?
254
263
  #
255
- # @param [String] query Query to match view
264
+ # @param [String, Hash, Calabash::Query] query Query to match view
256
265
  # @return [Object] Returns truthy if the `query` matches at least one view
257
266
  # @raise [ArgumentError] If given an invalid `query`
258
267
  def view_exists?(query)
@@ -271,7 +280,9 @@ module Calabash
271
280
 
272
281
  # Does the given `queries` all match at least one view?
273
282
  #
274
- # @param [Array<String>, String] queries List of queries or a query
283
+ # @param [String, Hash, Calabash::Query] queries List of queries or a
284
+ # query
285
+ #
275
286
  # @return Returns truthy if the `queries` all match at least one view
276
287
  # @raise [ArgumentError] If given an invalid list of queries
277
288
  def views_exist?(*queries)
@@ -291,7 +302,7 @@ module Calabash
291
302
  # Expect `query` to match at least one view. Raise an exception if it does
292
303
  # not.
293
304
  #
294
- # @param [String] query Query to match view
305
+ # @param [String, Hash, Calabash::Query] query Query to match a view
295
306
  # @raise [ArgumentError] If given an invalid `query`
296
307
  # @raise [ViewNotFoundError] If `query` does not match at least one view
297
308
  def expect_view(query)
@@ -303,6 +314,8 @@ module Calabash
303
314
  raise ViewNotFoundError,
304
315
  "No view matched #{parse_query_list(query)}"
305
316
  end
317
+
318
+ true
306
319
  end
307
320
 
308
321
  alias_method :view_should_exist, :expect_view
@@ -310,7 +323,8 @@ module Calabash
310
323
  # Expect `queries` to each match at least one view. Raise an exception if
311
324
  # they do not.
312
325
  #
313
- # @param [String] queries List of queries or a query
326
+ # @param [String, Hash, Calabash::Query] queries List of queries or a
327
+ # query.
314
328
  # @raise [ArgumentError] If given an invalid list of queries
315
329
  # @raise [ViewNotFoundError] If `queries` do not all match at least one
316
330
  # view.
@@ -323,12 +337,15 @@ module Calabash
323
337
  raise ViewNotFoundError,
324
338
  "Not all queries #{parse_query_list(queries)} matched a view"
325
339
  end
340
+
341
+ true
326
342
  end
327
343
 
328
344
  alias_method :views_should_exist, :expect_views
329
345
 
330
346
  # Expect `query` to match no views. Raise an exception if it does.
331
347
  #
348
+ # @param [String, Hash, Calabash::Query] query Query to match a view
332
349
  # @raise [ArgumentError] If given an invalid `query`
333
350
  # @raise [ViewFoundError] If `query` matches any views.
334
351
  def do_not_expect_view(query)
@@ -339,13 +356,16 @@ module Calabash
339
356
  if view_exists?(query)
340
357
  raise ViewFoundError, "A view matched #{parse_query_list(query)}"
341
358
  end
359
+
360
+ true
342
361
  end
343
362
 
344
363
  alias_method :view_should_not_exist, :do_not_expect_view
345
364
 
346
365
  # Expect `queries` to each match no views. Raise an exception if they do.
347
366
  #
348
- # @param [Array<String>, String] queries List of queries or a query
367
+ # @param [String, Hash, Calabash::Query] queries List of queries or a
368
+ # query.
349
369
  # @raise [ArgumentError] If given an invalid list of queries
350
370
  # @raise [ViewFoundError] If one of `queries` matched any views
351
371
  def do_not_expect_views(*queries)
@@ -357,6 +377,8 @@ module Calabash
357
377
  raise ViewFoundError,
358
378
  "Some views matched #{parse_query_list(queries)}"
359
379
  end
380
+
381
+ true
360
382
  end
361
383
 
362
384
  alias_method :views_should_not_exist, :do_not_expect_views
data/lib/calabash.rb CHANGED
@@ -45,22 +45,58 @@ module Calabash
45
45
 
46
46
  require 'calabash/page'
47
47
 
48
- # Instantiate a page object.
48
+ # Instantiate a page object for the current platform.
49
+ #
50
+ # @note Your pages **must** be in the scope of either Android or IOS. See the
51
+ # examples for details.
49
52
  #
50
53
  # @example
51
- # # android/pages/login_page.rb
52
- # class Android::LoginPage < Calabash::Page
54
+ # # android/pages/my_page.rb
55
+ # class Android::MyPage < Calabash::Page
53
56
  # include Calabash::Android
54
57
  #
55
- # [...]
58
+ # # [...]
56
59
  # end
57
60
  #
58
61
  # # step definition
59
- # Given([...]) do
62
+ # Given(/[...]/) do
60
63
  # # Calabash will determine your platform and pick the Android page.
61
- # page(LoginPage).method
64
+ # page(MyPage).method
65
+ # end
66
+ #
67
+ # @example
68
+ # # This example shows page code sharing across iOS and Android
69
+ # # Please see the sample 'shared-page-logic' for details.
70
+ # # pages/abstract_login_page.rb
71
+ # class AbstractLoginPage < Calabash::Page
72
+ # def login(username, password)
73
+ # enter_text_in(username_field, username)
74
+ # # [...]
75
+ # end
76
+ #
77
+ # private
78
+ #
79
+ # def username_field
80
+ # abstract_method!
81
+ # end
62
82
  # end
63
83
  #
84
+ # # pages/android_login_page.rb
85
+ # class Android::LoginPage < SharedLoginPage
86
+ # include Calabash::Android
87
+ #
88
+ # private
89
+ #
90
+ # def username_field
91
+ # "* marked:'a_username'"
92
+ # end
93
+ #
94
+ # # [...]
95
+ # end
96
+ #
97
+ #
98
+ # @see #android?
99
+ # @see #ios?
64
100
  # @param [Class] page_class The page to instantiate
65
101
  # @return [Calabash::Page] An instance of the page class
66
102
  def page(page_class)
@@ -76,9 +112,11 @@ module Calabash
76
112
  raise ArgumentError, "Expected a 'Class', got '#{page_class.class}'"
77
113
  end
78
114
 
79
- page_name = page_class.name.split('::').last
80
115
 
81
- if platform_module.const_defined?(page_name, false)
116
+ page_name = page_class.name
117
+ full_page_name = "#{platform_module}::#{page_name}"
118
+
119
+ if Calabash.is_defined?(full_page_name)
82
120
  page_class = platform_module.const_get(page_name, false)
83
121
 
84
122
  if page_class.is_a?(Class)
@@ -93,18 +131,26 @@ module Calabash
93
131
  raise "Page '#{page_class}' is not a class"
94
132
  end
95
133
  else
96
- raise "No such page defined '#{platform_module}::#{page_name}'"
134
+ raise "No such page defined '#{full_page_name}'"
97
135
  end
98
136
  end
99
137
 
100
- # Is the app under test running on Android?
138
+ # Is the device under test running Android?
139
+ #
140
+ # @return [Boolean] Returns true if
141
+ # {Calabash::Defaults#default_device Calabash.default_device} is an instance
142
+ # of {Calabash::Android::Device}.
101
143
  def android?
102
- Android.const_defined?(:Device) && Device.default.is_a?(Android::Device)
144
+ Android.const_defined?(:Device, false) && Device.default.is_a?(Android::Device)
103
145
  end
104
146
 
105
- # Is the app under test running on iOS?
147
+ # Is the device under test running iOS?
148
+ #
149
+ # @return [Boolean] Returns true if
150
+ # {Calabash::Defaults#default_device Calabash.default_device} is an instance
151
+ # of {Calabash::IOS::Device}.
106
152
  def ios?
107
- IOS.const_defined?(:Device) && Device.default.is_a?(IOS::Device)
153
+ IOS.const_defined?(:Device, false) && Device.default.is_a?(IOS::Device)
108
154
  end
109
155
 
110
156
  # @!visibility private
@@ -159,6 +205,29 @@ module Calabash
159
205
  end
160
206
  end
161
207
 
208
+ # @!visibility private
209
+ def self.is_defined?(string, scope = Object)
210
+ constant, rest = string.split('::', 2)
211
+
212
+ begin
213
+ scope.const_defined?(constant.to_sym, false) &&
214
+ (!rest || is_defined?(rest, scope.const_get(constant, false)))
215
+ rescue NameError => _
216
+ false
217
+ end
218
+ end
219
+
220
+ # @!visibility private
221
+ def self.recursive_const_get(string, scope = Object)
222
+ constant, rest = string.split('::', 2)
223
+
224
+ if rest
225
+ recursive_const_get(rest, scope.const_get(constant.to_sym, false))
226
+ else
227
+ scope.const_get(constant.to_sym, false)
228
+ end
229
+ end
230
+
162
231
  # @!visibility private
163
232
  def self.on_cucumber_context(base)
164
233
  on_new_context(base)
@@ -193,3 +262,45 @@ end
193
262
  unless Object.const_defined?(:IOS)
194
263
  Object.const_set(:IOS, Module.new)
195
264
  end
265
+
266
+ if Calabash::Environment::DEBUG_CALLED_METHODS
267
+ $stdout.puts "#{Calabash::Color.red("Will print every Calabash method called!")}"
268
+ $stdout.puts "#{Calabash::Color.red("Warning: This might slow down your test drastically")}"
269
+ $stdout.puts "#{Calabash::Color.red("and is an experimental feature.")}"
270
+
271
+ calabash_file = Calabash.method(:extended).source_location.first
272
+ $__calabash_dir_name = File.dirname(calabash_file)
273
+
274
+ trace_func = lambda do |event, file, line, id, binding, classname|
275
+ if event == 'call'
276
+ if classname.to_s.split('::').first == 'Calabash'
277
+ binding_caller_locations = binding.eval("caller_locations")
278
+ files = binding_caller_locations[3..-1].map(&:path)
279
+
280
+ calabash_not_in_stacktrace = files.none? do |file|
281
+ file.start_with?($__calabash_dir_name) &&
282
+ File.basename(file) != 'page.rb'
283
+ end
284
+
285
+ if calabash_not_in_stacktrace
286
+ unless id == :included || id == :extended || id == :inherited
287
+ arguments = {}
288
+
289
+ binding.eval('local_variables').each do |variable|
290
+ arguments[variable] = binding.eval(variable.to_s)
291
+ end
292
+
293
+ # The arguments will be in order
294
+ if arguments.empty?
295
+ $stdout.puts "Calabash method called: #{id}"
296
+ else
297
+ $stdout.puts "Calabash method called: #{id}(#{arguments.values.map(&:inspect).join(', ')})"
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+ end
304
+
305
+ set_trace_func(trace_func)
306
+ end