iCuke 0.6.3 → 0.6.4

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 (129) hide show
  1. data/.gitmodules +1 -1
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +41 -0
  4. data/README.markdown +126 -0
  5. data/Rakefile +34 -12
  6. data/VERSION +1 -1
  7. data/bin/icuke +12 -10
  8. data/ext/Rakefile +6 -0
  9. data/ext/iCuke/{sdk3.1/DefaultsResponse.h → DefaultsResponse.h} +0 -0
  10. data/ext/iCuke/{sdk3.1/DefaultsResponse.m → DefaultsResponse.m} +0 -0
  11. data/ext/iCuke/{sdk3.1/EventResponse.h → EventResponse.h} +0 -0
  12. data/ext/iCuke/{sdk3.1/EventResponse.m → EventResponse.m} +0 -0
  13. data/ext/iCuke/{sdk3.1/ModuleResponse.h → ModuleResponse.h} +0 -0
  14. data/ext/iCuke/{sdk3.1/ModuleResponse.m → ModuleResponse.m} +0 -0
  15. data/ext/iCuke/{sdk3.1/QuitResponse.h → QuitResponse.h} +0 -0
  16. data/ext/iCuke/{sdk3.1/QuitResponse.m → QuitResponse.m} +0 -0
  17. data/ext/iCuke/Rakefile +14 -13
  18. data/ext/iCuke/{sdk3.1/Recorder.h → Recorder.h} +0 -0
  19. data/ext/iCuke/{sdk3.1/Recorder.m → Recorder.m} +0 -0
  20. data/ext/iCuke/{sdk3.1/RecorderResponse.h → RecorderResponse.h} +0 -0
  21. data/ext/iCuke/{sdk3.1/RecorderResponse.m → RecorderResponse.m} +0 -0
  22. data/ext/iCuke/{sdk3.1/SynthesizeSingleton.h → SynthesizeSingleton.h} +0 -0
  23. data/ext/iCuke/{sdk3.1/ViewResponse.h → ViewResponse.h} +0 -0
  24. data/ext/iCuke/{sdk3.1/ViewResponse.m → ViewResponse.m} +0 -0
  25. data/ext/iCuke/{sdk3.1/Viewer.h → Viewer.h} +0 -0
  26. data/ext/iCuke/{sdk4.0/Viewer.m → Viewer.m} +0 -0
  27. data/ext/iCuke/{sdk3.1/iCukeHTTPResponseHandler.h → iCukeHTTPResponseHandler.h} +0 -0
  28. data/ext/iCuke/{sdk3.1/iCukeHTTPResponseHandler.m → iCukeHTTPResponseHandler.m} +0 -0
  29. data/ext/iCuke/{sdk3.1/iCukeHTTPServer.h → iCukeHTTPServer.h} +0 -0
  30. data/ext/iCuke/{sdk4.0/iCukeHTTPServer.m → iCukeHTTPServer.m} +4 -2
  31. data/ext/iCuke/{sdk3.1/iCukeServer.h → iCukeServer.h} +0 -0
  32. data/ext/iCuke/{sdk3.1/iCukeServer.m → iCukeServer.m} +0 -0
  33. data/ext/iCuke/{sdk3.1/json → json}/JSON.h +0 -0
  34. data/ext/iCuke/{sdk3.1/json → json}/NSObject+SBJSON.h +0 -0
  35. data/ext/iCuke/{sdk3.1/json → json}/NSObject+SBJSON.m +0 -0
  36. data/ext/iCuke/{sdk3.1/json → json}/NSString+SBJSON.h +0 -0
  37. data/ext/iCuke/{sdk3.1/json → json}/NSString+SBJSON.m +0 -0
  38. data/ext/iCuke/{sdk3.1/json → json}/SBJSON.h +0 -0
  39. data/ext/iCuke/{sdk3.1/json → json}/SBJSON.m +0 -0
  40. data/ext/iCuke/{sdk3.1/json → json}/SBJsonBase.h +0 -0
  41. data/ext/iCuke/{sdk3.1/json → json}/SBJsonBase.m +0 -0
  42. data/ext/iCuke/{sdk3.1/json → json}/SBJsonParser.h +0 -0
  43. data/ext/iCuke/{sdk3.1/json → json}/SBJsonParser.m +0 -0
  44. data/ext/iCuke/{sdk3.1/json → json}/SBJsonWriter.h +0 -0
  45. data/ext/iCuke/{sdk3.1/json → json}/SBJsonWriter.m +0 -0
  46. data/features/starting_project.feature +18 -0
  47. data/features/step_definitions/shell.rb +41 -0
  48. data/features/support/env.rb +2 -0
  49. data/features/support/environment.rb +40 -0
  50. data/features/supported_sdks.feature +12 -0
  51. data/iCuke.gemspec +149 -161
  52. data/lib/icuke/configuration.rb +19 -0
  53. data/lib/icuke/core_ext.rb +27 -0
  54. data/lib/icuke/cucumber.rb +29 -265
  55. data/lib/icuke/cucumber_compat.rb +4 -0
  56. data/lib/icuke/icuke_world.rb +149 -0
  57. data/lib/icuke/sdk.rb +5 -13
  58. data/lib/icuke/simulator_driver.rb +201 -0
  59. data/lib/icuke/waxsim.rb +47 -9
  60. data/spec/cucumber_spec.rb +130 -0
  61. data/spec/fixtures/controls_page.xml +252 -0
  62. data/spec/process_spec.rb +76 -0
  63. data/spec/screen_spec.rb +173 -0
  64. data/spec/simulate_spec.rb +75 -0
  65. data/spec/simulator_spec.rb +28 -0
  66. data/spec/spec.opts +2 -0
  67. data/spec/spec_helper.rb +67 -0
  68. metadata +222 -121
  69. data/.gitignore +0 -15
  70. data/README.rdoc +0 -68
  71. data/ext/WaxSim/Simulator.h +0 -31
  72. data/ext/WaxSim/Simulator.m +0 -131
  73. data/ext/WaxSim/WaxSim.m +0 -110
  74. data/ext/WaxSim/WaxSim.xcodeproj/project.pbxproj +0 -238
  75. data/ext/WaxSim/WaxSim_Prefix.pch +0 -7
  76. data/ext/WaxSim/build/Release/waxsim +0 -0
  77. data/ext/WaxSim/build/Release/waxsim.dSYM/Contents/Info.plist +0 -20
  78. data/ext/WaxSim/build/Release/waxsim.dSYM/Contents/Resources/DWARF/waxsim +0 -0
  79. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/Objects-normal/x86_64/Simulator.o +0 -0
  80. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/Objects-normal/x86_64/WaxSim.o +0 -0
  81. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/Objects-normal/x86_64/waxsim.LinkFileList +0 -2
  82. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/WaxSim.dep +0 -6
  83. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/WaxSim~.dep +0 -6
  84. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/build-state.dat +0 -227
  85. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/build-state~.dat +0 -227
  86. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim-all-target-headers.hmap +0 -0
  87. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim-generated-files.hmap +0 -0
  88. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim-own-target-headers.hmap +0 -0
  89. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim-project-headers.hmap +0 -0
  90. data/ext/WaxSim/build/WaxSim.build/Release/WaxSim.build/waxsim.hmap +0 -0
  91. data/ext/WaxSim/iPhoneSimulatorRemoteClient/iPhoneSimulatorRemoteClient.h +0 -126
  92. data/ext/iCuke/sdk3.1/Rakefile +0 -20
  93. data/ext/iCuke/sdk3.1/Viewer.m +0 -203
  94. data/ext/iCuke/sdk3.1/iCukeHTTPServer.m +0 -365
  95. data/ext/iCuke/sdk4.0/DefaultsResponse.h +0 -5
  96. data/ext/iCuke/sdk4.0/DefaultsResponse.m +0 -66
  97. data/ext/iCuke/sdk4.0/EventResponse.h +0 -5
  98. data/ext/iCuke/sdk4.0/EventResponse.m +0 -130
  99. data/ext/iCuke/sdk4.0/ModuleResponse.h +0 -5
  100. data/ext/iCuke/sdk4.0/ModuleResponse.m +0 -76
  101. data/ext/iCuke/sdk4.0/QuitResponse.h +0 -5
  102. data/ext/iCuke/sdk4.0/QuitResponse.m +0 -23
  103. data/ext/iCuke/sdk4.0/Rakefile +0 -20
  104. data/ext/iCuke/sdk4.0/Recorder.h +0 -17
  105. data/ext/iCuke/sdk4.0/Recorder.m +0 -90
  106. data/ext/iCuke/sdk4.0/RecorderResponse.h +0 -6
  107. data/ext/iCuke/sdk4.0/RecorderResponse.m +0 -68
  108. data/ext/iCuke/sdk4.0/SynthesizeSingleton.h +0 -68
  109. data/ext/iCuke/sdk4.0/ViewResponse.h +0 -5
  110. data/ext/iCuke/sdk4.0/ViewResponse.m +0 -84
  111. data/ext/iCuke/sdk4.0/Viewer.h +0 -8
  112. data/ext/iCuke/sdk4.0/iCukeHTTPResponseHandler.h +0 -50
  113. data/ext/iCuke/sdk4.0/iCukeHTTPResponseHandler.m +0 -381
  114. data/ext/iCuke/sdk4.0/iCukeHTTPServer.h +0 -53
  115. data/ext/iCuke/sdk4.0/iCukeServer.h +0 -14
  116. data/ext/iCuke/sdk4.0/iCukeServer.m +0 -65
  117. data/ext/iCuke/sdk4.0/json/JSON.h +0 -50
  118. data/ext/iCuke/sdk4.0/json/NSObject+SBJSON.h +0 -68
  119. data/ext/iCuke/sdk4.0/json/NSObject+SBJSON.m +0 -53
  120. data/ext/iCuke/sdk4.0/json/NSString+SBJSON.h +0 -58
  121. data/ext/iCuke/sdk4.0/json/NSString+SBJSON.m +0 -55
  122. data/ext/iCuke/sdk4.0/json/SBJSON.h +0 -75
  123. data/ext/iCuke/sdk4.0/json/SBJSON.m +0 -212
  124. data/ext/iCuke/sdk4.0/json/SBJsonBase.h +0 -86
  125. data/ext/iCuke/sdk4.0/json/SBJsonBase.m +0 -78
  126. data/ext/iCuke/sdk4.0/json/SBJsonParser.h +0 -87
  127. data/ext/iCuke/sdk4.0/json/SBJsonParser.m +0 -475
  128. data/ext/iCuke/sdk4.0/json/SBJsonWriter.h +0 -129
  129. data/ext/iCuke/sdk4.0/json/SBJsonWriter.m +0 -228
