diffux_ci 0.1.0 → 0.2.0

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: 0e45d93f1149b5ad73fe788533dc5ed95d737732
4
- data.tar.gz: de408672cf9cb59e357e9f08243b7a03760c60a3
3
+ metadata.gz: 2670d7b6c223c5706a067d1ca10528f02a7b4e7d
4
+ data.tar.gz: 1192da6f79d208279ef7fba9ae5ac8339f425893
5
5
  SHA512:
6
- metadata.gz: c1f8b36ff77a17db7742e695982346a7f8fc667c715888af935b3696de3bcd6ff589f37c98ca3fc28dc8c1b953929344b84d14d68222fe575374a69bd4bf04a2
7
- data.tar.gz: 50f65df9ec4732dc4451002c33fdae827c872ebd49a713eaea2a8c09eea67208d4f284a251d8cba0e132fad5355d4a0de137cde60aef9cd5d4e3005a168bd47e
6
+ metadata.gz: d09b57e16639125db313eb1786533bc26899ac703de45d04c4aa558c33588ce6f772ceb17e3d899e5f9c36c5fbd0ec45b64bbf0f224a100b735b90941a3df56f
7
+ data.tar.gz: bc514a8739c934f932393b2face0dbd06f0d7a926561f526ea6baddccb8b18ee7a3f63e296bedfa760197f7e598508c9e5722abd506718983b493de7d3fcee82
data/bin/diffux_ci CHANGED
@@ -15,6 +15,10 @@ when 'run'
15
15
  end
16
16
  require 'diffux_ci_server'
17
17
 
18
+ when 'debug'
19
+ system 'open', DiffuxCIUtils.construct_url('/debug')
20
+ require 'diffux_ci_server'
21
+
18
22
  when 'review'
19
23
  system 'open', DiffuxCIUtils.construct_url('/review')
20
24
  require 'diffux_ci_server'
@@ -25,13 +29,27 @@ when 'clean'
25
29
  end
26
30
 
27
31
  when 'approve', 'reject'
28
- abort 'Missing example name' unless example_name = ARGV[1]
29
- abort 'Missing viewport name' unless viewport_name = ARGV[2]
30
- DiffuxCIAction.new(example_name, viewport_name).send(action)
32
+ example_description = ARGV[1]
33
+ abort 'Missing example description' unless example_description
34
+ viewport_name = ARGV[2]
35
+ abort 'Missing viewport name' unless viewport_name
36
+ DiffuxCIAction.new(example_description, viewport_name).send(action)
31
37
 
32
38
  when 'upload_diffs'
33
39
  # `upload_diffs` returns a URL to a static html file
34
40
  puts DiffuxCIUploader.new.upload_diffs
41
+
42
+ when '--help'
43
+ puts <<-EOS
44
+ Commands:
45
+ run (default)
46
+ debug
47
+ review
48
+ clean
49
+ approve
50
+ reject
51
+ upload_diffs
52
+ EOS
35
53
  else
36
54
  abort "Unknown action \"#{action}\""
37
55
  end
@@ -9,7 +9,7 @@
9
9
 
10
10
  <% diff_images.each do |diff| %>
11
11
  <h3>
12
- <%= diff[:name] %> @ <%= diff[:viewport] %>
12
+ <%= diff[:description] %> @ <%= diff[:viewport] %>
13
13
  </h3>
14
14
  <p><img src="<%= diff[:url] %>"></p>
15
15
  <% end %>
@@ -2,26 +2,28 @@ require 'diffux_ci_utils'
2
2
  require 'fileutils'
3
3
 
4
4
  class DiffuxCIAction
5
- def initialize(example_name, viewport_name)
6
- @example_name = example_name
5
+ def initialize(example_description, viewport_name)
6
+ @example_description = example_description
7
7
  @viewport_name = viewport_name
8
8
  end
9
9
 
10
10
  def approve
11
- diff_path = DiffuxCIUtils.path_to(@example_name, @viewport_name, 'diff.png')
12
- baseline_path = DiffuxCIUtils.path_to(@example_name, @viewport_name, 'baseline.png')
13
- candidate_path = DiffuxCIUtils.path_to(@example_name, @viewport_name, 'candidate.png')
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')
14
17
 
15
18
  FileUtils.rm(diff_path, force: true)
16
-
17
- if File.exist? candidate_path
18
- FileUtils.mv(candidate_path, baseline_path)
19
- end
19
+ FileUtils.mv(candidate_path, baseline_path) if File.exist? candidate_path
20
20
  end
