no-regrets 0.0.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 +7 -0
- data/lib/no_regrets/image_diff.rb +27 -0
- data/lib/no_regrets.rb +96 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 19b04a4a36f665feef72458c32705b3289db89b1
|
4
|
+
data.tar.gz: 45212b45681d1fd064939a8c5dc492e497226b16
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0ca51809da3a62084f29266f24a24afe086da2a3c23cefeb005ad42f170dba05be91f895248c7fb6e5dfa0e5eac7342cb7369b483216ce024334a2bb50abfff6
|
7
|
+
data.tar.gz: 2a9f286ae537366e3dc125ea90a982de404ce51d8c9e667e294be50878b6e064798c6d34ac3d6dbcbbb907e58de642f644152abfb57ae03cbef5a4dc73fe739a
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'chunky_png'
|
2
|
+
|
3
|
+
class NoRegrets
|
4
|
+
class ImageDiff
|
5
|
+
|
6
|
+
def self.generate_diff(old_screenshot_path, new_screenshot_path, diff_path)
|
7
|
+
images = [
|
8
|
+
ChunkyPNG::Image.from_file(old_screenshot_path),
|
9
|
+
ChunkyPNG::Image.from_file(new_screenshot_path)
|
10
|
+
]
|
11
|
+
|
12
|
+
diff = []
|
13
|
+
|
14
|
+
images.first.height.times do |y|
|
15
|
+
images.first.row(y).each_with_index do |pixel, x|
|
16
|
+
diff << [x,y] unless pixel == images.last[x,y]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
x, y = diff.map{ |xy| xy[0] }, diff.map{ |xy| xy[1] }
|
21
|
+
|
22
|
+
images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(255,0,0))
|
23
|
+
images.last.save(diff_path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/lib/no_regrets.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'launchy'
|
3
|
+
require_relative "no_regrets/image_diff"
|
4
|
+
|
5
|
+
class NoRegrets
|
6
|
+
|
7
|
+
class ScreenshotMismatchError < StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.check_screenshot_for_regressions(screenshot_name)
|
11
|
+
new(screenshot_name).check_screenshot_for_regressions
|
12
|
+
end
|
13
|
+
|
14
|
+
def check_screenshot_for_regressions
|
15
|
+
path = Capybara.current_session.save_screenshot("#{screenshot_name}.png")
|
16
|
+
sha1 = Digest::SHA1.hexdigest(File.read(path))
|
17
|
+
if !File.exists?(cache_file_path(sha1))
|
18
|
+
FileUtils.mkdir_p(cache_dir)
|
19
|
+
FileUtils.cp(path, cache_file_path(sha1))
|
20
|
+
end
|
21
|
+
|
22
|
+
if old_sha1 && old_sha1 != sha1
|
23
|
+
raise_error(path, sha1)
|
24
|
+
end
|
25
|
+
|
26
|
+
FileUtils.rm(path)
|
27
|
+
if !fingerprints[screenshot_name]
|
28
|
+
puts "Saving a new screenshot fingerprint for \"#{screenshot_name}\" in #{fingerprint_file_path}"
|
29
|
+
end
|
30
|
+
fingerprints[screenshot_name] = sha1
|
31
|
+
File.write(fingerprint_file_path, fingerprints.to_yaml)
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(screenshot_name)
|
35
|
+
@screenshot_name = screenshot_name
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :screenshot_name
|
41
|
+
|
42
|
+
def fingerprints
|
43
|
+
@fingerprints ||= File.exists?(fingerprint_file_path) ? YAML.load(File.read(fingerprint_file_path)) : {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def raise_error(new_screenshot_path, new_sha1)
|
47
|
+
error_message = <<~ERROR_MESSAGE
|
48
|
+
The screenshot \"#{screenshot_name}\" has changed.
|
49
|
+
You can view the new screenshot by opening #{new_screenshot_path}.
|
50
|
+
|
51
|
+
If this was expected, you can remove this line:
|
52
|
+
#{screenshot_name}: #{fingerprints[screenshot_name]}
|
53
|
+
from the file #{fingerprint_file_path}, run this test again, and commit the result.
|
54
|
+
ERROR_MESSAGE
|
55
|
+
|
56
|
+
if diffable?(new_sha1)
|
57
|
+
error_message << "You can see the diff"
|
58
|
+
|
59
|
+
diff_path = "#{diff_dir}/#{screenshot_name}.png"
|
60
|
+
FileUtils.mkdir_p(diff_dir)
|
61
|
+
ImageDiff.generate_diff(
|
62
|
+
cache_file_path(old_sha1),
|
63
|
+
cache_file_path(new_sha1),
|
64
|
+
diff_path
|
65
|
+
)
|
66
|
+
Launchy.open(diff_path)
|
67
|
+
end
|
68
|
+
|
69
|
+
raise ScreenshotMismatchError, error_message
|
70
|
+
end
|
71
|
+
|
72
|
+
def old_sha1
|
73
|
+
fingerprints[screenshot_name]
|
74
|
+
end
|
75
|
+
|
76
|
+
def fingerprint_file_path
|
77
|
+
'spec/support/no_regret_fingerprints.yml'
|
78
|
+
end
|
79
|
+
|
80
|
+
def diffable?(new_sha1)
|
81
|
+
File.exists?(cache_file_path(old_sha1)) && File.exists?(cache_file_path(new_sha1))
|
82
|
+
end
|
83
|
+
|
84
|
+
def cache_file_path(sha1)
|
85
|
+
"#{cache_dir}/#{sha1}.png"
|
86
|
+
end
|
87
|
+
|
88
|
+
def cache_dir
|
89
|
+
"#{Capybara.save_path.to_s}/no_regrets"
|
90
|
+
end
|
91
|
+
|
92
|
+
def diff_dir
|
93
|
+
"#{cache_dir}/diffs"
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: no-regrets
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Victor Mours
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-11-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capybara
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: launchy
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: chunky_png
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: ''
|
56
|
+
email: victor@ahaoho.io
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- lib/no_regrets.rb
|
62
|
+
- lib/no_regrets/image_diff.rb
|
63
|
+
homepage:
|
64
|
+
licenses:
|
65
|
+
- MIT
|
66
|
+
metadata: {}
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 2.4.5
|
84
|
+
signing_key:
|
85
|
+
specification_version: 4
|
86
|
+
summary: Visual regression testing for Capybara specs
|
87
|
+
test_files: []
|
88
|
+
has_rdoc:
|