lookbook_visual_tester 0.5.4 → 0.5.7
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 +4 -4
- data/.agent/rules/style_guide.md +59 -0
- data/CHANGELOG.md +27 -0
- data/README.md +5 -2
- data/Rakefile +2 -0
- data/lib/lookbook_visual_tester/configuration.rb +11 -16
- data/lib/lookbook_visual_tester/drivers/ferrum_driver.rb +15 -9
- data/lib/lookbook_visual_tester/preview_checker.rb +22 -0
- data/lib/lookbook_visual_tester/runner.rb +2 -10
- data/lib/lookbook_visual_tester/scenario_run.rb +6 -6
- data/lib/lookbook_visual_tester/services/image_comparator.rb +24 -20
- data/lib/lookbook_visual_tester/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5198b58b3f8bffad2cb68f1bce804b1bce9d2ccc3e32513699f68a83e04fb054
|
|
4
|
+
data.tar.gz: bca7f0aa36413c702b5c65e3ed330ac18c4c05edeeeb36e5cb94b0ec1aaa4831
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7908ba3fb95002233392bc7b570bdf21f7bfd38f25c0206b0521f5fc89a8773173ea2689fbc1ddaca41b1e838d904118d47d4d3a2760dd829265e7e46d8148c9
|
|
7
|
+
data.tar.gz: ee266274b9ee9bfd9dd24c146bf6537618da8c10490cee78c8a667d072a8c1bb06e5a43d0ac402ca98131de425fe7e5df9ace5c9b015ca8830db35788940f8b6
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Lookbook Visual Tester Style Guide & Best Practices
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
`lookbook_visual_tester` is a Ruby gem designed for visual regression testing of Lookbook previews. It uses `Ferrum` for headless browser interactions and `ChunkyPNG` for image comparison.
|
|
5
|
+
|
|
6
|
+
## Architecture & patterns
|
|
7
|
+
|
|
8
|
+
### Service Objects
|
|
9
|
+
- Isolate complex logic in service objects inheriting from `LookbookVisualTester::Service` (if applicable) or plain Ruby classes in `lib/lookbook_visual_tester/services/`.
|
|
10
|
+
- Examples: `ImageComparator`, `ScenarioFinder`.
|
|
11
|
+
|
|
12
|
+
### Configuration
|
|
13
|
+
- Use `LookbookVisualTester.configure` to set global options.
|
|
14
|
+
- Options are defined in `lib/lookbook_visual_tester/configuration.rb`.
|
|
15
|
+
- Default base path for screenshots is `coverage/screenshots` (as of v0.5.5).
|
|
16
|
+
|
|
17
|
+
### Path Handling
|
|
18
|
+
- Use `Pathname` for all file system paths.
|
|
19
|
+
- **Screenshot Structure**:
|
|
20
|
+
- `[base_path]/[baseline|current|diffs]/[folder_name]/[filename].png`
|
|
21
|
+
- `folder_name` is either the variant slug (e.g., `dark-mode`) or `default` if no variant is present.
|
|
22
|
+
- Never allow files to be dumped at the root of the screenshot directories; always enforce a subdirectory.
|
|
23
|
+
|
|
24
|
+
## Visual Testing Logic
|
|
25
|
+
|
|
26
|
+
### Image Comparison
|
|
27
|
+
- **Dimension Mismatch**: Do not raise errors for images of different sizes.
|
|
28
|
+
- Create a canvas size equal to the maximum width and height of the two images.
|
|
29
|
+
- Compare overlapping pixels.
|
|
30
|
+
- Mark non-overlapping pixels (from the larger image) as differences.
|
|
31
|
+
- Used in: `LookbookVisualTester::Services::ImageComparator`.
|
|
32
|
+
|
|
33
|
+
### Screenshot Capture
|
|
34
|
+
- Use `Ferrum` to capture screenshots.
|
|
35
|
+
- Ensure consistent viewport sizes and wait for animations/fonts if necessary (managed in `Runner` logic).
|
|
36
|
+
|
|
37
|
+
## Testing (`RSpec`)
|
|
38
|
+
|
|
39
|
+
### Structure
|
|
40
|
+
- **Unit Tests**: `spec/lib/lookbook_visual_tester/...`
|
|
41
|
+
- **Integration Tests**: `spec/integration/...`
|
|
42
|
+
- Use `spec_helper.rb` for common setup.
|
|
43
|
+
|
|
44
|
+
### Best Practices
|
|
45
|
+
- **Reproduction Scripts**: somewhat complex bugs (like visual mismatches) should be isolated in top-level `repro_*.rb` scripts before fixing.
|
|
46
|
+
- **Mocking**: Be careful with circular dependencies when mocking `Lookbook` objects (e.g., `Scenario` <-> `Preview`). Use `allow(...).to receive(...)` logic in `before` blocks rather than definitions to break cycles.
|
|
47
|
+
|
|
48
|
+
## Versioning & Changelog
|
|
49
|
+
- **Versioning**: Semantic versioning in `lib/lookbook_visual_tester/version.rb`.
|
|
50
|
+
- **Changelog**: Maintain `CHANGELOG.md` with `[Unreleased]` and version headers. Group changes by `Added`, `Changed`, `Fixed`.
|
|
51
|
+
|
|
52
|
+
## Coding Style
|
|
53
|
+
- Standard Ruby style (indentation: 2 spaces).
|
|
54
|
+
- Prefer descriptive variable names over short cryptic ones.
|
|
55
|
+
- Use `frozen_string_literal: true` where appropriate (though not strictly enforced everywhere yet).
|
|
56
|
+
|
|
57
|
+
## Versioning & Changelog
|
|
58
|
+
|
|
59
|
+
When updating the version, make sure to update the `CHANGELOG.md` file with the new version number and a list of changes since the last release. The changes should be grouped by `Added`, `Changed`, and `Fixed`. Also update `README.md` accordingly.
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
## [0.5.7] - 2026-01-06
|
|
3
|
+
|
|
4
|
+
### Fixed
|
|
5
|
+
- **Flaky Screenshots**: Added `wait_time` configuration to `LookbookVisualTester.config` to allow explicit waiting before screenshot capture. This resolves blank or layout-only screenshots in slower environments.
|
|
6
|
+
- **Robust Driver**: Updated `FerrumDriver` to include consistent network idle checks and support the new `wait_time` option.
|
|
7
|
+
|
|
8
|
+
## [0.5.6] - 2026-01-06
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **Image Comparison**: Fixed `Dimensions mismatch` error by creating a diff canvas sized to the maximum dimensions of widely differing images.
|
|
12
|
+
- **Missing Action Error**: Resolved `ActionNotFound` for `render_scenario_to_string` by ensuring the preview controller properly includes `Lookbook::PreviewControllerActions`.
|
|
13
|
+
- **Unexpected Headers**: Fixed an issue where the `example_icons` preview in the dummy app included an unwanted `<h1>Icons</h1>` header.
|
|
14
|
+
- **Spec Fix**: Resolved a `SystemStackError` (circular dependency) in `ScenarioFinder` specs.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **Folder Structure**: Refactored screenshot organization. Non-variant screenshots are now stored in a `default` subfolder within `coverage/screenshots`.
|
|
18
|
+
- **Deep Check**: Enhanced `rake lookbook:deep_check` to validate that the configured preview controller supports required Lookbook actions.
|
|
19
|
+
|
|
20
|
+
## [0.5.5] - 2026-01-06
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- **Image Comparison**: Fixed `Dimensions mismatch` error. Now, when images have different dimensions, a diff image is generated on a canvas sized to the maximum dimensions, clearly showing the differences and the mismatched areas.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- **Folder Structure**: Screenshots are now saved in `coverage/screenshots` by default (previously `spec/visual_screenshots`).
|
|
27
|
+
- **Default Subfolder**: Non-variant screenshots are now stored in a `default` subfolder to maintain consistency with variant-based runs.
|
|
28
|
+
|
|
2
29
|
## [0.5.4] - 2026-01-06
|
|
3
30
|
|
|
4
31
|
### Fixed
|
data/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
A powerful visual regression testing tool for [ViewComponent](https://viewcomponent.org/) via [Lookbook](https://lookbook.build/). It automates the process of capturing screenshots of your components, comparing them against baselines, and highlighting differences with human-friendly aesthetics.
|
|
6
6
|
|
|
7
|
+
*This tool has been tested "at home". If it doesn't work for you, feel free to open an issue. **It works on my machine!***
|
|
8
|
+
|
|
7
9
|
### Key Features
|
|
8
10
|
|
|
9
11
|
- **Automated Visual Regression**: Captures and compares screenshots of all Lookbook previews.
|
|
@@ -45,9 +47,10 @@ You can configure the tester in a Rails initializer:
|
|
|
45
47
|
```ruby
|
|
46
48
|
LookbookVisualTester.configure do |config|
|
|
47
49
|
config.lookbook_host = "http://localhost:3000" # Where your rails app is running
|
|
48
|
-
config.base_path = "
|
|
50
|
+
config.base_path = "coverage/screenshots" # Root for screenshots
|
|
49
51
|
config.copy_to_clipboard = true # Enable xclip support
|
|
50
52
|
config.threads = 4 # Number of parallel threads (default: 4)
|
|
53
|
+
config.wait_time = 0.5 # Optional: Wait time (seconds) before screenshot (fixes blank screens)
|
|
51
54
|
end
|
|
52
55
|
```
|
|
53
56
|
|
|
@@ -101,7 +104,7 @@ You can run your visual tests against multiple configurations (variants), such a
|
|
|
101
104
|
* **`{"theme":"dark"}`**: Runs with `_display[theme]=dark`.
|
|
102
105
|
* **`{"width":"Mobile"}`**: Runs with `_display[width]=375px` AND automatically resizes the browser window to 375px width.
|
|
103
106
|
|
|
104
|
-
Screenshots for variants are saved in dedicated subfolders (e.g., `
|
|
107
|
+
Screenshots for variants are saved in dedicated subfolders (e.g., `coverage/screenshots/baseline/theme-dark/`).
|
|
105
108
|
|
|
106
109
|
|
|
107
110
|
### Baseline Management
|
data/Rakefile
CHANGED
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
module LookbookVisualTester
|
|
2
2
|
class Configuration
|
|
3
3
|
attr_reader :base_path
|
|
4
|
-
attr_accessor :lookbook_host,
|
|
5
|
-
:
|
|
6
|
-
:
|
|
7
|
-
:
|
|
8
|
-
:automatic_run,
|
|
9
|
-
:mask_selectors, :driver_adapter,
|
|
10
|
-
:preview_checker_setup,
|
|
11
|
-
:logger
|
|
4
|
+
attr_accessor :lookbook_host, :ui_comparison, :diff_dir, :baseline_dir, :current_dir,
|
|
5
|
+
:history_dir, :history_keep_last_n, :threads, :copy_to_clipboard,
|
|
6
|
+
:components_folder, :automatic_run, :mask_selectors, :driver_adapter,
|
|
7
|
+
:preview_checker_setup, :logger, :wait_time
|
|
12
8
|
|
|
13
9
|
DEFAULT_THREADS = 4
|
|
14
10
|
|
|
15
11
|
def initialize
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Pathname.new(Dir.pwd).join('spec/visual_screenshots')
|
|
23
|
-
end
|
|
12
|
+
root_path = if defined?(Rails) && Rails.respond_to?(:root) && Rails.root
|
|
13
|
+
Rails.root
|
|
14
|
+
else
|
|
15
|
+
Pathname.new(Dir.pwd)
|
|
16
|
+
end
|
|
17
|
+
@base_path = root_path.join('coverage/screenshots')
|
|
24
18
|
@baseline_dir = @base_path.join('baseline')
|
|
25
19
|
@current_dir = @base_path.join('current_run')
|
|
26
20
|
@diff_dir = @base_path.join('diff')
|
|
@@ -33,6 +27,7 @@ module LookbookVisualTester
|
|
|
33
27
|
@mask_selectors = []
|
|
34
28
|
@driver_adapter = :ferrum
|
|
35
29
|
@preview_checker_setup = nil
|
|
30
|
+
@wait_time = 0.5
|
|
36
31
|
@logger = if defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
|
|
37
32
|
Rails.logger
|
|
38
33
|
else
|
|
@@ -53,22 +53,26 @@ module LookbookVisualTester
|
|
|
53
53
|
wait_for_network_idle
|
|
54
54
|
wait_for_fonts
|
|
55
55
|
wait_for_custom_selectors
|
|
56
|
+
# Explicit wait if configured, for robustness against "blank screenshot" issues
|
|
57
|
+
sleep(config.wait_time) if config.wait_time.positive?
|
|
56
58
|
end
|
|
57
59
|
|
|
58
60
|
def wait_for_fonts
|
|
59
|
-
@browser.execute(
|
|
61
|
+
@browser.execute('return document.fonts.ready')
|
|
60
62
|
end
|
|
61
63
|
|
|
62
|
-
def wait_for_network_idle
|
|
63
|
-
# Ferrum has built-in network idle waiting
|
|
64
|
+
def wait_for_network_idle
|
|
65
|
+
# Ferrum has built-in network idle waiting.
|
|
66
|
+
# We rely on default settings or explicit sleep for extra safety.
|
|
64
67
|
@browser.network.wait_for_idle
|
|
65
68
|
rescue Ferrum::TimeoutError
|
|
66
|
-
# Log warning but proceed
|
|
69
|
+
# Log warning but proceed - sometimes long polling or other scripts keep net active
|
|
70
|
+
config.logger.warn 'LookbookVisualTester: Network idle timeout. Proceeding with screenshot.'
|
|
67
71
|
end
|
|
68
72
|
|
|
69
73
|
def save_screenshot(path)
|
|
70
74
|
@browser.screenshot(path: path, full: true)
|
|
71
|
-
#
|
|
75
|
+
# NOTE: full: true captures the whole page.
|
|
72
76
|
# If we capture viewport only, we should remove full: true.
|
|
73
77
|
# Usually for visual testing full page is better unless specifically testing viewport.
|
|
74
78
|
end
|
|
@@ -86,7 +90,7 @@ module LookbookVisualTester
|
|
|
86
90
|
end
|
|
87
91
|
|
|
88
92
|
def disable_animations
|
|
89
|
-
css =
|
|
93
|
+
css = '* { transition: none !important; animation: none !important; caret-color: transparent !important; }'
|
|
90
94
|
inject_style(css)
|
|
91
95
|
end
|
|
92
96
|
|
|
@@ -95,15 +99,17 @@ module LookbookVisualTester
|
|
|
95
99
|
start = Time.now
|
|
96
100
|
until @browser.execute("return document.fonts.status === 'loaded'")
|
|
97
101
|
break if Time.now - start > 5
|
|
102
|
+
|
|
98
103
|
sleep 0.1
|
|
99
104
|
end
|
|
100
105
|
|
|
101
106
|
# Also check for images loading attributes if needed
|
|
102
107
|
# "check that no images have loading attributes active"
|
|
103
108
|
# Often checking complete property is enough
|
|
104
|
-
until @browser.execute(
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
until @browser.execute('return Array.from(document.images).every(i => i.complete)')
|
|
110
|
+
break if Time.now - start > 5
|
|
111
|
+
|
|
112
|
+
sleep 0.1
|
|
107
113
|
end
|
|
108
114
|
end
|
|
109
115
|
end
|
|
@@ -18,6 +18,7 @@ module LookbookVisualTester
|
|
|
18
18
|
def deep_check
|
|
19
19
|
# Ensure custom setup is run before deep checks
|
|
20
20
|
run_setup
|
|
21
|
+
check_preview_controller_config
|
|
21
22
|
run_checks(:deep_render_check)
|
|
22
23
|
end
|
|
23
24
|
|
|
@@ -204,6 +205,27 @@ module LookbookVisualTester
|
|
|
204
205
|
end
|
|
205
206
|
end
|
|
206
207
|
|
|
208
|
+
def check_preview_controller_config
|
|
209
|
+
return unless defined?(Rails)
|
|
210
|
+
|
|
211
|
+
controller_name = Rails.application.config.view_component.preview_controller
|
|
212
|
+
return unless controller_name
|
|
213
|
+
|
|
214
|
+
begin
|
|
215
|
+
controller_class = controller_name.constantize
|
|
216
|
+
unless controller_class.action_methods.include?('render_scenario_to_string')
|
|
217
|
+
puts "WARNING: Configured preview controller '#{controller_name}' does not have 'render_scenario_to_string' action."
|
|
218
|
+
puts ' This is required for Lookbook to render previews correctly.'
|
|
219
|
+
puts " Please ensure your preview controller inherits from 'Lookbook::PreviewController'."
|
|
220
|
+
# We could raise an error here to fail deep_check
|
|
221
|
+
raise "Preview Controller '#{controller_name}' missing required action 'render_scenario_to_string'"
|
|
222
|
+
end
|
|
223
|
+
rescue NameError
|
|
224
|
+
puts "WARNING: Configured preview controller '#{controller_name}' could not be loaded."
|
|
225
|
+
raise "Preview Controller '#{controller_name}' could not be loaded"
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
207
229
|
def run_setup
|
|
208
230
|
if @config.preview_checker_setup
|
|
209
231
|
@config.preview_checker_setup.call
|
|
@@ -142,16 +142,8 @@ module LookbookVisualTester
|
|
|
142
142
|
# Determine paths
|
|
143
143
|
current_path = run_data.current_path
|
|
144
144
|
baseline_path = run_data.baseline_path
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
# Actually ScenarioRun#diff_filename is just flat for now but let's fix that?
|
|
148
|
-
# ScenarioRun doesn't expose diff_path with slug. Let's fix that manually here if needed or update ScenarioRun.
|
|
149
|
-
# Wait, ScenarioRun stores baseline/current in folders but diff_filename is just name.
|
|
150
|
-
# We should probably put diffs in folders too.
|
|
151
|
-
# Let's adjust diff_path here:
|
|
152
|
-
if variant_slug.present?
|
|
153
|
-
diff_path = @config.diff_dir.join(variant_slug, run_data.diff_filename)
|
|
154
|
-
end
|
|
145
|
+
folder_name = variant_slug.presence || 'default'
|
|
146
|
+
diff_path = @config.diff_dir.join(folder_name, run_data.diff_filename)
|
|
155
147
|
|
|
156
148
|
FileUtils.mkdir_p(File.dirname(current_path))
|
|
157
149
|
FileUtils.mkdir_p(File.dirname(diff_path))
|
|
@@ -40,16 +40,16 @@ module LookbookVisualTester
|
|
|
40
40
|
"#{preview_name}_#{scenario_name}_diff.png"
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
def folder_name
|
|
44
|
+
variant_slug.presence || 'default'
|
|
45
|
+
end
|
|
46
|
+
|
|
43
47
|
def current_path
|
|
44
|
-
|
|
45
|
-
base = base.join(variant_slug) if variant_slug.present?
|
|
46
|
-
base.join(filename)
|
|
48
|
+
LookbookVisualTester.config.current_dir.join(folder_name).join(filename)
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def baseline_path
|
|
50
|
-
|
|
51
|
-
base = base.join(variant_slug) if variant_slug.present?
|
|
52
|
-
base.join(filename)
|
|
52
|
+
LookbookVisualTester.config.baseline_dir.join(folder_name).join(filename)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def preview_url
|
|
@@ -16,41 +16,45 @@ module LookbookVisualTester
|
|
|
16
16
|
|
|
17
17
|
def call
|
|
18
18
|
unless File.exist?(baseline_path)
|
|
19
|
-
return { diff_path: nil, mismatch: 0.0, error:
|
|
19
|
+
return { diff_path: nil, mismatch: 0.0, error: 'Baseline not found' }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
baseline = ChunkyPNG::Image.from_file(baseline_path)
|
|
23
23
|
current = ChunkyPNG::Image.from_file(current_path)
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
diff_path: nil,
|
|
28
|
-
mismatch: 100.0,
|
|
29
|
-
error: "Dimensions mismatch: #{baseline.width}x#{baseline.height} vs #{current.width}x#{current.height}"
|
|
30
|
-
}
|
|
31
|
-
end
|
|
25
|
+
max_width = [baseline.width, current.width].max
|
|
26
|
+
max_height = [baseline.height, current.height].max
|
|
32
27
|
|
|
33
28
|
diff_pixels_count = 0
|
|
34
|
-
diff_image = ChunkyPNG::Image.new(
|
|
29
|
+
diff_image = ChunkyPNG::Image.new(max_width, max_height, ChunkyPNG::Color::WHITE)
|
|
30
|
+
|
|
31
|
+
max_height.times do |y|
|
|
32
|
+
max_width.times do |x|
|
|
33
|
+
in_baseline = x < baseline.width && y < baseline.height
|
|
34
|
+
in_current = x < current.width && y < current.height
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
pixel2 = current[x, y]
|
|
36
|
+
if in_baseline && in_current
|
|
37
|
+
pixel1 = baseline[x, y]
|
|
38
|
+
pixel2 = current[x, y]
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
if pixel1 == pixel2
|
|
41
|
+
# Blue context for unchanged pixels to make it easier for humans
|
|
42
|
+
gray_val = ChunkyPNG::Color.r(ChunkyPNG::Color.grayscale_teint(pixel1))
|
|
43
|
+
# Keep intensity in R/G but push blue to make it the dominant tint
|
|
44
|
+
diff_image[x, y] = ChunkyPNG::Color.rgba(gray_val, gray_val, 255, 50)
|
|
45
|
+
else
|
|
46
|
+
diff_image[x, y] = DIFF_COLOR
|
|
47
|
+
diff_pixels_count += 1
|
|
48
|
+
end
|
|
49
|
+
elsif in_baseline || in_current
|
|
50
|
+
# Pixel exists in one but not the other -> Mismatch
|
|
42
51
|
diff_image[x, y] = DIFF_COLOR
|
|
43
52
|
diff_pixels_count += 1
|
|
44
|
-
else
|
|
45
|
-
# Blue context for unchanged pixels to make it easier for humans
|
|
46
|
-
gray_val = ChunkyPNG::Color.r(ChunkyPNG::Color.grayscale_teint(pixel1))
|
|
47
|
-
# Keep intensity in R/G but push blue to make it the dominant tint
|
|
48
|
-
diff_image[x, y] = ChunkyPNG::Color.rgba(gray_val, gray_val, 255, 50)
|
|
49
53
|
end
|
|
50
54
|
end
|
|
51
55
|
end
|
|
52
56
|
|
|
53
|
-
mismatch_percentage = (diff_pixels_count.to_f /
|
|
57
|
+
mismatch_percentage = (diff_pixels_count.to_f / (max_width * max_height)) * 100.0
|
|
54
58
|
|
|
55
59
|
if diff_pixels_count > 0
|
|
56
60
|
FileUtils.mkdir_p(File.dirname(diff_path))
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lookbook_visual_tester
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Murilo Vasconcelos
|
|
@@ -172,6 +172,7 @@ executables: []
|
|
|
172
172
|
extensions: []
|
|
173
173
|
extra_rdoc_files: []
|
|
174
174
|
files:
|
|
175
|
+
- ".agent/rules/style_guide.md"
|
|
175
176
|
- ".rubocop.yml"
|
|
176
177
|
- ".ruby-version"
|
|
177
178
|
- CHANGELOG.md
|