21
21
 
22
22
  def reject
23
- diff_path = DiffuxCIUtils.path_to(@example_name, @viewport_name, 'diff.png')
24
- candidate_path = DiffuxCIUtils.path_to(@example_name, @viewport_name, 'candidate.png')
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')
25
27
 
26
28
  FileUtils.rm(diff_path, force: true)
27
29
  FileUtils.rm(candidate_path, force: true)
@@ -5,26 +5,32 @@ require 'diffux_core/snapshot_comparison_image/gutter'
5
5
  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
- require 'chunky_png'
8
+ require 'oily_png'
9
9
  require 'diffux_ci_utils'
10
10
  require 'fileutils'
11
11
 
12
12
  def resolve_viewports(example)
13
13
  configured_viewports = DiffuxCIUtils.config['viewports']
14
14
 
15
- (example['options']['viewports'] || [configured_viewports.first.first]).map do |viewport|
15
+ viewports =
16
+ example['options']['viewports'] || [configured_viewports.first.first]
17
+
18
+ viewports.map do |viewport|
16
19
  configured_viewports[viewport].merge('name' => viewport)
17
20
  end
18
21
  end
19
22
 
23
+ tries = 0
20
24
  begin
21
25
  driver = Selenium::WebDriver.for DiffuxCIUtils.config['driver'].to_sym
22
- rescue Selenium::WebDriver::Error::WebDriverError
26
+ rescue Selenium::WebDriver::Error::WebDriverError => e
23
27
  # "unable to obtain stable firefox connection in 60 seconds"
24
28
  #
25
29
  # This seems to happen sporadically for some versions of Firefox, so we want
26
- # to retry it in case it will work the second time around.
27
- driver = Selenium::WebDriver.for DiffuxCIUtils.config['driver'].to_sym
30
+ # to retry a couple of times it in case it will work the second time around.
31
+ tries += 1
32
+ retry if tries <= 3
33
+ raise e
28
34
  end
29
35
 
30
36
  begin
@@ -37,8 +43,28 @@ begin
37
43
  fail "JavaScript errors found during initialization: \n#{errors.inspect}"
38
44
  end
39
45
 
46
+ # We use the description of the example to store the snapshot. If a
47
+ # description is duplicated with different code, it can cause seemingly random
48
+ # and confusing differences. To avoid this issue, we want to keep track of the
49
+ # descriptions that we've seen and fail if we come across the same description
50
+ # twice.
51
+ seen_descriptions = {}
52
+
40
53
  while current = driver.execute_script('return window.diffux.next()') do
54
+ description = current['description']
55
+
41
56
  resolve_viewports(current).each do |viewport|
57
+ # Make sure we don't have a duplicate description
58
+ seen_descriptions[description] ||= {}
59
+ if seen_descriptions[description][viewport['name']]
60
+ fail <<-EOS
61
+ Error while rendering "#{description}" @#{viewport['name']}:
62
+ Duplicate description detected
63
+ EOS
64
+ else
65
+ seen_descriptions[description][viewport['name']] = true
66
+ end
67
+
42
68
  # Resize window to the right size before rendering
43
69
  driver.manage.window.resize_to(viewport['width'], viewport['height'])
44
70
 
@@ -63,51 +89,62 @@ begin
63
89
 
64
90
  if rendered['error']
65
91
  fail <<-EOS
66
- Error while rendering "#{current['name']}" @#{viewport['name']}:
92
+ Error while rendering "#{description}" @#{viewport['name']}:
67
93
  #{rendered['error']}
68
94
  Debug by pointing your browser to
69
- #{DiffuxCIUtils.construct_url('/', name: current['name'])}
95
+ #{DiffuxCIUtils.construct_url('/', description: description)}
70
96
  EOS
71
97
  end
72
- output_file = DiffuxCIUtils.path_to(
73
- current['name'], viewport['name'], 'candidate.png')
74
-
75
- # Create the folder structure if it doesn't already exist
76
- unless File.directory?(dirname = File.dirname(output_file))
77
- FileUtils.mkdir_p(dirname)
78
- end
79
98
 
