diffux_ci 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f25586ff4d7dd99dbe60ef93c34fb501f1c61447
4
- data.tar.gz: 0b16cf2a646f2fd16467f7bab6eca4d5a18f1b34
3
+ metadata.gz: 655dc75096ce2012e0e6f1ccd231d57c086d4d7b
4
+ data.tar.gz: 8f3a8617e9b91e630efd7c8ba79b323dcff33c2f
5
5
  SHA512:
6
- metadata.gz: 0b6d5127b86bb9024e84d660f19eeafd933f902ca78dcde1b5b59b3fb1742fbfbf5122d8d099639691db913a522acc175a1418f2a195e5969a3cc3b2454ca730
7
- data.tar.gz: 0ca9eb6f83b7419d5ec05d9d4cc17fe251cd2ad8fe14460f32a9f446ffa2c6161ed79fe804db1f7c4cbab3c67004ee8bd0e08bcd278b8c53b42aead87a49d1cf
6
+ metadata.gz: f6f420363c7def23d0115ebc21a12782f68c2863a7888a423cc15342a4c86d882f00779b379b34b3b585bbe36ead7033c98f042f47f537cc4201286af60ad6eb
7
+ data.tar.gz: 9497fc103436f030f9b2978496707e6ad4be3de35fc6cbfc7da9650203e149b8359f6eeaffc26402a59006829cc00cd7dd60647401b4338c60286ef8a5279c02
data/bin/diffux CHANGED
@@ -1,9 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'diffux_ci_utils'
4
- require 'diffux_ci_action'
5
- require 'diffux_ci_uploader'
6
- require 'diffux_ci_version'
3
+ require 'diffux_ci'
7
4
  require 'fileutils'
8
5
 
9
6
  help_text = <<-EOS
@@ -24,22 +21,22 @@ case action
24
21
  when 'run'
25
22
  Thread.abort_on_exception = true
26
23
  Thread.new do
27
- require 'diffux_ci_runner'
24
+ require 'diffux_ci/runner'
28
25
  exit
29
26
  end
30
- require 'diffux_ci_server'
27
+ require 'diffux_ci/server'
31
28
 
32
29
  when 'debug'
33
- system 'open', DiffuxCIUtils.construct_url('/debug')
34
- require 'diffux_ci_server'
30
+ system 'open', DiffuxCI::Utils.construct_url('/debug')
31
+ require 'diffux_ci/server'
35
32
 
36
33
  when 'review'
37
- system 'open', DiffuxCIUtils.construct_url('/review')
38
- require 'diffux_ci_server'
34
+ system 'open', DiffuxCI::Utils.construct_url('/review')
35
+ require 'diffux_ci/server'
39
36
 
40
37
  when 'clean'
41
- if File.directory? DiffuxCIUtils.config['snapshots_folder']
42
- FileUtils.remove_entry_secure DiffuxCIUtils.config['snapshots_folder']
38
+ if File.directory? DiffuxCI::Utils.config['snapshots_folder']
39
+ FileUtils.remove_entry_secure DiffuxCI::Utils.config['snapshots_folder']
43
40
  end
44
41
 
45
42
  when 'approve', 'reject'
@@ -47,11 +44,11 @@ when 'approve', 'reject'
47
44
  abort 'Missing example description' unless example_description
48
45
  viewport_name = ARGV[2]
49
46
  abort 'Missing viewport name' unless viewport_name
50
- DiffuxCIAction.new(example_description, viewport_name).send(action)
47
+ DiffuxCI::Action.new(example_description, viewport_name).send(action)
51
48
 
52
49
  when 'upload_diffs'
53
50
  # `upload_diffs` returns a URL to a static html file
54
- puts DiffuxCIUploader.new.upload_diffs
51
+ puts DiffuxCI::Uploader.new.upload_diffs
55
52
 
56
53
  when '--version'
57
54
  puts "diffux_ci version #{DiffuxCI::VERSION}"
