testautoi 0.9.127

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 (121) hide show
  1. data/.gitignore +4 -0
  2. data/CHANGES.txt +1 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +8 -0
  5. data/Rakefile +2 -0
  6. data/bin/CalabashSetup +0 -0
  7. data/bin/cal.xcconfig +3 -0
  8. data/bin/calabash-ios +79 -0
  9. data/bin/calabash-ios-build.rb +110 -0
  10. data/bin/calabash-ios-generate.rb +26 -0
  11. data/bin/calabash-ios-helpers.rb +130 -0
  12. data/bin/calabash-ios-setup.rb +334 -0
  13. data/bin/calabash-ios-sim.rb +149 -0
  14. data/calabash-cucumber.gemspec +29 -0
  15. data/doc/calabash-ios-help.txt +73 -0
  16. data/epl-v10.html +261 -0
  17. data/features-skeleton/.irbrc +23 -0
  18. data/features-skeleton/irb_ios4.sh +2 -0
  19. data/features-skeleton/irb_ios5.sh +2 -0
  20. data/features-skeleton/my_first.feature +12 -0
  21. data/features-skeleton/step_definitions/calabash_steps.rb +1 -0
  22. data/features-skeleton/step_definitions/my_first_steps.rb +4 -0
  23. data/features-skeleton/support/env.rb +1 -0
  24. data/features-skeleton/support/hooks.rb +0 -0
  25. data/features-skeleton/support/launch.rb +77 -0
  26. data/features/step_definitions/calabash_steps.rb +439 -0
  27. data/lib/calabash-cucumber.rb +7 -0
  28. data/lib/calabash-cucumber/calabash_steps.rb +1 -0
  29. data/lib/calabash-cucumber/core.rb +553 -0
  30. data/lib/calabash-cucumber/cucumber.rb +8 -0
  31. data/lib/calabash-cucumber/ibase.rb +45 -0
  32. data/lib/calabash-cucumber/keyboard_helpers.rb +124 -0
  33. data/lib/calabash-cucumber/launch/simulator_helper.rb +297 -0
  34. data/lib/calabash-cucumber/location.rb +26 -0
  35. data/lib/calabash-cucumber/operations.rb +162 -0
  36. data/lib/calabash-cucumber/resources/cell_swipe_ios4_ipad.base64 +51 -0
  37. data/lib/calabash-cucumber/resources/cell_swipe_ios4_iphone.base64 +51 -0
  38. data/lib/calabash-cucumber/resources/cell_swipe_ios5_ipad.base64 +74 -0
  39. data/lib/calabash-cucumber/resources/cell_swipe_ios5_iphone.base64 +74 -0
  40. data/lib/calabash-cucumber/resources/pinch_in_ios4_ipad.base64 +104 -0
  41. data/lib/calabash-cucumber/resources/pinch_in_ios4_iphone.base64 +104 -0
  42. data/lib/calabash-cucumber/resources/pinch_in_ios5_ipad.base64 +144 -0
  43. data/lib/calabash-cucumber/resources/pinch_in_ios5_iphone.base64 +144 -0
  44. data/lib/calabash-cucumber/resources/pinch_in_ios6_ipad.base64 +70 -0
  45. data/lib/calabash-cucumber/resources/pinch_in_ios6_iphone.base64 +70 -0
  46. data/lib/calabash-cucumber/resources/pinch_out_ios5_ipad.base64 +207 -0
  47. data/lib/calabash-cucumber/resources/pinch_out_ios5_iphone.base64 +207 -0
  48. data/lib/calabash-cucumber/resources/pinch_out_ios6_ipad.base64 +96 -0
  49. data/lib/calabash-cucumber/resources/pinch_out_ios6_iphone.base64 +96 -0
  50. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_ipad.base64 +2 -0
  51. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_iphone.base64 +2 -0
  52. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_ipad.base64 +2 -0
  53. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_iphone.base64 +2 -0
  54. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_ipad.base64 +2 -0
  55. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_iphone.base64 +2 -0
  56. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_ipad.base64 +2 -0
  57. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_iphone.base64 +2 -0
  58. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_ipad.base64 +2 -0
  59. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_iphone.base64 +2 -0
  60. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_ipad.base64 +2 -0
  61. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_iphone.base64 +2 -0
  62. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_ipad.base64 +2 -0
  63. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_iphone.base64 +2 -0
  64. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_ipad.base64 +2 -0
  65. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_iphone.base64 +2 -0
  66. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_ipad.base64 +2 -0
  67. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_iphone.base64 +2 -0
  68. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_ipad.base64 +2 -0
  69. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_iphone.base64 +2 -0
  70. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_ipad.base64 +2 -0
  71. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_iphone.base64 +2 -0
  72. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_ipad.base64 +2 -0
  73. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_iphone.base64 +2 -0
  74. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_ipad.base64 +2 -0
  75. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_iphone.base64 +2 -0
  76. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_ipad.base64 +2 -0
  77. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_iphone.base64 +2 -0
  78. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_ipad.base64 +2 -0
  79. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_iphone.base64 +2 -0
  80. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_ipad.base64 +2 -0
  81. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_iphone.base64 +2 -0
  82. data/lib/calabash-cucumber/resources/swipe_down_ios5_ipad.base64 +18 -0
  83. data/lib/calabash-cucumber/resources/swipe_down_ios5_iphone.base64 +18 -0
  84. data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_ipad.base64 +15 -0
  85. data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_iphone.base64 +15 -0
  86. data/lib/calabash-cucumber/resources/swipe_left_ios4_ipad.base64 +18 -0
  87. data/lib/calabash-cucumber/resources/swipe_left_ios4_iphone.base64 +18 -0
  88. data/lib/calabash-cucumber/resources/swipe_left_ios5_ipad.base64 +17 -0
  89. data/lib/calabash-cucumber/resources/swipe_left_ios5_iphone.base64 +17 -0
  90. data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_ipad.base64 +17 -0
  91. data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_iphone.base64 +17 -0
  92. data/lib/calabash-cucumber/resources/swipe_right_ios4_ipad.base64 +13 -0
  93. data/lib/calabash-cucumber/resources/swipe_right_ios4_iphone.base64 +13 -0
  94. data/lib/calabash-cucumber/resources/swipe_right_ios5_ipad.base64 +17 -0
  95. data/lib/calabash-cucumber/resources/swipe_right_ios5_iphone.base64 +17 -0
  96. data/lib/calabash-cucumber/resources/swipe_up_ios5_ipad.base64 +34 -0
  97. data/lib/calabash-cucumber/resources/swipe_up_ios5_iphone.base64 +34 -0
  98. data/lib/calabash-cucumber/resources/touch_done_ios4_ipad.base64 +7 -0
  99. data/lib/calabash-cucumber/resources/touch_done_ios4_iphone.base64 +9 -0
  100. data/lib/calabash-cucumber/resources/touch_done_ios5_ipad.base64 +7 -0
  101. data/lib/calabash-cucumber/resources/touch_done_ios5_iphone.base64 +9 -0
  102. data/lib/calabash-cucumber/resources/touch_ios4_ipad.base64 +9 -0
  103. data/lib/calabash-cucumber/resources/touch_ios4_iphone.base64 +9 -0
  104. data/lib/calabash-cucumber/resources/touch_ios5_ipad.base64 +9 -0
  105. data/lib/calabash-cucumber/resources/touch_ios5_iphone.base64 +9 -0
  106. data/lib/calabash-cucumber/resources/wheel_down_ios4_ipad.base64 +159 -0
  107. data/lib/calabash-cucumber/resources/wheel_down_ios4_iphone.base64 +159 -0
  108. data/lib/calabash-cucumber/resources/wheel_down_ios5_ipad.base64 +156 -0
  109. data/lib/calabash-cucumber/resources/wheel_down_ios5_iphone.base64 +156 -0
  110. data/lib/calabash-cucumber/resources/wheel_up_ios4_ipad.base64 +166 -0
  111. data/lib/calabash-cucumber/resources/wheel_up_ios4_iphone.base64 +166 -0
  112. data/lib/calabash-cucumber/resources/wheel_up_ios5_ipad.base64 +156 -0
  113. data/lib/calabash-cucumber/resources/wheel_up_ios5_iphone.base64 +156 -0
  114. data/lib/calabash-cucumber/tests_helpers.rb +136 -0
  115. data/lib/calabash-cucumber/version.rb +6 -0
  116. data/lib/calabash-cucumber/wait_helpers.rb +149 -0
  117. data/scripts/data/.GlobalPreferences.plist +0 -0
  118. data/scripts/data/clients.plist +0 -0
  119. data/scripts/data/com.apple.Accessibility.plist +0 -0
  120. data/scripts/reset_simulator.scpt +0 -0
  121. metadata +319 -0