@@ -0,0 +1,19 @@
1
+ module ICuke
2
+ class Configuration
3
+ def initialize(defaults = {})
4
+ @data = defaults
5
+ end
6
+
7
+ def set(key, value)
8
+ @data[key] = value
9
+ end
10
+
11
+ def get(key)
12
+ @data[key]
13
+ end
14
+
15
+ def [](key)
16
+ get(key)
17
+ end
18
+ end
19
+ end
@@ -24,3 +24,30 @@ end
24
24
  if Net::HTTP::Revision.to_i == 25851
25
25
  Net::HTTP.send :include, RequestWithSocketCheck
26
26
  end
27
+
28
+
29
+ class Hash
30
+
31
+ # Merges self with another hash, recursively.
32
+ #
33
+ # This code was lovingly stolen from some random gem:
34
+ # http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
35
+ #
36
+ # Thanks to whoever made it.
37
+
38
+ def deep_merge(hash)
39
+ target = dup
40
+
41
+ hash.keys.each do |key|
42
+ if hash[key].is_a? Hash and self[key].is_a? Hash
43
+ target[key] = target[key].deep_merge(hash[key])
44
+ next
45
+ end
46
+
47
+ target[key] = hash[key]
48
+ end
49
+
50
+ target
51
+ end
52
+
53
+ end
@@ -1,269 +1,33 @@
1
- require 'nokogiri'
2
-
3
- require 'icuke/sdk'
4
- require 'icuke/simulator'
5
- require 'icuke/simulate'
6
- require 'icuke/screen'
7
-
8
- class ICukeWorld
9
- include ICuke::Simulate::Gestures
10
-
11
- attr_reader :response, :simulator
12
-
13
- def initialize
14
- @simulator = ICuke::Simulator.new
15
- end
16
-
17
- def launch(application, options = {})
18
- process = ICuke::Simulator::Process.new(application, options)
19
- @simulator.launch(process)
20
- end
21
-
22
- def quit
23
- @simulator.quit
24
- end
25
-
26
- def suspend
27
- @simulator.suspend
28
- end
29
-
30
- def resume
31
- @simulator.resume
32
- end
33
-
34
- def screen
35
- @screen ||= Screen.new(response)
36
- end
37
-
38
- def response
39
- @response ||= @simulator.view
40
- end
41
-
42
- def record
43
- @simulator.record
44
- end
45
-
46
- def tap(label, options = {}, &block)
47
- options = {
48
- :pause => true
49
- }.merge(options)
50
-
51
- element = screen.first_tappable_element(label)
52
- x, y = screen.element_center(element)
53
-
54
- @simulator.fire_event(Tap.new(x, y, options))
55
-
56
- sleep(options[:pause] ? 2 : 0.2)
57
-
58
- refresh
59
-
60
- yield element if block_given?
61
- end
62
-
63
- def swipe(direction, options = {})
64
- x, y, x2, y2 = screen.swipe_coordinates(direction)
65
- @simulator.fire_event(Swipe.new(x, y, x2, y2, 0.015, options))
66
- sleep(1)
67
- refresh
68
- end
69
-
70
- def drag(source_x, source_y, dest_x, dest_y, options = {})
71
- @simulator.fire_event(Drag.new(source_x, source_y, dest_x, dest_y, 0.15, options))
72
- sleep(1)
73
- refresh
74
- end
75
-
76
- def drag_with_source(source, destination)
77
- sources = source.split(',').collect {|val| val.strip.to_i}
78
- destinations = destination.split(',').collect {|val| val.strip.to_i}
79
- drag(sources[0], sources[1], destinations[0], destinations[1])
80
- end
81
-
82
- def drag_slider_to(label, direction, distance)
83
- element = screen.first_slider_element(label)
84
- x, y = screen.find_slider_button(element)
85
-
86
- dest_x, dest_y = x, y
87
- modifier = direction_modifier(direction)
88
-
89
- if [:up, :down].include?(direction)
90
- dest_y += modifier * distance
91
- else
92
- dest_x += modifier * distance
93
- end
94
-
95
- drag(x, y, dest_x, dest_y)
96
- end
97
-
98
- def drag_slider_to_percentage(label, percentage)
99
- element = screen.first_slider_element(label)
100
- x, y = screen.find_slider_button(element)
101
- dest_x, dest_y = screen.find_slider_percentage_location(element, percentage)
102
- drag(x, y, dest_x, dest_y)
103
- end
104
-
105
- def type(textfield, text, options = {})
106
- tap(textfield, :hold_for => 0.75) do |field|
107
- if field['value']
108
- tap('Select All')
109
- tap('Delete')
110
- end
111
- end
112
-
113
- # Without this sleep fields which have auto-capitilisation/correction can
114
- # miss the first keystroke for some reason.
115
- sleep(0.5)
116
-
117
- text.split('').each do |c|
118
- begin
119
- tap(c == ' ' ? 'space' : c, :pause => false)
120
- rescue Exception => e
121
- try_keyboards =
122
- case c
123
- when /[a-zA-Z]/
124
- ['more, letters', 'shift']
125
- when /[0-9]/
126
- ['more, numbers']
127
- else
128
- ['more, numbers', 'more, symbols']
129
- end
130
- until try_keyboards.empty?
131
- begin
132
- tap(try_keyboards.shift, :pause => false)
133
- retry
134
- rescue
135
- end
136
- end
137
- raise e
1
+ require 'icuke/icuke_world'
2
+
3
+ module ICukeWorld
4
+
5
+ # Blatantly ripped from Capybara: (http://github.com/jnicklas/capybara)
6
+ #
7
+ # This block rewrites each of the driver methods in ICukeWorld to make
8
+ # them available as "bare" methods on the World object.
9
+ #
10
+ # icuke_driver.screen becomes #screen, for example. icuke_driver.tap
11
+ # becomes #tap.
12
+ #
13
+ # Obviously this is just syntactic sugar, but isn't that what makes life
14
+ # worth living?
15
+ #
16
+ # The trap with this is that some of the methods produced by this
17
+ # rewriting may conflict with other methods that are already in the World
18
+ # object. For example, there is a #drag method added by Capybara that
19
+ # conflicts with the #drag method in ICukeWorld.
20
+ #
21
+ # If you're stuck with this conflict, require 'icuke/cucumber_compat'
22
+ # instead of 'icuke/cucumber' to get the methods still scoped to an
23
+ # icuke_driver object.
24
+ #
25
+ ICuke::SimulatorDriver::DSL_METHODS.each do |method|
26
+ class_eval %Q{
27
+ def #{method}(*args, &block)
28
+ icuke_driver.#{method}(*args, &block)
138
29
  end
139
- end
140
-
141
- # From UIReturnKeyType
142
- # Should probably sort these in rough order of likelyhood?
143
- return_keys = ['return', 'go', 'google', 'join', 'next', 'route', 'search', 'send', 'yahoo', 'done', 'emergency call']
144
- return_keys.each do |key|
145
- begin
146
- tap(key)
147
- return
148
- rescue
149
- end
150
- end
151
- end
152
-
153
- def scroll_to(text, options = {})
154
- x, y, x2, y2 = screen.swipe_coordinates(swipe_direction(options[:direction]))
155
- previous_response = response.dup
156
- until screen.visible?(text) do
157
- @simulator.fire_event(Swipe.new(x, y, x2, y2, 0.15, options))
158
- refresh
159
- raise %Q{Content "#{text}" not found in: #{screen}} if response == previous_response
160
- end
161
- end
162
-
163
- def scroll(direction)
164
- swipe(swipe_direction(direction))
30
+ }, __FILE__, __LINE__
165
31
  end
166
-
167
- def set_application_defaults(defaults)
168
- @simulator.set_defaults(defaults)
169
- end
170
-
171
- private
172
-
173
- def refresh
174
- @response = nil
175
- @screen = nil
176
- end
177
-
178
- def swipe_direction(direction)
179
- swipe_directions = { :up => :down, :down => :up, :left => :right, :right => :left }
180
- swipe_directions[direction]
181
- end
182
-
183
- def direction_modifier(direction)
184
- [:up, :left].include?(direction) ? -1 : 1
185
- end
186
-
187
- end
188
-
189
- World do
190
- ICukeWorld.new
191
- end
192
-
193
- After do
194
- quit
195
- end
196
-
197
- Given /^(?:"([^\"]*)" from )?"([^\"]*)" is loaded in the (?:(iphone|ipad) )?simulator(?: with SDK ([0-9.]+))?$/ do |target, project, platform, sdk_version|
198
- if sdk_version
199
- ICuke::SDK.use(sdk_version)
200
- elsif platform
201
- ICuke::SDK.use_latest(platform.downcase.to_sym)
202
- else
203
- ICuke::SDK.use_latest
204
- end
205
-
206
- launch File.expand_path(project),
207
- :target => target,
208
- :platform => platform,
209
- :env => {
210
- 'DYLD_INSERT_LIBRARIES' => ICuke::SDK.dylib_fullpath
211
- }
212
- end
213
-
214
- Given /^the module "([^\"]*)" is loaded in the simulator$/ do |path|
215
- path.sub!(/#{File.basename(path)}$/, ICuke::SDK.dylib(File.basename(path)))
216
- simulator.load_module(File.expand_path(path))
217
- end
218
-
219
- Then /^I should see "([^\"]*)"(?: within "([^\"]*)")?$/ do |text, scope|
220
- raise %Q{Content "#{text}" not found in: #{screen.xml}} unless screen.visible?(text, scope)
221
- end
222
-
223
- Then /^I should not see "([^\"]*)"(?: within "([^\"]*)")?$/ do |text, scope|
224
- raise %Q{Content "#{text}" was found but was not expected in: #{screen.xml}} if screen.visible?(text, scope)
225
- end
226
-
227
- When /^I tap "([^\"]*)"$/ do |label|
228
- tap(label)
229
- end
230
-
231
- When /^I type "([^\"]*)" in "([^\"]*)"$/ do |text, textfield|
232
- type(textfield, text)
233
- end
234
-
235
- When /^I drag from (.*) to (.*)$/ do |source, destination|
236
- drag_with_source(source, destination)
237
- end
238
-
239
- When /^I select the "(.*)" slider and drag (.*) pixels (down|up|left|right)$/ do |label, distance, direction|
240
- drag_slider_to(label, direction.to_sym, distance.to_i)
241
- end
242
-
243
- When /^I move the "([^\"]*)" slider to (.*) percent$/ do |label, percent|
244
- drag_slider_to_percentage(label, percent.to_i)
245
- end
246
-
247
- When /^I scroll (down|up|left|right)(?: to "([^\"]*)")?$/ do |direction, text|
248
- if text
249
- scroll_to(text, :direction => direction.to_sym)
250
- else
251
- scroll(direction.to_sym)
252
- end
253
- end
254
-
255
- When /^I suspend the application/ do
256
- suspend
257
- end
258
-
259
- When /^I resume the application/ do
260
- resume
261
- end
262
-
263
- Then /^I put the phone into recording mode$/ do
264
- record
265
- end
266
32
 
267
- Then /^show me the screen$/ do
268
- puts screen.xml.to_s
269
33
  end
@@ -0,0 +1,4 @@
1
+ # This file is just a stub to allow us to provide different methods
2
+ # by requiring icuke/cucumber_compat or icuke/cucumber. See the README
3
+ # and icuke/cucumber.rb for the rationale for that.
4
+ require 'icuke/icuke_world'
@@ -0,0 +1,149 @@
1
+ require 'nokogiri'
2
+
3
+ require 'icuke/sdk'
4
+ require 'icuke/simulator_driver'
5
+
6
+ module ICukeWorld
7
+ def icuke_driver
8
+ @icuke_driver ||= ICuke::SimulatorDriver.default_driver(icuke_configuration)
9
+ end
10
+
11
+ def icuke_configuration
12
+ @icuke_configuration ||= ICuke::Configuration.new({
13
+ :build_configuration => 'Debug'
14
+ })
15
+ end
16
+ end
17
+
18
+ After do
19
+ icuke_driver.quit
20
+ end
21
+
22
+ ##
23
+ # :section: Loading the iOS Application
24
+ #
25
+ # Launching the application is the most difficult part. Many parts can be
26
+ # omitted, but the full form looks like this:
27
+ #
28
+ # Given "iCuke" from "app/iCuke/iCuke.xcodeproj" with build configuration "Debug" is loaded in the retina iphone simulator with SDK 4.1
29
+ #
30
+ # In this case:
31
+ # * "iCuke" is the name of the app to load.
32
+ # * "app/iCuke/iCuke.xcodeproj" is the path to the Xcode project.
33
+ # * "Debug" specifies the build configuration. "Debug" is used if not
34
+ # specified.
35
+ # * "retina" or "non-retina" can optionally be specified. If specified, the
36
+ # simulator is configured for retina or non-retina version of the device
37
+ # before launching the application. If not specified, the simulator
38
+ # chooses, which means that it will run with the last selected resolution.
39
+ # * "iphone" or "ipad" selects the device type. "iphone" is the default.
40
+ # * The optional clause "with SDK 4.0" selects the version of the simulator
41
+ # used. The iPhone simulator for that version of the SDK must be installed.
42
+ #
43
+ Given /^(?:"([^\"]*)" from )?"([^\"]*)"(?: with build configuration "([^\"]*)")? is loaded in the (?:(retina|non-retina) )?(?:(iphone|ipad) )?simulator(?: with SDK ([0-9.]+))?$/ do |target, project, configuration, retina, platform, sdk_version|
44
+ if sdk_version
45
+ ICuke::SDK.use(sdk_version)
46
+ elsif platform
47
+ ICuke::SDK.use_latest(platform.downcase.to_sym)
48
+ else
49
+ ICuke::SDK.use_latest
50
+ end
51
+ attrs = { :target => target,
52
+ :platform => platform,
53
+ :env => {
54
+ 'DYLD_INSERT_LIBRARIES' => ICuke::SDK.dylib_fullpath
55
+ }
56
+ }
57
+ attrs.merge!(:retina => !(retina =~ /non/)) if retina
58
+ attrs.merge!(:build_configuration => configuration) if configuration
59
+ icuke_driver.launch(File.expand_path(project), attrs)
60
+ end
61
+
62
+ Given /^the module "([^\"]*)" is loaded in the simulator$/ do |path|
63
+ path.sub!(/#{File.basename(path)}$/, ICuke::SDK.dylib(File.basename(path)))
64
+ simulator.load_module(File.expand_path(path))
65
+ end
66
+
67
+ ##
68
+ # :section: Seeing What's on the Screen
69
+ #
70
+ # The two following rules detect accessibility text on the screen:
71
+ #
72
+ # Then I should see "some text" within "some scope"
73
+ # Then I should not see "some text" within "some scope"
74
+ #
75
+ Then /^I should see "([^\"]*)"(?: within "([^\"]*)")?$/ do |text, scope|
76
+ raise %Q{Content "#{text}" not found in: #{screen.xml}} unless icuke_driver.screen.visible?(text, scope)
77
+ end
78
+
79
+ Then /^I should not see "([^\"]*)"(?: within "([^\"]*)")?$/ do |text, scope|
80
+ raise %Q{Content "#{text}" was found but was not expected in: #{screen.xml}} if icuke_driver.screen.visible?(text, scope)
81
+ end
82
+
83
+ ##
84
+ # :section: Sending Input to the App
85
+ #
86
+ # The following rules are available:
87
+ #
88
+ # When I tap "some label"
89
+ # When I type "some text" in "some field label"
90
+ # When I drag from <source> to <destination>
91
+ # When I select the "some label" slider and drag <distance> pixels <direction>
92
+ # When I move the "label" slider to <n> percent
93
+ # When I scroll <direction> to "some text"
94
+ # When I suspend the application
95
+ # When I resume the application
96
+ #
97
+ When /^I tap "([^\"]*)"$/ do |label|
98
+ icuke_driver.tap(label)
99
+ end
100
+
101
+ When /^I type "([^\"]*)" in "([^\"]*)"$/ do |text, textfield|
102
+ icuke_driver.type(textfield, text)
103
+ end
104
+
105
+ When /^I drag from (.*) to (.*)$/ do |source, destination|
106
+ icuke_driver.drag_with_source(source, destination)
107
+ end
108
+
109
+ When /^I select the "(.*)" slider and drag (.*) pixels (down|up|left|right)$/ do |label, distance, direction|
110
+ icuke_driver.drag_slider_to(label, direction.to_sym, distance.to_i)
111
+ end
112
+
113
+ When /^I move the "([^\"]*)" slider to (.*) percent$/ do |label, percent|
114
+ icuke_driver.drag_slider_to_percentage(label, percent.to_i)
115
+ end
116
+
117
+ When /^I scroll (down|up|left|right)(?: to "([^\"]*)")?$/ do |direction, text|
118
+ if text
119
+ icuke_driver.scroll_to(text, :direction => direction.to_sym)
120
+ else
121
+ icuke_driver.scroll(direction.to_sym)
122
+ end
123
+ end
124
+
125
+ When /^I suspend the application/ do
126
+ icuke_driver.suspend
127
+ end
128
+
129
+ When /^I resume the application/ do
130
+ icuke_driver.resume
131
+ end
132
+
133
+ ##
134
+ # :section: Debugging Tools
135
+ #
136
+ # Then I put the phone into recording mode
137
+ #
138
+ # Then show me the screen
139
+ #
140
+ # "show me the screen" is the quintessential step used for debugging tests. It dumps
141
+ # the raw XML received from the iOS app.
142
+ #
143
+ Then /^I put the phone into recording mode$/ do
144
+ icuke_driver.record
145
+ end
146
+
147
+ Then /^show me the screen$/ do
148
+ puts icuke_driver.screen.xml.to_s
149
+ end