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