@@ -0,0 +1,8 @@
1
+ require 'calabash-cucumber/wait_helpers'
2
+ require 'calabash-cucumber/operations'
3
+
4
+ World(Calabash::Cucumber::Operations)
5
+
6
+ AfterConfiguration do
7
+ require 'calabash-cucumber/calabash_steps'
8
+ end
@@ -0,0 +1,45 @@
1
+ require 'calabash-cucumber/core'
2
+ require 'calabash-cucumber/operations'
3
+
4
+ class Calabash::IBase
5
+ include Calabash::Cucumber::Operations
6
+
7
+ def initialize(world)
8
+ @world = world
9
+ end
10
+
11
+ def embed(*args)
12
+ @world.send(:embed,*args)
13
+ end
14
+
15
+ def puts(*args)
16
+ @world.send(:puts, *args)
17
+ end
18
+
19
+ def trait
20
+ "navigationItemView marked:'#{self.title}'"
21
+ end
22
+
23
+ def page(clz,*args)
24
+ clz.new(@world,*args)
25
+ end
26
+
27
+ def step(s)
28
+
29
+ end
30
+
31
+ def steps(ss)
32
+
33
+ end
34
+
35
+ def await(opts={})
36
+ wait_for_elements_exist([trait], opts)
37
+ self
38
+ end
39
+
40
+ def await_screenshot(wait_opts={},screenshot_opts={})
41
+ await(wait_opts)
42
+ screenshot_embed(screenshot_opts)
43
+ end
44
+
45
+ end
@@ -0,0 +1,124 @@
1
+ require 'calabash-cucumber/tests_helpers'
2
+
3
+ module Calabash
4
+ module Cucumber
5
+ module KeyboardHelpers
6
+ include Calabash::Cucumber::Core
7
+ include Calabash::Cucumber::TestsHelpers
8
+
9
+ KEYPLANE_NAMES = {
10
+ :small_letters => "small-letters",
11
+ :capital_letters => "capital-letters",
12
+ :numbers_and_punctuation => "numbers-and-punctuation",
13
+ :first_alternate => "first-alternate",
14
+ :numbers_and_punctuation_alternate => "numbers-and-punctuation-alternate"
15
+ }
16
+
17
+ #Possible values
18
+ # 'Dictation'
19
+ # 'Shift'
20
+ # 'Delete'
21
+ # 'International'
22
+ # 'More'
23
+ # 'Return'
24
+ def keyboard_enter_char(chr, should_screenshot=true)
25
+ #map(nil, :keyboard, load_playback_data("touch_done"), chr)
26
+ res = http({:method => :post, :path => 'keyboard'},
27
+ {:key => chr, :events => load_playback_data("touch_done")})
28
+ res = JSON.parse(res)
29
+ if res['outcome'] != 'SUCCESS'
30
+ msg = "Keyboard enter failed failed because: #{res['reason']}\n#{res['details']}"
31
+ if should_screenshot
32
+ screenshot_and_raise msg
33
+ else
34
+ raise msg
35
+ end
36
+ end
37
+ if ENV['POST_ENTER_KEYBOARD']
38
+ w = ENV['POST_ENTER_KEYBOARD'].to_f
39
+ if w > 0
40
+ sleep(w)
41
+ end
42
+ end
43
+ res['results']
44
+ end
45
+
46
+ def done
47
+ keyboard_enter_char "Return"
48
+ end
49
+
50
+
51
+ def current_keyplane
52
+ kp_arr = _do_keyplane(
53
+ lambda { query("view:'UIKBKeyplaneView'", "keyplane", "componentName") },
54
+ lambda { query("view:'UIKBKeyplaneView'", "keyplane", "name") })
55
+ kp_arr.first.downcase
56
+ end
57
+
58
+ def search_keyplanes_and_enter_char(chr, visited=Set.new)
59
+ cur_kp = current_keyplane
60
+ begin
61
+ keyboard_enter_char(chr, false)
62
+ return true #found
63
+ rescue
64
+ visited.add(cur_kp)
65
+
66
+ #figure out keyplane alternates
67
+ props = _do_keyplane(
68
+ lambda { query("view:'UIKBKeyplaneView'", "keyplane", "properties") },
69
+ lambda { query("view:'UIKBKeyplaneView'", "keyplane", "attributes", "dict") }
70
+ ).first
71
+
72
+ known = KEYPLANE_NAMES.values
73
+
74
+ found = false
75
+ ["shift", "more"].each do |key|
76
+ plane = props["#{key}-alternate"]
77
+ if (known.member?(plane) and
78
+ not visited.member?(plane))
79
+ keyboard_enter_char(key.capitalize, false)
80
+ found = search_keyplanes_and_enter_char(chr, visited)
81
+ return true if found
82
+ #not found => go back
83
+ keyboard_enter_char(key.capitalize, false)
84
+ end
85
+ end
86
+ return false
87
+ end
88
+ end
89
+
90
+ def await_keyboard
91
+ wait_for_elements_exist(["view:'UIKBKeyplaneView'"])
92
+ sleep(0.3)
93
+ end
94
+
95
+ def keyboard_enter_text(text)
96
+ fail("No visible keyboard") if element_does_not_exist("view:'UIKBKeyplaneView'")
97
+
98
+ text.each_char do |ch|
99
+ begin
100
+ keyboard_enter_char(ch, false)
101
+ rescue
102
+ search_keyplanes_and_enter_char(ch)
103
+ end
104
+ end
105
+ end
106
+
107
+
108
+ def _do_keyplane(kbtree_proc, keyplane_proc)
109
+ desc = query("view:'UIKBKeyplaneView'", "keyplane")
110
+ fail("No keyplane (UIKBKeyplaneView keyplane)") if desc.empty?
111
+ fail("Several keyplanes (UIKBKeyplaneView keyplane)") if desc.count > 1
112
+ kp_desc = desc.first
113
+ if /^<UIKBTree/.match(kp_desc)
114
+ #ios5+
115
+ kbtree_proc.call
116
+ elsif /^<UIKBKeyplane/.match(kp_desc)
117
+ #ios4
118
+ keyplane_proc.call
119
+ end
120
+ end
121
+
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,297 @@
1
+ require 'sim_launcher'
2
+ require 'json'
3
+ require 'run_loop'
4
+ require 'net/http'
5
+ require 'cfpropertylist'
6
+
7
+ module Calabash
8
+ module Cucumber
9
+
10
+ module SimulatorHelper
11
+
12
+ class TimeoutErr < RuntimeError
13
+ end
14
+
15
+ DERIVED_DATA = File.expand_path("~/Library/Developer/Xcode/DerivedData")
16
+ DEFAULT_DERIVED_DATA_INFO = File.expand_path("#{DERIVED_DATA}/*/info.plist")
17
+
18
+ DEFAULT_SIM_WAIT = 30
19
+
20
+ DEFAULT_SIM_RETRY = 2
21
+
22
+ def self.relaunch(path, sdk = nil, version = 'iphone', args = nil)
23
+
24
+ app_bundle_path = app_bundle_or_raise(path)
25
+ ensure_connectivity(app_bundle_path, sdk, version, args)
26
+
27
+ end
28
+
29
+ def self.stop
30
+ simulator = SimLauncher::Simulator.new
31
+ simulator.quit_simulator
32
+ end
33
+
34
+
35
+ def self.derived_data_dir_for_project
36
+ dir = project_dir
37
+ xcode_workspace_name = ''
38
+ info_plist = Dir.glob(DEFAULT_DERIVED_DATA_INFO).find { |plist_file|
39
+ begin
40
+ plist = CFPropertyList::List.new(:file => plist_file)
41
+ hash = CFPropertyList.native_types(plist.value)
42
+ ws_dir = File.dirname(hash['WorkspacePath']).downcase
43
+ p_dir = dir.downcase
44
+ if (p_dir.include? ws_dir)
45
+ xcode_workspace_name = ws_dir.split('/').last
46
+ end
47
+ ws_dir == p_dir
48
+ rescue
49
+ false
50
+ end
51
+ }
52
+
53
+ if not info_plist.nil?
54
+ return File.dirname(info_plist)
55
+ else
56
+ res = Dir.glob("#{dir}/*.xcodeproj")
57
+ if res.empty?
58
+ raise "Unable to find *.xcodeproj in #{dir}"
59
+ elsif res.count > 1
60
+ raise "Unable to found several *.xcodeproj in #{dir}: #{res}"
61
+ end
62
+
63
+ xcode_proj_name = res.first.split(".xcodeproj")[0]
64
+
65
+ xcode_proj_name = File.basename(xcode_proj_name)
66
+
67
+ build_dirs = Dir.glob("#{DERIVED_DATA}/*").find_all do |xc_proj|
68
+ File.basename(xc_proj).start_with?(xcode_proj_name)
69
+ end
70
+
71
+ if (build_dirs.count == 0 && !xcode_workspace_name.empty?)
72
+ # check for directory named "workspace-{deriveddirectoryrandomcharacters}"
73
+ build_dirs = Dir.glob("#{DERIVED_DATA}/*").find_all do |xc_proj|
74
+ File.basename(xc_proj).downcase.start_with?(xcode_workspace_name)
75
+ end
76
+ end
77
+
78
+ if (build_dirs.count == 0)
79
+ msg = ["Unable to find your built app."]
80
+ msg << "This means that Calabash can't automatically launch iOS simulator."
81
+ msg << "Searched in Xcode 4.x default: #{DEFAULT_DERIVED_DATA_INFO}"
82
+ msg << ""
83
+ msg << "To fix there are a couple of options:\n"
84
+ msg << "Option 1) Make sure you are running this command from your project directory, "
85
+ msg << "i.e., the directory containing your .xcodeproj file."
86
+ msg << "In Xcode, build your calabash target for simulator."
87
+ msg << "Check that your app can be found in\n #{File.expand_path("~/Library/Developer/Xcode/DerivedData")}"
88
+ msg << "\n\nOption 2). In features/support/launch.rb set APP_BUNDLE_PATH to"
89
+ msg << "the path where Xcode has built your Calabash target."
90
+ msg << "Alternatively you can use the environment variable APP_BUNDLE_PATH.\n"
91
+ raise msg.join("\n")
92
+
93
+ elsif (build_dirs.count > 1)
94
+ msg = ["Unable to auto detect APP_BUNDLE_PATH."]
95
+ msg << "You have several projects with the same name: #{xcode_proj_name} in #{DERIVED_DATA}:\n"
96
+ msg << build_dirs.join("\n")
97
+
98
+ msg << "\nThis means that Calabash can't automatically launch iOS simulator."
99
+ msg << "Searched in Xcode 4.x default: #{DEFAULT_DERIVED_DATA_INFO}"
100
+ msg << "\nIn features/support/launch.rb set APP_BUNDLE_PATH to"
101
+ msg << "the path where Xcode has built your Calabash target."
102
+ msg << "Alternatively you can use the environment variable APP_BUNDLE_PATH.\n"
103
+ raise msg.join("\n")
104
+ else
105
+ puts "Found potential build dir: #{build_dirs.first}"
106
+ puts "Checking..."
107
+ return build_dirs.first
108
+ end
109
+ end
110
+ end
111
+
112
+ def self.project_dir
113
+ File.expand_path(ENV['PROJECT_DIR'] || Dir.pwd)
114
+ end
115
+
116
+ def self.app_bundle_or_raise(path)
117
+ bundle_path = nil
118
+ path = File.expand_path(path) if path
119
+
120
+ if path and not File.directory?(path)
121
+ puts "Unable to find .app bundle at #{path}. It should be an .app directory."
122
+ dd_dir = derived_data_dir_for_project
123
+ app_bundles = Dir.glob(File.join(dd_dir, "Build", "Products", "*", "*.app"))
124
+ msg = "Try setting APP_BUNDLE_PATH in features/support/launch.rb to one of:\n\n"
125
+ msg << app_bundles.join("\n")
126
+ raise msg
127
+ elsif path
128
+ bundle_path = path
129
+ else
130
+ dd_dir = derived_data_dir_for_project
131
+ sim_dirs = Dir.glob(File.join(dd_dir, "Build", "Products", "*-iphonesimulator", "*.app"))
132
+ if sim_dirs.empty?
133
+ msg = ["Unable to auto detect APP_BUNDLE_PATH."]
134
+ msg << "Have you built your app for simulator?."
135
+ msg << "Searched dir: #{dd_dir}/Build/Products"
136
+ msg << "Please build your app from Xcode"
137
+ msg << "You should build the -cal target."
138
+ msg << ""
139
+ msg << "Alternatively, specify APP_BUNDLE_PATH in features/support/launch.rb"
140
+ msg << "This should point to the location of your built app linked with calabash.\n"
141
+ raise msg.join("\n")
142
+ end
143
+ preferred_dir = find_preferred_dir(sim_dirs)
144
+ if preferred_dir.nil?
145
+ msg = ["Error... Unable to find APP_BUNDLE_PATH."]
146
+ msg << "Cannot find a built app that is linked with calabash.framework"
147
+ msg << "Please build your app from Xcode"
148
+ msg << "You should build your calabash target."
149
+ msg << ""
150
+ msg << "Alternatively, specify APP_BUNDLE_PATH in features/support/launch.rb"
151
+ msg << "This should point to the location of your built app linked with calabash.\n"
152
+ raise msg.join("\n")
153
+ end
154
+ puts("-"*37)
155
+ puts "Auto detected APP_BUNDLE_PATH:\n\n"
156
+
157
+ puts "APP_BUNDLE_PATH=#{preferred_dir || sim_dirs[0]}\n\n"
158
+ puts "Please verify!"
159
+ puts "If this is wrong please set it as APP_BUNDLE_PATH in features/support/launch.rb\n"
160
+ puts("-"*37)
161
+ bundle_path = sim_dirs[0]
162
+ end
163
+ bundle_path
164
+ end
165
+
166
+ def self.find_preferred_dir(sim_dirs)
167
+ sim_dirs.find do |d|
168
+ out = `otool "#{File.expand_path(d)}"/* -o 2> /dev/null | grep CalabashServer`
169
+ /CalabashServer/.match(out)
170
+ end
171
+ end
172
+
173
+ def self.ensure_connectivity(app_bundle_path, sdk, version, args = nil)
174
+ begin
175
+ max_retry_count = (ENV['MAX_CONNECT_RETRY'] || DEFAULT_SIM_RETRY).to_i
176
+ timeout = (ENV['CONNECT_TIMEOUT'] || DEFAULT_SIM_WAIT).to_i
177
+ retry_count = 0
178
+ connected = false
179
+ puts "Waiting at most #{timeout} seconds for simulator (CONNECT_TIMEOUT)"
180
+ puts "Retrying at most #{max_retry_count} times (MAX_CONNECT_RETRY)"
181
+ until connected do
182
+ raise "MAX_RETRIES" if retry_count == max_retry_count
183
+ retry_count += 1
184
+ puts "(#{retry_count}.) Start Simulator #{sdk}, #{version}, for #{app_bundle_path}"
185
+ begin
186
+ Timeout::timeout(timeout, TimeoutErr) do
187
+ simulator = launch(app_bundle_path, sdk, version, args)
188
+ until connected
189
+ begin
190
+ connected = (ping_app == '405')
191
+ if ENV['POST_START_BREAK']
192
+ puts "Environment var POST_START_BREAK is deprecated and should no longer be necessary."
193
+ post_connect_sleep = (ENV['POST_START_BREAK'] || "2").to_f
194
+ sleep(post_connect_sleep) unless post_connect_sleep <= 0
195
+ end
196
+ if connected
197
+ server_version = get_version
198
+ if server_version
199
+ p server_version
200
+ unless version_check(server_version)
201
+ msgs = ["You're running an older version of Calabash server with a newer client",
202
+ "Client:#{Calabash::Cucumber::VERSION}",
203
+ "Server:#{server_version}",
204
+ "Minimum server version #{Calabash::Cucumber::FRAMEWORK_VERSION}",
205
+ "Update recommended:",
206
+ "https://github.com/calabash/calabash-ios/wiki/B1-Updating-your-Calabash-iOS-version"
207
+ ]
208
+ raise msgs.join("\n")
209
+ end
210
+ else
211
+ connected = false
212
+ end
213
+ end
214
+ rescue Exception => e
215
+
216
+ ensure
217
+ sleep 1 unless connected
218
+ end
219
+ end
220
+ end
221
+ rescue TimeoutErr => e
222
+ puts "Timed out..."
223
+ end
224
+ end
225
+ rescue e
226
+ p e
227
+ msg = "Unable to make connection to Calabash Server at #{ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/"}\n"
228
+ msg << "Make sure you've' linked correctly with calabash.framework and set Other Linker Flags.\n"
229
+ msg << "Make sure you don't have a firewall blocking traffic to #{ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/"}.\n"
230
+ raise msg
231
+ end
232
+ end
233
+
234
+
235
+ def self.launch(app_bundle_path, sdk, version, args = nil)
236
+ simulator = SimLauncher::Simulator.new
237
+ simulator.quit_simulator
238
+ simulator.launch_ios_app(app_bundle_path, sdk, version) #, args wait for update to sim launcher
239
+ simulator
240
+ end
241
+
242
+ def self.ping_app
243
+ url = URI.parse(ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/")
244
+ puts "Ping #{url}..."
245
+ http = Net::HTTP.new(url.host, url.port)
246
+ res = http.start do |sess|
247
+ sess.request Net::HTTP::Get.new url.path
248
+ end
249
+ status = res.code
250
+ begin
251
+ http.finish if http and http.started?
252
+ rescue
253
+
254
+ end
255
+ status
256
+ end
257
+
258
+ def self.get_version
259
+ endpoint = ENV['DEVICE_ENDPOINT']|| "http://localhost:37265"
260
+ endpoint += "/" unless endpoint.end_with? "/"
261
+ url = URI.parse("#{endpoint}version")
262
+
263
+ puts "Fetch version #{url}..."
264
+ begin
265
+ body = Net::HTTP.get_response(url).body
266
+ res = JSON.parse(body)
267
+ if res['iOS_version']
268
+ @ios_version = res['iOS_version']
269
+ end
270
+ res
271
+ rescue
272
+ nil
273
+ end
274
+ end
275
+
276
+ def self.ios_version
277
+ unless @ios_version
278
+ get_version
279
+ end
280
+ @ios_version
281
+ end
282
+
283
+ def self.ios_major_version
284
+ v = ios_version
285
+ if v
286
+ v.split(".")[0]
287
+ end
288
+ end
289
+
290
+ def self.version_check(version)
291
+ server_version = version["version"]
292
+ Calabash::Cucumber::FRAMEWORK_VERSION == server_version
293
+ end
294
+ end
295
+
296
+ end
297
+ end