80
- # Save and crop the screenshot
81
- driver.save_screenshot(output_file)
82
- cropped = ChunkyPNG::Image.from_file(output_file)
83
- cropped.crop!(rendered['left'],
84
- rendered['top'],
85
- [rendered['width'], 1].max,
86
- [rendered['height'], 1].max)
87
- cropped.save(output_file)
99
+ # Crop the screenshot to the size of the rendered element
100
+ screenshot = ChunkyPNG::Image.from_blob(driver.screenshot_as(:png))
101
+ screenshot.crop!(rendered['left'],
102
+ rendered['top'],
103
+ [rendered['width'], 1].max,
104
+ [rendered['height'], 1].max)
88
105
 
89
- print "Checking \"#{current['name']}\" at [#{viewport['name']}]... "
106
+ print "Checking \"#{description}\" at [#{viewport['name']}]... "
90
107
 
91
108
  # Run the diff if needed
92
- baseline_file = DiffuxCIUtils.path_to(current['name'], viewport['name'], 'baseline.png')
109
+ baseline_path = DiffuxCIUtils.path_to(
110
+ description, viewport['name'], 'baseline.png')
93
111
 
94
- if File.exist? baseline_file
112
+ if File.exist? baseline_path
113
+ # A baseline image exists, so we want to compare the new snapshot
114
+ # against the baseline.
95
115
  comparison = Diffux::SnapshotComparer.new(
96
- ChunkyPNG::Image.from_file(baseline_file),
97
- cropped
116
+ ChunkyPNG::Image.from_file(baseline_path),
117
+ screenshot
98
118
  ).compare!
99
119
 
100
- if img = comparison[:diff_image]
101
- diff_output = DiffuxCIUtils.path_to(current['name'], viewport['name'], 'diff.png')
102
- img.save(diff_output)
120
+ if comparison[:diff_image]
121
+ # There was a visual difference between the new snapshot and the
122
+ # baseline, so we want to write the diff image and the new snapshot
123
+ # image to disk. This will allow it to be reviewed by someone.
124
+ diff_path = DiffuxCIUtils.path_to(
125
+ description, viewport['name'], 'diff.png')
126
+ comparison[:diff_image].save(diff_path)
127
+
128
+ candidate_path = DiffuxCIUtils.path_to(
129
+ description, viewport['name'], 'candidate.png')
130
+ screenshot.save(candidate_path)
131
+
103
132
  puts "#{comparison[:diff_in_percent].round(1)}% (#{diff_output})"
104
133
  else
105
- File.delete(output_file)
134
+ # No visual difference was found, so we don't need to do any more
135
+ # work.
106
136
  puts 'No diff.'
107
137
  end
108
138
  else
109
- File.rename(output_file, baseline_file)
110
- puts "First snapshot created (#{baseline_file})"
139
+ # There was no baseline image yet, so we want to start by saving a new
140
+ # baseline image.
141
+
142
+ # Create the folder structure if it doesn't already exist
143
+ unless File.directory?(dirname = File.dirname(baseline_path))
144
+ FileUtils.mkdir_p(dirname)
145
+ end
146
+ screenshot.save(baseline_path)
147
+ puts "First snapshot created (#{baseline_path})"
111
148
  end
112
149
  end
113
150
  end
@@ -14,6 +14,11 @@ class DiffuxCIServer < Sinatra::Base
14
14
  erb :index
15
15
  end
16
16
 
17
+ get '/debug' do
18
+ @config = DiffuxCIUtils.config
19
+ erb :debug
20
+ end
21
+
17
22
  get '/review' do
18
23
  @snapshots = DiffuxCIUtils.current_snapshots
19
24
  erb :review
@@ -29,12 +34,12 @@ class DiffuxCIServer < Sinatra::Base
29
34
  end
30
35
 
31
36
  post '/reject' do
32
- DiffuxCIAction.new(params[:name], params[:viewport]).reject
37
+ DiffuxCIAction.new(params[:description], params[:viewport]).reject
33
38
  redirect back
34
39
  end
35
40
 
36
41
  post '/approve' do
37
- DiffuxCIAction.new(params[:name], params[:viewport]).approve
42
+ DiffuxCIAction.new(params[:description], params[:viewport]).approve
38
43
  redirect back
39
44
  end
40
45
 
@@ -19,7 +19,8 @@ class DiffuxCIUploader
19
19
  dir = SecureRandom.uuid
20
20
 
21
21
  diff_images = current_snapshots[:diffs].map do |diff|
22
- image = bucket.objects.build("#{dir}/#{diff[:name]}_#{diff[:viewport]}.png")
22
+ image = bucket.objects.build(
23
+ "#{dir}/#{diff[:description]}_#{diff[:viewport]}.png")
23
24
  image.content = open(diff[:file])
