run_loop_tcc 2.1.3

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 (87) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/bin/run-loop +19 -0
  4. data/lib/run_loop/abstract.rb +18 -0
  5. data/lib/run_loop/app.rb +372 -0
  6. data/lib/run_loop/cache/cache.rb +68 -0
  7. data/lib/run_loop/cli/cli.rb +48 -0
  8. data/lib/run_loop/cli/codesign.rb +24 -0
  9. data/lib/run_loop/cli/errors.rb +11 -0
  10. data/lib/run_loop/cli/instruments.rb +160 -0
  11. data/lib/run_loop/cli/locale.rb +31 -0
  12. data/lib/run_loop/cli/simctl.rb +257 -0
  13. data/lib/run_loop/cli/tcc.rb +139 -0
  14. data/lib/run_loop/codesign.rb +76 -0
  15. data/lib/run_loop/core.rb +902 -0
  16. data/lib/run_loop/core_simulator.rb +960 -0
  17. data/lib/run_loop/detect_aut/detect.rb +185 -0
  18. data/lib/run_loop/detect_aut/errors.rb +126 -0
  19. data/lib/run_loop/detect_aut/xamarin_studio.rb +46 -0
  20. data/lib/run_loop/detect_aut/xcode.rb +157 -0
  21. data/lib/run_loop/device.rb +722 -0
  22. data/lib/run_loop/device_agent/app/CBX-Runner.app.zip +0 -0
  23. data/lib/run_loop/device_agent/bin/xctestctl +0 -0
  24. data/lib/run_loop/device_agent/cbxrunner.rb +156 -0
  25. data/lib/run_loop/device_agent/frameworks/Frameworks.zip +0 -0
  26. data/lib/run_loop/device_agent/frameworks.rb +65 -0
  27. data/lib/run_loop/device_agent/ipa/CBX-Runner.app.zip +0 -0
  28. data/lib/run_loop/device_agent/launcher.rb +51 -0
  29. data/lib/run_loop/device_agent/xcodebuild.rb +91 -0
  30. data/lib/run_loop/device_agent/xctestctl.rb +109 -0
  31. data/lib/run_loop/directory.rb +179 -0
  32. data/lib/run_loop/dnssd.rb +148 -0
  33. data/lib/run_loop/dot_dir.rb +87 -0
  34. data/lib/run_loop/dylib_injector.rb +145 -0
  35. data/lib/run_loop/encoding.rb +56 -0
  36. data/lib/run_loop/environment.rb +361 -0
  37. data/lib/run_loop/fifo.rb +40 -0
  38. data/lib/run_loop/host_cache.rb +128 -0
  39. data/lib/run_loop/http/error.rb +15 -0
  40. data/lib/run_loop/http/request.rb +44 -0
  41. data/lib/run_loop/http/retriable_client.rb +166 -0
  42. data/lib/run_loop/http/server.rb +17 -0
  43. data/lib/run_loop/instruments.rb +436 -0
  44. data/lib/run_loop/ipa.rb +142 -0
  45. data/lib/run_loop/l10n.rb +93 -0
  46. data/lib/run_loop/language.rb +63 -0
  47. data/lib/run_loop/lipo.rb +132 -0
  48. data/lib/run_loop/lldb.rb +52 -0
  49. data/lib/run_loop/locale.rb +101 -0
  50. data/lib/run_loop/logging.rb +111 -0
  51. data/lib/run_loop/otool.rb +76 -0
  52. data/lib/run_loop/patches/awesome_print.rb +17 -0
  53. data/lib/run_loop/physical_device/life_cycle.rb +268 -0
  54. data/lib/run_loop/plist_buddy.rb +189 -0
  55. data/lib/run_loop/process_terminator.rb +128 -0
  56. data/lib/run_loop/process_waiter.rb +117 -0
  57. data/lib/run_loop/regex.rb +19 -0
  58. data/lib/run_loop/shell.rb +103 -0
  59. data/lib/run_loop/sim_control.rb +1264 -0
  60. data/lib/run_loop/simctl.rb +275 -0
  61. data/lib/run_loop/sqlite.rb +61 -0
  62. data/lib/run_loop/strings.rb +88 -0
  63. data/lib/run_loop/tcc/TCC.db +0 -0
  64. data/lib/run_loop/tcc/tcc.rb +240 -0
  65. data/lib/run_loop/template.rb +61 -0
  66. data/lib/run_loop/version.rb +182 -0
  67. data/lib/run_loop/xcode.rb +318 -0
  68. data/lib/run_loop/xcrun.rb +107 -0
  69. data/lib/run_loop/xcuitest.rb +550 -0
  70. data/lib/run_loop.rb +230 -0
  71. data/plists/simctl/com.apple.UIAutomation.plist +0 -0
  72. data/plists/simctl/com.apple.UIAutomationPlugIn.plist +0 -0
  73. data/scripts/calabash_script_uia.js +28184 -0
  74. data/scripts/lib/json2.min.js +26 -0
  75. data/scripts/lib/log.js +26 -0
  76. data/scripts/lib/on_alert.js +224 -0
  77. data/scripts/read-cmd.sh +2 -0
  78. data/scripts/run_dismiss_location.js +89 -0
  79. data/scripts/run_loop_basic.js +34 -0
  80. data/scripts/run_loop_fast_uia.js +188 -0
  81. data/scripts/run_loop_host.js +117 -0
  82. data/scripts/run_loop_shared_element.js +125 -0
  83. data/scripts/timeout3 +23 -0
  84. data/scripts/udidetect +0 -0
  85. data/vendor-licenses/FBSimulatorControl.LICENSE +30 -0
  86. data/vendor-licenses/xctestctl.LICENSE +32 -0
  87. metadata +443 -0
