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.
Files changed (136) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +38 -0
  4. data/bin/frank +6 -0
  5. data/bin/frank-skeleton +33 -0
  6. data/frank-skeleton/features/my_first.feature +12 -0
  7. data/frank-skeleton/features/step_definitions/launch_steps.rb +20 -0
  8. data/frank-skeleton/features/support/env.rb +8 -0
  9. data/frank-skeleton/frank_static_resources.bundle/ViewAttributeMapping.plist +63 -0
  10. data/frank-skeleton/frank_static_resources.bundle/ViewAttributeMappingMac.plist +99 -0
  11. data/frank-skeleton/frank_static_resources.bundle/images/ajax-loader.gif +0 -0
  12. data/frank-skeleton/frank_static_resources.bundle/images/file.gif +0 -0
  13. data/frank-skeleton/frank_static_resources.bundle/images/folder-closed.gif +0 -0
  14. data/frank-skeleton/frank_static_resources.bundle/images/folder.gif +0 -0
  15. data/frank-skeleton/frank_static_resources.bundle/images/loader.gif +0 -0
  16. data/frank-skeleton/frank_static_resources.bundle/images/loader.png +0 -0
  17. data/frank-skeleton/frank_static_resources.bundle/images/minus.gif +0 -0
  18. data/frank-skeleton/frank_static_resources.bundle/images/plus.gif +0 -0
  19. data/frank-skeleton/frank_static_resources.bundle/images/treeview-black-line.gif +0 -0
  20. data/frank-skeleton/frank_static_resources.bundle/images/treeview-black.gif +0 -0
  21. data/frank-skeleton/frank_static_resources.bundle/images/treeview-default-line.gif +0 -0
  22. data/frank-skeleton/frank_static_resources.bundle/images/treeview-default.gif +0 -0
  23. data/frank-skeleton/frank_static_resources.bundle/images/treeview-famfamfam-line.gif +0 -0
  24. data/frank-skeleton/frank_static_resources.bundle/images/treeview-famfamfam.gif +0 -0
  25. data/frank-skeleton/frank_static_resources.bundle/images/treeview-gray-line.gif +0 -0
  26. data/frank-skeleton/frank_static_resources.bundle/images/treeview-gray.gif +0 -0
  27. data/frank-skeleton/frank_static_resources.bundle/images/treeview-red-line.gif +0 -0
  28. data/frank-skeleton/frank_static_resources.bundle/images/treeview-red.gif +0 -0
  29. data/frank-skeleton/frank_static_resources.bundle/index.html +86 -0
  30. data/frank-skeleton/frank_static_resources.bundle/index.html.haml +76 -0
  31. data/frank-skeleton/frank_static_resources.bundle/js/accessible_views_view.coffee +41 -0
  32. data/frank-skeleton/frank_static_resources.bundle/js/accessible_views_view.js +46 -0
  33. data/frank-skeleton/frank_static_resources.bundle/js/controller.coffee +134 -0
  34. data/frank-skeleton/frank_static_resources.bundle/js/controller.js +139 -0
  35. data/frank-skeleton/frank_static_resources.bundle/js/details_view.coffee +42 -0
  36. data/frank-skeleton/frank_static_resources.bundle/js/details_view.js +51 -0
  37. data/frank-skeleton/frank_static_resources.bundle/js/dropdown_control.coffee +64 -0
  38. data/frank-skeleton/frank_static_resources.bundle/js/dropdown_control.js +73 -0
  39. data/frank-skeleton/frank_static_resources.bundle/js/ersatz_model.coffee +46 -0
  40. data/frank-skeleton/frank_static_resources.bundle/js/ersatz_model.js +60 -0
  41. data/frank-skeleton/frank_static_resources.bundle/js/ersatz_view.coffee +167 -0
  42. data/frank-skeleton/frank_static_resources.bundle/js/ersatz_view.js +205 -0
  43. data/frank-skeleton/frank_static_resources.bundle/js/experiment_bar_model.coffee +10 -0
  44. data/frank-skeleton/frank_static_resources.bundle/js/experiment_bar_model.js +17 -0
  45. data/frank-skeleton/frank_static_resources.bundle/js/experiment_bar_view.coffee +44 -0
  46. data/frank-skeleton/frank_static_resources.bundle/js/experiment_bar_view.js +63 -0
  47. data/frank-skeleton/frank_static_resources.bundle/js/frank.coffee +96 -0
  48. data/frank-skeleton/frank_static_resources.bundle/js/frank.js +146 -0
  49. data/frank-skeleton/frank_static_resources.bundle/js/lib/backbone.js +1431 -0
  50. data/frank-skeleton/frank_static_resources.bundle/js/lib/coffee-script.js +8 -0
  51. data/frank-skeleton/frank_static_resources.bundle/js/lib/jquery-ui.min.js +405 -0
  52. data/frank-skeleton/frank_static_resources.bundle/js/lib/jquery.min.js +4 -0
  53. data/frank-skeleton/frank_static_resources.bundle/js/lib/jquery.treeview.js +251 -0
  54. data/frank-skeleton/frank_static_resources.bundle/js/lib/json2.js +481 -0
  55. data/frank-skeleton/frank_static_resources.bundle/js/lib/raphael.js +5815 -0
  56. data/frank-skeleton/frank_static_resources.bundle/js/lib/require.js +2053 -0
  57. data/frank-skeleton/frank_static_resources.bundle/js/lib/underscore.js +1059 -0
  58. data/frank-skeleton/frank_static_resources.bundle/js/main.coffee +27 -0
  59. data/frank-skeleton/frank_static_resources.bundle/js/main.js +29 -0
  60. data/frank-skeleton/frank_static_resources.bundle/js/tabs_controller.coffee +13 -0
  61. data/frank-skeleton/frank_static_resources.bundle/js/tabs_controller.js +22 -0
  62. data/frank-skeleton/frank_static_resources.bundle/js/toast_controller.coffee +15 -0
  63. data/frank-skeleton/frank_static_resources.bundle/js/toast_controller.js +28 -0
  64. data/frank-skeleton/frank_static_resources.bundle/js/transform_stack.coffee +59 -0
  65. data/frank-skeleton/frank_static_resources.bundle/js/transform_stack.js +78 -0
  66. data/frank-skeleton/frank_static_resources.bundle/js/tree_view.coffee +53 -0
  67. data/frank-skeleton/frank_static_resources.bundle/js/tree_view.js +64 -0
  68. data/frank-skeleton/frank_static_resources.bundle/js/view_hier_model.coffee +37 -0
  69. data/frank-skeleton/frank_static_resources.bundle/js/view_hier_model.js +48 -0
  70. data/frank-skeleton/frank_static_resources.bundle/js/view_model.coffee +39 -0
  71. data/frank-skeleton/frank_static_resources.bundle/js/view_model.js +62 -0
  72. data/frank-skeleton/frank_static_resources.bundle/pictos/index.html +329 -0
  73. data/frank-skeleton/frank_static_resources.bundle/pictos/pictos-web.eot +0 -0
  74. data/frank-skeleton/frank_static_resources.bundle/pictos/pictos-web.svg +114 -0
  75. data/frank-skeleton/frank_static_resources.bundle/pictos/pictos-web.ttf +0 -0
  76. data/frank-skeleton/frank_static_resources.bundle/pictos/pictos-web.woff +0 -0
  77. data/frank-skeleton/frank_static_resources.bundle/pictos/pictos.css +20 -0
  78. data/frank-skeleton/frank_static_resources.bundle/pictos/pictos_base64.css +18 -0
  79. data/frank-skeleton/frank_static_resources.bundle/stylesheets/css/symbiote.css +1 -0
  80. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_elements.scss +28 -0
  81. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_header.scss +61 -0
  82. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_inspect_tabs_list_tabs.scss +194 -0
  83. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_jquery.treeview.scss +68 -0
  84. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_jqui.scss +2 -0
  85. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_layout.scss +13 -0
  86. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_mixins.sass +137 -0
  87. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_reset.scss +32 -0
  88. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_selector_test_toolbar.scss +81 -0
  89. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_solarized.scss +16 -0
  90. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_typography.scss +11 -0
  91. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_unicode.scss +3 -0
  92. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/_z_index.scss +2 -0
  93. data/frank-skeleton/frank_static_resources.bundle/stylesheets/sass/symbiote.scss +26 -0
  94. data/frank-skeleton/frankify.xcconfig.tt +6 -0
  95. data/frank-skeleton/libCocoaAsyncSocket.a +0 -0
  96. data/frank-skeleton/libCocoaAsyncSocketMac.a +0 -0
  97. data/frank-skeleton/libCocoaHTTPServer.a +0 -0
  98. data/frank-skeleton/libCocoaHTTPServerMac.a +0 -0
  99. data/frank-skeleton/libCocoaLumberjack.a +0 -0
  100. data/frank-skeleton/libCocoaLumberjackMac.a +0 -0
  101. data/frank-skeleton/libFrank.a +0 -0
  102. data/frank-skeleton/libFrankMac.a +0 -0
  103. data/frank-skeleton/libShelley.a +0 -0
  104. data/frank-skeleton/libShelleyMac.a +0 -0
  105. data/frank-skeleton/plugins/.empty_directory +0 -0
  106. data/lib/frank-cucumber.rb +15 -0
  107. data/lib/frank-cucumber/app_bundle_locator.rb +58 -0
  108. data/lib/frank-cucumber/bonjour.rb +73 -0
  109. data/lib/frank-cucumber/cli.rb +299 -0
  110. data/lib/frank-cucumber/color_helper.rb +13 -0
  111. data/lib/frank-cucumber/console.rb +28 -0
  112. data/lib/frank-cucumber/core_frank_steps.rb +260 -0
  113. data/lib/frank-cucumber/frank.xcconfig.erb +17 -0
  114. data/lib/frank-cucumber/frank_helper.rb +459 -0
  115. data/lib/frank-cucumber/frank_localize.rb +43 -0
  116. data/lib/frank-cucumber/frank_mac_helper.rb +120 -0
  117. data/lib/frank-cucumber/frankifier.rb +150 -0
  118. data/lib/frank-cucumber/gateway.rb +135 -0
  119. data/lib/frank-cucumber/gesture_helper.rb +99 -0
  120. data/lib/frank-cucumber/host_scripting.rb +96 -0
  121. data/lib/frank-cucumber/keyboard_helper.rb +69 -0
  122. data/lib/frank-cucumber/launcher.rb +70 -0
  123. data/lib/frank-cucumber/localize.yml +104 -0
  124. data/lib/frank-cucumber/location_helper.rb +20 -0
  125. data/lib/frank-cucumber/mac_launcher.rb +35 -0
  126. data/lib/frank-cucumber/plugins/plugin.rb +57 -0
  127. data/lib/frank-cucumber/rect.rb +26 -0
  128. data/lib/frank-cucumber/scroll_helper.rb +24 -0
  129. data/lib/frank-cucumber/version.rb +5 -0
  130. data/lib/frank-cucumber/wait_helper.rb +57 -0
  131. data/sc-frank-cucumber.gemspec +37 -0
  132. data/test/keyboard_helper_test.rb +84 -0
  133. data/test/launcher_test.rb +57 -0
  134. data/test/rect_test.rb +25 -0
  135. data/test/test_helper.rb +16 -0
  136. 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