24
25
  image.content_type = 'image/png'
25
26
  image.save
@@ -28,11 +29,9 @@ class DiffuxCIUploader
28
29
  end
29
30
 
30
31
  html = bucket.objects.build("#{dir}/index.html")
31
- html.content =
32
- ERB.new(
33
- File.read(File.expand_path(
34
- File.join(File.dirname(__FILE__), 'diffux_ci-diffs.html.erb')))
35
- ).result(binding)
32
+ path = File.expand_path(
33
+ File.join(File.dirname(__FILE__), 'diffux_ci-diffs.html.erb'))
34
+ html.content = ERB.new(File.read(path)).result(binding)
36
35
  html.content_type = 'text/html'
37
36
  html.save
38
37
  html.url
@@ -3,6 +3,7 @@ require 'erb'
3
3
 
4
4
  class DiffuxCIUtils
5
5
  def self.config
6
+ config_file_name = ENV['DIFFUX_CI_CONFIG_FILE'] || '.diffux_ci.yaml'
6
7
  @@config ||= {
7
8
  'snapshots_folder' => './snapshots',
8
9
  'source_files' => [],
@@ -23,46 +24,44 @@ class DiffuxCIUtils
23
24
  'height' => 444
24
25
  }
25
26
  }
26
- }.merge(YAML.load(ERB.new(File.read(
27
- ENV['DIFFUX_CI_CONFIG_FILE'] || '.diffux_ci.yaml')).result))
27
+ }.merge(YAML.load(ERB.new(File.read(config_file_name)).result))
28
28
  end
29
29
 
30
- def self.normalize_name(name)
31
- name.gsub(/[^a-zA-Z0-9\-_]/, '_')
30
+ def self.normalize_description(description)
31
+ description.gsub(/[^a-zA-Z0-9\-_]/, '_')
32
32
  end
33
33
 
34
- def self.path_to(name, viewport_name, file_name)
34
+ def self.path_to(description, viewport_name, file_name)
35
35
  File.join(
36
36
  config['snapshots_folder'],
37
- normalize_name(name),
37
+ normalize_description(description),
38
38
  "@#{viewport_name}",
39
39
  file_name
40
40
  )
41
41
  end
42
42
 
43
43
  def self.construct_url(absolute_path, params = {})
44
- params_str = params.map do |key, value|
45
- "#{key}=#{URI.escape(value)}"
46
- end.join('&')
47
- unless params_str.empty?
48
- params_str = "?#{params_str}"
49
- end
50
-
51
- return "http://localhost:#{config['port']}#{absolute_path}#{params_str}"
44
+ URI::HTTP.build(host: 'localhost',
45
+ port: config['port'],
46
+ path: absolute_path,
47
+ query: URI.encode_www_form(params))
52
48
  end
53
49
 
54
50
  def self.current_snapshots
55
51
  prepare_file = lambda do |file|
56
52
  viewport_dir = File.expand_path('..', file)
57
- name_dir = File.expand_path('..', viewport_dir)
53
+ description_dir = File.expand_path('..', viewport_dir)
58
54
  {
59
- name: File.basename(name_dir),
55
+ description: File.basename(description_dir),
60
56
  viewport: File.basename(viewport_dir).sub('@', ''),
61
- file: file,
57
+ file: file
62
58
  }
63
59
  end
