sc-frank-cucumber 1.2.1.00af28c
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +38 -0
- data/bin/frank +6 -0
- data/bin/frank-skeleton +33 -0
- data/frank-skeleton/features/my_first.feature +12 -0
- data/frank-skeleton/features/step_definitions/launch_steps.rb +20 -0
- data/frank-skeleton/features/support/env.rb +8 -0
- data/frank-skeleton/frank_static_resources.bundle/ViewAttributeMapping.plist +63 -0
- data/frank-skeleton/frank_static_resources.bundle/ViewAttributeMappingMac.plist +99 -0
- data/frank-skeleton/frank_static_resources.bundle/images/ajax-loader.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/file.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/folder-closed.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/folder.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/loader.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/loader.png +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/minus.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/plus.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-black-line.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-black.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-default-line.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-default.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-famfamfam-line.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-famfamfam.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-gray-line.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-gray.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-red-line.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/images/treeview-red.gif +0 -0
- data/frank-skeleton/frank_static_resources.bundle/index.html +86 -0
- data/frank-skeleton/frank_static_resources.bundle/index.html.haml +76 -0
- data/frank-skeleton/frank_static_resources.bundle/js/accessible_views_view.coffee +41 -0
- data/frank-skeleton/frank_static_resources.bundle/js/accessible_views_view.js +46 -0
- data/frank-skeleton/frank_static_resources.bundle/js/controller.coffee +134 -0
- data/frank-skeleton/frank_static_resources.bundle/js/controller.js +139 -0
- data/frank-skeleton/frank_static_resources.bundle/js/details_view.coffee +42 -0
- data/frank-skeleton/frank_static_resources.bundle/js/details_view.js +51 -0
- data/frank-skeleton/frank_static_resources.bundle/js/dropdown_control.coffee +64 -0
- data/frank-skeleton/frank_static_resources.bundle/js/dropdown_control.js +73 -0
- data/frank-skeleton/frank_static_resources.bundle/js/ersatz_model.coffee +46 -0
- data/frank-skeleton/frank_static_resources.bundle/js/ersatz_model.js +60 -0
- data/frank-skeleton/frank_static_resources.bundle/js/ersatz_view.coffee +167 -0
- data/frank-skeleton/frank_static_resources.bundle/js/ersatz_view.js +205 -0
- data/frank-skeleton/frank_static_resources.bundle/js/experiment_bar_model.coffee +10 -0
- data/frank-skeleton/frank_static_resources.bundle/js/experiment_bar_model.js +17 -0
- data/frank-skeleton/frank_static_resources.bundle/js/experiment_bar_view.coffee +44 -0
- data/frank-skeleton/frank_static_resources.bundle/js/experiment_bar_view.js +63 -0
- data/frank-skeleton/frank_static_resources.bundle/js/frank.coffee +96 -0
- data/frank-skeleton/frank_static_resources.bundle/js/frank.js +146 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/backbone.js +1431 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/coffee-script.js +8 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/jquery-ui.min.js +405 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/jquery.min.js +4 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/jquery.treeview.js +251 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/json2.js +481 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/raphael.js +5815 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/require.js +2053 -0
- data/frank-skeleton/frank_static_resources.bundle/js/lib/underscore.js +1059 -0
- data/frank-skeleton/frank_static_resources.bundle/js/main.coffee +27 -0
- data/frank-skeleton/frank_static_resources.bundle/js/main.js +29 -0
- data/frank-skeleton/frank_static_resources.bundle/js/tabs_controller.coffee +13 -0
- data/frank-skeleton/frank_static_resources.bundle/js/tabs_controller.js +22 -0
- data/frank-skeleton/frank_static_resources.bundle/js/toast_controller.coffee +15 -0
- data/frank-skeleton/frank_static_resources.bundle/js/toast_controller.js +28 -0
- data/frank-skeleton/frank_static_resources.bundle/js/transform_stack.coffee +59 -0
- data/frank-skeleton/frank_static_resources.bundle/js/transform_stack.js +78 -0
- data/frank-skeleton/frank_static_resources.bundle/js/tree_view.coffee +53 -0
- data/frank-skeleton/frank_static_resources.bundle/js/tree_view.js +64 -0
- data/frank-skeleton/frank_static_resources.bundle/js/view_hier_model.coffee +37 -0
- data/frank-skeleton/frank_static_resources.bundle/js/view_hier_model.js +48 -0
- data/frank-skeleton/frank_static_resources.bundle/js/view_model.coffee +39 -0
- data/frank-skeleton/frank_static_resources.bundle/js/view_model.js +62 -0
- data/frank-skeleton/frank_static_resources.bundle/pictos/index.html +329 -0
- data/frank-skeleton/frank_static_resources.bundle/pictos/pictos-web.eot +0 -0
- data/frank-skeleton/frank_static_resources.bundle/pictos/pictos-web.svg +114 -0
- data/frank-skeleton/frank_static_resources.bundle/pictos/pictos-web.ttf +0 -0
- data/frank-skeleton/frank_static_resources.bundle/pictos/pictos-web.woff +0 -0
- data/frank-skeleton/frank_static_resources.bundle/pictos/pictos.css +20 -0
- data/frank-skeleton/frank_static_resources.bundle/pictos/pictos_base64.css +18 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/css/symbiote.css +1 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_elements.scss +28 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_header.scss +61 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_inspect_tabs_list_tabs.scss +194 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_jquery.treeview.scss +68 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_jqui.scss +2 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_layout.scss +13 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_mixins.sass +137 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_reset.scss +32 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_selector_test_toolbar.scss +81 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_solarized.scss +16 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_typography.scss +11 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_unicode.scss +3 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_z_index.scss +2 -0
- data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/symbiote.scss +26 -0
- data/frank-skeleton/frankify.xcconfig.tt +6 -0
- 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/libShelleyMac.a +0 -0
- data/frank-skeleton/plugins/.empty_directory +0 -0
- data/lib/frank-cucumber.rb +15 -0
- data/lib/frank-cucumber/app_bundle_locator.rb +58 -0
- data/lib/frank-cucumber/bonjour.rb +73 -0
- data/lib/frank-cucumber/cli.rb +299 -0
- data/lib/frank-cucumber/color_helper.rb +13 -0
- data/lib/frank-cucumber/console.rb +28 -0
- data/lib/frank-cucumber/core_frank_steps.rb +260 -0
- data/lib/frank-cucumber/frank.xcconfig.erb +17 -0
- data/lib/frank-cucumber/frank_helper.rb +459 -0
- data/lib/frank-cucumber/frank_localize.rb +43 -0
- data/lib/frank-cucumber/frank_mac_helper.rb +120 -0
- data/lib/frank-cucumber/frankifier.rb +150 -0
- data/lib/frank-cucumber/gateway.rb +135 -0
- data/lib/frank-cucumber/gesture_helper.rb +99 -0
- data/lib/frank-cucumber/host_scripting.rb +96 -0
- data/lib/frank-cucumber/keyboard_helper.rb +69 -0
- data/lib/frank-cucumber/launcher.rb +70 -0
- data/lib/frank-cucumber/localize.yml +104 -0
- data/lib/frank-cucumber/location_helper.rb +20 -0
- data/lib/frank-cucumber/mac_launcher.rb +35 -0
- data/lib/frank-cucumber/plugins/plugin.rb +57 -0
- data/lib/frank-cucumber/rect.rb +26 -0
- data/lib/frank-cucumber/scroll_helper.rb +24 -0
- data/lib/frank-cucumber/version.rb +5 -0
- data/lib/frank-cucumber/wait_helper.rb +57 -0
- data/sc-frank-cucumber.gemspec +37 -0
- data/test/keyboard_helper_test.rb +84 -0
- data/test/launcher_test.rb +57 -0
- data/test/rect_test.rb +25 -0
- data/test/test_helper.rb +16 -0
- metadata +395 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
module Frank
|
4
|
+
module Cucumber
|
5
|
+
module Localize
|
6
|
+
|
7
|
+
def self.system_locale
|
8
|
+
case ENV['LANG']
|
9
|
+
when /^fr_/
|
10
|
+
:fr
|
11
|
+
when /^de_/
|
12
|
+
:de
|
13
|
+
when /^ru_/
|
14
|
+
:ru
|
15
|
+
when /^zh_/
|
16
|
+
:zh
|
17
|
+
when /^ja_/
|
18
|
+
:ja
|
19
|
+
when /^es_/
|
20
|
+
:es
|
21
|
+
when /^it_/
|
22
|
+
:it
|
23
|
+
else
|
24
|
+
:en
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.load_translations
|
29
|
+
if I18n.backend.send(:translations).size == 0
|
30
|
+
I18n.locale = self.system_locale
|
31
|
+
I18n.load_path = [ File.join(File.dirname(__FILE__), 'localize.yml') ]
|
32
|
+
I18n.backend.load_translations
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.t(key)
|
37
|
+
self.load_translations
|
38
|
+
I18n.t(key)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'frank-cucumber/frank_helper'
|
2
|
+
|
3
|
+
module Frank module Cucumber
|
4
|
+
|
5
|
+
module FrankMacHelper
|
6
|
+
|
7
|
+
# Performs a click at the center of the selected object.
|
8
|
+
#
|
9
|
+
# This method creates CGEvents to move and click the mouse. Before calling this method,
|
10
|
+
# you should make sure that the element that you want to click is frontmost by calling
|
11
|
+
# bring_to_front.
|
12
|
+
#
|
13
|
+
# This method is designed to act on a single object, so do not pass a selector that will
|
14
|
+
# return multiple objects.
|
15
|
+
def click ( selector )
|
16
|
+
frame = accessibility_frame(selector)
|
17
|
+
frankly_map( selector, 'FEX_mouseDownX:y:', frame.center.x, frame.center.y )
|
18
|
+
frankly_map( selector, 'FEX_mouseUpX:y:', frame.center.x, frame.center.y )
|
19
|
+
end
|
20
|
+
|
21
|
+
# Performs a double-click at the center of the selected object.
|
22
|
+
#
|
23
|
+
# This method creates CGEvents to move and click the mouse. Before calling this method,
|
24
|
+
# you should make sure that the element that you want to click is frontmost by calling
|
25
|
+
# bring_to_front.
|
26
|
+
#
|
27
|
+
# This method is designed to act on a single object, so do not pass a selector that will
|
28
|
+
# return multiple objects.
|
29
|
+
def double_click ( selector )
|
30
|
+
click(selector)
|
31
|
+
click(selector)
|
32
|
+
end
|
33
|
+
|
34
|
+
#@api private
|
35
|
+
def perform_action_on_selector( action, selector )
|
36
|
+
touch_successes = frankly_map( selector, action )
|
37
|
+
raise "could not find anything matching [#{selector}] which supports that action" if touch_successes == nil or touch_successes.empty?
|
38
|
+
raise "some objects do not support that action" if touch_successes.include?(false)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Simulates the effect of clicking on the selected objects without actually moving the
|
42
|
+
# mouse or clicking.
|
43
|
+
#
|
44
|
+
# If the object supports the NSAccessibilityPressAction, that action is performed.
|
45
|
+
# Otherwise, if the object is a table cell or row, that row is selected,
|
46
|
+
# Otherwise, if the object is an NSView, it is made the first responder, if possible
|
47
|
+
# Otherwise, if the object is a menu item, it opens its submenu if it has one, or
|
48
|
+
# performs it's action if not.
|
49
|
+
def simulate_click( selector )
|
50
|
+
perform_action_on_selector( 'FEX_simulateClick', selector )
|
51
|
+
end
|
52
|
+
|
53
|
+
# Brings the selected application or window to the front.
|
54
|
+
def bring_to_front( selector )
|
55
|
+
perform_action_on_selector( 'FEX_raise', selector )
|
56
|
+
end
|
57
|
+
|
58
|
+
# Cancels the current action, such as editing a text field.
|
59
|
+
def cancel( selector )
|
60
|
+
perform_action_on_selector( 'FEX_cancel', selector )
|
61
|
+
end
|
62
|
+
|
63
|
+
# Finishes the current action, such as editing a text field.
|
64
|
+
def confirm( selector )
|
65
|
+
perform_action_on_selector( 'FEX_confirm', selector )
|
66
|
+
end
|
67
|
+
|
68
|
+
# Decrements the value of NSSliders, NSSteppers, and similar controls
|
69
|
+
def decrement_value( selector )
|
70
|
+
perform_action_on_selector( 'FEX_decrement', selector )
|
71
|
+
end
|
72
|
+
|
73
|
+
# Deletes the user-inputted value
|
74
|
+
def delete_value( selector )
|
75
|
+
perform_action_on_selector( 'FEX_delete', selector )
|
76
|
+
end
|
77
|
+
|
78
|
+
# Increments the value of NSSliders, NSSteppers, and similar controls
|
79
|
+
def increment_value( selector )
|
80
|
+
perform_action_on_selector( 'FEX_increment', selector )
|
81
|
+
end
|
82
|
+
|
83
|
+
# Selects a menu item. This action is considered "outdated" by the Accessibility API, so
|
84
|
+
# don't use it without a good reason.
|
85
|
+
def pick( selector )
|
86
|
+
perform_action_on_selector( 'FEX_pick', selector )
|
87
|
+
end
|
88
|
+
|
89
|
+
# Shows the contextual menu associated with the selector. This is the menu that would
|
90
|
+
# appear if the user right-clicked the selector, or, in some cases, held down the left
|
91
|
+
# mouse button on the selector.
|
92
|
+
def show_menu( selector )
|
93
|
+
perform_action_on_selector( 'FEX_showMenu', selector )
|
94
|
+
end
|
95
|
+
|
96
|
+
# Expands the row the selector belongs to in an NSOutlineView. Do not expand more than
|
97
|
+
# one row at a time.
|
98
|
+
def expand_row( selector )
|
99
|
+
perform_action_on_selector( 'FEX_expand', selector )
|
100
|
+
end
|
101
|
+
|
102
|
+
# Collapses the row the selector belongs to in an NSOutlineView. Do not expand more than
|
103
|
+
# one row at a time.
|
104
|
+
def collapse_row( selector )
|
105
|
+
perform_action_on_selector( 'FEX_collapse', selector )
|
106
|
+
end
|
107
|
+
|
108
|
+
# @return [Boolean] whether the rows the selectors belong to in an NSOutlineView are all
|
109
|
+
# expanded
|
110
|
+
def row_is_expanded( selector )
|
111
|
+
successes = frankly_map( selector, "FEX_isExpanded" )
|
112
|
+
return false if successes == nil or successes.empty?
|
113
|
+
return !successes.include?(false)
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'xcodeproj'
|
3
|
+
|
4
|
+
class Frankifier
|
5
|
+
include Thor::Shell
|
6
|
+
|
7
|
+
def self.frankify! root_dir, options = {}
|
8
|
+
me = new(root_dir, options)
|
9
|
+
me.frankify!
|
10
|
+
me
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize( root_dir, options = {} )
|
14
|
+
@root = Pathname.new( root_dir )
|
15
|
+
@target_build_configuration = options[:build_config]
|
16
|
+
@target_selection = options[:target]
|
17
|
+
load_xcode_proj_option(options[:project])
|
18
|
+
end
|
19
|
+
|
20
|
+
def frankify!
|
21
|
+
decide_on_project if @project.nil?
|
22
|
+
decide_on_target
|
23
|
+
report_project_and_target
|
24
|
+
|
25
|
+
check_target_build_configuration_is_valid!
|
26
|
+
|
27
|
+
say ''
|
28
|
+
add_linker_flag
|
29
|
+
|
30
|
+
say ''
|
31
|
+
add_library_search_path
|
32
|
+
|
33
|
+
save_changes
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def load_xcode_proj_option(xcodeproj)
|
38
|
+
if xcodeproj
|
39
|
+
unless File.exists?(xcodeproj)
|
40
|
+
raise "Project file '#{xcodeproj}' does not exist. Please specify the relative path."
|
41
|
+
end
|
42
|
+
|
43
|
+
@xcodeproj_path = Pathname.new(xcodeproj)
|
44
|
+
@project = Xcodeproj::Project.open(@xcodeproj_path)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def decide_on_project
|
49
|
+
projects = Pathname.glob( @root+'*.xcodeproj' )
|
50
|
+
xcodeproj = case projects.size
|
51
|
+
when 0
|
52
|
+
raise "There are no .xcodeproj files in this directory. Please move to your root project directory and try again."
|
53
|
+
when 1
|
54
|
+
projects.first
|
55
|
+
else
|
56
|
+
choice = ask_menu(
|
57
|
+
"I found more than one .xcodeproj. Which is the main app project that you wish to Frankify?",
|
58
|
+
projects.map(&:basename)
|
59
|
+
)
|
60
|
+
projects[choice]
|
61
|
+
end
|
62
|
+
|
63
|
+
@xcodeproj_path = xcodeproj
|
64
|
+
@project = Xcodeproj::Project.open(xcodeproj)
|
65
|
+
end
|
66
|
+
|
67
|
+
def decide_on_target
|
68
|
+
targets = @project.targets
|
69
|
+
@target = targets.find { |item| item.name.eql?(@target_selection) } if @target_selection
|
70
|
+
return @target if @target
|
71
|
+
@target = case targets.size
|
72
|
+
when 0
|
73
|
+
raise "Sorry, this project appears to contain no targets. Nothing I can do here."
|
74
|
+
when 1
|
75
|
+
targets.first
|
76
|
+
else
|
77
|
+
choice = ask_menu(
|
78
|
+
"I found more than one target in this project. Which is the main app target that you wish to Frankify?",
|
79
|
+
targets.map(&:name)
|
80
|
+
)
|
81
|
+
targets.to_a[choice]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def report_project_and_target
|
86
|
+
puts "Frankifying target [#{@target.name}] in project #{@xcodeproj_path.basename}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_linker_flag
|
90
|
+
add_frank_entry_to_build_setting( 'OTHER_LDFLAGS', 'FRANK_LDFLAGS' )
|
91
|
+
end
|
92
|
+
|
93
|
+
def add_library_search_path
|
94
|
+
add_frank_entry_to_build_setting( 'LIBRARY_SEARCH_PATHS', 'FRANK_LIBRARY_SEARCH_PATHS' )
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_frank_entry_to_build_setting( build_setting, entry_to_add )
|
98
|
+
setting_array = Array( build_settings_to_edit[build_setting] )
|
99
|
+
|
100
|
+
if setting_array.find{ |flag| flag.start_with? "$(FRANK_" }
|
101
|
+
say "It appears that your '#{@target_build_configuration}' configuration's #{build_setting} build setting already include some FRANK setup. Namely: #{setting_array.inspect}. I won't change anything here."
|
102
|
+
return
|
103
|
+
end
|
104
|
+
|
105
|
+
say "Adding $(inherited) and $(#{entry_to_add}) to your '#{@target_build_configuration}' configuration's #{build_setting} build setting ..."
|
106
|
+
setting_array.unshift "$(inherited)"
|
107
|
+
setting_array << "$(#{entry_to_add})"
|
108
|
+
setting_array.uniq! # mainly to avoid duplicate $(inherited) entries
|
109
|
+
say "... #{build_setting} is now: #{setting_array.inspect}"
|
110
|
+
|
111
|
+
build_settings_to_edit[build_setting] = setting_array
|
112
|
+
end
|
113
|
+
|
114
|
+
def check_target_build_configuration_is_valid!
|
115
|
+
unless @target.build_configuration_list.build_settings(@target_build_configuration)
|
116
|
+
say %Q|I'm trying to Frankify the '#{@target_build_configuration}' build configuration, but I don't see it that build configuration in your XCode target. Here's a list of the build configurations I see:|
|
117
|
+
@target.build_configuration_list.build_configurations.each do |bc|
|
118
|
+
say " '#{bc.name}'"
|
119
|
+
end
|
120
|
+
say ''
|
121
|
+
say %Q|Please specify one of those build configurations using the --build_configuration flag|
|
122
|
+
exit
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
def build_settings_to_edit
|
128
|
+
@_build_settings_to_edit ||= @target.build_configuration_list.build_settings(@target_build_configuration)
|
129
|
+
end
|
130
|
+
|
131
|
+
def save_changes
|
132
|
+
@project.save
|
133
|
+
end
|
134
|
+
|
135
|
+
# TODO: send this as a pull request to thor
|
136
|
+
def ask_menu message, options
|
137
|
+
option_lines = options.each_with_index.map{ |o,i| "#{i+1}: #{o}" }
|
138
|
+
full_message = ([message,'']+option_lines+[">"]).join("\n")
|
139
|
+
|
140
|
+
allowed_range = (1..options.length)
|
141
|
+
valid_choice = nil
|
142
|
+
until valid_choice
|
143
|
+
choice = ask(full_message).to_i
|
144
|
+
valid_choice = choice if allowed_range.include?(choice)
|
145
|
+
say("You must choose an option between #{allowed_range.first} and #{allowed_range.last}") unless valid_choice
|
146
|
+
end
|
147
|
+
valid_choice-1
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Frank module Cucumber
|
5
|
+
|
6
|
+
class Gateway
|
7
|
+
DEFAULT_BASE_URL = "http://localhost:37265/"
|
8
|
+
|
9
|
+
def initialize( base_url = nil )
|
10
|
+
@base_url = URI.parse( (base_url || DEFAULT_BASE_URL).to_s )
|
11
|
+
end
|
12
|
+
|
13
|
+
def ping
|
14
|
+
send_get('')
|
15
|
+
return true
|
16
|
+
rescue FrankNetworkError
|
17
|
+
return false
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def build_operation_map( method_sig, method_args )
|
22
|
+
num_args_according_to_method_sig = method_sig.count(':')
|
23
|
+
|
24
|
+
if num_args_according_to_method_sig != method_args.count
|
25
|
+
raise <<-EOS
|
26
|
+
|
27
|
+
The method you've specified - #{method_sig} - wants #{num_args_according_to_method_sig} arguments, but you've supplied #{method_args.count} arguments.
|
28
|
+
|
29
|
+
EOS
|
30
|
+
end
|
31
|
+
|
32
|
+
if num_args_according_to_method_sig > 0 && !method_sig.end_with?(':')
|
33
|
+
raise <<-EOS
|
34
|
+
|
35
|
+
The method signature you've specified - #{method_sig} - is invalid. Objective C method signatures which take parameters must end with a :
|
36
|
+
|
37
|
+
EOS
|
38
|
+
end
|
39
|
+
|
40
|
+
{
|
41
|
+
:method_name => method_sig,
|
42
|
+
:arguments => method_args,
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def evaluate_frankly_response( json, req_desc )
|
47
|
+
res = JSON.parse( json )
|
48
|
+
if res['outcome'] != 'SUCCESS'
|
49
|
+
raise "#{req_desc} failed because: #{res['reason']}\n#{res['details']}"
|
50
|
+
end
|
51
|
+
|
52
|
+
res['results']
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#taken from Ian Dee's Encumber
|
57
|
+
def send_post( verb, command )
|
58
|
+
command = command.to_json unless command.is_a? String
|
59
|
+
|
60
|
+
url = frank_url_for( verb )
|
61
|
+
req = Net::HTTP::Post.new url.path
|
62
|
+
req.body = command
|
63
|
+
|
64
|
+
make_http_request( url, req )
|
65
|
+
end
|
66
|
+
|
67
|
+
def send_get( verb )
|
68
|
+
url = frank_url_for( verb )
|
69
|
+
req = Net::HTTP::Get.new url.path
|
70
|
+
make_http_request( url, req )
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def frank_url_for( verb )
|
76
|
+
url = @base_url.clone
|
77
|
+
url.path = '/'+verb
|
78
|
+
url
|
79
|
+
end
|
80
|
+
|
81
|
+
def make_http_request( url, req )
|
82
|
+
http = Net::HTTP.new(url.host, url.port)
|
83
|
+
|
84
|
+
begin
|
85
|
+
res = http.start do |sess|
|
86
|
+
sess.request req
|
87
|
+
end
|
88
|
+
|
89
|
+
res.body
|
90
|
+
rescue Errno::ECONNREFUSED
|
91
|
+
raise FrankNetworkError
|
92
|
+
rescue EOFError
|
93
|
+
raise FrankNetworkError
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
class FrankNetworkError < RuntimeError
|
101
|
+
OVERLY_VERBOSE_YET_HELPFUL_ERROR_MESSAGE = <<EOS
|
102
|
+
|
103
|
+
|
104
|
+
*********************************************
|
105
|
+
Oh dear. Your app fell over and can't get up.
|
106
|
+
*********************************************
|
107
|
+
|
108
|
+
|
109
|
+
We just encountered an error while trying to talk to the Frank server embedded
|
110
|
+
within the app under test. This usually means that the app has just crashed,
|
111
|
+
either while carrying out the current step or while finishing up the previous
|
112
|
+
step.
|
113
|
+
|
114
|
+
Here are some things you could do next:
|
115
|
+
|
116
|
+
- Take a look at the app's logs to see why it crashed. You can view the logs
|
117
|
+
in Console.app (a search for 'Frankified' will usually find your frankified
|
118
|
+
app's output).
|
119
|
+
|
120
|
+
- Launch your frankified app in the XCode debugger and then run this scenario
|
121
|
+
again. You'll get lots of helpful output from XCode. Don't forget to do
|
122
|
+
something to prevent cucumber from automatically re-launching your app when
|
123
|
+
you run the scenario by hand. If you don't prevent the relaunch then you
|
124
|
+
won't still be in the XCode debugger when the crash happens.
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
EOS
|
129
|
+
|
130
|
+
def initialize
|
131
|
+
super OVERLY_VERBOSE_YET_HELPFUL_ERROR_MESSAGE
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end end
|