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.
- 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
|