testautoi 0.9.127

Sign up to get free protection for your applications and to get access to all the features.
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