64
- diff_files = Dir.glob("#{DiffuxCIUtils.config['snapshots_folder']}/**/diff.png")
65
- baselines = Dir.glob("#{DiffuxCIUtils.config['snapshots_folder']}/**/baseline.png")
60
+
61
+ snapshots_folder = DiffuxCIUtils.config['snapshots_folder']
62
+ diff_files = Dir.glob("#{snapshots_folder}/**/diff.png")
63
+ baselines = Dir.glob("#{snapshots_folder}/**/baseline.png")
64
+
66
65
  {
67
66
  diffs: diff_files.map(&prepare_file),
68
67
  baselines: baselines.map(&prepare_file)
@@ -0,0 +1,4 @@
1
+ # Defines the gem version.
2
+ module DiffuxCI
3
+ VERSION = '0.2.0'
4
+ end
@@ -1,3 +1,5 @@
1
+ 'use strict';
2
+
1
3
  window.diffux = {
2
4
  defined: [],
3
5
  currentIndex: 0,
@@ -5,9 +7,9 @@ window.diffux = {
5
7
  currentRenderedElement: undefined,
6
8
  errors: [],
7
9
 
8
- define: function(name, func, options) {
10
+ define: function(description, func, options) {
9
11
  this.defined.push({
10
- name: name,
12
+ description: description,
11
13
  func: func,
12
14
  options: options || {}
13
15
  });
@@ -24,7 +26,8 @@ window.diffux = {
24
26
  if (window.React) {
25
27
  window.React.unmountComponentAtNode(document.body.lastChild);
26
28
  } else {
27
- this.currentRenderedElement.parentNode.removeChild(this.currentRenderedElement);
29
+ this.currentRenderedElement.parentNode
30
+ .removeChild(this.currentRenderedElement);
28
31
  }
29
32
  }
30
33
  this.currentExample = this.defined[this.currentIndex];
@@ -35,31 +38,31 @@ window.diffux = {
35
38
  return this.currentExample;
36
39
  },
37
40
 
38
- setCurrent: function(exampleName) {
41
+ setCurrent: function(exampleDescription) {
39
42
  this.defined.forEach(function(example, index) {
40
- if (example.name === exampleName) {
43
+ if (example.description === exampleDescription) {
41
44
  this.currentExample = example;
42
45
  }
43
46
  }.bind(this));
44
47
  if (!this.currentExample) {
45
- throw 'No example found with name "' + exampleName + '"';
48
+ throw 'No example found with description "' + exampleDescription + '"';
46
49
  }
47
50
  },
48
51
 
49
52
  clearVisibleElements: function() {
50
- var allElements = Array.prototype.slice.call(document.querySelectorAll('body > *'));
51
- allElements.forEach(function(element) {
53
+ var allElements = document.querySelectorAll('body > *');
54
+ for (var element of allElements) {
52
55
  var style = window.getComputedStyle(element);
53
56
  if (style.display !== 'none') {
54
57
  element.parentNode.removeChild(element);
55
58
  }
56
- });
59
+ }
57
60
  },
58
61
 
59
62
  handleError: function(error) {
60
63
  console.error(error);
61
64
  return {
62
- name: this.currentExample.name,
65
+ description: this.currentExample.description,
63
66
  error: error.message
64
67
  };
65
68
  },
@@ -150,7 +153,7 @@ window.diffux = {
150
153
  left = 0;
151
154
  }
152
155
  return {
153
- name: this.currentExample.name,
156
+ description: this.currentExample.description,
154
157
  width: width,
155
158
  height: height,
156
159
  top: top,
@@ -163,13 +166,13 @@ window.diffux = {
163
166
  };
164
167
 
165
168
  window.addEventListener('load', function() {
166
- var matches = window.location.search.match(/name=([^&]*)/);
169
+ var matches = window.location.search.match(/description=([^&]*)/);
167
170
  if (!matches) {
168
171
  return;
169
172
  }
170
173
  var example = decodeURIComponent(matches[1]);
171
174
  window.diffux.setCurrent(example);
172
- window.diffux.renderCurrent();
175
+ window.diffux.renderCurrent(function() {});
173
176
  });
174
177
 
175
178
  // We need to redefine a few global functions that halt execution. Without this,
@@ -177,15 +180,21 @@ window.addEventListener('load', function() {
177
180
  window.alert = function(message) {
178
181
  console.log('`window.alert` called', message);
179
182
  };
183
+
180
184
  window.confirm = function(message) {
181
185
  console.log('`window.confirm` called', message);
182
186
  return true;
183
187
  };
188
+
184
189
  window.prompt = function(message, value) {
185
190
  console.log('`window.prompt` called', message, value);
186
191
  return null;
187
192
  };
188
193
 
189
194
  window.onerror = function(message, url, lineNumber) {
190
- window.diffux.errors.push({ message: message, url: url, lineNumber: lineNumber });
195
+ window.diffux.errors.push({
196
+ message: message,
197
+ url: url,
198
+ lineNumber: lineNumber
199
+ });
191
200
  }
@@ -0,0 +1,8 @@
1
+ body {
2
+ background-color: #f0f0f0;
3
+ font-family: helvetica, arial;
4
+ }
5
+
6
+ form {
7
+ display: inline-block;
8
+ }
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" href="/diffux_ci-styles.css"></link>
5
+ <script src="/diffux_ci-runner.js"></script>
6
+ <% @config['source_files'].each do |source_file| %>
7
+ <script src="/resource?file=<%= ERB::Util.url_encode(source_file) %>"></script>
8
+ <% end %>
9
+ <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
10
+ </head>
11
+ <body>
12
+ <h1>Diffux-CI Debug Tool</h1>
13
+ <p>Click on an item to render that example in isolation.</p>
14
+ <script>
15
+ (function() {
16
+ var ul = $('<ul>');
17
+ $('body').append(ul);
18
+ $.each(diffux.defined, function(_, example) {
19
+ ul.append($('<li>').append(
20
+ $('<a>', {
21
+ href: '/?description=' + encodeURIComponent(example.description)
22
+ }).text(example.description)
23
+ ));
24
+ });
25
+ }());
26
+ </script>
27
+ </body>
28
+ </html>
data/lib/views/review.erb CHANGED
@@ -1,31 +1,23 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <style type="text/css">
5
- body {
6
- background-color: #f0f0f0;
7
- font-family: helvetica, arial;
8
- }
9
- form {
10
- display: inline-block;
11
- }
12
- </style>
4
+ <link rel="stylesheet" href="/diffux_ci-styles.css"></link>
13
5
  </head>
14
6
  <body>
15
7
  <h1>Diffux-CI Review Tool</h1>
16
8
  <h2>DIFFS</h2>
17
9
  <% @snapshots[:diffs].each do |diff| %>
18
10
  <h3>
19
- <%= diff[:name] %> @ <%= diff[:viewport] %>
11
+ <%= diff[:description] %> @ <%= diff[:viewport] %>
20
12
  </h3>
21
13
  <p><img src="/resource?file=<%= ERB::Util.url_encode(diff[:file]) %>"></p>
22
14
  <form style="display: inline-block"
23
- action="/approve?name=<%= diff[:name] %>&viewport=<%= diff[:viewport] %>"
15
+ action="/approve?description=<%= diff[:description] %>&viewport=<%= diff[:viewport] %>"
24
16
  method="POST">
25
17
  <button type="submit">Approve</button>
26
18
  </form>
27
19
  <form style="display: inline-block"
28
- action="/reject?name=<%= diff[:name] %>&viewport=<%= diff[:viewport] %>"
20
+ action="/reject?description=<%= diff[:description] %>&viewport=<%= diff[:viewport] %>"
29
21
  method="POST">
30
22
  <button type="submit">Reject</button>
31
23
  </form>
@@ -36,7 +28,7 @@
36
28
  <h2>BASELINES</h2>
37
29
  <% @snapshots[:baselines].each do |baseline| %>
38
30
  <h3>
39
- <%= baseline[:name] %> @ <%= baseline[:viewport] %>
31
+ <%= baseline[:description] %> @ <%= baseline[:viewport] %>
40
32
  </h3>
41
33
  <p><img src="/resource?file=<%= ERB::Util.url_encode(baseline[:file]) %>"></p>
42
34
  <% end %>
metadata CHANGED
@@ -1,10 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diffux_ci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henric Trotzig
8
+ - Joe Lencioni
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
@@ -31,25 +32,19 @@ dependencies:
31
32
  - !ruby/object:Gem::Version
32
33
  version: 0.0.2
33
34
  - !ruby/object:Gem::Dependency
34
- name: chunky_png
35
+ name: oily_png
35
36
  requirement: !ruby/object:Gem::Requirement
36
37
  requirements:
37
38
  - - "~>"
38
39
  - !ruby/object:Gem::Version
39
- version: '1.3'
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- version: 1.3.4
40
+ version: '1.1'
43
41
  type: :runtime
44
42
  prerelease: false
45
43
  version_requirements: !ruby/object:Gem::Requirement
46
44
  requirements:
47
45
  - - "~>"
48
46
  - !ruby/object:Gem::Version
49
- version: '1.3'
50
- - - ">="
51
- - !ruby/object:Gem::Version
52
- version: 1.3.4
47
+ version: '1.1'
53
48
  - !ruby/object:Gem::Dependency
54
49
  name: selenium-webdriver
55
50
  requirement: !ruby/object:Gem::Requirement
@@ -144,7 +139,10 @@ files:
144
139
  - lib/diffux_ci_server.rb
145
140
  - lib/diffux_ci_uploader.rb
146
141
  - lib/diffux_ci_utils.rb
142
+ - lib/diffux_ci_version.rb
147
143
  - lib/public/diffux_ci-runner.js
144
+ - lib/public/diffux_ci-styles.css
145
+ - lib/views/debug.erb
148
146
  - lib/views/index.erb
149
147
  - lib/views/review.erb
150
148
  homepage: http://rubygems.org/gems/diffux_ci