snapshot 0.10.2 → 1.0.1
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.
- checksums.yaml +4 -4
- data/README.md +92 -333
- data/bin/snapshot +11 -28
- data/lib/assets/SnapfileTemplate +14 -33
- data/lib/assets/SnapshotHelper.swift +50 -0
- data/lib/snapshot.rb +23 -4
- data/lib/snapshot/collector.rb +72 -0
- data/lib/snapshot/dependency_checker.rb +14 -26
- data/lib/snapshot/detect_values.rb +33 -0
- data/lib/snapshot/error_handler.rb +31 -0
- data/lib/snapshot/latest_ios_version.rb +9 -4
- data/lib/snapshot/options.rb +98 -0
- data/lib/snapshot/page.html.erb +1 -1
- data/lib/snapshot/reports_generator.rb +33 -37
- data/lib/snapshot/reset_simulators.rb +4 -4
- data/lib/snapshot/runner.rb +59 -246
- data/lib/snapshot/screenshot_flatten.rb +2 -2
- data/lib/snapshot/screenshot_rotate.rb +7 -9
- data/lib/snapshot/setup.rb +33 -0
- data/lib/snapshot/test_command_generator.rb +93 -0
- data/lib/snapshot/version.rb +2 -1
- metadata +83 -13
- data/lib/assets/SnapshotHelper.js +0 -63
- data/lib/assets/snapshot.js +0 -9
- data/lib/snapshot/builder.rb +0 -85
- data/lib/snapshot/simulators.rb +0 -40
- data/lib/snapshot/snapfile_creator.rb +0 -21
- data/lib/snapshot/snapshot_config.rb +0 -233
- data/lib/snapshot/snapshot_file.rb +0 -87
data/lib/snapshot/simulators.rb
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
require 'open3'
|
|
2
|
-
|
|
3
|
-
module Snapshot
|
|
4
|
-
class Simulators
|
|
5
|
-
# @return the raw value of the `instruments -s` command
|
|
6
|
-
# we do it using `open3` since only ` just randomly hangs with instruments -s
|
|
7
|
-
def self.raw_simulators
|
|
8
|
-
return @result if @result
|
|
9
|
-
|
|
10
|
-
Open3.popen3('instruments -s') do |stdin, stdout, stderr, wait_thr|
|
|
11
|
-
@result = stdout.read
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
@result || ''
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def self.available_devices(name_only = false)
|
|
18
|
-
Helper.log.info "Fetching available devices" if $verbose
|
|
19
|
-
result = []
|
|
20
|
-
|
|
21
|
-
output = self.raw_simulators
|
|
22
|
-
|
|
23
|
-
output.split("\n").each do |current|
|
|
24
|
-
# Example: "iPhone 5 (8.1 Simulator) [C49ECC4A-5A3D-44B6-B9BF-4E25BC326400]"
|
|
25
|
-
# Example: "iPhone 6 (9.0) [072E4EA2-861F-44CD-AB77-FB1FE07E541C]"
|
|
26
|
-
|
|
27
|
-
match = current.match /((.+?) \(.+?\)) \[.+?\]/
|
|
28
|
-
next if match.nil?
|
|
29
|
-
|
|
30
|
-
if name_only
|
|
31
|
-
result << match[2]
|
|
32
|
-
else
|
|
33
|
-
result << match[1]
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
return result
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module Snapshot
|
|
2
|
-
class SnapfileCreator
|
|
3
|
-
# This method will take care of creating a Snapfile
|
|
4
|
-
def self.create(path)
|
|
5
|
-
snapfile_path = File.join(path, 'Snapfile')
|
|
6
|
-
|
|
7
|
-
raise "Snapfile already exists at path '#{snapfile_path}'. Run 'snapshot' to use Snapshot.".red if File.exists?(snapfile_path)
|
|
8
|
-
|
|
9
|
-
gem_path = Helper.gem_path("snapshot")
|
|
10
|
-
File.write(snapfile_path, File.read("#{gem_path}/lib/assets/SnapfileTemplate"))
|
|
11
|
-
File.write([path, 'snapshot.js'].join('/'), File.read("#{gem_path}/lib/assets/snapshot.js"))
|
|
12
|
-
File.write([path, 'snapshot-iPad.js'].join('/'), File.read("#{gem_path}/lib/assets/snapshot.js"))
|
|
13
|
-
File.write([path, 'SnapshotHelper.js'].join('/'), File.read("#{gem_path}/lib/assets/SnapshotHelper.js"))
|
|
14
|
-
|
|
15
|
-
puts "Successfully created SnapshotHelper.js '#{File.join(path, 'SnapshotHelper.js')}'".green
|
|
16
|
-
puts "Successfully created new UI Automation JS file at '#{File.join(path, 'snapshot.js')}'".green
|
|
17
|
-
puts "Successfully created new UI Automation JS file for iPad at '#{File.join(path, 'snapshot-iPad.js')}'".green
|
|
18
|
-
puts "Successfully created new Snapfile at '#{snapfile_path}'".green
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
module Snapshot
|
|
2
|
-
class SnapshotConfig
|
|
3
|
-
|
|
4
|
-
# @return (SnapshotFile)
|
|
5
|
-
attr_accessor :snapshot_file
|
|
6
|
-
|
|
7
|
-
# @return (Array) List of simulators to use
|
|
8
|
-
attr_accessor :devices
|
|
9
|
-
|
|
10
|
-
# @return (Array) A list of languages which should be used
|
|
11
|
-
attr_accessor :languages
|
|
12
|
-
|
|
13
|
-
# @return (String) The iOS version (e.g. 8.1)
|
|
14
|
-
attr_accessor :ios_version
|
|
15
|
-
|
|
16
|
-
# @return (String) The path to the project/workspace
|
|
17
|
-
attr_accessor :project_path
|
|
18
|
-
|
|
19
|
-
# @return (String) The name of a scheme, manually set by the user using the config file
|
|
20
|
-
attr_accessor :manual_scheme
|
|
21
|
-
|
|
22
|
-
# @return (String) The path to the JavaScript file to use
|
|
23
|
-
attr_accessor :manual_js_file
|
|
24
|
-
|
|
25
|
-
# @return (String) The path, in which the screenshots should be stored
|
|
26
|
-
attr_accessor :screenshots_path
|
|
27
|
-
|
|
28
|
-
# @return (String) The build command, wich should build the app to build_dir (/tmp/snapshot by default)
|
|
29
|
-
attr_accessor :build_command
|
|
30
|
-
|
|
31
|
-
# @return (String) The build directory, defaults to '/tmp/snapshot'
|
|
32
|
-
attr_accessor :build_dir
|
|
33
|
-
|
|
34
|
-
# @return (BOOL) Skip the removal of the alpha channel from the screenshots
|
|
35
|
-
attr_accessor :skip_alpha_removal
|
|
36
|
-
|
|
37
|
-
# @return (BOOL) Clear previously generated screenshots before creating new ones
|
|
38
|
-
attr_accessor :clear_previous_screenshots
|
|
39
|
-
|
|
40
|
-
# @return (String) This will be prepended before the actual build command
|
|
41
|
-
attr_accessor :custom_args
|
|
42
|
-
|
|
43
|
-
# @return (String) This will be appended to the actual build command
|
|
44
|
-
attr_accessor :custom_build_args
|
|
45
|
-
|
|
46
|
-
# @return (String) This will be appended to the run command
|
|
47
|
-
attr_accessor :custom_run_args
|
|
48
|
-
|
|
49
|
-
# @return (Hash) All the blocks, which are called on specific actions
|
|
50
|
-
attr_accessor :blocks
|
|
51
|
-
|
|
52
|
-
attr_accessor :html_title
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# A shared singleton
|
|
56
|
-
def self.shared_instance(path = nil)
|
|
57
|
-
@@instance ||= SnapshotConfig.new(path)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# @param path (String) the path to the config file to use (including the file name)
|
|
61
|
-
def initialize(path = nil)
|
|
62
|
-
DependencyChecker.check_simulators
|
|
63
|
-
path ||= './Snapfile'
|
|
64
|
-
set_defaults
|
|
65
|
-
|
|
66
|
-
if File.exists?path
|
|
67
|
-
Helper.log.info "Using '#{path}'".green if $verbose
|
|
68
|
-
self.snapshot_file = SnapshotFile.new(path, self)
|
|
69
|
-
|
|
70
|
-
self.verify_devices
|
|
71
|
-
else
|
|
72
|
-
if path != './Snapfile'
|
|
73
|
-
raise "Could not find Snapfile at path '#{path}'. Make sure you pass the full path, including 'Snapfile'".red
|
|
74
|
-
else
|
|
75
|
-
# Using default settings, since user didn't provide a path
|
|
76
|
-
Helper.log.error "Could not find './Snapfile'. It is recommended to create a file using 'snapshot init' into the current directory. Using the defaults now.".red
|
|
77
|
-
self.verify_devices
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
load_env
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def set_defaults
|
|
85
|
-
self.ios_version = Snapshot::LatestIosVersion.version
|
|
86
|
-
|
|
87
|
-
self.languages = [
|
|
88
|
-
'de-DE',
|
|
89
|
-
'en-US'
|
|
90
|
-
]
|
|
91
|
-
|
|
92
|
-
self.screenshots_path = './screenshots'
|
|
93
|
-
|
|
94
|
-
folders = ["./*.xcworkspace"] # we prefer workspaces
|
|
95
|
-
folders << "./*.xcodeproj"
|
|
96
|
-
folders << "../*.xcworkspace"
|
|
97
|
-
folders << "../*.xcodeproj"
|
|
98
|
-
|
|
99
|
-
folders.each do |current|
|
|
100
|
-
self.project_path ||= (File.expand_path(Dir[current].first) rescue nil)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
empty = Proc.new {}
|
|
104
|
-
self.blocks = {
|
|
105
|
-
setup_for_device_change: empty,
|
|
106
|
-
teardown_device: empty,
|
|
107
|
-
setup_for_language_change: empty,
|
|
108
|
-
teardown_language: empty
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
self.html_title = self.project_name || 'KrauseFx/snapshot'
|
|
112
|
-
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# This has to be done after parsing the Snapfile (iOS version)
|
|
116
|
-
def set_default_simulators
|
|
117
|
-
self.devices ||= [
|
|
118
|
-
"iPhone 6" + version_suffix(self.ios_version),
|
|
119
|
-
"iPhone 6 Plus" + version_suffix(self.ios_version),
|
|
120
|
-
"iPhone 5" + version_suffix(self.ios_version),
|
|
121
|
-
"iPhone 4s" + version_suffix(self.ios_version),
|
|
122
|
-
]
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# This method takes care of appending the iOS version to the simulator name
|
|
126
|
-
def verify_devices
|
|
127
|
-
self.set_default_simulators
|
|
128
|
-
|
|
129
|
-
actual_devices = []
|
|
130
|
-
self.devices.each do |current|
|
|
131
|
-
current += version_suffix(self.ios_version) unless current.include? " ("
|
|
132
|
-
|
|
133
|
-
if Simulators.available_devices.include? current
|
|
134
|
-
actual_devices << current
|
|
135
|
-
else
|
|
136
|
-
raise "Device '#{current}' not found. Available device types: #{Simulators.available_devices}".red
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
self.devices = actual_devices
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def load_env
|
|
143
|
-
# Load environment variables
|
|
144
|
-
self.manual_scheme = ENV["SNAPSHOT_SCHEME"] if ENV["SNAPSHOT_SCHEME"]
|
|
145
|
-
self.screenshots_path = ENV["SNAPSHOT_SCREENSHOTS_PATH"] if ENV["SNAPSHOT_SCREENSHOTS_PATH"]
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
# Getters
|
|
149
|
-
|
|
150
|
-
# Returns the file name of the project
|
|
151
|
-
def project_name
|
|
152
|
-
File.basename(self.project_path, ".*" ) if self.project_path
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# The JavaScript UIAutomation file
|
|
156
|
-
def js_file(ipad = false)
|
|
157
|
-
return ENV["SNAPSHOT_JS_FILE"] if ENV["SNAPSHOT_JS_FILE"]
|
|
158
|
-
|
|
159
|
-
result = manual_js_file
|
|
160
|
-
|
|
161
|
-
unless result
|
|
162
|
-
files = Dir.glob("./*.js").delete_if { |path| (path.include?"SnapshotHelper.js" or path.include?"iPad.js") }
|
|
163
|
-
if files.count == 1
|
|
164
|
-
result = files.first
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
if ipad
|
|
169
|
-
ipad_file = result.split('.js').join('/') + '-iPad.js'
|
|
170
|
-
if File.exists?(ipad_file)
|
|
171
|
-
result = ipad_file
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
unless File.exists?(result || '')
|
|
176
|
-
raise "Could not determine which UIAutomation file to use. Please pass a path to your Javascript file using 'js_file'.".red
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
return result
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
# The scheme to use (either it's set, or there is only one, or user has to enter it)
|
|
183
|
-
def scheme
|
|
184
|
-
begin
|
|
185
|
-
project_key = 'project'
|
|
186
|
-
project_key = 'workspace' if project_path.end_with?'.xcworkspace'
|
|
187
|
-
command = "xcodebuild -#{project_key} '#{project_path}' -list"
|
|
188
|
-
Helper.log.debug command if $verbose
|
|
189
|
-
|
|
190
|
-
schemes = `#{command}`.split("Schemes:").last.split("\n").each { |a| a.strip! }.delete_if { |a| a == '' }
|
|
191
|
-
|
|
192
|
-
Helper.log.debug "Found available schemes: #{schemes}" if $verbose
|
|
193
|
-
|
|
194
|
-
self.manual_scheme = schemes.first if schemes.count == 1
|
|
195
|
-
|
|
196
|
-
if self.manual_scheme
|
|
197
|
-
if not schemes.include?manual_scheme
|
|
198
|
-
raise "Could not find requested scheme '#{self.manual_scheme}' in Xcode's schemes #{schemes}"
|
|
199
|
-
else
|
|
200
|
-
return self.manual_scheme
|
|
201
|
-
end
|
|
202
|
-
else
|
|
203
|
-
# We have to ask the user first
|
|
204
|
-
puts "Found the following schemes in your project:".green
|
|
205
|
-
puts "You can use 'scheme \"Name\"' in your Snapfile".green
|
|
206
|
-
puts "--------------------------------------------".green
|
|
207
|
-
while not schemes.include?self.manual_scheme
|
|
208
|
-
schemes.each_with_index do |current, index|
|
|
209
|
-
puts "#{index + 1}) #{current}"
|
|
210
|
-
end
|
|
211
|
-
val = gets.strip.to_i
|
|
212
|
-
if val > 0
|
|
213
|
-
self.manual_scheme = (schemes[val - 1] rescue nil)
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
return self.manual_scheme
|
|
217
|
-
end
|
|
218
|
-
rescue => ex
|
|
219
|
-
raise "Could not fetch available schemes: #{ex}".red
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def version_suffix version
|
|
224
|
-
# Xcode 6 and before: "iPhone 5 (8.0 Simulator)"
|
|
225
|
-
# Xcode 7 and later: "iPhone 6 (9.0)"
|
|
226
|
-
if LatestIosVersion.version.to_i >= 9
|
|
227
|
-
" (#{version})"
|
|
228
|
-
else
|
|
229
|
-
" (#{version} Simulator)"
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
end
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
module Snapshot
|
|
2
|
-
class SnapshotFile
|
|
3
|
-
|
|
4
|
-
# @return (String) The path to the used Deliverfile.
|
|
5
|
-
attr_accessor :path
|
|
6
|
-
|
|
7
|
-
# @param path (String) the path to the config file to use (including the file name)
|
|
8
|
-
def initialize(path, config)
|
|
9
|
-
raise "Config file not found at path '#{path}'".red unless File.exists?(path.to_s)
|
|
10
|
-
|
|
11
|
-
self.path = path
|
|
12
|
-
|
|
13
|
-
@config = config
|
|
14
|
-
|
|
15
|
-
eval(File.read(self.path))
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def method_missing(method_sym, *arguments, &block)
|
|
19
|
-
if ["setup", "teardown"].any?{|a| method_sym.to_s.include?a }
|
|
20
|
-
value = nil # this is a block
|
|
21
|
-
else
|
|
22
|
-
value = arguments.first || (block.call if block_given?) # this is either a block or a value
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
case method_sym
|
|
26
|
-
when :devices
|
|
27
|
-
raise "Devices has to be an array".red unless value.kind_of?Array
|
|
28
|
-
@config.devices = value
|
|
29
|
-
when :languages
|
|
30
|
-
@config.languages = value
|
|
31
|
-
when :ios_version
|
|
32
|
-
raise "ios_version has to be an String".red unless value.kind_of?String
|
|
33
|
-
@config.ios_version = value
|
|
34
|
-
when :scheme
|
|
35
|
-
raise "scheme has to be an String".red unless value.kind_of?String
|
|
36
|
-
@config.manual_scheme = value
|
|
37
|
-
when :js_file
|
|
38
|
-
raise "js_file has to be an String".red unless value.kind_of?String
|
|
39
|
-
raise "js_file at path '#{value}' not found".red unless File.exists?value
|
|
40
|
-
@config.manual_js_file = File.expand_path(value)
|
|
41
|
-
when :screenshots_path
|
|
42
|
-
raise "screenshots_path has to be an String".red unless value.kind_of?String
|
|
43
|
-
@config.screenshots_path = File.expand_path(value)
|
|
44
|
-
when :build_command
|
|
45
|
-
raise "build_command has to be an String".red unless value.kind_of?String
|
|
46
|
-
@config.build_command = value
|
|
47
|
-
when :build_dir
|
|
48
|
-
raise "build_dir has to be an String".red unless value.kind_of?String
|
|
49
|
-
@config.build_dir = File.expand_path(value)
|
|
50
|
-
when :custom_args
|
|
51
|
-
raise "custom_args has to be an String".red unless value.kind_of?String
|
|
52
|
-
@config.custom_args = value
|
|
53
|
-
when :custom_build_args
|
|
54
|
-
raise "custom_build_args has to be an String".red unless value.kind_of?String
|
|
55
|
-
@config.custom_build_args = value
|
|
56
|
-
when :custom_run_args
|
|
57
|
-
raise "custom_run_args has to be an String".red unless value.kind_of?String
|
|
58
|
-
@config.custom_run_args = value
|
|
59
|
-
when :skip_alpha_removal
|
|
60
|
-
@config.skip_alpha_removal = true
|
|
61
|
-
when :clear_previous_screenshots
|
|
62
|
-
@config.clear_previous_screenshots = true
|
|
63
|
-
when :project_path
|
|
64
|
-
raise "project_path has to be an String".red unless value.kind_of?String
|
|
65
|
-
|
|
66
|
-
path = File.expand_path(value)
|
|
67
|
-
if File.exists?path and (path.end_with?".xcworkspace" or path.end_with?".xcodeproj")
|
|
68
|
-
@config.project_path = path
|
|
69
|
-
else
|
|
70
|
-
raise "The given project_path '#{path}' could not be found. Make sure to include the extension as well.".red
|
|
71
|
-
end
|
|
72
|
-
when :html_path
|
|
73
|
-
raise "The `html_path` options was removed from snapshot. The default location is now the screenshots path. Please remove this line from your 'Snapfile'.".red
|
|
74
|
-
# Blocks
|
|
75
|
-
when :setup_for_device_change, :teardown_device, :setup_for_language_change, :teardown_language
|
|
76
|
-
raise "#{method_sym} needs to have a block provided." unless block_given?
|
|
77
|
-
Helper.log.warn("'setup_for_language_change' and 'teardown_language' are deprecated.".yellow) if [:setup_for_language_change, :teardown_language].include?method_sym
|
|
78
|
-
@config.blocks[method_sym] = block
|
|
79
|
-
when :html_title
|
|
80
|
-
raise "html_title has to be an String".red unless value.kind_of?String
|
|
81
|
-
@config.html_title = value
|
|
82
|
-
else
|
|
83
|
-
Helper.log.error "Unknown method #{method_sym}"
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|