@@ -0,0 +1,33 @@
1
+ require 'diffux_ci/utils'
2
+ require 'fileutils'
3
+
4
+ module DiffuxCI
5
+ class Action
6
+ def initialize(example_description, viewport_name)
7
+ @example_description = example_description
8
+ @viewport_name = viewport_name
9
+ end
10
+
11
+ def approve
12
+ diff_path = DiffuxCI::Utils.path_to(
13
+ @example_description, @viewport_name, 'diff.png')
14
+ baseline_path = DiffuxCI::Utils.path_to(
15
+ @example_description, @viewport_name, 'baseline.png')
16
+ candidate_path = DiffuxCI::Utils.path_to(
17
+ @example_description, @viewport_name, 'candidate.png')
18
+
19
+ FileUtils.rm(diff_path, force: true)
20
+ FileUtils.mv(candidate_path, baseline_path) if File.exist? candidate_path
21
+ end
22
+
23
+ def reject
24
+ diff_path = DiffuxCI::Utils.path_to(
25
+ @example_description, @viewport_name, 'diff.png')
26
+ candidate_path = DiffuxCI::Utils.path_to(
27
+ @example_description, @viewport_name, 'candidate.png')
28
+
29
+ FileUtils.rm(diff_path, force: true)
30
+ FileUtils.rm(candidate_path, force: true)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ module DiffuxCI
2
+ # Used for all CLI output
3
+ class Logger
4
+ # @param out [IO] the output destination
5
+ def initialize(out = STDOUT)
6
+ @out = out
7
+ end
8
+
9
+ # Print the specified output
10
+ # @param str [String] the output to send
11
+ # @param newline [Boolean] whether to append a newline
12
+ def log(str, newline = true)
13
+ @out.print(str)
14
+ @out.print("\n") if newline
15
+ end
16
+
17
+ # Mark the string in cyan
18
+ # @param str [String] the str to format
19
+ def cyan(str)
20
+ color(36, str)
21
+ end
22
+
23
+ private
24
+
25
+ # Whether this logger is outputting to a TTY
26
+ #
27
+ # @return [Boolean]
28
+ def tty?
29
+ @out.respond_to?(:tty?) && @out.tty?
30
+ end
31
+
32
+ # Mark the string in a color
33
+ # @see http://ascii-table.com/ansi-escape-sequences.php
34
+ # @param color_code [Number] the ANSI color code
35
+ # @param str [String] the str to format
36
+ def color(color_code, str)
37
+ tty? ? str : "\033[#{color_code}m#{str}\033[0m"
38
+ end
39
+ end
40
+ end
@@ -101,7 +101,7 @@ window.diffux = {
101
101
  *
102
102
  * @param {String} exampleDescription
103
103
  * @param {Function} doneFunc injected by driver.execute_async_script in
104
- * diffux_ci_runner.rb
104
+ * diffux_ci/runner.rb
105
105
  */
106
106
  renderExample: function(exampleDescription, doneFunc) {
107
107
  try {
@@ -6,12 +6,12 @@ require 'diffux_core/snapshot_comparison_image/before'
6
6
  require 'diffux_core/snapshot_comparison_image/overlayed'
7
7
  require 'diffux_core/snapshot_comparison_image/after'
8
8
  require 'oily_png'
9
- require 'diffux_ci_utils'
9
+ require 'diffux_ci'
10
10
  require 'fileutils'
11
11
  require 'yaml'
12
12
 
13
13
  def resolve_viewports(example)
14
- configured_viewports = DiffuxCIUtils.config['viewports']
14
+ configured_viewports = DiffuxCI::Utils.config['viewports']
15
15
 
16
16
  viewports =
17
17
  example['options']['viewports'] || [configured_viewports.first.first]
@@ -24,7 +24,7 @@ end
24
24
  def init_driver
25
25
  tries = 0
26
26
  begin
27
- driver = Selenium::WebDriver.for DiffuxCIUtils.config['driver'].to_sym
27
+ driver = Selenium::WebDriver.for DiffuxCI::Utils.config['driver'].to_sym
28
28
  rescue Selenium::WebDriver::Error::WebDriverError => e
29
29
  # "unable to obtain stable firefox connection in 60 seconds"
30
30
  #
@@ -40,10 +40,11 @@ def init_driver
40
40
  driver
41
41
  end
42
42
 
43
+ log = DiffuxCI::Logger.new(STDOUT)
43
44
  driver = init_driver
44
45
 
45
46
  begin
46
- driver.navigate.to DiffuxCIUtils.construct_url('/')
47
+ driver.navigate.to DiffuxCI::Utils.construct_url('/')
47
48
 
48
49
  # Check for errors during startup
49
50
  errors = driver.execute_script('return window.diffux.errors;')
@@ -80,21 +81,21 @@ begin
80
81
  viewport = example_by_viewport[:viewport]
81
82
  examples = example_by_viewport[:examples]
82
83
 
83
- puts "#{viewport['name']} (#{viewport['width']}x#{viewport['height']})"
84
+ log.log "#{viewport['name']} (#{viewport['width']}x#{viewport['height']})"
84
85
 
85
86
  # Resize window to the right size before rendering
86
87
  driver.manage.window.resize_to(viewport['width'], viewport['height'])
87
88
 
88
89
  examples.each do |example|
89
90
  if example == examples.last
90
- print '└─ '
91
+ log.log '└─ ', false
91
92
  else
92
- print '├─ '
93
+ log.log '├─ ', false
93
94
  end
94
95
  description = example['description']
95
- print " #{description} "
96
+ log.log " #{description} ", false
96
97
 
97
- print '.'
98
+ log.log '.', false
98
99
 
99
100
  # Render the example
100
101
 
@@ -114,20 +115,20 @@ begin
114
115
  window.diffux.renderExample(arguments[0], doneFunc);
115
116
  EOS
116
117
  rendered = driver.execute_async_script(script, description)
117
- print '.'
118
+ log.log '.', false
118
119
 
119
120
  if rendered['error']
120
121
  fail <<-EOS
121
122
  Error while rendering "#{description}" @#{viewport['name']}:
122
123
  #{rendered['error']}
123
124
  Debug by pointing your browser to
124
- #{DiffuxCIUtils.construct_url('/', description: description)}
125
+ #{DiffuxCI::Utils.construct_url('/', description: description)}
125
126
  EOS
126
127
  end
127
128
 
128
129
  # Crop the screenshot to the size of the rendered element
129
130
  screenshot = ChunkyPNG::Image.from_blob(driver.screenshot_as(:png))
130
- print '.'
131
+ log.log '.', false
131
132
 
132
133
  # In our JavaScript we are rounding up, which can sometimes give us a
133
134
  # dimensions that are larger than the screenshot dimensions. We need to
@@ -146,11 +147,11 @@ begin
146
147
  rendered['top'],
147
148
  crop_width,
148
149
  crop_height)
149
- print '.'
150
+ log.log '.', false
150
151
  end
151
152
 
152
153
  # Run the diff if needed
153
- baseline_path = DiffuxCIUtils.path_to(
154
+ baseline_path = DiffuxCI::Utils.path_to(
154
155
  description, viewport['name'], 'baseline.png')
155
156
 
156
157
  if File.exist? baseline_path
@@ -160,23 +161,24 @@ begin
160
161
  ChunkyPNG::Image.from_file(baseline_path),
161
162
  screenshot
162
163
  ).compare!
163
- print '.'
164
+ log.log '.', false
164
165
 
165
166
  if comparison[:diff_image]
166
167
  # There was a visual difference between the new snapshot and the
167
168
  # baseline, so we want to write the diff image and the new snapshot
168
169
  # image to disk. This will allow it to be reviewed by someone.
169
- diff_path = DiffuxCIUtils.path_to(
170
+ diff_path = DiffuxCI::Utils.path_to(
170
171
  description, viewport['name'], 'diff.png')
171
172
  comparison[:diff_image].save(diff_path, :fast_rgba)
172
- print '.'
173
+ log.log '.', false
173
174
 
174
- candidate_path = DiffuxCIUtils.path_to(
175
+ candidate_path = DiffuxCI::Utils.path_to(
175
176
  description, viewport['name'], 'candidate.png')
176
177
  screenshot.save(candidate_path, :fast_rgba)
177
- print '.'
178
+ log.log '.', false
178
179
 
179
- puts " #{comparison[:diff_in_percent].round(1)}% (#{candidate_path})"
180
+ percent = comparison[:diff_in_percent].round(1)
181
+ log.log log.cyan(" #{percent}% (#{candidate_path})")
180
182
  result_summary[:diff_examples] << {
181
183
  description: description,
182
184
  viewport: viewport['name']
@@ -184,7 +186,7 @@ begin
184
186
  else
185
187
  # No visual difference was found, so we don't need to do any more
186
188
  # work.
187
- puts ' No diff.'
189
+ log.log ' No diff.'
188
190
  result_summary[:okay_examples] << {
189
191
  description: description,
190
192
  viewport: viewport['name']
@@ -199,8 +201,8 @@ begin
199
201
  FileUtils.mkdir_p(dirname)
200
202
  end
201
203
  screenshot.save(baseline_path, :fast_rgba)
202
- print '.'
203
- puts " First snapshot created (#{baseline_path})"
204
+ log.log '.', false
205
+ log.log " First snapshot created (#{baseline_path})"
204
206
  result_summary[:new_examples] << {
205
207
  description: description,
206
208
  viewport: viewport['name']
@@ -209,7 +211,7 @@ begin
209
211
  end
210
212
  end
211
213
 
212
- result_summary_file = File.join(DiffuxCIUtils.config['snapshots_folder'],
214
+ result_summary_file = File.join(DiffuxCI::Utils.config['snapshots_folder'],
213
215
  'result_summary.yaml')
214
216
  File.open(result_summary_file, 'w') do |file|
215
217
  file.write result_summary.to_yaml
@@ -0,0 +1,53 @@
1
+ require 'sinatra/base'
2
+ require 'yaml'
3
+
4
+ module DiffuxCI
5
+ class Server < Sinatra::Base
6
+ configure do
7
+ enable :static
8
+ set :port, DiffuxCI::Utils.config['port']
9
+ end
10
+
11
+ helpers do
12
+ def h(text)
13
+ Rack::Utils.escape_html(text)
14
+ end
15
+ end
16
+
17
+ get '/' do
18
+ @config = DiffuxCI::Utils.config
19
+ erb :index
20
+ end
21
+
22
+ get '/debug' do
23
+ @config = DiffuxCI::Utils.config
24
+ erb :debug
25
+ end
26
+
27
+ get '/review' do
28
+ @snapshots = DiffuxCI::Utils.current_snapshots
29
+ erb :review
30
+ end
31
+
32
+ get '/resource' do
33
+ file = params[:file]
34
+ if file.start_with? 'http'
35
+ redirect file
36
+ else
37
+ send_file file
38
+ end
39
+ end
40
+
41
+ post '/reject' do
42
+ DiffuxCI::Action.new(params[:description], params[:viewport]).reject
43
+ redirect back
44
+ end
45
+
46
+ post '/approve' do
47
+ DiffuxCI::Action.new(params[:description], params[:viewport]).approve
48
+ redirect back
49
+ end
50
+
51
+ run!
52
+ end
53
+ end
@@ -0,0 +1,70 @@
1
+ require 's3'
2
+ require 'securerandom'
3
+
4
+ module DiffuxCI
5
+ class Uploader
6
+ def initialize
7
+ @s3_access_key_id = DiffuxCI::Utils.config['s3_access_key_id']
8
+ @s3_secret_access_key = DiffuxCI::Utils.config['s3_secret_access_key']
9
+ @s3_bucket_name = DiffuxCI::Utils.config['s3_bucket_name']
10
+ end
11
+
12
+ def upload_diffs
13
+ result_summary = YAML.load(File.read(File.join(
14
+ DiffuxCI::Utils.config['snapshots_folder'], 'result_summary.yaml')))
15
+
16
+ return [] if result_summary[:diff_examples].empty? &&
17
+ result_summary[:new_examples].empty?
18
+
19
+ bucket = find_or_build_bucket
20
+ dir = SecureRandom.uuid
21
+
22
+ diff_images = result_summary[:diff_examples].map do |diff|
23
+ image = bucket.objects.build(
24
+ "#{dir}/#{diff[:description]}_#{diff[:viewport]}.png")
25
+ image.content = open(DiffuxCI::Utils.path_to(diff[:description],
26
+ diff[:viewport],
27
+ 'diff.png'))
28
+ image.content_type = 'image/png'
29
+ image.save
30
+ diff[:url] = image.url
31
+ diff
32
+ end
33
+
34
+ new_images = result_summary[:new_examples].map do |example|
35
+ image = bucket.objects.build(
36
+ "#{dir}/#{example[:description]}_#{example[:viewport]}.png")
37
+ image.content = open(DiffuxCI::Utils.path_to(example[:description],
38
+ example[:viewport],
39
+ 'baseline.png'))
40
+ image.content_type = 'image/png'
41
+ image.save
42
+ example[:url] = image.url
43
+ example
44
+ end
45
+
46
+ html = bucket.objects.build("#{dir}/index.html")
47
+ path = File.expand_path(
48
+ File.join(File.dirname(__FILE__), 'diffs.html.erb'))
49
+ html.content = ERB.new(File.read(path)).result(binding)
50
+ html.content_type = 'text/html'
51
+ html.save
52
+ html.url
53
+ end
54
+
55
+ private
56
+
57
+ def find_or_build_bucket
58
+ service = S3::Service.new(access_key_id: @s3_access_key_id,
59
+ secret_access_key: @s3_secret_access_key)
60
+ bucket = service.buckets.find(@s3_bucket_name)
61
+
62
+ if bucket.nil?
63
+ bucket = service.buckets.build(@s3_bucket_name)
64
+ bucket.save(location: :us)
65
+ end
66
+
67
+ bucket
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,80 @@
1
+ require 'yaml'
2
+ require 'erb'
3
+ require 'uri'
4
+ require 'base64'
5
+
6
+ module DiffuxCI
7
+ class Utils
8
+ def self.config
9
+ @@config ||= {
10
+ 'snapshots_folder' => './snapshots',
11
+ 'source_files' => [],
12
+ 'stylesheets' => [],
13
+ 'port' => 4567,
14
+ 'driver' => :firefox,
15
+ 'viewports' => {
16
+ 'large' => {
17
+ 'width' => 1024,
18
+ 'height' => 768
19
+ },
20
+ 'medium' => {
21
+ 'width' => 640,
22
+ 'height' => 888
23
+ },
24
+ 'small' => {
25
+ 'width' => 320,
26
+ 'height' => 444
27
+ }
28
+ }
29
+ }.merge(config_from_file)
30
+ end
31
+
32
+ def self.config_from_file
33
+ config_file_name = ENV['DIFFUX_CI_CONFIG_FILE'] || '.diffux_ci.yaml'
34
+ YAML.load(ERB.new(File.read(config_file_name)).result)
35
+ end
36
+
37
+ def self.normalize_description(description)
38
+ Base64.encode64(description).strip
39
+ end
40
+
41
+ def self.path_to(description, viewport_name, file_name)
42
+ File.join(
43
+ config['snapshots_folder'],
44
+ normalize_description(description),
45
+ "@#{viewport_name}",
46
+ file_name
47
+ )
48
+ end
49
+
50
+ def self.construct_url(absolute_path, params = {})
51
+ query = URI.encode_www_form(params) unless params.empty?
52
+
53
+ URI::HTTP.build(host: 'localhost',
54
+ port: config['port'],
55
+ path: absolute_path,
56
+ query: query).to_s
57
+ end
58
+
59
+ def self.current_snapshots
60
+ prepare_file = lambda do |file|
61
+ viewport_dir = File.expand_path('..', file)
62
+ description_dir = File.expand_path('..', viewport_dir)
63
+ {
64
+ description: Base64.decode64(File.basename(description_dir)),
65
+ viewport: File.basename(viewport_dir).sub('@', ''),
66
+ file: file
67
+ }
68
+ end
69
+
70
+ snapshots_folder = DiffuxCI::Utils.config['snapshots_folder']
71
+ diff_files = Dir.glob("#{snapshots_folder}/**/diff.png")
72
+ baselines = Dir.glob("#{snapshots_folder}/**/baseline.png")
73
+
74
+ {
75
+ diffs: diff_files.map(&prepare_file),
76
+ baselines: baselines.map(&prepare_file)
77
+ }
78
+ end
79
+ end
80
+ end
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module DiffuxCI
3
- VERSION = '0.4.3'
3
+ VERSION = '0.4.4'
4
4
  end
File without changes
File without changes
File without changes
data/lib/diffux_ci.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'diffux_ci/utils'
2
+ require 'diffux_ci/action'
3
+ require 'diffux_ci/uploader'
4
+ require 'diffux_ci/version'
5
+ require 'diffux_ci/logger'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diffux_ci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henric Trotzig
@@ -51,20 +51,20 @@ dependencies:
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.44'
54
+ version: '2.53'
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
- version: 2.44.0
57
+ version: 2.53.0
58
58
  type: :runtime
59
59
  prerelease: false
60
60
  version_requirements: !ruby/object:Gem::Requirement
61
61
  requirements:
62
62
  - - "~>"
63
63
  - !ruby/object:Gem::Version
64
- version: '2.44'
64
+ version: '2.53'
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: 2.44.0
67
+ version: 2.53.0
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: thin
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -135,19 +135,21 @@ extensions: []
135
135
  extra_rdoc_files: []
136
136
  files:
137
137
  - bin/diffux
138
- - lib/diffux_ci-diffs.html.erb
139
- - lib/diffux_ci_action.rb
140
- - lib/diffux_ci_runner.rb
141
- - lib/diffux_ci_server.rb
142
- - lib/diffux_ci_uploader.rb
143
- - lib/diffux_ci_utils.rb
144
- - lib/diffux_ci_version.rb
145
- - lib/public/diffux_ci-runner.js
138
+ - lib/diffux_ci.rb
139
+ - lib/diffux_ci/action.rb
140
+ - lib/diffux_ci/diffs.html.erb
141
+ - lib/diffux_ci/logger.rb
142
+ - lib/diffux_ci/public/diffux_ci-runner.js
143
+ - lib/diffux_ci/public/diffux_ci-styles.css
144
+ - lib/diffux_ci/runner.rb
145
+ - lib/diffux_ci/server.rb
146
+ - lib/diffux_ci/uploader.rb
147
+ - lib/diffux_ci/utils.rb
148
+ - lib/diffux_ci/version.rb
149
+ - lib/diffux_ci/views/debug.erb
150
+ - lib/diffux_ci/views/index.erb
151
+ - lib/diffux_ci/views/review.erb
146
152
  - lib/public/diffux_ci-scripts.js
147
- - lib/public/diffux_ci-styles.css
148
- - lib/views/debug.erb
149
- - lib/views/index.erb
150
- - lib/views/review.erb
151
153
  homepage: http://rubygems.org/gems/diffux_ci
152
154
  licenses:
153
155
  - MIT
@@ -168,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
170
  version: '0'
169
171
  requirements: []
170
172
  rubyforge_project:
171
- rubygems_version: 2.4.5.1
173
+ rubygems_version: 2.5.1
172
174
  signing_key:
173
175
  specification_version: 4
174
176
  summary: Diffux-CI
@@ -1,31 +0,0 @@
1
- require 'diffux_ci_utils'
2
- require 'fileutils'
3
-
4
- class DiffuxCIAction
5
- def initialize(example_description, viewport_name)
6
- @example_description = example_description
7
- @viewport_name = viewport_name
8
- end
9
-
10
- def approve
11
- diff_path = DiffuxCIUtils.path_to(
12
- @example_description, @viewport_name, 'diff.png')
13
- baseline_path = DiffuxCIUtils.path_to(
14
- @example_description, @viewport_name, 'baseline.png')
15
- candidate_path = DiffuxCIUtils.path_to(
16
- @example_description, @viewport_name, 'candidate.png')
17
-
18
- FileUtils.rm(diff_path, force: true)
19
- FileUtils.mv(candidate_path, baseline_path) if File.exist? candidate_path
20
- end
21
-
22
- def reject
23
- diff_path = DiffuxCIUtils.path_to(
24
- @example_description, @viewport_name, 'diff.png')
25
- candidate_path = DiffuxCIUtils.path_to(
26
- @example_description, @viewport_name, 'candidate.png')
27
-
28
- FileUtils.rm(diff_path, force: true)
29
- FileUtils.rm(candidate_path, force: true)
30
- end
31
- end
@@ -1,53 +0,0 @@
1
- require 'sinatra/base'
2
- require 'yaml'
3
- require 'diffux_ci_utils'
4
- require 'diffux_ci_action'
5
-
6
- class DiffuxCIServer < Sinatra::Base
7
- configure do
8
- enable :static
9
- set :port, DiffuxCIUtils.config['port']
10
- end
11
-
12
- helpers do
13
- def h(text)
14
- Rack::Utils.escape_html(text)
15
- end
16
- end
17
-
18
- get '/' do
19
- @config = DiffuxCIUtils.config
20
- erb :index
21
- end
22
-
23
- get '/debug' do
24
- @config = DiffuxCIUtils.config
25
- erb :debug
26
- end
27
-
28
- get '/review' do
29
- @snapshots = DiffuxCIUtils.current_snapshots
30
- erb :review
31
- end
32
-
33
- get '/resource' do
34
- file = params[:file]
35
- if file.start_with? 'http'
36
- redirect file
37
- else
38
- send_file file
39
- end
40
- end
41
-
42
- post '/reject' do
43
- DiffuxCIAction.new(params[:description], params[:viewport]).reject
44
- redirect back
45
- end
46
-
47
- post '/approve' do
48
- DiffuxCIAction.new(params[:description], params[:viewport]).approve
49
- redirect back
50
- end
51
-
52
- run!
53
- end
@@ -1,69 +0,0 @@
1
- require 'diffux_ci_utils'
2
- require 's3'
3
- require 'securerandom'
4
-
5
- class DiffuxCIUploader
6
- def initialize
7
- @s3_access_key_id = DiffuxCIUtils.config['s3_access_key_id']
8
- @s3_secret_access_key = DiffuxCIUtils.config['s3_secret_access_key']
9
- @s3_bucket_name = DiffuxCIUtils.config['s3_bucket_name']
10
- end
11
-
12
- def upload_diffs
13
- result_summary = YAML.load(File.read(File.join(
14
- DiffuxCIUtils.config['snapshots_folder'], 'result_summary.yaml')))
15
-
16
- return [] if result_summary[:diff_examples].empty? &&
17
- result_summary[:new_examples].empty?
18
-
19
- bucket = find_or_build_bucket
20
- dir = SecureRandom.uuid
21
-
22
- diff_images = result_summary[:diff_examples].map do |diff|
23
- image = bucket.objects.build(
24
- "#{dir}/#{diff[:description]}_#{diff[:viewport]}.png")
25
- image.content = open(DiffuxCIUtils.path_to(diff[:description],
26
- diff[:viewport],
27
- 'diff.png'))
28
- image.content_type = 'image/png'
29
- image.save
30
- diff[:url] = image.url
31
- diff
32
- end
33
-
34
- new_images = result_summary[:new_examples].map do |example|
35
- image = bucket.objects.build(
36
- "#{dir}/#{example[:description]}_#{example[:viewport]}.png")
37
- image.content = open(DiffuxCIUtils.path_to(example[:description],
38
- example[:viewport],
39
- 'baseline.png'))
40
- image.content_type = 'image/png'
41
- image.save
42
- example[:url] = image.url
43
- example
44
- end
45
-
46
- html = bucket.objects.build("#{dir}/index.html")
47
- path = File.expand_path(
48
- File.join(File.dirname(__FILE__), 'diffux_ci-diffs.html.erb'))
49
- html.content = ERB.new(File.read(path)).result(binding)
50
- html.content_type = 'text/html'
51
- html.save
52
- html.url
53
- end
54
-
55
- private
56
-
57
- def find_or_build_bucket
58
- service = S3::Service.new(access_key_id: @s3_access_key_id,
59
- secret_access_key: @s3_secret_access_key)
60
- bucket = service.buckets.find(@s3_bucket_name)
61
-
62
- if bucket.nil?
63
- bucket = service.buckets.build(@s3_bucket_name)
64
- bucket.save(location: :us)
65
- end
66
-
67
- bucket
68
- end
69
- end
@@ -1,78 +0,0 @@
1
- require 'yaml'
2
- require 'erb'
3
- require 'uri'
4
- require 'base64'
5
-
6
- class DiffuxCIUtils
7
- def self.config
8
- @@config ||= {
9
- 'snapshots_folder' => './snapshots',
10
- 'source_files' => [],
11
- 'stylesheets' => [],
12
- 'port' => 4567,
13
- 'driver' => :firefox,
14
- 'viewports' => {
15
- 'large' => {
16
- 'width' => 1024,
17
- 'height' => 768
18
- },
19
- 'medium' => {
20
- 'width' => 640,
21
- 'height' => 888
22
- },
23
- 'small' => {
24
- 'width' => 320,
25
- 'height' => 444
26
- }
27
- }
28
- }.merge(config_from_file)
29
- end
30
-
31
- def self.config_from_file
32
- config_file_name = ENV['DIFFUX_CI_CONFIG_FILE'] || '.diffux_ci.yaml'
33
- YAML.load(ERB.new(File.read(config_file_name)).result)
34
- end
35
-
36
- def self.normalize_description(description)
37
- Base64.encode64(description).strip
38
- end
39
-
40
- def self.path_to(description, viewport_name, file_name)
41
- File.join(
42
- config['snapshots_folder'],
43
- normalize_description(description),
44
- "@#{viewport_name}",
45
- file_name
46
- )
47
- end
48
-
49
- def self.construct_url(absolute_path, params = {})
50
- query = URI.encode_www_form(params) unless params.empty?
51
-
52
- URI::HTTP.build(host: 'localhost',
53
- port: config['port'],
54
- path: absolute_path,
55
- query: query).to_s
56
- end
57
-
58
- def self.current_snapshots
59
- prepare_file = lambda do |file|
60
- viewport_dir = File.expand_path('..', file)
61
- description_dir = File.expand_path('..', viewport_dir)
62
- {
63
- description: Base64.decode64(File.basename(description_dir)),
64
- viewport: File.basename(viewport_dir).sub('@', ''),
65
- file: file
66
- }
67
- end
68
-
69
- snapshots_folder = DiffuxCIUtils.config['snapshots_folder']
70
- diff_files = Dir.glob("#{snapshots_folder}/**/diff.png")
71
- baselines = Dir.glob("#{snapshots_folder}/**/baseline.png")
72
-
73
- {
74
- diffs: diff_files.map(&prepare_file),
75
- baselines: baselines.map(&prepare_file)
76
- }
77
- end
78
- end