frank-cucumber 0.8.12 → 0.8.13
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.
- data/frank-skeleton/features/support/env.rb +3 -0
- data/frank-skeleton/frank_static_resources.bundle/ViewAttributeMapping.plist +1 -0
- data/frank-skeleton/libFrank.a +0 -0
- data/frank-skeleton/libShelley.a +0 -0
- data/lib/frank-cucumber/core_frank_steps.rb +19 -32
- data/lib/frank-cucumber/frank_helper.rb +77 -155
- data/lib/frank-cucumber/gateway.rb +134 -0
- data/lib/frank-cucumber/host_scripting.rb +83 -0
- data/lib/frank-cucumber/version.rb +1 -1
- data/lib/frank-cucumber/wait_helper.rb +30 -0
- metadata +17 -14
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'frank-cucumber'
|
2
2
|
|
3
|
+
# UIQuery is deprecated. Please use the shelley selector engine.
|
4
|
+
Frank::Cucumber::FrankHelper.use_shelley_from_now_on
|
5
|
+
|
3
6
|
# TODO: set this constant to the full path for your Frankified target's app bundle.
|
4
7
|
# See the "Given I launch the app" step definition in launch_steps.rb for more details
|
5
8
|
APP_BUNDLE_PATH = nil
|
data/frank-skeleton/libFrank.a
CHANGED
Binary file
|
data/frank-skeleton/libShelley.a
CHANGED
Binary file
|
@@ -4,40 +4,33 @@ require 'rspec/expectations'
|
|
4
4
|
|
5
5
|
# -- See -- #
|
6
6
|
Then /^I wait to see "([^\"]*)"$/ do |expected_mark|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
7
|
+
wait_until(:message => "waited to see view marked '#{expected_mark}'"){
|
8
|
+
view_with_mark_exists( expected_mark )
|
9
|
+
}
|
12
10
|
end
|
13
11
|
|
14
12
|
Then /^I wait to not see "([^\"]*)"$/ do |expected_mark|
|
15
|
-
sleep 3
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
sleep 3 # ugh, this should be removed but I'm worried it'll break existing tests
|
14
|
+
|
15
|
+
wait_until(:message => "waited to not see view marked '#{expected_mark}'"){
|
16
|
+
!view_with_mark_exists( expected_mark )
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
Then /^I should see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
|
21
|
+
check_element_exists( "navigationItemView marked:'#{expected_mark}'" )
|
21
22
|
end
|
22
23
|
|
23
24
|
Then /^I wait to see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
values = frankly_map( 'navigationItemView', 'accessibilityLabel' )
|
28
|
-
sleep 0.1
|
29
|
-
end
|
30
|
-
end
|
25
|
+
wait_until( :timeout => 30, :message => "waited to see a navigation bar titled '#{expected_mark}'" ) {
|
26
|
+
element_exists( "navigationItemView marked:'#{expected_mark}'" )
|
27
|
+
}
|
31
28
|
end
|
32
29
|
|
33
30
|
Then /^I wait to not see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
values = frankly_map( 'navigationItemView', 'accessibilityLabel' )
|
38
|
-
sleep 0.1
|
39
|
-
end
|
40
|
-
end
|
31
|
+
wait_until( :timeout => 30, :message => "waited to not see a navigation bar titled '#{expected_mark}'" ) {
|
32
|
+
!element_exists( "navigationItemView marked:'#{expected_mark}'" )
|
33
|
+
}
|
41
34
|
end
|
42
35
|
|
43
36
|
Then /^I should see a "([^\"]*)" button$/ do |expected_mark|
|
@@ -45,7 +38,7 @@ Then /^I should see a "([^\"]*)" button$/ do |expected_mark|
|
|
45
38
|
end
|
46
39
|
|
47
40
|
Then /^I should see "([^\"]*)"$/ do |expected_mark|
|
48
|
-
|
41
|
+
check_view_with_mark_exists(expected_mark)
|
49
42
|
end
|
50
43
|
|
51
44
|
Then /^I should not see "([^\"]*)"$/ do |expected_mark|
|
@@ -66,14 +59,8 @@ Then /I should not see the following:/ do |table|
|
|
66
59
|
end
|
67
60
|
end
|
68
61
|
|
69
|
-
Then /^I should see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
|
70
|
-
values = frankly_map( 'navigationItemView', 'accessibilityLabel' )
|
71
|
-
values.should include(expected_mark)
|
72
|
-
end
|
73
|
-
|
74
62
|
Then /^I should see an alert view titled "([^\"]*)"$/ do |expected_mark|
|
75
63
|
values = frankly_map( 'alertView', 'message')
|
76
|
-
puts values
|
77
64
|
values.should include(expected_mark)
|
78
65
|
end
|
79
66
|
|
@@ -1,12 +1,13 @@
|
|
1
|
-
require 'net/http'
|
2
1
|
require 'json'
|
3
|
-
require 'frank-cucumber/
|
2
|
+
require 'frank-cucumber/gateway'
|
3
|
+
require 'frank-cucumber/host_scripting'
|
4
|
+
require 'frank-cucumber/wait_helper'
|
4
5
|
|
5
6
|
module Frank module Cucumber
|
6
7
|
|
7
8
|
module FrankHelper
|
8
|
-
|
9
|
-
|
9
|
+
include WaitHelper
|
10
|
+
include HostScripting
|
10
11
|
|
11
12
|
class << self
|
12
13
|
# TODO: adding an ivar to the module itself is a big ugyl hack. We need a FrankDriver class, or similar
|
@@ -16,12 +17,16 @@ module FrankHelper
|
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
-
|
21
|
-
raise "could not find anything matching [#{uiquery}] to touch" if views_touched.empty?
|
22
|
-
#TODO raise warning if views_touched.count > 1
|
20
|
+
def selector_engine
|
21
|
+
Frank::Cucumber::FrankHelper.selector_engine || 'uiquery' # default to UIQuery for backwards compatibility
|
23
22
|
end
|
24
23
|
|
24
|
+
def touch( uiquery )
|
25
|
+
touch_successes = frankly_map( uiquery, 'touch' )
|
26
|
+
raise "could not find anything matching [#{uiquery}] to touch" if touch_successes.empty?
|
27
|
+
raise "some views could not be touched (probably because they are not within the current viewport)" if touch_successes.include?(false)
|
28
|
+
end
|
29
|
+
|
25
30
|
def element_exists( query )
|
26
31
|
matches = frankly_map( query, 'accessibilityLabel' )
|
27
32
|
# TODO: raise warning if matches.count > 1
|
@@ -46,6 +51,46 @@ module FrankHelper
|
|
46
51
|
check_element_exists( "view marked:'#{expected_mark}'" )
|
47
52
|
end
|
48
53
|
|
54
|
+
def check_view_with_mark_does_not_exist(expected_mark)
|
55
|
+
check_element_does_not_exist( "view marked:'#{expected_mark}'" )
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Waits for any of the selectors provided to match a view. Returns true
|
60
|
+
# as soon as we find a matching view, otherwise keeps testing until timeout.
|
61
|
+
# The first selector which matches is passed to a block if it was provided.
|
62
|
+
def wait_for_element_to_exist(*selectors,&block)
|
63
|
+
wait_until(:message => "Waited for element matching any of #{selectors.join(', ')} to exist") do
|
64
|
+
at_least_one_exists = false
|
65
|
+
selectors.each do |selector|
|
66
|
+
if element_exists( selector )
|
67
|
+
at_least_one_exists = true
|
68
|
+
block.call(selector) if block
|
69
|
+
end
|
70
|
+
end
|
71
|
+
at_least_one_exists
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def wait_for_element_to_not_exist(selector)
|
76
|
+
wait_until(:message => "Waited for element #{selector} to not exist") do
|
77
|
+
!element_exists(selector)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def wait_for_element_to_exist_and_then_touch_it(*selectors)
|
82
|
+
wait_for_element_to_exist(*selectors) do |sel|
|
83
|
+
touch(sel)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def wait_for_nothing_to_be_animating( timeout = false )
|
88
|
+
wait_until :timeout => timeout do
|
89
|
+
!element_exists('view isAnimating')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
49
94
|
# a better name would be element_exists_and_is_not_hidden
|
50
95
|
def element_is_not_hidden(query)
|
51
96
|
matches = frankly_map( query, 'isHidden' )
|
@@ -54,45 +99,31 @@ module FrankHelper
|
|
54
99
|
end
|
55
100
|
|
56
101
|
def app_exec(method_name, *method_args)
|
57
|
-
operation_map =
|
58
|
-
:method_name => method_name,
|
59
|
-
:arguments => method_args
|
60
|
-
}
|
102
|
+
operation_map = Gateway.build_operation_map(method_name,method_args)
|
61
103
|
|
62
|
-
|
63
|
-
|
104
|
+
res = frank_server.send_post(
|
105
|
+
'app_exec',
|
106
|
+
:operation => operation_map
|
107
|
+
)
|
64
108
|
|
65
|
-
|
66
|
-
|
67
|
-
res = JSON.parse( res )
|
68
|
-
if res['outcome'] != 'SUCCESS'
|
69
|
-
raise "app_exec #{method_name} failed because: #{res['reason']}\n#{res['details']}"
|
70
|
-
end
|
71
|
-
|
72
|
-
res['results']
|
109
|
+
return Gateway.evaluate_frankly_response( res, "app_exec #{method_name}" )
|
73
110
|
end
|
74
111
|
|
75
|
-
def frankly_engine_map( selector_engine, query, method_name, *method_args )
|
76
|
-
operation_map = {
|
77
|
-
:method_name => method_name,
|
78
|
-
:arguments => method_args,
|
79
|
-
}
|
80
|
-
res = post_to_uispec_server( 'map', :query => query, :operation => operation_map, :selector_engine => selector_engine )
|
81
|
-
res = JSON.parse( res )
|
82
|
-
if res['outcome'] != 'SUCCESS'
|
83
|
-
raise "frankly_map #{query} #{method_name} failed because: #{res['reason']}\n#{res['details']}"
|
84
|
-
end
|
85
|
-
|
86
|
-
res['results']
|
87
|
-
end
|
88
|
-
|
89
112
|
def frankly_map( query, method_name, *method_args )
|
90
|
-
|
91
|
-
|
113
|
+
operation_map = Gateway.build_operation_map(method_name,method_args)
|
114
|
+
|
115
|
+
res = frank_server.send_post(
|
116
|
+
'map',
|
117
|
+
:query => query,
|
118
|
+
:operation => operation_map,
|
119
|
+
:selector_engine => selector_engine
|
120
|
+
)
|
121
|
+
|
122
|
+
return Gateway.evaluate_frankly_response( res, "frankly_map #{query} #{method_name}" )
|
92
123
|
end
|
93
124
|
|
94
125
|
def frankly_dump
|
95
|
-
res =
|
126
|
+
res = frank_server.send_get( 'dump' )
|
96
127
|
puts JSON.pretty_generate(JSON.parse(res)) rescue puts res #dumping a super-deep DOM causes errors
|
97
128
|
end
|
98
129
|
|
@@ -101,7 +132,7 @@ module FrankHelper
|
|
101
132
|
path += '/allwindows' if allwindows
|
102
133
|
path += "/frame/" + URI.escape(subframe) if (subframe != nil)
|
103
134
|
|
104
|
-
data =
|
135
|
+
data = frank_server.send_get( path )
|
105
136
|
|
106
137
|
open(filename, "wb") do |file|
|
107
138
|
file.write(data)
|
@@ -117,15 +148,14 @@ module FrankHelper
|
|
117
148
|
end
|
118
149
|
|
119
150
|
def frankly_current_orientation
|
120
|
-
res =
|
151
|
+
res = frank_server.send_get( 'orientation' )
|
121
152
|
orientation = JSON.parse( res )['orientation']
|
122
153
|
puts "orientation reported as '#{orientation}'" if $DEBUG
|
123
154
|
orientation
|
124
155
|
end
|
125
156
|
|
126
|
-
|
127
157
|
def frankly_is_accessibility_enabled
|
128
|
-
res =
|
158
|
+
res = frank_server.send_get( 'accessibility_check' )
|
129
159
|
JSON.parse( res )['accessibility_enabled'] == 'true'
|
130
160
|
end
|
131
161
|
|
@@ -167,121 +197,13 @@ module FrankHelper
|
|
167
197
|
end
|
168
198
|
|
169
199
|
def frankly_ping
|
170
|
-
|
171
|
-
return true
|
172
|
-
rescue Errno::ECONNREFUSED
|
173
|
-
return false
|
174
|
-
rescue EOFError
|
175
|
-
return false
|
176
|
-
end
|
177
|
-
|
178
|
-
#taken from Ian Dee's Encumber
|
179
|
-
def post_to_uispec_server( verb, command_hash )
|
180
|
-
url = frank_url_for( verb )
|
181
|
-
req = Net::HTTP::Post.new url.path
|
182
|
-
req.body = command_hash.to_json
|
183
|
-
|
184
|
-
make_http_request( url, req )
|
185
|
-
end
|
186
|
-
|
187
|
-
def get_to_uispec_server( verb )
|
188
|
-
url = frank_url_for( verb )
|
189
|
-
req = Net::HTTP::Get.new url.path
|
190
|
-
make_http_request( url, req )
|
191
|
-
end
|
192
|
-
|
193
|
-
def frank_url_for( verb , port=nil )
|
194
|
-
port ||= FRANK_PORT
|
195
|
-
|
196
|
-
url = URI.parse "http://#{HOST}:#{port}/"
|
197
|
-
url.path = '/'+verb
|
198
|
-
url
|
199
|
-
end
|
200
|
-
|
201
|
-
def make_http_request( url, req )
|
202
|
-
http = Net::HTTP.new(url.host, url.port)
|
203
|
-
|
204
|
-
res = http.start do |sess|
|
205
|
-
sess.request req
|
206
|
-
end
|
207
|
-
|
208
|
-
res.body
|
209
|
-
end
|
210
|
-
|
211
|
-
def start_recording
|
212
|
-
%x{osascript<<APPLESCRIPT
|
213
|
-
tell application "QuickTime Player"
|
214
|
-
set sr to new screen recording
|
215
|
-
tell sr to start
|
216
|
-
end tell
|
217
|
-
APPLESCRIPT}
|
218
|
-
|
219
|
-
end
|
220
|
-
|
221
|
-
def stop_recording
|
222
|
-
%x{osascript<<APPLESCRIPT
|
223
|
-
tell application "QuickTime Player"
|
224
|
-
set sr to (document 1)
|
225
|
-
tell sr to stop
|
226
|
-
end tell
|
227
|
-
APPLESCRIPT}
|
228
|
-
end
|
229
|
-
|
230
|
-
def quit_simulator
|
231
|
-
%x{osascript<<APPLESCRIPT-
|
232
|
-
application "iPhone Simulator" quit
|
233
|
-
APPLESCRIPT}
|
234
|
-
end
|
235
|
-
|
236
|
-
def simulator_reset_data
|
237
|
-
%x{osascript<<APPLESCRIPT
|
238
|
-
activate application "iPhone Simulator"
|
239
|
-
tell application "System Events"
|
240
|
-
click menu item 5 of menu 1 of menu bar item 2 of menu bar 1 of process "#{Localize.t(:iphone_simulator)}"
|
241
|
-
delay 0.5
|
242
|
-
click button 2 of window 1 of process "#{Localize.t(:iphone_simulator)}"
|
243
|
-
end tell
|
244
|
-
APPLESCRIPT}
|
245
|
-
end
|
246
|
-
|
247
|
-
#Note this needs to have "Enable access for assistive devices"
|
248
|
-
#chcked in the Universal Access system preferences
|
249
|
-
def simulator_hardware_menu_press( menu_label )
|
250
|
-
%x{osascript<<APPLESCRIPT
|
251
|
-
activate application "iPhone Simulator"
|
252
|
-
tell application "System Events"
|
253
|
-
click menu item "#{menu_label}" of menu "#{Localize.t(:hardware)}" of menu bar of process "#{Localize.t(:iphone_simulator)}"
|
254
|
-
end tell
|
255
|
-
APPLESCRIPT}
|
256
|
-
end
|
257
|
-
|
258
|
-
def press_home_on_simulator
|
259
|
-
simulator_hardware_menu_press Localize.t(:home)
|
260
|
-
end
|
261
|
-
|
262
|
-
def rotate_simulator_left
|
263
|
-
simulator_hardware_menu_press Localize.t(:rotate_left)
|
200
|
+
frank_server.ping
|
264
201
|
end
|
265
202
|
|
266
|
-
def
|
267
|
-
|
268
|
-
end
|
269
|
-
|
270
|
-
def shake_simulator
|
271
|
-
simulator_hardware_menu_press Localize.t(:shake_gesture)
|
272
|
-
end
|
273
|
-
|
274
|
-
def simulate_memory_warning
|
275
|
-
simulator_hardware_menu_press Localize.t(:simulate_memory_warning)
|
276
|
-
end
|
277
|
-
|
278
|
-
def toggle_call_status_bar
|
279
|
-
simulator_hardware_menu_press Localize.t(:toggle_call_status_bar)
|
280
|
-
end
|
281
|
-
|
282
|
-
def simulate_hardware_keyboard
|
283
|
-
simulator_hardware_menu_press Localize.t(:simulate_hardware_keyboard)
|
203
|
+
def frank_server
|
204
|
+
@_frank_server ||= Frank::Cucumber::Gateway.new
|
284
205
|
end
|
206
|
+
|
285
207
|
end
|
286
208
|
|
287
209
|
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Frank module Cucumber
|
5
|
+
|
6
|
+
class Gateway
|
7
|
+
DEFAULT_HOST = "localhost"
|
8
|
+
DEFAULT_PORT = 37265
|
9
|
+
|
10
|
+
def initialize( host=DEFAULT_HOST, port=DEFAULT_PORT )
|
11
|
+
@base_uri = URI.parse "http://#{host}:#{port}/"
|
12
|
+
end
|
13
|
+
|
14
|
+
def ping
|
15
|
+
send_get('')
|
16
|
+
return true
|
17
|
+
rescue FrankNetworkError
|
18
|
+
return false
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def build_operation_map( method_sig, method_args )
|
23
|
+
num_args_according_to_method_sig = method_sig.count(':')
|
24
|
+
|
25
|
+
if num_args_according_to_method_sig != method_args.count
|
26
|
+
raise <<-EOS
|
27
|
+
|
28
|
+
The method you've specified - #{method_sig} - wants #{num_args_according_to_method_sig} arguments, but you've supplied #{method_args.count} arguments.
|
29
|
+
|
30
|
+
EOS
|
31
|
+
end
|
32
|
+
|
33
|
+
if num_args_according_to_method_sig > 0 && !method_sig.end_with?(':')
|
34
|
+
raise <<-EOS
|
35
|
+
|
36
|
+
The method signature you've specified - #{method_sig} - is invalid. Objective C method signatures which take parameters must end with a :
|
37
|
+
|
38
|
+
EOS
|
39
|
+
end
|
40
|
+
|
41
|
+
{
|
42
|
+
:method_name => method_sig,
|
43
|
+
:arguments => method_args,
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def evaluate_frankly_response( json, req_desc )
|
48
|
+
res = JSON.parse( json )
|
49
|
+
if res['outcome'] != 'SUCCESS'
|
50
|
+
raise "#{req_desc} failed because: #{res['reason']}\n#{res['details']}"
|
51
|
+
end
|
52
|
+
|
53
|
+
res['results']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
#taken from Ian Dee's Encumber
|
58
|
+
def send_post( verb, command_hash )
|
59
|
+
url = frank_url_for( verb )
|
60
|
+
req = Net::HTTP::Post.new url.path
|
61
|
+
req.body = command_hash.to_json
|
62
|
+
|
63
|
+
make_http_request( url, req )
|
64
|
+
end
|
65
|
+
|
66
|
+
def send_get( verb )
|
67
|
+
url = frank_url_for( verb )
|
68
|
+
req = Net::HTTP::Get.new url.path
|
69
|
+
make_http_request( url, req )
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def frank_url_for( verb )
|
75
|
+
url = @base_uri.clone
|
76
|
+
url.path = '/'+verb
|
77
|
+
url
|
78
|
+
end
|
79
|
+
|
80
|
+
def make_http_request( url, req )
|
81
|
+
http = Net::HTTP.new(url.host, url.port)
|
82
|
+
|
83
|
+
begin
|
84
|
+
res = http.start do |sess|
|
85
|
+
sess.request req
|
86
|
+
end
|
87
|
+
|
88
|
+
res.body
|
89
|
+
rescue Errno::ECONNREFUSED
|
90
|
+
raise FrankNetworkError
|
91
|
+
rescue EOFError
|
92
|
+
raise FrankNetworkError
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
class FrankNetworkError < RuntimeError
|
100
|
+
OVERLY_VERBOSE_YET_HELPFUL_ERROR_MESSAGE = <<EOS
|
101
|
+
|
102
|
+
|
103
|
+
*********************************************
|
104
|
+
Oh dear. Your app fell over and can't get up.
|
105
|
+
*********************************************
|
106
|
+
|
107
|
+
|
108
|
+
We just encountered an error while trying to talk to the Frank server embedded
|
109
|
+
within the app under test. This usually means that the app has just crashed,
|
110
|
+
either while carrying out the current step or while finishing up the previous
|
111
|
+
step.
|
112
|
+
|
113
|
+
Here are some things you could do next:
|
114
|
+
|
115
|
+
- Take a look at the app's logs to see why it crashed. You can view the logs
|
116
|
+
in Console.app (a search for 'Frankified' will usually find your frankified
|
117
|
+
app's output).
|
118
|
+
|
119
|
+
- Launch your frankified app in the XCode debugger and then run this scenario
|
120
|
+
again. You'll get lots of helpful output from XCode. Don't forget to do
|
121
|
+
something to prevent cucumber from automatically re-launching your app when
|
122
|
+
you run the scenario by hand. If you don't prevent the relaunch then you
|
123
|
+
won't still be in the XCode debugger when the crash happens.
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
EOS
|
128
|
+
|
129
|
+
def initialize
|
130
|
+
super OVERLY_VERBOSE_YET_HELPFUL_ERROR_MESSAGE
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'frank-cucumber/frank_localize'
|
2
|
+
|
3
|
+
module Frank module Cucumber
|
4
|
+
|
5
|
+
module HostScripting
|
6
|
+
|
7
|
+
def start_recording
|
8
|
+
%x{osascript<<APPLESCRIPT
|
9
|
+
tell application "QuickTime Player"
|
10
|
+
set sr to new screen recording
|
11
|
+
tell sr to start
|
12
|
+
end tell
|
13
|
+
APPLESCRIPT}
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def stop_recording
|
18
|
+
%x{osascript<<APPLESCRIPT
|
19
|
+
tell application "QuickTime Player"
|
20
|
+
set sr to (document 1)
|
21
|
+
tell sr to stop
|
22
|
+
end tell
|
23
|
+
APPLESCRIPT}
|
24
|
+
end
|
25
|
+
|
26
|
+
def quit_simulator
|
27
|
+
%x{osascript<<APPLESCRIPT-
|
28
|
+
application "iPhone Simulator" quit
|
29
|
+
APPLESCRIPT}
|
30
|
+
end
|
31
|
+
|
32
|
+
def simulator_reset_data
|
33
|
+
%x{osascript<<APPLESCRIPT
|
34
|
+
activate application "iPhone Simulator"
|
35
|
+
tell application "System Events"
|
36
|
+
click menu item 5 of menu 1 of menu bar item 2 of menu bar 1 of process "#{Localize.t(:iphone_simulator)}"
|
37
|
+
delay 0.5
|
38
|
+
click button 2 of window 1 of process "#{Localize.t(:iphone_simulator)}"
|
39
|
+
end tell
|
40
|
+
APPLESCRIPT}
|
41
|
+
end
|
42
|
+
|
43
|
+
#Note this needs to have "Enable access for assistive devices"
|
44
|
+
#chcked in the Universal Access system preferences
|
45
|
+
def simulator_hardware_menu_press( menu_label )
|
46
|
+
%x{osascript<<APPLESCRIPT
|
47
|
+
activate application "iPhone Simulator"
|
48
|
+
tell application "System Events"
|
49
|
+
click menu item "#{menu_label}" of menu "#{Localize.t(:hardware)}" of menu bar of process "#{Localize.t(:iphone_simulator)}"
|
50
|
+
end tell
|
51
|
+
APPLESCRIPT}
|
52
|
+
end
|
53
|
+
|
54
|
+
def press_home_on_simulator
|
55
|
+
simulator_hardware_menu_press Localize.t(:home)
|
56
|
+
end
|
57
|
+
|
58
|
+
def rotate_simulator_left
|
59
|
+
simulator_hardware_menu_press Localize.t(:rotate_left)
|
60
|
+
end
|
61
|
+
|
62
|
+
def rotate_simulator_right
|
63
|
+
simulator_hardware_menu_press Localize.t(:rotate_right)
|
64
|
+
end
|
65
|
+
|
66
|
+
def shake_simulator
|
67
|
+
simulator_hardware_menu_press Localize.t(:shake_gesture)
|
68
|
+
end
|
69
|
+
|
70
|
+
def simulate_memory_warning
|
71
|
+
simulator_hardware_menu_press Localize.t(:simulate_memory_warning)
|
72
|
+
end
|
73
|
+
|
74
|
+
def toggle_call_status_bar
|
75
|
+
simulator_hardware_menu_press Localize.t(:toggle_call_status_bar)
|
76
|
+
end
|
77
|
+
|
78
|
+
def simulate_hardware_keyboard
|
79
|
+
simulator_hardware_menu_press Localize.t(:simulate_hardware_keyboard)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
3
|
+
module Frank
|
4
|
+
module Cucumber
|
5
|
+
|
6
|
+
module WaitHelper
|
7
|
+
TIMEOUT = ENV['WAIT_TIMEOUT'].to_i || 240
|
8
|
+
POLL_SLEEP = 0.1 #seconds
|
9
|
+
|
10
|
+
def wait_until(opts = {})
|
11
|
+
timeout = opts[:timeout] || TIMEOUT
|
12
|
+
message = opts[:message]
|
13
|
+
|
14
|
+
begin
|
15
|
+
Timeout::timeout(timeout) do
|
16
|
+
until yield
|
17
|
+
sleep POLL_SLEEP
|
18
|
+
end
|
19
|
+
end
|
20
|
+
rescue Timeout::Error => e
|
21
|
+
raise message if message
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module_function :wait_until
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: frank-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.13
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-05-17 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: cucumber
|
17
|
-
requirement: &
|
17
|
+
requirement: &70094361339780 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70094361339780
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: rspec
|
28
|
-
requirement: &
|
28
|
+
requirement: &70094361337940 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '2.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70094361337940
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: sim_launcher
|
39
|
-
requirement: &
|
39
|
+
requirement: &70094361335880 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *70094361335880
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: i18n
|
50
|
-
requirement: &
|
50
|
+
requirement: &70094361333760 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *70094361333760
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: plist
|
61
|
-
requirement: &
|
61
|
+
requirement: &70094361332940 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ! '>='
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: '0'
|
67
67
|
type: :runtime
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *70094361332940
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: json
|
72
|
-
requirement: &
|
72
|
+
requirement: &70094361331940 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ! '>='
|
@@ -77,7 +77,7 @@ dependencies:
|
|
77
77
|
version: '0'
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *70094361331940
|
81
81
|
description: Use cucumber to test native iOS apps via Frank
|
82
82
|
email:
|
83
83
|
- gems@thepete.net
|
@@ -131,9 +131,12 @@ files:
|
|
131
131
|
- lib/frank-cucumber/core_frank_steps.rb
|
132
132
|
- lib/frank-cucumber/frank_helper.rb
|
133
133
|
- lib/frank-cucumber/frank_localize.rb
|
134
|
+
- lib/frank-cucumber/gateway.rb
|
135
|
+
- lib/frank-cucumber/host_scripting.rb
|
134
136
|
- lib/frank-cucumber/launcher.rb
|
135
137
|
- lib/frank-cucumber/localize.yml
|
136
138
|
- lib/frank-cucumber/version.rb
|
139
|
+
- lib/frank-cucumber/wait_helper.rb
|
137
140
|
- test/launcher_test.rb
|
138
141
|
- test/test_helper.rb
|
139
142
|
homepage: http://rubygems.org/gems/frank-cucumber
|