luffa 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a03176e4d52343fcd2cb6947dfb7e54da45fb29b
4
+ data.tar.gz: 11b02be320fc50a246f797b7e9fdffacbe99c721
5
+ SHA512:
6
+ metadata.gz: 2093f3e95bdffe5167f906bb93cf07b419fe9888b43a4aee69031a88d8e56a6cf2073df6e8c224568bae0256227177d541616555b0c1c30703c23528026abe55
7
+ data.tar.gz: 8c7f2b41b7893c56ce72cbcfd77a2d303d487fef3ff651cb197104df00649476d34c6de2814c84446d293368cc623b6ac8cc038cc4df9d2002cf7f349ed68cab
@@ -0,0 +1,39 @@
1
+ ## Contributing
2
+
3
+ ***All pull requests should be based off the `develop` branch.***
4
+
5
+ The Calabash Toolchain uses git-flow.
6
+
7
+ See these links for information about git-flow and git best practices.
8
+
9
+ ##### Git Flow Step-by-Step guide
10
+
11
+ * https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow
12
+
13
+ ##### Git Best Practices
14
+
15
+ * http://justinhileman.info/article/changing-history/
16
+
17
+ ##### git-flow command line tool
18
+
19
+ We don't use the git-flow tools, but this is useful anyway.
20
+
21
+ * http://danielkummer.github.io/git-flow-cheatsheet/
22
+
23
+ ## Start a Feature
24
+
25
+ Start your work on a feature branch based off develop.
26
+
27
+ ```
28
+ # If you don't already have the develop branch
29
+ $ git fetch origin
30
+ $ git co -t origin/develop
31
+
32
+ # If you already have the develop branch
33
+ $ git co develop
34
+ $ git pull origin develop
35
+ $ git co -b feature/my-new-feature
36
+
37
+ # Publish your branch and make a pull-request on `develop`
38
+ $ git push -u origin feature/my-new-feature
39
+ ```
data/LICENSE ADDED
@@ -0,0 +1,204 @@
1
+ Eclipse Public License - v 1.0
2
+
3
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
4
+ LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
5
+ CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
6
+
7
+ 1. DEFINITIONS
8
+
9
+ "Contribution" means:
10
+
11
+ a) in the case of the initial Contributor, the initial code and documentation
12
+ distributed under this Agreement, and
13
+ b) in the case of each subsequent Contributor:
14
+ i) changes to the Program, and
15
+ ii) additions to the Program;
16
+
17
+ where such changes and/or additions to the Program originate from and are
18
+ distributed by that particular Contributor. A Contribution 'originates'
19
+ from a Contributor if it was added to the Program by such Contributor
20
+ itself or anyone acting on such Contributor's behalf. Contributions do not
21
+ include additions to the Program which: (i) are separate modules of
22
+ software distributed in conjunction with the Program under their own
23
+ license agreement, and (ii) are not derivative works of the Program.
24
+
25
+ "Contributor" means any person or entity that distributes the Program.
26
+
27
+ "Licensed Patents" mean patent claims licensable by a Contributor which are
28
+ necessarily infringed by the use or sale of its Contribution alone or when
29
+ combined with the Program.
30
+
31
+ "Program" means the Contributions distributed in accordance with this
32
+ Agreement.
33
+
34
+ "Recipient" means anyone who receives the Program under this Agreement,
35
+ including all Contributors.
36
+
37
+ 2. GRANT OF RIGHTS
38
+ a) Subject to the terms of this Agreement, each Contributor hereby grants
39
+ Recipient a non-exclusive, worldwide, royalty-free copyright license to
40
+ reproduce, prepare derivative works of, publicly display, publicly
41
+ perform, distribute and sublicense the Contribution of such Contributor,
42
+ if any, and such derivative works, in source code and object code form.
43
+ b) Subject to the terms of this Agreement, each Contributor hereby grants
44
+ Recipient a non-exclusive, worldwide, royalty-free patent license under
45
+ Licensed Patents to make, use, sell, offer to sell, import and otherwise
46
+ transfer the Contribution of such Contributor, if any, in source code and
47
+ object code form. This patent license shall apply to the combination of
48
+ the Contribution and the Program if, at the time the Contribution is
49
+ added by the Contributor, such addition of the Contribution causes such
50
+ combination to be covered by the Licensed Patents. The patent license
51
+ shall not apply to any other combinations which include the Contribution.
52
+ No hardware per se is licensed hereunder.
53
+ c) Recipient understands that although each Contributor grants the licenses
54
+ to its Contributions set forth herein, no assurances are provided by any
55
+ Contributor that the Program does not infringe the patent or other
56
+ intellectual property rights of any other entity. Each Contributor
57
+ disclaims any liability to Recipient for claims brought by any other
58
+ entity based on infringement of intellectual property rights or
59
+ otherwise. As a condition to exercising the rights and licenses granted
60
+ hereunder, each Recipient hereby assumes sole responsibility to secure
61
+ any other intellectual property rights needed, if any. For example, if a
62
+ third party patent license is required to allow Recipient to distribute
63
+ the Program, it is Recipient's responsibility to acquire that license
64
+ before distributing the Program.
65
+ d) Each Contributor represents that to its knowledge it has sufficient
66
+ copyright rights in its Contribution, if any, to grant the copyright
67
+ license set forth in this Agreement.
68
+
69
+ 3. REQUIREMENTS
70
+
71
+ A Contributor may choose to distribute the Program in object code form under
72
+ its own license agreement, provided that:
73
+
74
+ a) it complies with the terms and conditions of this Agreement; and
75
+ b) its license agreement:
76
+ i) effectively disclaims on behalf of all Contributors all warranties
77
+ and conditions, express and implied, including warranties or
78
+ conditions of title and non-infringement, and implied warranties or
79
+ conditions of merchantability and fitness for a particular purpose;
80
+ ii) effectively excludes on behalf of all Contributors all liability for
81
+ damages, including direct, indirect, special, incidental and
82
+ consequential damages, such as lost profits;
83
+ iii) states that any provisions which differ from this Agreement are
84
+ offered by that Contributor alone and not by any other party; and
85
+ iv) states that source code for the Program is available from such
86
+ Contributor, and informs licensees how to obtain it in a reasonable
87
+ manner on or through a medium customarily used for software exchange.
88
+
89
+ When the Program is made available in source code form:
90
+
91
+ a) it must be made available under this Agreement; and
92
+ b) a copy of this Agreement must be included with each copy of the Program.
93
+ Contributors may not remove or alter any copyright notices contained
94
+ within the Program.
95
+
96
+ Each Contributor must identify itself as the originator of its Contribution,
97
+ if
98
+ any, in a manner that reasonably allows subsequent Recipients to identify the
99
+ originator of the Contribution.
100
+
101
+ 4. COMMERCIAL DISTRIBUTION
102
+
103
+ Commercial distributors of software may accept certain responsibilities with
104
+ respect to end users, business partners and the like. While this license is
105
+ intended to facilitate the commercial use of the Program, the Contributor who
106
+ includes the Program in a commercial product offering should do so in a manner
107
+ which does not create potential liability for other Contributors. Therefore,
108
+ if a Contributor includes the Program in a commercial product offering, such
109
+ Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
110
+ every other Contributor ("Indemnified Contributor") against any losses,
111
+ damages and costs (collectively "Losses") arising from claims, lawsuits and
112
+ other legal actions brought by a third party against the Indemnified
113
+ Contributor to the extent caused by the acts or omissions of such Commercial
114
+ Contributor in connection with its distribution of the Program in a commercial
115
+ product offering. The obligations in this section do not apply to any claims
116
+ or Losses relating to any actual or alleged intellectual property
117
+ infringement. In order to qualify, an Indemnified Contributor must:
118
+ a) promptly notify the Commercial Contributor in writing of such claim, and
119
+ b) allow the Commercial Contributor to control, and cooperate with the
120
+ Commercial Contributor in, the defense and any related settlement
121
+ negotiations. The Indemnified Contributor may participate in any such claim at
122
+ its own expense.
123
+
124
+ For example, a Contributor might include the Program in a commercial product
125
+ offering, Product X. That Contributor is then a Commercial Contributor. If
126
+ that Commercial Contributor then makes performance claims, or offers
127
+ warranties related to Product X, those performance claims and warranties are
128
+ such Commercial Contributor's responsibility alone. Under this section, the
129
+ Commercial Contributor would have to defend claims against the other
130
+ Contributors related to those performance claims and warranties, and if a
131
+ court requires any other Contributor to pay any damages as a result, the
132
+ Commercial Contributor must pay those damages.
133
+
134
+ 5. NO WARRANTY
135
+
136
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
137
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
138
+ IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
139
+ NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
140
+ Recipient is solely responsible for determining the appropriateness of using
141
+ and distributing the Program and assumes all risks associated with its
142
+ exercise of rights under this Agreement , including but not limited to the
143
+ risks and costs of program errors, compliance with applicable laws, damage to
144
+ or loss of data, programs or equipment, and unavailability or interruption of
145
+ operations.
146
+
147
+ 6. DISCLAIMER OF LIABILITY
148
+
149
+ EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
150
+ CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
151
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
152
+ LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
153
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
154
+ ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
155
+ EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
156
+ OF SUCH DAMAGES.
157
+
158
+ 7. GENERAL
159
+
160
+ If any provision of this Agreement is invalid or unenforceable under
161
+ applicable law, it shall not affect the validity or enforceability of the
162
+ remainder of the terms of this Agreement, and without further action by the
163
+ parties hereto, such provision shall be reformed to the minimum extent
164
+ necessary to make such provision valid and enforceable.
165
+
166
+ If Recipient institutes patent litigation against any entity (including a
167
+ cross-claim or counterclaim in a lawsuit) alleging that the Program itself
168
+ (excluding combinations of the Program with other software or hardware)
169
+ infringes such Recipient's patent(s), then such Recipient's rights granted
170
+ under Section 2(b) shall terminate as of the date such litigation is filed.
171
+
172
+ All Recipient's rights under this Agreement shall terminate if it fails to
173
+ comply with any of the material terms or conditions of this Agreement and does
174
+ not cure such failure in a reasonable period of time after becoming aware of
175
+ such noncompliance. If all Recipient's rights under this Agreement terminate,
176
+ Recipient agrees to cease use and distribution of the Program as soon as
177
+ reasonably practicable. However, Recipient's obligations under this Agreement
178
+ and any licenses granted by Recipient relating to the Program shall continue
179
+ and survive.
180
+
181
+ Everyone is permitted to copy and distribute copies of this Agreement, but in
182
+ order to avoid inconsistency the Agreement is copyrighted and may only be
183
+ modified in the following manner. The Agreement Steward reserves the right to
184
+ publish new versions (including revisions) of this Agreement from time to
185
+ time. No one other than the Agreement Steward has the right to modify this
186
+ Agreement. The Eclipse Foundation is the initial Agreement Steward. The
187
+ Eclipse Foundation may assign the responsibility to serve as the Agreement
188
+ Steward to a suitable separate entity. Each new version of the Agreement will
189
+ be given a distinguishing version number. The Program (including
190
+ Contributions) may always be distributed subject to the version of the
191
+ Agreement under which it was received. In addition, after a new version of the
192
+ Agreement is published, Contributor may elect to distribute the Program
193
+ (including its Contributions) under the new version. Except as expressly
194
+ stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
195
+ licenses to the intellectual property of any Contributor under this Agreement,
196
+ whether expressly, by implication, estoppel or otherwise. All rights in the
197
+ Program not expressly granted under this Agreement are reserved.
198
+
199
+ This Agreement is governed by the laws of the State of New York and the
200
+ intellectual property laws of the United States of America. No party to this
201
+ Agreement will bring a legal action under this Agreement more than one year
202
+ after the cause of action arose. Each party waives its rights to a jury trial in
203
+ any resulting litigation.
204
+
@@ -0,0 +1,7 @@
1
+ | master | develop | [versioning](VERSIONING.md) | [license](LICENSE) | [contributing](CONTRIBUTING.md)|
2
+ |---------|---------|-----------------------------|--------------------|--------------------------------|
3
+ |[![Build Status](https://travis-ci.org/calabash/luffa.svg?branch=master)](https://travis-ci.org/calabash/luffa)| [![Build Status](https://travis-ci.org/calabash/luffa.svg?branch=develop)](https://travis-ci.org/calabash/luffa)| [![GitHub version](https://badge.fury.io/gh/calabash%2Fluffa.svg)](http://badge.fury.io/gh/calabash%2Fluffa) |[![License](https://img.shields.io/badge/licence-Eclipse-blue.svg)](http://opensource.org/licenses/EPL-1.0) | [![Contributing](https://img.shields.io/badge/contrib-gitflow-orange.svg)](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow/)|
4
+
5
+ ## Calabash Luffa
6
+
7
+ A gem to help test the Calabash Toolchain.
@@ -0,0 +1,16 @@
1
+ ## Versioning
2
+
3
+ Calabash tries very hard to comply with Semantic Versioning [1] rules.
4
+
5
+ However, the semantic versioning spec is incompatible with RubyGem's patterns for pre-release gems.
6
+
7
+ > "But returning to the practical: No release version of SemVer is compatible with Rubygems." - _David Kellum_ [2]
8
+
9
+ Calabash version numbers will be in this form:
10
+
11
+ ```
12
+ <major>.<minor>.<patch>[.pre<N>]
13
+ ```
14
+
15
+ - [1] http://semver.org/
16
+ - [2] http://gravitext.com/2012/07/22/versioning.html
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require 'luffa/cli/cli'
3
+
4
+ begin
5
+ Luffa::CLI.start
6
+ exit 0
7
+ rescue Luffa::ValidationError, Thor::RequiredArgumentMissingError, Thor::UndefinedCommandError => e
8
+ puts e.message
9
+ exit 64
10
+ rescue Thor::Error => e
11
+ puts e.message
12
+ if ENV['DEBUG'] == '1'
13
+ puts e.backtrace.join("\n") if e.backtrace
14
+ p e.class
15
+ end
16
+ exit 70
17
+ end
@@ -0,0 +1,12 @@
1
+ require 'luffa/environment'
2
+ require 'luffa/patches/awesome_print'
3
+ require 'luffa/patches/kernel'
4
+ require 'luffa/logging'
5
+ require 'luffa/version'
6
+ require 'luffa/unix_command'
7
+ require 'luffa/with_debugging'
8
+ require 'luffa/retry'
9
+ require 'luffa/gem'
10
+ require 'luffa/ios/xcode'
11
+ require 'luffa/ios/simulator'
12
+ require 'luffa/ios/ideviceinstaller'
@@ -0,0 +1,65 @@
1
+ require 'thor'
2
+ require 'luffa'
3
+
4
+ trap 'SIGINT' do
5
+ puts 'Exiting'
6
+ exit 10
7
+ end
8
+
9
+ module Luffa
10
+
11
+ class ValidationError < Thor::InvocationError
12
+ end
13
+
14
+ class CLI < Thor
15
+ include Thor::Actions
16
+
17
+ def self.exit_on_failure?
18
+ true
19
+ end
20
+
21
+ desc 'version', 'Prints version of the luffa gem'
22
+ def version
23
+ puts Luffa::VERSION
24
+ end
25
+
26
+ desc 'authorize', 'Runs instruments authorization scripts - will only run on travis-ci'
27
+ def authorize
28
+ this_dir = File.dirname(__FILE__)
29
+ relative_path = File.join(this_dir, '..', '..', '..', 'script', 'ci')
30
+ plist_path = File.expand_path(relative_path)
31
+
32
+ analysis_plist = "#{plist_path}/com.apple.dt.instruments.process.analysis.plist"
33
+ kill_plist = "#{plist_path}/com.apple.dt.instruments.process.kill.plist"
34
+
35
+ analysis_domain = 'com.apple.dt.instruments.process.analysis'
36
+ analysis_args = ['security', 'authorizationdb', 'write', analysis_domain]
37
+
38
+ kill_domain = 'com.apple.dt.instruments.process.kill'
39
+ kill_args = ['security', 'authorizationdb', 'write', kill_domain]
40
+
41
+ if Luffa::Environment.travis_ci?
42
+ cmd = "sudo #{analysis_args.join(' ')} < \"#{analysis_plist}\""
43
+ options = {
44
+ :pass_msg => 'Wrote analysis.plist',
45
+ :fail_msg => 'Could not write analysis.plist',
46
+ :exit_on_nonzero_status => false
47
+ }
48
+ analysis_code = Luffa.unix_command(cmd, options)
49
+
50
+ cmd = "sudo #{kill_args.join(' ')} < \"#{kill_plist}\""
51
+ options = {
52
+ :pass_msg => 'Wrote kill.plist',
53
+ :fail_msg => 'Could not write kill.plist',
54
+ :exit_on_nonzero_status => false
55
+ }
56
+
57
+ kill_code = Luffa.unix_command(cmd, options)
58
+ analysis_code == 0 && kill_code == 0
59
+ else
60
+ puts "Skipping 'security authorizationdb write' because it requires sudo"
61
+ true
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,31 @@
1
+ module Luffa
2
+ module Environment
3
+ def self.travis_ci?
4
+ value = ENV['TRAVIS']
5
+ !value.nil? && value != ''
6
+ end
7
+
8
+ def self.jenkins_ci?
9
+ value = ENV['JENKINS_HOME']
10
+ !value.nil? && value != ''
11
+ end
12
+
13
+ def self.ci?
14
+ self.travis_ci? || self.jenkins_ci?
15
+ end
16
+
17
+ def self.developer_dir
18
+ value = ENV['DEVELOPER_DIR']
19
+ if value && value != ''
20
+ value
21
+ else
22
+ nil
23
+ end
24
+ end
25
+
26
+ # Returns true if debugging is enabled.
27
+ def self.debug?
28
+ ENV['DEBUG'] == '1'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ module Luffa
2
+ class Gem
3
+
4
+ def self.update_rubygems(unix_command_opts={})
5
+ default_opts = {:pass_msg => 'Updated rubygems',
6
+ :fail_msg => 'Could not update rubygems'}
7
+
8
+ Luffa.unix_command('gem update --system',
9
+ default_opts.merge(unix_command_opts))
10
+ end
11
+
12
+ def self.uninstall_gem(gem_name, unix_command_opts={})
13
+ default_opts = {:pass_msg => "Uninstalled '#{gem_name}'",
14
+ :fail_msg => "Could not uninstall '#{gem_name}'"}
15
+ Luffa.unix_command("gem uninstall -Vax --force --no-abort-on-dependent #{gem_name}",
16
+ default_opts.merge(unix_command_opts))
17
+ end
18
+
19
+ def self.install_gem(gem_name, opts={})
20
+ default_opts = {:prerelease => false,
21
+ :no_document => true,
22
+ :pass_msg => "Installed '#{gem_name}'",
23
+ :fail_msg => "Could not install '#{gem_name}'"}
24
+
25
+ merged_opts = default_opts.merge(opts)
26
+
27
+ pre = merged_opts[:prerelease] ? '--pre' : ''
28
+ no_document = merged_opts[:no_document] ? '--no-document' : ''
29
+
30
+ Luffa.unix_command("gem install #{no_document} #{gem_name} #{pre}",
31
+ merged_opts)
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,116 @@
1
+ require 'retriable'
2
+
3
+ module Luffa
4
+ class IDeviceInstaller
5
+
6
+ attr_reader :ipa
7
+ attr_reader :bundle_id
8
+
9
+ def initialize(ipa, bundle_id)
10
+ @ipa = ipa
11
+ @bundle_id = bundle_id
12
+ end
13
+
14
+ def bin_path
15
+ @bin_path ||= `which ideviceinstaller`.chomp!
16
+ end
17
+
18
+ def ideviceinstaller_available?
19
+ path = bin_path
20
+ path and File.exist? bin_path
21
+ end
22
+
23
+ def install(udid, cmd)
24
+ case cmd
25
+ when :install_internal
26
+ ipa
27
+ Retriable.retriable do
28
+ uninstall udid
29
+ end
30
+ Retriable.retriable do
31
+ install_internal udid
32
+ end
33
+ when :uninstall
34
+ Retriable.retriable do
35
+ uninstall udid
36
+ end
37
+ else
38
+ cmds = [:install_internal, :uninstall]
39
+ raise ArgumentError, "expected '#{cmd}' to be one of '#{cmds}'"
40
+ end
41
+ end
42
+
43
+ def bundle_installed?(udid)
44
+ cmd = "#{bin_path} --udid #{udid} --list-apps"
45
+ Luffa.log_unix_cmd(cmd) if Luffa::Environment.debug?
46
+
47
+ Open3.popen3(cmd) do |_, stdout, stderr, _|
48
+ err = stderr.read.strip
49
+ Luffa.log_fail(err) if err && err != ''
50
+
51
+ out = stdout.read.strip
52
+ out.strip.split(/\s/).include? bundle_id
53
+ end
54
+ end
55
+
56
+ def install_internal(udid)
57
+ return true if bundle_installed? udid
58
+
59
+ cmd = "#{bin_path} --udid #{udid} --install #{ipa}"
60
+ Luffa.log_unix_cmd(cmd) if Luffa::Environment.debug?
61
+
62
+ Open3.popen3(cmd) do |_, _, stderr, _|
63
+ err = stderr.read.strip
64
+ Luffa.log_fail(err) if err && err != ''
65
+ end
66
+
67
+ unless bundle_installed? udid
68
+ raise "could not install '#{ipa}' on '#{udid}' with '#{bundle_id}'"
69
+ end
70
+ true
71
+ end
72
+
73
+ def uninstall(udid)
74
+ return true unless bundle_installed? udid
75
+
76
+ cmd = "#{bin_path} -udid #{udid} --uninstall #{bundle_id}"
77
+ Luffa.log_unix_cmd(cmd) if Luffa::Environment.debug?
78
+
79
+ Open3.popen3(cmd) do |_, _, stderr, _|
80
+ err = stderr.read.strip
81
+ Luffa.log_fail(err) if err && err != ''
82
+ end
83
+
84
+ if bundle_installed? udid
85
+ raise "could not uninstall '#{bundle_id}' on '#{udid}'"
86
+ end
87
+ true
88
+ end
89
+
90
+ def idevice_id_bin_path
91
+ @idevice_id_bin_path ||= `which idevice_id`.chomp!
92
+ end
93
+
94
+ def idevice_id_available?
95
+ path = idevice_id_bin_path
96
+ path and File.exist? path
97
+ end
98
+
99
+ def physical_devices_for_testing(xcode_tools)
100
+ # Xcode 6 + iOS 8 - devices on the same network, whether development or
101
+ # not, appear when calling $ xcrun instruments -s devices. For the
102
+ # purposes of testing, we will only try to connect to devices that are
103
+ # connected via USB.
104
+ @physical_devices_for_testing ||= lambda {
105
+ devices = xcode_tools.instruments(:devices)
106
+ if idevice_id_available?
107
+ white_list = `#{idevice_id_bin_path} -l`.strip.split("\n")
108
+ devices.select { | device | white_list.include?(device.udid) }
109
+ else
110
+ devices
111
+ end
112
+ }.call
113
+ end
114
+
115
+ end
116
+ end