@@ -0,0 +1,185 @@
1
+ module RunLoop
2
+
3
+ # @!visibility private
4
+ module DetectAUT
5
+
6
+ # @!visibility private
7
+ def self.detect_app_under_test(options)
8
+ app = self.detect_app(options)
9
+ if app.is_a?(RunLoop::App) || app.is_a?(RunLoop::Ipa)
10
+ {
11
+ :app => app,
12
+ :bundle_id => app.bundle_identifier,
13
+ :is_ipa => app.is_a?(RunLoop::Ipa)
14
+ }
15
+ else
16
+ {
17
+ :app => nil,
18
+ :bundle_id => app,
19
+ :is_ipa => false
20
+ }
21
+ end
22
+ end
23
+
24
+ # @!visibility private
25
+ class Detect
26
+ include RunLoop::DetectAUT::Errors
27
+ include RunLoop::DetectAUT::XamarinStudio
28
+ include RunLoop::DetectAUT::Xcode
29
+
30
+ # @!visibility private
31
+ DEFAULTS = {
32
+ :search_depth => 10
33
+ }
34
+
35
+ # @!visibility private
36
+ def app_for_simulator
37
+ path = RunLoop::Environment.path_to_app_bundle
38
+ return RunLoop::App.new(path) if path
39
+
40
+ if xcode_project?
41
+ apps, search_dirs = detect_xcode_apps
42
+ elsif xamarin_project?
43
+ search_dirs = [solution_directory]
44
+ apps = candidate_apps(search_dirs.first)
45
+ else
46
+ search_dirs = [Dir.pwd]
47
+ apps = candidate_apps(search_dirs.first)
48
+ end
49
+
50
+ if apps.empty?
51
+ raise_no_simulator_app_found(search_dirs, DEFAULTS[:search_depth])
52
+ end
53
+
54
+ app = select_most_recent_app(apps)
55
+
56
+ RunLoop.log_info2("Detected app at path:")
57
+ RunLoop.log_info2("#{app.path}")
58
+ time_str = mtime(app).strftime("%a %d %b %Y %H:%M:%S %Z")
59
+ RunLoop.log_info2("Modification time of app: #{time_str}")
60
+ RunLoop.log_info2("If this is incorrect, set the APP variable and/or rebuild your app")
61
+ RunLoop.log_info2("It is your responsibility to ensure you are testing the right app.")
62
+
63
+ app
64
+ end
65
+
66
+ # @!visibility private
67
+ # @param [Array<RunLoop::Detect>] apps
68
+ def select_most_recent_app(apps)
69
+ apps.max do |a, b|
70
+ mtime(a).to_i <=> mtime(b).to_i
71
+ end
72
+ end
73
+
74
+ # @!visibility private
75
+ # @param [String] bundle_path
76
+ def app_with_bundle(bundle_path)
77
+ RunLoop::App.new(bundle_path)
78
+ end
79
+
80
+ # @!visibility private
81
+ # @param [String] base_dir where to start the recursive search
82
+ def candidate_apps(base_dir)
83
+ candidates = []
84
+
85
+ globs = globs_for_app_search(base_dir)
86
+ Dir.glob(globs).each do |bundle_path|
87
+ # Gems, like run-loop, can contain *.app if the user is building
88
+ # from :git =>, :github =>, or :path => sources.
89
+ next if bundle_path[/vendor\/cache/, 0] != nil
90
+ app = app_or_nil(bundle_path)
91
+ candidates << app if app
92
+ end
93
+ candidates
94
+ end
95
+
96
+ # @!visibility private
97
+ # @param [String] bundle_path path to .app
98
+ def app_or_nil(bundle_path)
99
+ return nil if !RunLoop::App.valid?(bundle_path)
100
+
101
+ app = app_with_bundle(bundle_path)
102
+ if app.simulator? && app.calabash_server_version
103
+ app
104
+ else
105
+ nil
106
+ end
107
+ end
108
+
109
+ # @!visibility private
110
+ # @param [RunLoop::Detect] app
111
+ def mtime(app)
112
+ path = File.join(app.path, app.executable_name)
113
+ File.mtime(path)
114
+ end
115
+
116
+ # @!visibility private
117
+ def globs_for_app_search(base_dir)
118
+ search_depth = DEFAULTS[:search_depth]
119
+ Array.new(search_depth) do |depth|
120
+ File.join(base_dir, *Array.new(depth) { |_| "*"}, "*.app")
121
+ end
122
+ end
123
+ end
124
+
125
+ private
126
+
127
+ # @!visibility private
128
+ def self.app_from_options(options)
129
+ options[:app] || options[:bundle_id]
130
+ end
131
+
132
+ # @!visibility private
133
+ def self.app_from_environment
134
+ app_bundle_path = RunLoop::Environment.path_to_app_bundle
135
+
136
+ candidate = app_bundle_path
137
+ if app_bundle_path && !File.exist?(app_bundle_path)
138
+ candidate = File.basename(app_bundle_path)
139
+ end
140
+
141
+ candidate || RunLoop::Environment.bundle_id
142
+ end
143
+
144
+ # @!visibility private
145
+ def self.app_from_constant
146
+ (defined?(APP_BUNDLE_PATH) && APP_BUNDLE_PATH) ||
147
+ (defined?(APP) && APP)
148
+ end
149
+
150
+ # @!visibility private
151
+ def self.app_from_opts_or_env_or_constant(options)
152
+ self.app_from_options(options) ||
153
+ self.app_from_environment ||
154
+ self.app_from_constant
155
+ end
156
+
157
+ # @!visibility private
158
+ def self.detector
159
+ RunLoop::DetectAUT::Detect.new
160
+ end
161
+
162
+ # @!visibility private
163
+ def self.detect_app(options)
164
+ app = self.app_from_opts_or_env_or_constant(options)
165
+
166
+ # Options or constant defined an instance of App or Ipa
167
+ return app if app && (app.is_a?(RunLoop::App) || app.is_a?(RunLoop::Ipa))
168
+
169
+ # User provided no information, so we attempt to auto detect
170
+ if app.nil? || app == ""
171
+ return self.detector.app_for_simulator
172
+ end
173
+
174
+ extension = File.extname(app)
175
+ if extension == ".ipa" && File.exist?(app)
176
+ RunLoop::Ipa.new(app)
177
+ elsif extension == ".app" && File.exist?(app)
178
+ RunLoop::App.new(app)
179
+ else
180
+ # Probably a bundle identifier.
181
+ app
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,126 @@
1
+ module RunLoop
2
+
3
+ # @!visibility private
4
+ class SolutionMissingError < RuntimeError ; end
5
+
6
+ # @!visibility private
7
+ class XcodeprojMissingError < RuntimeError; end
8
+
9
+ # @!visibility private
10
+ class MultipleXcodeprojError < RuntimeError; end
11
+
12
+ # @!visibility private
13
+ class NoSimulatorAppFoundError < RuntimeError; end
14
+
15
+ # @!visibility private
16
+ module DetectAUT
17
+
18
+ # @!visibility private
19
+ module Errors
20
+
21
+ # @!visibility private
22
+ #
23
+ # Raised when XCODEPROJ is defined, but does not exist
24
+ def raise_xcodeproj_missing(xcodeproj)
25
+ raise RunLoop::XcodeprojMissingError,
26
+ %Q[The XCODEPROJ environment variable has been set to:
27
+
28
+ #{xcodeproj}
29
+
30
+ but no directory exists at that path.
31
+
32
+ You should only set XCODEPROJ variable if your Calabash project has more than
33
+ one .xcodeproj directory or your .xcodeproj directory is located above the
34
+ current directory (where you run `cucumber` from). Calabash will discover the
35
+ .xcodeproj if is below the current working directory.
36
+
37
+ # .xcodeproj is above the working directory
38
+ $ ls ../*.xcodeproj
39
+ MyApp.xcodeproj
40
+
41
+ $ XCODEPROJ=../*.xcodeproj cucumber
42
+
43
+ # There is more than one .xcodeproj
44
+ $ ls *.xcodeproj
45
+ MyiOSApp.xcodeproj
46
+ MyMacApp.xcodeproj
47
+
48
+ $ XCODEPROJ=MyiOSApp.xcodeproj
49
+ ]
50
+ end
51
+
52
+ # @!visibility private
53
+ #
54
+ # Raised when there are more than > 1 .xcodeproj in **/*
55
+ # Is not raised when there are 0 .xcodeproj in **/*
56
+ #
57
+ # @param [Array<String>] projects a list of paths to .xcodeproj
58
+ def raise_multiple_xcodeproj(projects)
59
+ raise RunLoop::MultipleXcodeprojError,
60
+ %Q[Found multiple .xcodeproj directories:
61
+
62
+ #{projects.join($-0)}
63
+
64
+ Which project contains the target of the application you are trying to test?
65
+
66
+ Set the XCODEPROJ variable to specify the correct .xcodeproj directory.
67
+
68
+ # Examples
69
+ $ XCODEPROJ="../MyApp.xcodeproj" cucumber
70
+ $ XCODEPROJ="iOS/MyApp.xcodeproj" cucumber
71
+ ]
72
+ end
73
+
74
+ # @!visibility private
75
+ #
76
+ # Raised when SOLUTION is defined but does not exist
77
+ def raise_solution_missing(solution)
78
+ raise RunLoop::SolutionMissingError,
79
+ %Q[The SOLUTION environment variable has been set to:
80
+
81
+ #{solution}
82
+
83
+ but no solution exists at that path.
84
+
85
+ You should only set SOLUTION variable if your .sln is not located in
86
+ the current directory or in the directory just above the current
87
+ directory (where you run `cucumber` from). Calabash will discover the
88
+ .snl if it is in the current working directory or the directory just
89
+ above.
90
+
91
+ # Calabash will discover solution - don't set SOLUTION
92
+ $ ls *.sln => MyApp.sln
93
+ $ ls ../*.sln => MyApp.sln
94
+
95
+ # Calabash will _not_ discover solution
96
+ $ ls ../../*.sln => MyApp.sln
97
+ $ SOLUTION=../../MyApp.sln cucumber
98
+
99
+ $ ls project/*.sln => MyApp.sln
100
+ $ SOLUTION=project/MyApp.sln cucumber
101
+
102
+ $ ls ~/some/other/directory/*.sln => MyApp.sln
103
+ $ SOLUTION=~/some/other/directory/MyApp.sln
104
+ ]
105
+ end
106
+
107
+ # @!visibility private
108
+ # Raised when no app can found by the discovery algorithm
109
+ def raise_no_simulator_app_found(search_directories, search_depth)
110
+ raise RunLoop::NoSimulatorAppFoundError,
111
+ %Q[Recursively searched these directories to depth #{search_depth}:
112
+
113
+ #{search_directories.join($-0)}
114
+
115
+ but could not find any .app for the simulator that links the Calabash iOS server.
116
+
117
+ Make sure you have built your app for a simulator target from Xcode.
118
+
119
+ If you are testing a stand-alone .app (you don't have an Xcode project), put
120
+ your .app in the same directory (or below) the directory you run `cucumber` from.
121
+ ]
122
+ end
123
+ end
124
+ end
125
+ end
126
+
@@ -0,0 +1,46 @@
1
+ module RunLoop
2
+ # @!visibility private
3
+ module DetectAUT
4
+
5
+ # @!visibility private
6
+ module XamarinStudio
7
+
8
+ # @!visibility private
9
+ def xamarin_project?
10
+ solution_directory != nil
11
+ end
12
+
13
+ # @!visibility private
14
+ def solution_directory
15
+ solution = RunLoop::Environment.solution
16
+
17
+ if solution && !File.exist?(solution)
18
+ raise_solution_missing(solution)
19
+ end
20
+
21
+ # SOLUTION defined and exists
22
+ return File.dirname(solution) if solution
23
+
24
+ solution_dir = find_solution_directory
25
+ return nil if solution_dir.nil?
26
+
27
+ solution_dir
28
+ end
29
+
30
+ # @!visibility private
31
+ def find_solution_directory
32
+ pwd = Dir.pwd
33
+ solutions = Dir.glob("#{pwd}/*.sln")
34
+
35
+ if solutions.empty?
36
+ solutions = Dir.glob("#{pwd}/../*.sln")
37
+ end
38
+
39
+ return nil if solutions.empty?
40
+
41
+ File.expand_path(File.dirname(solutions.first))
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,157 @@
1
+ module RunLoop
2
+ # @!visibility private
3
+ module DetectAUT
4
+ # @!visibility private
5
+ module Xcode
6
+
7
+ # @!visibility private
8
+ def xcode_project?
9
+ xcodeproj != nil
10
+ end
11
+
12
+ # @!visibility private
13
+ def xcodeproj
14
+ xcodeproj = RunLoop::Environment.xcodeproj
15
+
16
+ if xcodeproj && !File.directory?(xcodeproj)
17
+ raise_xcodeproj_missing(xcodeproj)
18
+ end
19
+
20
+ # XCODEPROJ defined and exists
21
+ return xcodeproj if xcodeproj
22
+
23
+ projects = find_xcodeproj
24
+
25
+ return nil if projects.empty?
26
+ return projects[0] if projects.count == 1
27
+
28
+ raise_multiple_xcodeproj(projects)
29
+ end
30
+
31
+ # @!visibility private
32
+ def find_xcodeproj
33
+ xcode_projects = []
34
+ Dir.glob("#{Dir.pwd}/**/*.xcodeproj").each do |path|
35
+ next if ignore_xcodeproj?(path)
36
+ xcode_projects << path
37
+ end
38
+ xcode_projects
39
+ end
40
+
41
+ # @!visibility private
42
+ def ignore_xcodeproj?(path)
43
+ path[/CordovaLib/, 0] ||
44
+ path[/Pods/, 0] ||
45
+ path[/Carthage/, 0] ||
46
+ path[/Airship(Kit|Lib)/, 0] ||
47
+ path[/google-plus-ios-sdk/, 0]
48
+ end
49
+
50
+ # @!visibility private
51
+ def detect_xcode_apps
52
+ dirs_to_search = derived_data_search_dirs
53
+
54
+ dir_from_prefs = xcode_preferences_search_dir
55
+ if dir_from_prefs
56
+ dirs_to_search << dir_from_prefs
57
+ end
58
+
59
+ dirs_to_search << Dir.pwd
60
+ dirs_to_search.uniq!
61
+
62
+ apps = []
63
+ dirs_to_search.each do |dir|
64
+ # defined in detect_aut/apps.rb
65
+ candidates = candidate_apps(dir)
66
+ apps = apps.concat(candidates)
67
+ end
68
+
69
+ return apps, dirs_to_search
70
+ end
71
+
72
+ # @!visibility private
73
+ PLIST_KEYS = {
74
+ :workspace => "WorkspacePath",
75
+ :shared_build => "IDESharedBuildFolderName",
76
+ :custom_build => "IDECustomBuildProductsPath"
77
+ }
78
+
79
+ # @!visibility private
80
+ # TODO Needs unit tests
81
+ def derived_data_search_dirs
82
+ project = xcodeproj
83
+ project_name = File.basename(project)
84
+ matches = []
85
+
86
+ # WorkspacePath could be a .xcodeproj or .xcworkspace
87
+ #
88
+ # # Exact match.
89
+ # xcodeproj = path/to/MyApp/MyApp.xcodeproj
90
+ # WorkspacePath = path/to/MyApp/MyApp.xcodeproj
91
+ #
92
+ # # CocoaPods projects are often configured like this. As are legacy
93
+ # # projects that have been added to a new workspace.
94
+ # xcodeproj = path/to/MyApp/MyApp.xcodeproj
95
+ # WorkspacePath = path/to/MyApp/MyApp.xcworkspace
96
+ #
97
+ # # This is the Xcode default when creating new iOS project
98
+ # xcodeproj = path/to/MyApp/MyApp/MyApp.xcodeproj
99
+ # WorkspacePath = path/to/MyApp/MyApp.xcworkspace
100
+ key = PLIST_KEYS[:workspace]
101
+ Dir.glob("#{derived_data}/*/info.plist") do |plist|
102
+ workspace = pbuddy.plist_read(key, plist)
103
+ if workspace == project
104
+ matches << File.dirname(plist)
105
+ else
106
+ base_dir = File.dirname(workspace)
107
+ if File.exist?(File.join(base_dir, project_name))
108
+ matches << File.dirname(plist)
109
+ elsif !Dir.glob("#{File.dirname(workspace)}/*/#{project_name}").empty?
110
+ matches << File.dirname(plist)
111
+ elsif !Dir.glob("#{File.dirname(workspace)}/**/#{project_name}").empty?
112
+ matches << File.dirname(plist)
113
+ end
114
+ end
115
+ end
116
+ matches
117
+ end
118
+
119
+ # @!visibility private
120
+ def xcode_preferences_search_dir
121
+ plist = xcode_preferences_plist
122
+
123
+ shared_build_folder = pbuddy.plist_read(PLIST_KEYS[:shared_build], plist)
124
+ custom_build_folder = pbuddy.plist_read(PLIST_KEYS[:custom_build], plist)
125
+
126
+ if shared_build_folder
127
+ File.join(derived_data, shared_build_folder, "Products")
128
+ elsif custom_build_folder
129
+ File.join(File.dirname(xcodeproj), custom_build_folder)
130
+ else
131
+ nil
132
+ end
133
+ end
134
+
135
+ # @!visibility private
136
+ def derived_data
137
+ RunLoop::Environment.derived_data ||
138
+ File.join(RunLoop::Environment.user_home_directory,
139
+ "Library", "Developer", "Xcode", "DerivedData")
140
+ end
141
+
142
+ # @!visibility private
143
+ def xcode_preferences_plist
144
+ File.join(RunLoop::Environment.user_home_directory,
145
+ "Library",
146
+ "Preferences",
147
+ "com.apple.dt.Xcode.plist")
148
+ end
149
+
150
+ # @!visibility private
151
+ def pbuddy
152
+ @pbuddy ||= RunLoop::PlistBuddy.new
153
+ end
154
+ end
155
+ end
156
+ end
157
+