frank-cucumber 1.1.12 → 1.1.13.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/frank-skeleton/frankify.xcconfig.tt +3 -3
- data/frank-skeleton/libCocoaAsyncSocket.a +0 -0
- data/frank-skeleton/libCocoaAsyncSocketMac.a +0 -0
- data/frank-skeleton/libCocoaHTTPServer.a +0 -0
- data/frank-skeleton/libCocoaHTTPServerMac.a +0 -0
- data/frank-skeleton/libCocoaLumberjack.a +0 -0
- data/frank-skeleton/libCocoaLumberjackMac.a +0 -0
- data/frank-skeleton/libFrank.a +0 -0
- data/frank-skeleton/libFrankMac.a +0 -0
- data/frank-skeleton/libShelley.a +0 -0
- data/frank-skeleton/plugins/.empty_directory +0 -0
- data/lib/frank-cucumber/cli.rb +55 -7
- data/lib/frank-cucumber/core_frank_steps.rb +10 -10
- data/lib/frank-cucumber/frank.xcconfig.erb +11 -0
- data/lib/frank-cucumber/frank_helper.rb +77 -27
- data/lib/frank-cucumber/frank_localize.rb +2 -0
- data/lib/frank-cucumber/localize.yml +13 -0
- data/lib/frank-cucumber/plugins/plugin.rb +57 -0
- data/lib/frank-cucumber/version.rb +1 -1
- data/lib/frank-cucumber/wait_helper.rb +1 -1
- metadata +9 -7
@@ -1,6 +1,6 @@
|
|
1
1
|
INSTALL_PATH = /./
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
FRANK_CORE_LDFLAGS = -all_load -ObjC -framework CFNetwork -framework Security <%= @libs.map { |lib| "-l#{lib}" }.join(' ') %>
|
4
|
+
FRANK_CORE_MAC_LDFLAGS = -all_load -ObjC -framework CFNetwork -framework Security <%= @libsMac.map { |lib| "-l#{lib}" }.join(' ') %>
|
5
5
|
|
6
|
-
|
6
|
+
FRANK_CORE_GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = FRANKIFIED
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/frank-skeleton/libFrank.a
CHANGED
Binary file
|
Binary file
|
data/frank-skeleton/libShelley.a
CHANGED
Binary file
|
File without changes
|
data/lib/frank-cucumber/cli.rb
CHANGED
@@ -8,6 +8,7 @@ require 'frank-cucumber/launcher'
|
|
8
8
|
require 'frank-cucumber/console'
|
9
9
|
require 'frank-cucumber/frankifier'
|
10
10
|
require 'frank-cucumber/mac_launcher'
|
11
|
+
require 'frank-cucumber/plugins/plugin'
|
11
12
|
require 'xcodeproj'
|
12
13
|
|
13
14
|
module Frank
|
@@ -36,7 +37,7 @@ module Frank
|
|
36
37
|
method_option :project, :type=>:string
|
37
38
|
def setup
|
38
39
|
@libs = %w(Shelley CocoaAsyncSocket CocoaLumberjack CocoaHTTPServer Frank)
|
39
|
-
@libsMac = %w(CocoaAsyncSocketMac CocoaLumberjackMac CocoaHTTPServerMac FrankMac)
|
40
|
+
@libsMac = %w(ShelleyMac CocoaAsyncSocketMac CocoaLumberjackMac CocoaHTTPServerMac FrankMac)
|
40
41
|
@libs -= %w(CocoaHTTPServer) if options[WITHOUT_SERVER]
|
41
42
|
@libsMac -= %w(CocoaHTTPServerMac) if options[WITHOUT_SERVER]
|
42
43
|
@libs -= %w(CocoaAsyncSocket) if options[WITHOUT_ASYNC_SOCKET]
|
@@ -58,14 +59,20 @@ module Frank
|
|
58
59
|
end
|
59
60
|
|
60
61
|
XCODEBUILD_OPTIONS = %w{workspace project scheme target configuration}
|
61
|
-
desc "build", "builds a Frankified version of your native app"
|
62
|
+
desc "build [<buildsetting>=<value>]...", "builds a Frankified version of your native app"
|
62
63
|
XCODEBUILD_OPTIONS.each do |option|
|
63
64
|
method_option option
|
64
65
|
end
|
66
|
+
|
67
|
+
WITHOUT_DEPS = 'without-dependencies'
|
68
|
+
method_option 'no-plugins', :type => :boolean, :default => false, :aliases => '--np', :desc => 'Disable plugins'
|
65
69
|
method_option 'arch', :type => :string, :default => 'i386'
|
66
70
|
method_option :noclean, :type => :boolean, :default => false, :aliases => '--nc', :desc => "Don't clean the build directory before building"
|
67
|
-
|
71
|
+
method_option WITHOUT_DEPS, :type => :array, :desc => 'An array (space separated list) of plugin dependencies to exclude'
|
72
|
+
def build(*args)
|
68
73
|
clean = !options['noclean']
|
74
|
+
use_plugins = !options['no-plugins']
|
75
|
+
exclude_dependencies = options[WITHOUT_DEPS] || []
|
69
76
|
|
70
77
|
in_root do
|
71
78
|
unless File.directory? 'Frank'
|
@@ -90,6 +97,19 @@ module Frank
|
|
90
97
|
build_steps = 'clean ' + build_steps
|
91
98
|
end
|
92
99
|
|
100
|
+
plugins = use_plugins ? gather_plugins : []
|
101
|
+
|
102
|
+
say "Detected plugins: #{plugins.map {|p| p.name}.join(', ')}" unless plugins.empty?
|
103
|
+
|
104
|
+
say "Excluding plugin dependencies: #{exclude_dependencies.join(', ')}" unless exclude_dependencies.empty?
|
105
|
+
|
106
|
+
plugins.each {|plugin| plugin.write_xcconfig(exclude_dependencies)}
|
107
|
+
|
108
|
+
xcconfig_data = Frank::Plugins::Plugin.generate_core_xcconfig(plugins)
|
109
|
+
|
110
|
+
xcconfig_file = 'Frank/frank.xcconfig'
|
111
|
+
File.open(xcconfig_file,'w') {|f| f.write(xcconfig_data) }
|
112
|
+
|
93
113
|
extra_opts = XCODEBUILD_OPTIONS.map{ |o| "-#{o} \"#{options[o]}\"" if options[o] }.compact.join(' ')
|
94
114
|
|
95
115
|
# If there is a scheme specified we don't want to inject the default configuration
|
@@ -102,12 +122,14 @@ module Frank
|
|
102
122
|
|
103
123
|
build_mac = determine_build_patform(options) == :osx
|
104
124
|
|
125
|
+
xcodebuild_args = args.join(" ")
|
126
|
+
|
105
127
|
if build_mac
|
106
|
-
run %Q|xcodebuild -xcconfig
|
128
|
+
run %Q|xcodebuild -xcconfig #{xcconfig_file} #{build_steps} #{extra_opts} #{separate_configuration_option} DEPLOYMENT_LOCATION=YES DSTROOT="#{build_output_dir}" FRANK_LIBRARY_SEARCH_PATHS="#{frank_lib_search_paths}" #{xcodebuild_args}|
|
107
129
|
else
|
108
130
|
extra_opts += " -arch #{options['arch']}"
|
109
131
|
|
110
|
-
run %Q|xcodebuild -xcconfig
|
132
|
+
run %Q|xcodebuild -xcconfig #{xcconfig_file} #{build_steps} #{extra_opts} #{separate_configuration_option} -sdk iphonesimulator DEPLOYMENT_LOCATION=YES DSTROOT="#{build_output_dir}" FRANK_LIBRARY_SEARCH_PATHS="#{frank_lib_search_paths}" #{xcodebuild_args}|
|
111
133
|
end
|
112
134
|
exit $?.exitstatus if not $?.success?
|
113
135
|
|
@@ -213,6 +235,15 @@ module Frank
|
|
213
235
|
File.expand_path "Frank"
|
214
236
|
end
|
215
237
|
|
238
|
+
def frank_lib_search_paths
|
239
|
+
paths = [frank_lib_directory]
|
240
|
+
each_plugin_path do |path|
|
241
|
+
paths << path
|
242
|
+
end
|
243
|
+
|
244
|
+
paths.map {|path| %Q[\\"#{path}\\"]}.join(' ')
|
245
|
+
end
|
246
|
+
|
216
247
|
def build_output_dir
|
217
248
|
File.expand_path "Frank/frankified_build"
|
218
249
|
end
|
@@ -221,6 +252,10 @@ module Frank
|
|
221
252
|
File.join( build_output_dir, app_bundle_name )
|
222
253
|
end
|
223
254
|
|
255
|
+
def plugin_dir
|
256
|
+
File.expand_path 'Frank/plugins'
|
257
|
+
end
|
258
|
+
|
224
259
|
def built_product_is_mac_app ( app_dir )
|
225
260
|
return File.exists? File.join( app_dir, "Contents", "MacOS" )
|
226
261
|
end
|
@@ -314,14 +349,27 @@ module Frank
|
|
314
349
|
end
|
315
350
|
|
316
351
|
if target == nil
|
317
|
-
say "Unable to determine a target from the options provided"
|
318
|
-
|
352
|
+
say "Unable to determine a target from the options provided. Assuming iOS"
|
353
|
+
return :ios
|
319
354
|
end
|
320
355
|
|
321
356
|
return target.platform_name
|
322
357
|
|
323
358
|
end
|
324
359
|
|
360
|
+
def each_plugin_path(&block)
|
361
|
+
plugin_glob = File.join("#{plugin_dir}",'*')
|
362
|
+
Dir[plugin_glob].map do |plugin_path|
|
363
|
+
yield plugin_path
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def gather_plugins
|
368
|
+
each_plugin_path do |plugin_path|
|
369
|
+
Frank::Plugins::Plugin.from_plugin_directory(plugin_path)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
325
373
|
end
|
326
374
|
end
|
327
375
|
|
@@ -6,7 +6,7 @@ require 'rspec/expectations'
|
|
6
6
|
Then /^I wait to see "([^\"]*)"$/ do |expected_mark|
|
7
7
|
quote = get_selector_quote(expected_mark)
|
8
8
|
wait_until(:message => "waited to see view marked #{quote}#{expected_mark}#{quote}"){
|
9
|
-
view_with_mark_exists( expected_mark )
|
9
|
+
view_with_mark_exists( expected_mark )
|
10
10
|
}
|
11
11
|
end
|
12
12
|
|
@@ -52,14 +52,14 @@ Then /^I should not see "([^\"]*)"$/ do |expected_mark|
|
|
52
52
|
end
|
53
53
|
|
54
54
|
Then /I should see the following:/ do |table|
|
55
|
-
values = frankly_map( 'view', '
|
55
|
+
values = frankly_map( 'view', 'FEX_accessibilityLabel' )
|
56
56
|
table.raw.each do |expected_mark|
|
57
57
|
values.should include( expected_mark.first )
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
Then /I should not see the following:/ do |table|
|
62
|
-
values = frankly_map( 'view', '
|
62
|
+
values = frankly_map( 'view', 'FEX_accessibilityLabel' )
|
63
63
|
table.raw.each do |expected_mark|
|
64
64
|
values.should_not include( expected_mark.first )
|
65
65
|
end
|
@@ -127,7 +127,7 @@ Then /^I rotate to the "([^\"]*)"$/ do |direction|
|
|
127
127
|
rotate_simulator_right
|
128
128
|
elsif direction == "left"
|
129
129
|
rotate_simulator_left
|
130
|
-
else
|
130
|
+
else
|
131
131
|
raise %Q|Rotation direction specified ("#{direction}") is invalid. Please specify right or left.|
|
132
132
|
end
|
133
133
|
sleep 1
|
@@ -141,7 +141,7 @@ When /^I touch "([^\"]*)"$/ do |mark|
|
|
141
141
|
if element_exists(selector)
|
142
142
|
touch( selector )
|
143
143
|
else
|
144
|
-
raise "Could not touch [#{mark}], it does not exist."
|
144
|
+
raise "Could not touch [#{mark}], it does not exist."
|
145
145
|
end
|
146
146
|
sleep 1
|
147
147
|
end
|
@@ -171,7 +171,7 @@ When /^I touch the (\d*)(?:st|nd|rd|th)? table cell$/ do |ordinal|
|
|
171
171
|
end
|
172
172
|
|
173
173
|
Then /I touch the following:/ do |table|
|
174
|
-
values = frankly_map( 'view', '
|
174
|
+
values = frankly_map( 'view', 'FEX_accessibilityLabel' )
|
175
175
|
table.raw.each do |expected_mark|
|
176
176
|
quote = get_selector_quote(expected_mark)
|
177
177
|
touch( "view marked:#{quote}#{expected_mark}#{quote}" )
|
@@ -198,10 +198,10 @@ end
|
|
198
198
|
|
199
199
|
# alert views
|
200
200
|
When /^I touch the "([^\"]*)" alert view button$/ do |mark|
|
201
|
-
quote = get_selector_quote(mark)
|
201
|
+
quote = get_selector_quote(mark)
|
202
202
|
touch( "alertView threePartButton marked:#{quote}#{mark}#{quote}" )
|
203
203
|
end
|
204
|
-
|
204
|
+
|
205
205
|
When /^I touch the (\d*)(?:st|nd|rd|th)? alert view button$/ do |ordinal|
|
206
206
|
ordinal = ordinal.to_i
|
207
207
|
touch( "alertView threePartButton tag:#{ordinal}" )
|
@@ -217,7 +217,7 @@ end
|
|
217
217
|
|
218
218
|
Then /^switch "([^\"]*)" should be (on|off)$/ do |mark,expected_state|
|
219
219
|
expected_state = expected_state == 'on'
|
220
|
-
|
220
|
+
|
221
221
|
quote = get_selector_quote(mark)
|
222
222
|
selector = "view:'UISwitch' marked:#{quote}#{mark}#{quote}"
|
223
223
|
switch_states = frankly_map( selector, "isOn" )
|
@@ -252,7 +252,7 @@ When /^I dump the DOM$/ do
|
|
252
252
|
end
|
253
253
|
|
254
254
|
When /^I quit the simulator/ do
|
255
|
-
quit_simulator
|
255
|
+
quit_simulator
|
256
256
|
end
|
257
257
|
|
258
258
|
When /^I reset the simulator/ do
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#include "frankify.xcconfig"
|
2
|
+
<% plugins.each do |plugin| %>
|
3
|
+
#include "plugins/<%=plugin.name%>/<%=plugin.xcconfig%>"
|
4
|
+
<% end %>
|
5
|
+
INSTALL_PATH = /./
|
6
|
+
|
7
|
+
<% plugin_names = plugins.map {|plugin| plugin.name } %>
|
8
|
+
|
9
|
+
FRANK_LDFLAGS = $(FRANK_CORE_LDFLAGS) <%= plugin_names.map {|name| "$(#{name.upcase}_LDFLAGS)"}.join(' ') %>
|
10
|
+
|
11
|
+
FRANK_GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = $(FRANK_CORE_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS) <%= plugin_names.map {|name| "$(#{name.upcase}_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS)"}.join(' ') %>
|
@@ -7,6 +7,7 @@ require 'frank-cucumber/scroll_helper'
|
|
7
7
|
require 'frank-cucumber/gesture_helper'
|
8
8
|
require 'frank-cucumber/location_helper'
|
9
9
|
require 'frank-cucumber/bonjour'
|
10
|
+
require 'frank-cucumber/rect.rb'
|
10
11
|
|
11
12
|
module Frank module Cucumber
|
12
13
|
|
@@ -20,11 +21,11 @@ module Frank module Cucumber
|
|
20
21
|
# * {#app_exec}
|
21
22
|
#
|
22
23
|
# == Configuring the Frank driver
|
23
|
-
# There are some class-level facilities which configure how all Frank interactions work. For example you can specify which selector engine to use
|
24
|
+
# There are some class-level facilities which configure how all Frank interactions work. For example you can specify which selector engine to use
|
24
25
|
# with {FrankHelper.selector_engine}. You can specify the base url which the native app's Frank server is listening on with {FrankHelper.server_base_url}.
|
25
26
|
#
|
26
27
|
# Two common use cases are covered more conveniently with {FrankHelper.use_shelley_from_now_on} and {FrankHelper.test_on_physical_device_via_bonjour}.
|
27
|
-
module FrankHelper
|
28
|
+
module FrankHelper
|
28
29
|
include WaitHelper
|
29
30
|
include KeyboardHelper
|
30
31
|
include ScrollHelper
|
@@ -34,7 +35,7 @@ module FrankHelper
|
|
34
35
|
|
35
36
|
# @!attribute [rw] selector_engine
|
36
37
|
class << self
|
37
|
-
# @return [String] the selector engine we tell Frank to use when interpreting view selectors.
|
38
|
+
# @return [String] the selector engine we tell Frank to use when interpreting view selectors.
|
38
39
|
attr_accessor :selector_engine
|
39
40
|
# @return [String] the base url which the Frank server is running on. All Frank commands will be sent to that server.
|
40
41
|
attr_accessor :server_base_url
|
@@ -51,7 +52,7 @@ module FrankHelper
|
|
51
52
|
raise 'could not detect running Frank server' unless @server_base_url
|
52
53
|
end
|
53
54
|
end
|
54
|
-
|
55
|
+
|
55
56
|
# Get the correct quote for the selector
|
56
57
|
def get_selector_quote(selector)
|
57
58
|
if selector.index("'") == nil
|
@@ -59,6 +60,13 @@ module FrankHelper
|
|
59
60
|
else
|
60
61
|
return '"'
|
61
62
|
end
|
63
|
+
|
64
|
+
# Specify ip address to run on
|
65
|
+
def test_on_physical_device_with_ip(ip_address)
|
66
|
+
@server_base_url = ip_address
|
67
|
+
raise 'IP Address is incorrect' unless @server_base_url.match(%r{\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b})
|
68
|
+
puts "Running on Frank server #{@server_base_url}"
|
69
|
+
end
|
62
70
|
end
|
63
71
|
|
64
72
|
#@api private
|
@@ -72,7 +80,7 @@ module FrankHelper
|
|
72
80
|
def base_server_url
|
73
81
|
Frank::Cucumber::FrankHelper.server_base_url
|
74
82
|
end
|
75
|
-
|
83
|
+
|
76
84
|
# Ask Frank to touch all views matching the specified selector. There may be views in the view heirarchy which match the selector but
|
77
85
|
# which Frank cannot or will not touch - for example views which are outside the current viewport. You can discover which of the matching
|
78
86
|
# views were actually touched by inspecting the Array which is returned.
|
@@ -109,7 +117,7 @@ module FrankHelper
|
|
109
117
|
# @return [Boolean]
|
110
118
|
# @see #check_element_exists
|
111
119
|
def element_exists( selector )
|
112
|
-
matches = frankly_map( selector, '
|
120
|
+
matches = frankly_map( selector, 'FEX_accessibilityLabel' )
|
113
121
|
# TODO: raise warning if matches.count > 1
|
114
122
|
!matches.empty?
|
115
123
|
end
|
@@ -166,9 +174,9 @@ module FrankHelper
|
|
166
174
|
end
|
167
175
|
|
168
176
|
|
169
|
-
# Waits for any of the specified selectors to match a view.
|
177
|
+
# Waits for any of the specified selectors to match a view.
|
170
178
|
#
|
171
|
-
# Checks each selector in turn within a {http://sauceio.com/index.php/2011/04/how-to-lose-races-and-win-at-selenium/ spin assert} loop and yields the first one which is found to exist in the view heirarchy.
|
179
|
+
# Checks each selector in turn within a {http://sauceio.com/index.php/2011/04/how-to-lose-races-and-win-at-selenium/ spin assert} loop and yields the first one which is found to exist in the view heirarchy.
|
172
180
|
# Raises an exception if no views could be found to match any of the provided selectors within {WaitHelper::TIMEOUT} seconds.
|
173
181
|
#
|
174
182
|
# @see WaitHelper#wait_until
|
@@ -187,7 +195,7 @@ module FrankHelper
|
|
187
195
|
|
188
196
|
# Waits for the specified selector to not match any views.
|
189
197
|
#
|
190
|
-
# Uses {WaitHelper#wait_until} to check for any matching views within a {http://sauceio.com/index.php/2011/04/how-to-lose-races-and-win-at-selenium/ spin assert} loop.
|
198
|
+
# Uses {WaitHelper#wait_until} to check for any matching views within a {http://sauceio.com/index.php/2011/04/how-to-lose-races-and-win-at-selenium/ spin assert} loop.
|
191
199
|
# Returns as soon as no views match the specified selector.
|
192
200
|
# Raises an exception if there continued to be at least one view which matched the selector by the time {WaitHelper::TIMEOUT} seconds passed.
|
193
201
|
#
|
@@ -199,14 +207,14 @@ module FrankHelper
|
|
199
207
|
end
|
200
208
|
end
|
201
209
|
|
202
|
-
# Waits for a view to exist and then send a touch command to that view.
|
210
|
+
# Waits for a view to exist and then send a touch command to that view.
|
203
211
|
#
|
204
212
|
# @param selectors takes one or more selectors to use to search for a view. The first selector which is found to matches a view is the selector
|
205
213
|
# which is then used to send a touch command.
|
206
214
|
#
|
207
215
|
# Raises an exception if no views could be found to match any of the provided selectors within {WaitHelper::TIMEOUT} seconds.
|
208
216
|
def wait_for_element_to_exist_and_then_touch_it(*selectors)
|
209
|
-
wait_for_element_to_exist(*selectors) do |sel|
|
217
|
+
wait_for_element_to_exist(*selectors) do |sel|
|
210
218
|
touch(sel)
|
211
219
|
end
|
212
220
|
end
|
@@ -223,7 +231,7 @@ module FrankHelper
|
|
223
231
|
end
|
224
232
|
|
225
233
|
|
226
|
-
# Checks that the specified selector matches at least one view, and that at least one of the matched
|
234
|
+
# Checks that the specified selector matches at least one view, and that at least one of the matched
|
227
235
|
# views has an isHidden property set to false
|
228
236
|
#
|
229
237
|
# a better name for this method would be element_exists_and_is_not_hidden
|
@@ -234,7 +242,7 @@ module FrankHelper
|
|
234
242
|
end
|
235
243
|
|
236
244
|
def accessibility_frame(selector)
|
237
|
-
frames = frankly_map( selector, '
|
245
|
+
frames = frankly_map( selector, 'FEX_accessibilityFrame' )
|
238
246
|
raise "the supplied selector [#{selector}] did not match any views" if frames.empty?
|
239
247
|
raise "the supplied selector [#{selector}] matched more than one views (#{frames.count} views matched)" if frames.count > 1
|
240
248
|
Rect.from_api_repr( frames.first )
|
@@ -247,7 +255,25 @@ module FrankHelper
|
|
247
255
|
|
248
256
|
dest_frame = accessibility_frame(to)
|
249
257
|
|
250
|
-
|
258
|
+
if is_mac
|
259
|
+
from_frame = accessibility_frame(from)
|
260
|
+
|
261
|
+
frankly_map( from, 'FEX_mouseDownX:y:', from_frame.center.x, from_frame.center.y )
|
262
|
+
|
263
|
+
sleep 0.3
|
264
|
+
|
265
|
+
frankly_map( from, 'FEX_dragToX:y:', dest_frame.center.x, dest_frame.center.y )
|
266
|
+
|
267
|
+
sleep 0.3
|
268
|
+
|
269
|
+
frankly_map( from, 'FEX_mouseUpX:y:', dest_frame.center.x, dest_frame.center.y )
|
270
|
+
|
271
|
+
else
|
272
|
+
|
273
|
+
frankly_map( from, 'FEX_dragWithInitialDelayToX:y:', dest_frame.center.x, dest_frame.center.y )
|
274
|
+
|
275
|
+
end
|
276
|
+
|
251
277
|
end
|
252
278
|
|
253
279
|
|
@@ -255,8 +281,8 @@ module FrankHelper
|
|
255
281
|
# @param method_sig [String] the method signature
|
256
282
|
# @param method_args the method arguments
|
257
283
|
#
|
258
|
-
# @example
|
259
|
-
# # the same as calling
|
284
|
+
# @example
|
285
|
+
# # the same as calling
|
260
286
|
# # [[[UIApplication sharedApplication] appDelegate] setServiceBaseUrl:@"http://example.com/my_api" withPort:8080]
|
261
287
|
# # from your native app
|
262
288
|
# app_exec( "setServiceBaseUrl:withPort:", "http://example.com/my_api", 8080 )
|
@@ -264,24 +290,24 @@ module FrankHelper
|
|
264
290
|
#
|
265
291
|
def app_exec(method_sig, *method_args)
|
266
292
|
operation_map = Gateway.build_operation_map(method_sig.to_s, method_args)
|
267
|
-
|
268
|
-
res = frank_server.send_post(
|
269
|
-
'app_exec',
|
270
|
-
:operation => operation_map
|
293
|
+
|
294
|
+
res = frank_server.send_post(
|
295
|
+
'app_exec',
|
296
|
+
:operation => operation_map
|
271
297
|
)
|
272
298
|
|
273
299
|
return Gateway.evaluate_frankly_response( res, "app_exec #{method_sig}" )
|
274
300
|
end
|
275
301
|
|
276
|
-
# Ask Frank to execute an arbitrary Objective-C method on each view which matches the specified selector.
|
302
|
+
# Ask Frank to execute an arbitrary Objective-C method on each view which matches the specified selector.
|
277
303
|
#
|
278
304
|
# @return [Array] an array with an element for each view matched by the selector, each element in the array gives the return value from invoking the specified method on that view.
|
279
305
|
def frankly_map( selector, method_name, *method_args )
|
280
306
|
operation_map = Gateway.build_operation_map(method_name.to_s, method_args)
|
281
|
-
res = frank_server.send_post(
|
307
|
+
res = frank_server.send_post(
|
282
308
|
'map',
|
283
|
-
:query => selector,
|
284
|
-
:operation => operation_map,
|
309
|
+
:query => selector,
|
310
|
+
:operation => operation_map,
|
285
311
|
:selector_engine => selector_engine
|
286
312
|
)
|
287
313
|
|
@@ -337,7 +363,7 @@ module FrankHelper
|
|
337
363
|
# @param orientation can be 'landscape','landscape_left','landscape_right','portrait', or 'portrait_upside_down'
|
338
364
|
def frankly_set_orientation(orientation)
|
339
365
|
orientation = orientation.to_s
|
340
|
-
orientation = 'landscape_left' if orientation == 'landscape'
|
366
|
+
orientation = 'landscape_left' if orientation == 'landscape'
|
341
367
|
res = frank_server.send_post( 'orientation', orientation )
|
342
368
|
return Gateway.evaluate_frankly_response( res, "set_orientation #{orientation}" )
|
343
369
|
end
|
@@ -391,7 +417,31 @@ module FrankHelper
|
|
391
417
|
raise "ACCESSIBILITY DOES NOT APPEAR TO BE ENABLED ON YOUR SIMULATOR. Hit the home button, go to settings, select Accessibility, and turn the inspector on."
|
392
418
|
end
|
393
419
|
end
|
394
|
-
|
420
|
+
|
421
|
+
# @return [String] the name of the device currently running the application
|
422
|
+
# @note this is a low-level API. In most cases you should use {is_iphone}, {is_ipad} or {is_mac} instead.
|
423
|
+
def frankly_device_name
|
424
|
+
res = frank_server.send_get( 'device' )
|
425
|
+
device = JSON.parse( res )['device']
|
426
|
+
puts "device reported as '#{device}'" if $DEBUG
|
427
|
+
device
|
428
|
+
end
|
429
|
+
|
430
|
+
# @return [Boolean] is the device running the application an iPhone.
|
431
|
+
def is_iphone
|
432
|
+
return frankly_device_name == "iphone"
|
433
|
+
end
|
434
|
+
|
435
|
+
# @return [Boolean] is the device running the application an iPhone.
|
436
|
+
def is_ipad
|
437
|
+
return frankly_device_name == "ipad"
|
438
|
+
end
|
439
|
+
|
440
|
+
# @return [Boolean] is the device running the application a Mac.
|
441
|
+
def is_mac
|
442
|
+
return frankly_device_name == "mac"
|
443
|
+
end
|
444
|
+
|
395
445
|
# Check whether Frank is able to communicate with the application under automation
|
396
446
|
def frankly_ping
|
397
447
|
frank_server.ping
|
@@ -402,7 +452,7 @@ module FrankHelper
|
|
402
452
|
def frank_server
|
403
453
|
@_frank_server ||= Frank::Cucumber::Gateway.new( base_server_url )
|
404
454
|
end
|
405
|
-
|
455
|
+
|
406
456
|
end
|
407
457
|
|
408
458
|
|
@@ -81,3 +81,16 @@ es:
|
|
81
81
|
toggle_in_call_status_bar: Activar/Desactivar barra de estado durante llamada
|
82
82
|
simulate_hardware_keyboard: Simular teclado físico
|
83
83
|
only_one_simulator: Sólo se puede ejecutar un Simulador iOS a la vez.
|
84
|
+
|
85
|
+
it:
|
86
|
+
iphone_simulator: Simulatore iOS
|
87
|
+
hardware: Hardware
|
88
|
+
home: Home
|
89
|
+
rotate_left: Ruota a sinistra
|
90
|
+
rotate_right: Ruota a destra
|
91
|
+
shake_gesture: Gesto Agita
|
92
|
+
simulate_memory_warning: Simula avviso memoria
|
93
|
+
toggle_in_call_status_bar: Attiva/disattiva barra di state chiamata
|
94
|
+
simulate_hardware_keyboard: Simula la tastiera hardware
|
95
|
+
only_one_simulator: Solo un Simulatore iOS può essere eseguito in un momento.
|
96
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Frank
|
4
|
+
module Plugins
|
5
|
+
class Plugin
|
6
|
+
|
7
|
+
attr_accessor :plugin_dir, :name, :exclude_dependencies
|
8
|
+
|
9
|
+
def initialize(plugin_dir, name)
|
10
|
+
self.plugin_dir= plugin_dir
|
11
|
+
self.name = name
|
12
|
+
end
|
13
|
+
|
14
|
+
def dependency(lib,linker_flag="-l#{lib}")
|
15
|
+
return linker_flag unless exclude_dependencies.include?(lib)
|
16
|
+
''
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_xcconfig(exclude_dependencies)
|
20
|
+
self.exclude_dependencies= exclude_dependencies
|
21
|
+
|
22
|
+
_xcconfig_erb = File.join(plugin_dir,"#{xcconfig}.erb")
|
23
|
+
|
24
|
+
unless File.exist?(_xcconfig_erb)
|
25
|
+
raise "Invalid plugin #{name} at #{File.join(plugin_dir)}.\nDoesn't have an erb file: #{_xcconfig_erb}"
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
_template = ERB.new(File.read(_xcconfig_erb))
|
30
|
+
result = _template.result(binding)
|
31
|
+
output_path = File.join(plugin_dir, xcconfig)
|
32
|
+
File.open(output_path,'w') {|f| f.write(result)}
|
33
|
+
output_path
|
34
|
+
end
|
35
|
+
|
36
|
+
def xcconfig
|
37
|
+
"#{name}.xcconfig"
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.from_plugin_directory(path)
|
41
|
+
plugin_name = File.basename(path)
|
42
|
+
Plugin.new(path, plugin_name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.generate_core_xcconfig(plugins)
|
46
|
+
_template = ERB.new(File.read(core_xcconfig_path))
|
47
|
+
|
48
|
+
_template.result(binding)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.core_xcconfig_path
|
52
|
+
File.expand_path(File.join(File.dirname(__FILE__), '..', 'frank.xcconfig.erb'))
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -11,7 +11,7 @@ module Cucumber
|
|
11
11
|
#
|
12
12
|
module WaitHelper
|
13
13
|
# Default option for how long (in seconds) to keep checking before timing out the entire wait
|
14
|
-
TIMEOUT = ENV['WAIT_TIMEOUT']
|
14
|
+
TIMEOUT = (ENV['WAIT_TIMEOUT'] || 240).to_i
|
15
15
|
# How long to pause (in seconds) inbetween each spin through the assertion block
|
16
16
|
POLL_SLEEP = 0.1
|
17
17
|
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: frank-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.13.pre1
|
5
|
+
prerelease: 7
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Pete Hodgson
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-06-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: cucumber
|
@@ -249,6 +249,7 @@ files:
|
|
249
249
|
- frank-skeleton/libFrankMac.a
|
250
250
|
- frank-skeleton/libShelley.a
|
251
251
|
- frank-skeleton/libShelleyMac.a
|
252
|
+
- frank-skeleton/plugins/.empty_directory
|
252
253
|
- lib/frank-cucumber.rb
|
253
254
|
- lib/frank-cucumber/app_bundle_locator.rb
|
254
255
|
- lib/frank-cucumber/bonjour.rb
|
@@ -256,6 +257,7 @@ files:
|
|
256
257
|
- lib/frank-cucumber/color_helper.rb
|
257
258
|
- lib/frank-cucumber/console.rb
|
258
259
|
- lib/frank-cucumber/core_frank_steps.rb
|
260
|
+
- lib/frank-cucumber/frank.xcconfig.erb
|
259
261
|
- lib/frank-cucumber/frank_helper.rb
|
260
262
|
- lib/frank-cucumber/frank_localize.rb
|
261
263
|
- lib/frank-cucumber/frank_mac_helper.rb
|
@@ -268,6 +270,7 @@ files:
|
|
268
270
|
- lib/frank-cucumber/localize.yml
|
269
271
|
- lib/frank-cucumber/location_helper.rb
|
270
272
|
- lib/frank-cucumber/mac_launcher.rb
|
273
|
+
- lib/frank-cucumber/plugins/plugin.rb
|
271
274
|
- lib/frank-cucumber/rect.rb
|
272
275
|
- lib/frank-cucumber/scroll_helper.rb
|
273
276
|
- lib/frank-cucumber/version.rb
|
@@ -376,12 +379,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
376
379
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
377
380
|
none: false
|
378
381
|
requirements:
|
379
|
-
- - ! '
|
382
|
+
- - ! '>'
|
380
383
|
- !ruby/object:Gem::Version
|
381
|
-
version:
|
384
|
+
version: 1.3.1
|
382
385
|
requirements: []
|
383
386
|
rubyforge_project:
|
384
|
-
rubygems_version: 1.8.
|
387
|
+
rubygems_version: 1.8.25
|
385
388
|
signing_key:
|
386
389
|
specification_version: 3
|
387
390
|
summary: Use cucumber to test native iOS apps via Frank
|
@@ -390,4 +393,3 @@ test_files:
|
|
390
393
|
- test/launcher_test.rb
|
391
394
|
- test/rect_test.rb
|
392
395
|
- test/test_helper.rb
|
393
|
-
has_rdoc:
|