sc-frank-cucumber 1.2.1.00af28c
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/.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
|