diffux_ci 0.2.0 → 0.3.0

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: 2670d7b6c223c5706a067d1ca10528f02a7b4e7d
4
- data.tar.gz: 1192da6f79d208279ef7fba9ae5ac8339f425893
3
+ metadata.gz: 792c6b08f42ae6f8715b7283bbd5e48de674281d
4
+ data.tar.gz: fe881d359ff8ac648c74802f0092ff862184ac1f
5
5
  SHA512:
6
- metadata.gz: d09b57e16639125db313eb1786533bc26899ac703de45d04c4aa558c33588ce6f772ceb17e3d899e5f9c36c5fbd0ec45b64bbf0f224a100b735b90941a3df56f
7
- data.tar.gz: bc514a8739c934f932393b2face0dbd06f0d7a926561f526ea6baddccb8b18ee7a3f63e296bedfa760197f7e598508c9e5722abd506718983b493de7d3fcee82
6
+ metadata.gz: 777f67034c3e7cd0bb60f246892cebebfb982602acddbd957f004f98b73cb8e06a273ae4c77002f55eca5b4128eade1b76f200a4872489f50d4dff1eee0bb105
7
+ data.tar.gz: ec413e930adecf64943f5f95d7f9d6bd519e63fa37c063b07297e2933249ae9ba9c328cbc0b0c40fe5f60b584eaaee91d4c2e7211475904ff6eb31b98f196692
data/bin/diffux_ci CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'diffux_ci_utils'
4
4
  require 'diffux_ci_action'
5
5
  require 'diffux_ci_uploader'
6
+ require 'diffux_ci_version'
6
7
  require 'fileutils'
7
8
 
8
9
  action = ARGV[0] || 'run'
@@ -39,6 +40,9 @@ when 'upload_diffs'
39
40
  # `upload_diffs` returns a URL to a static html file
40
41
  puts DiffuxCIUploader.new.upload_diffs
41
42
 
43
+ when '--version'
44
+ puts "diffux_ci version #{DiffuxCI::VERSION}"
45
+
42
46
  when '--help'
43
47
  puts <<-EOS
44
48
  Commands:
@@ -49,6 +53,8 @@ Commands:
49
53
  approve
50
54
  reject
51
55
  upload_diffs
56
+ --help
57
+ --version
52
58
  EOS
53
59
  else
54
60
  abort "Unknown action \"#{action}\""
@@ -20,21 +20,28 @@ def resolve_viewports(example)
20
20
  end
21
21
  end
22
22
 
23
- tries = 0
24
- begin
25
- driver = Selenium::WebDriver.for DiffuxCIUtils.config['driver'].to_sym
26
- rescue Selenium::WebDriver::Error::WebDriverError => e
27
- # "unable to obtain stable firefox connection in 60 seconds"
28
- #
29
- # This seems to happen sporadically for some versions of Firefox, so we want
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
23
+ def init_driver
24
+ tries = 0
25
+ begin
26
+ driver = Selenium::WebDriver.for DiffuxCIUtils.config['driver'].to_sym
27
+ rescue Selenium::WebDriver::Error::WebDriverError => e
28
+ # "unable to obtain stable firefox connection in 60 seconds"
29
+ #
30
+ # This seems to happen sporadically for some versions of Firefox, so we want
31
+ # to retry a couple of times it in case it will work the second time around.
32
+ tries += 1
33
+ retry if tries <= 3
34
+ raise e
35
+ end
36
+
37
+ driver.manage.timeouts.script_timeout = 3 # move to config?
38
+
39
+ driver
34
40
  end
35
41
 
42
+ driver = init_driver
43
+
36
44
  begin
37
- driver.manage.timeouts.script_timeout = 3 # move to config?
38
45
  driver.navigate.to DiffuxCIUtils.construct_url('/')
39
46
 
40
47
  # Check for errors during startup
@@ -98,10 +105,23 @@ begin
98
105
 
99
106
  # Crop the screenshot to the size of the rendered element
100
107
  screenshot = ChunkyPNG::Image.from_blob(driver.screenshot_as(:png))
108
+
109
+ # In our JavScript we are rounding up, which can sometimes give us a
110
+ # dimensions that are larger than the screenshot dimensions. We need to
111
+ # guard against that here.
112
+ crop_width = [
113
+ [rendered['width'], 1].max,
114
+ screenshot.width - rendered['left']
115
+ ].min
116
+ crop_height = [
117
+ [rendered['height'], 1].max,
118
+ screenshot.height - rendered['top']
119
+ ].min
120
+
101
121
  screenshot.crop!(rendered['left'],
102
122
  rendered['top'],
103
- [rendered['width'], 1].max,
104
- [rendered['height'], 1].max)
123
+ crop_width,
124
+ crop_height)
105
125
 
106
126
  print "Checking \"#{description}\" at [#{viewport['name']}]... "
107
127
 
@@ -123,13 +143,13 @@ begin
123
143
  # image to disk. This will allow it to be reviewed by someone.
124
144
  diff_path = DiffuxCIUtils.path_to(
125
145
  description, viewport['name'], 'diff.png')
126
- comparison[:diff_image].save(diff_path)
146
+ comparison[:diff_image].save(diff_path, :fast_rgb)
127
147
 
128
148
  candidate_path = DiffuxCIUtils.path_to(
129
149
  description, viewport['name'], 'candidate.png')
130
- screenshot.save(candidate_path)
150
+ screenshot.save(candidate_path, :fast_rgb)
131
151
 
132
- puts "#{comparison[:diff_in_percent].round(1)}% (#{diff_output})"
152
+ puts "#{comparison[:diff_in_percent].round(1)}% (#{candidate_path})"
133
153
  else
