testautoi 0.9.127
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/CHANGES.txt +1 -0
- data/Gemfile +4 -0
- data/LICENSE +8 -0
- data/Rakefile +2 -0
- data/bin/CalabashSetup +0 -0
- data/bin/cal.xcconfig +3 -0
- data/bin/calabash-ios +79 -0
- data/bin/calabash-ios-build.rb +110 -0
- data/bin/calabash-ios-generate.rb +26 -0
- data/bin/calabash-ios-helpers.rb +130 -0
- data/bin/calabash-ios-setup.rb +334 -0
- data/bin/calabash-ios-sim.rb +149 -0
- data/calabash-cucumber.gemspec +29 -0
- data/doc/calabash-ios-help.txt +73 -0
- data/epl-v10.html +261 -0
- data/features-skeleton/.irbrc +23 -0
- data/features-skeleton/irb_ios4.sh +2 -0
- data/features-skeleton/irb_ios5.sh +2 -0
- data/features-skeleton/my_first.feature +12 -0
- data/features-skeleton/step_definitions/calabash_steps.rb +1 -0
- data/features-skeleton/step_definitions/my_first_steps.rb +4 -0
- data/features-skeleton/support/env.rb +1 -0
- data/features-skeleton/support/hooks.rb +0 -0
- data/features-skeleton/support/launch.rb +77 -0
- data/features/step_definitions/calabash_steps.rb +439 -0
- data/lib/calabash-cucumber.rb +7 -0
- data/lib/calabash-cucumber/calabash_steps.rb +1 -0
- data/lib/calabash-cucumber/core.rb +553 -0
- data/lib/calabash-cucumber/cucumber.rb +8 -0
- data/lib/calabash-cucumber/ibase.rb +45 -0
- data/lib/calabash-cucumber/keyboard_helpers.rb +124 -0
- data/lib/calabash-cucumber/launch/simulator_helper.rb +297 -0
- data/lib/calabash-cucumber/location.rb +26 -0
- data/lib/calabash-cucumber/operations.rb +162 -0
- data/lib/calabash-cucumber/resources/cell_swipe_ios4_ipad.base64 +51 -0
- data/lib/calabash-cucumber/resources/cell_swipe_ios4_iphone.base64 +51 -0
- data/lib/calabash-cucumber/resources/cell_swipe_ios5_ipad.base64 +74 -0
- data/lib/calabash-cucumber/resources/cell_swipe_ios5_iphone.base64 +74 -0
- data/lib/calabash-cucumber/resources/pinch_in_ios4_ipad.base64 +104 -0
- data/lib/calabash-cucumber/resources/pinch_in_ios4_iphone.base64 +104 -0
- data/lib/calabash-cucumber/resources/pinch_in_ios5_ipad.base64 +144 -0
- data/lib/calabash-cucumber/resources/pinch_in_ios5_iphone.base64 +144 -0
- data/lib/calabash-cucumber/resources/pinch_in_ios6_ipad.base64 +70 -0
- data/lib/calabash-cucumber/resources/pinch_in_ios6_iphone.base64 +70 -0
- data/lib/calabash-cucumber/resources/pinch_out_ios5_ipad.base64 +207 -0
- data/lib/calabash-cucumber/resources/pinch_out_ios5_iphone.base64 +207 -0
- data/lib/calabash-cucumber/resources/pinch_out_ios6_ipad.base64 +96 -0
- data/lib/calabash-cucumber/resources/pinch_out_ios6_iphone.base64 +96 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_ipad.base64 +2 -0
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_iphone.base64 +2 -0
- data/lib/calabash-cucumber/resources/swipe_down_ios5_ipad.base64 +18 -0
- data/lib/calabash-cucumber/resources/swipe_down_ios5_iphone.base64 +18 -0
- data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_ipad.base64 +15 -0
- data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_iphone.base64 +15 -0
- data/lib/calabash-cucumber/resources/swipe_left_ios4_ipad.base64 +18 -0
- data/lib/calabash-cucumber/resources/swipe_left_ios4_iphone.base64 +18 -0
- data/lib/calabash-cucumber/resources/swipe_left_ios5_ipad.base64 +17 -0
- data/lib/calabash-cucumber/resources/swipe_left_ios5_iphone.base64 +17 -0
- data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_ipad.base64 +17 -0
- data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_iphone.base64 +17 -0
- data/lib/calabash-cucumber/resources/swipe_right_ios4_ipad.base64 +13 -0
- data/lib/calabash-cucumber/resources/swipe_right_ios4_iphone.base64 +13 -0
- data/lib/calabash-cucumber/resources/swipe_right_ios5_ipad.base64 +17 -0
- data/lib/calabash-cucumber/resources/swipe_right_ios5_iphone.base64 +17 -0
- data/lib/calabash-cucumber/resources/swipe_up_ios5_ipad.base64 +34 -0
- data/lib/calabash-cucumber/resources/swipe_up_ios5_iphone.base64 +34 -0
- data/lib/calabash-cucumber/resources/touch_done_ios4_ipad.base64 +7 -0
- data/lib/calabash-cucumber/resources/touch_done_ios4_iphone.base64 +9 -0
- data/lib/calabash-cucumber/resources/touch_done_ios5_ipad.base64 +7 -0
- data/lib/calabash-cucumber/resources/touch_done_ios5_iphone.base64 +9 -0
- data/lib/calabash-cucumber/resources/touch_ios4_ipad.base64 +9 -0
- data/lib/calabash-cucumber/resources/touch_ios4_iphone.base64 +9 -0
- data/lib/calabash-cucumber/resources/touch_ios5_ipad.base64 +9 -0
- data/lib/calabash-cucumber/resources/touch_ios5_iphone.base64 +9 -0
- data/lib/calabash-cucumber/resources/wheel_down_ios4_ipad.base64 +159 -0
- data/lib/calabash-cucumber/resources/wheel_down_ios4_iphone.base64 +159 -0
- data/lib/calabash-cucumber/resources/wheel_down_ios5_ipad.base64 +156 -0
- data/lib/calabash-cucumber/resources/wheel_down_ios5_iphone.base64 +156 -0
- data/lib/calabash-cucumber/resources/wheel_up_ios4_ipad.base64 +166 -0
- data/lib/calabash-cucumber/resources/wheel_up_ios4_iphone.base64 +166 -0
- data/lib/calabash-cucumber/resources/wheel_up_ios5_ipad.base64 +156 -0
- data/lib/calabash-cucumber/resources/wheel_up_ios5_iphone.base64 +156 -0
- data/lib/calabash-cucumber/tests_helpers.rb +136 -0
- data/lib/calabash-cucumber/version.rb +6 -0
- data/lib/calabash-cucumber/wait_helpers.rb +149 -0
- data/scripts/data/.GlobalPreferences.plist +0 -0
- data/scripts/data/clients.plist +0 -0
- data/scripts/data/com.apple.Accessibility.plist +0 -0
- data/scripts/reset_simulator.scpt +0 -0
- metadata +319 -0
@@ -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
|