diffux_ci 0.4.3 → 0.4.4

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