134
154
  # No visual difference was found, so we don't need to do any more
135
155
  # work.
@@ -143,7 +163,7 @@ begin
143
163
  unless File.directory?(dirname = File.dirname(baseline_path))
144
164
  FileUtils.mkdir_p(dirname)
145
165
  end
146
- screenshot.save(baseline_path)
166
+ screenshot.save(baseline_path, :fast_rgb)
147
167
  puts "First snapshot created (#{baseline_path})"
148
168
  end
149
169
  end
@@ -1,9 +1,9 @@
1
1
  require 'yaml'
2
2
  require 'erb'
3
+ require 'uri'
3
4
 
4
5
  class DiffuxCIUtils
5
6
  def self.config
6
- config_file_name = ENV['DIFFUX_CI_CONFIG_FILE'] || '.diffux_ci.yaml'
7
7
  @@config ||= {
8
8
  'snapshots_folder' => './snapshots',
9
9
  'source_files' => [],
@@ -24,7 +24,12 @@ class DiffuxCIUtils
24
24
  'height' => 444
25
25
  }
26
26
  }
27
- }.merge(YAML.load(ERB.new(File.read(config_file_name)).result))
27
+ }.merge(config_from_file)
28
+ end
29
+
30
+ def self.config_from_file
31
+ config_file_name = ENV['DIFFUX_CI_CONFIG_FILE'] || '.diffux_ci.yaml'
32
+ YAML.load(ERB.new(File.read(config_file_name)).result)
28
33
  end
29
34
 
30
35
  def self.normalize_description(description)
@@ -41,10 +46,12 @@ class DiffuxCIUtils
41
46
  end
42
47
 
43
48
  def self.construct_url(absolute_path, params = {})
49
+ query = URI.encode_www_form(params) unless params.empty?
50
+
44
51
  URI::HTTP.build(host: 'localhost',
45
52
  port: config['port'],
46
53
  path: absolute_path,
47
- query: URI.encode_www_form(params))
54
+ query: query).to_s
48
55
  end
49
56
 
50
57
  def self.current_snapshots
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module DiffuxCI
3
- VERSION = '0.2.0'
3
+ VERSION = '0.3.0'
4
4
  end
@@ -49,11 +49,18 @@ window.diffux = {
49
49
  }
50
50
  },
51
51
 
52
+ isElementVisible: function(element) {
53
+ // element.offsetParent is a cheap way to determine visibility for most
54
+ // elements, but it doesn't work for elements with fixed positioning so we
55
+ // will need to fall back to the more expensive getComputedStyle.
56
+ return element.offsetParent ||
57
+ window.getComputedStyle(element).display !== 'none';
58
+ },
59
+
52
60
  clearVisibleElements: function() {
53
61
  var allElements = document.querySelectorAll('body > *');
54
62
  for (var element of allElements) {
55
- var style = window.getComputedStyle(element);
56
- if (style.display !== 'none') {
63
+ if (this.isElementVisible(element)) {
57
64
  element.parentNode.removeChild(element);
58
65
  }
59
66
  }
@@ -75,7 +82,7 @@ window.diffux = {
75
82
  */
76
83
  tryAsync: function(func) {
77
84
  return new Promise(function(resolve, reject) {
78
- // Saftey valve: if the function does not finish after 3s, then something
85
+ // Safety valve: if the function does not finish after 3s, then something
79
86
  // went haywire and we need to move on.
80
87
  var timeout = setTimeout(function() {
81
88
  reject(new Error('Async callback was not invoked within timeout.'));
@@ -131,8 +138,8 @@ window.diffux = {
131
138
  processElem: function(elem) {
132
139
  try {
133
140
  // TODO: elem.getDOMNode is deprecated in React, so we need to convert
134
- // this to React.findDOMNode(elem) at some point, or push this requirement
135
- // into the examples.
141
+ // this to ReactDOM.findDOMNode(elem) at some point, or push this
142
+ // requirement into the examples.
136
143
  if (elem.getDOMNode) {
137
144
  // Soft-dependency to React here. If the thing returned has a
138
145
  // `getDOMNode` method, call it to get the real DOM node.
@@ -141,23 +148,31 @@ window.diffux = {
141
148
 
142
149
  this.currentRenderedElement = elem;
143
150
 
144
- var width = elem.offsetWidth;
145
- var height = elem.offsetHeight;
146
- var top = elem.offsetTop;
147
- var left = elem.offsetLeft;
148
-
151
+ var rect;
149
152
  if (this.currentExample.options.snapshotEntireScreen) {
150
- width = window.innerWidth;
151
- height = window.innerHeight;
152
- top = 0;
153
- left = 0;
153
+ rect = {
154
+ width: window.innerWidth,
155
+ height: window.innerHeight,
156
+ top: 0,
157
+ left: 0,
158
+ };
159
+ } else {
160
+ // We use elem.getBoundingClientRect() instead of offsetTop and its ilk
161
+ // because elem.getBoundingClientRect() is more accurate and it also
162
+ // takes CSS transformations and other things of that nature into
163
+ // account whereas offsetTop and company do not.
164
+ //
165
+ // Note that this method returns floats, so we need to round those off
166
+ // to integers before returning.
167
+ rect = elem.getBoundingClientRect();
154
168
  }
169
+
155
170
  return {
156
171
  description: this.currentExample.description,
157
- width: width,
158
- height: height,
159
- top: top,
160
- left: left
172
+ width: Math.ceil(rect.width),
173
+ height: Math.ceil(rect.height),
174
+ top: Math.floor(rect.top),
175
+ left: Math.floor(rect.left),
161
176
  };
162
177
  } catch (error) {
163
178
  return this.handleError(error);
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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henric Trotzig