capybara-screenshot-diff 1.6.3 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/lint.yml +1 -1
- data/.github/workflows/test.yml +36 -18
- data/.gitignore +2 -0
- data/CONTRIBUTING.md +3 -1
- data/Dockerfile +2 -3
- data/README.md +39 -27
- data/bin/install-vips +1 -1
- data/capybara-screenshot-diff.gemspec +2 -2
- data/lib/capybara/screenshot/diff/browser_helpers.rb +101 -0
- data/lib/capybara/screenshot/diff/drivers/chunky_png_driver.rb +30 -17
- data/lib/capybara/screenshot/diff/drivers/vips_driver.rb +26 -17
- data/lib/capybara/screenshot/diff/image_compare.rb +85 -72
- data/lib/capybara/screenshot/diff/region.rb +86 -0
- data/lib/capybara/screenshot/diff/stabilization.rb +14 -38
- data/lib/capybara/screenshot/diff/test_methods.rb +68 -35
- data/lib/capybara/screenshot/diff/vcs.rb +6 -5
- data/lib/capybara/screenshot/diff/version.rb +1 -1
- metadata +8 -6
- data/gemfiles/rails52.gemfile +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2aaf70ea2e2737e435920bc94a4504a2d2d3fe9d92874a4f1a9ac2f66527ed1
|
4
|
+
data.tar.gz: '087a7e5e2636a56318884f7d272126e62faea68c49401e96fa40a4a0d43bfb8b'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c636d231583f4b3df1404aff861ef94000752e8b07edc829e2c16d56e34e2ba7418849c7e875a9e625832a6b8259f854c3ff3e0883c20d5942350d34181bc7d
|
7
|
+
data.tar.gz: f706ccc8937cd86a53b0a0dd04cb2429e77d4ef1ac643b898ce7bc08c4b623c976ce3f402136fccf0851c99509ec346102a48ef724a4711f70e73e438cf2a973
|
data/.github/workflows/lint.yml
CHANGED
data/.github/workflows/test.yml
CHANGED
@@ -14,19 +14,24 @@ env:
|
|
14
14
|
FERRUM_PROCESS_TIMEOUT: '15'
|
15
15
|
WD_CACHE_TIME: '864000' # 10 days
|
16
16
|
|
17
|
+
concurrency:
|
18
|
+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
19
|
+
cancel-in-progress: true
|
20
|
+
|
17
21
|
jobs:
|
18
22
|
test:
|
19
23
|
name: Functional Testing
|
20
|
-
runs-on: ubuntu-
|
24
|
+
runs-on: ubuntu-22.04 # In order to install libvips 8.9+ version
|
25
|
+
timeout-minutes: 5
|
21
26
|
|
22
27
|
steps:
|
23
28
|
- name: Checkout code
|
24
|
-
uses: actions/checkout@
|
29
|
+
uses: actions/checkout@v3
|
25
30
|
|
26
31
|
- name: Set up Ruby
|
27
32
|
uses: ruby/setup-ruby@v1
|
28
33
|
with:
|
29
|
-
ruby-version: '3.
|
34
|
+
ruby-version: '3.1'
|
30
35
|
bundler-cache: true
|
31
36
|
|
32
37
|
- name: Install libvips
|
@@ -38,42 +43,44 @@ jobs:
|
|
38
43
|
COVERAGE: enabled
|
39
44
|
|
40
45
|
- name: Upload Screenshots
|
41
|
-
if:
|
42
|
-
uses: actions/upload-artifact@
|
46
|
+
if: always()
|
47
|
+
uses: actions/upload-artifact@v3
|
43
48
|
with:
|
44
|
-
|
49
|
+
name: screenshots
|
50
|
+
retention-days: 1
|
51
|
+
path: |
|
52
|
+
test/fixtures/app/doc/screenshots/
|
53
|
+
tmp/capybara/screenshots-diffs/
|
45
54
|
|
46
55
|
- name: Upload Coverage
|
47
|
-
uses: actions/upload-artifact@
|
56
|
+
uses: actions/upload-artifact@v3
|
48
57
|
with:
|
49
58
|
name: coverage
|
59
|
+
retention-days: 1
|
50
60
|
path: coverage
|
51
61
|
|
52
62
|
matrix:
|
53
63
|
name: Test Integration Rails & Ruby
|
54
64
|
needs: [ 'test' ]
|
55
65
|
runs-on: ubuntu-20.04
|
66
|
+
timeout-minutes: 5
|
56
67
|
|
57
68
|
strategy:
|
58
69
|
matrix:
|
59
|
-
ruby-version: [ '3.1', '3.0', '2.7', '
|
70
|
+
ruby-version: [ '3.1', '3.0', '2.7', 'jruby' ]
|
60
71
|
gemfile:
|
72
|
+
- 'rails70_gems.rb'
|
61
73
|
- 'rails61_gems.rb'
|
62
74
|
- 'rails60_gems.rb'
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
gemfile: rails70_gems.rb
|
67
|
-
- ruby-version: 3.0
|
68
|
-
gemfile: rails70_gems.rb
|
69
|
-
- ruby-version: 3.1
|
70
|
-
gemfile: rails70_gems.rb
|
75
|
+
exclude:
|
76
|
+
- ruby-version: 'jruby'
|
77
|
+
gemfile: 'rails70_gems.rb'
|
71
78
|
env:
|
72
79
|
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}
|
73
80
|
|
74
81
|
steps:
|
75
82
|
- name: Checkout code
|
76
|
-
uses: actions/checkout@
|
83
|
+
uses: actions/checkout@v3
|
77
84
|
|
78
85
|
- name: Set up Ruby
|
79
86
|
uses: ruby/setup-ruby@v1
|
@@ -91,6 +98,7 @@ jobs:
|
|
91
98
|
name: Test Integration Capybara & Image Drivers
|
92
99
|
needs: [ 'test' ]
|
93
100
|
runs-on: ubuntu-20.04
|
101
|
+
timeout-minutes: 5
|
94
102
|
|
95
103
|
strategy:
|
96
104
|
matrix:
|
@@ -102,7 +110,7 @@ jobs:
|
|
102
110
|
|
103
111
|
steps:
|
104
112
|
- name: Checkout code
|
105
|
-
uses: actions/checkout@
|
113
|
+
uses: actions/checkout@v3
|
106
114
|
|
107
115
|
- name: Set up Ruby
|
108
116
|
uses: ruby/setup-ruby@v1
|
@@ -118,3 +126,13 @@ jobs:
|
|
118
126
|
env:
|
119
127
|
SCREENSHOT_DRIVER: ${{ matrix.screenshot-driver }}
|
120
128
|
CAPYBARA_DRIVER: ${{ matrix.capybara-driver }}
|
129
|
+
|
130
|
+
- name: Upload Screenshots
|
131
|
+
uses: actions/upload-artifact@v3
|
132
|
+
if: failure()
|
133
|
+
with:
|
134
|
+
name: screenshots-${{ matrix.screenshot-driver }}-${{ matrix.capybara-driver }}
|
135
|
+
retention-days: 1
|
136
|
+
path: |
|
137
|
+
test/fixtures/app/doc/screenshots/
|
138
|
+
tmp/capybara/screenshots-diffs/
|
data/.gitignore
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -19,4 +19,6 @@ Run the tests for a matrix of configurations of Ruby implementations and Rails v
|
|
19
19
|
|
20
20
|
## Merging to master
|
21
21
|
|
22
|
-
Before merging to master
|
22
|
+
Before merging to `master`,
|
23
|
+
please have a member of the project review your changes,
|
24
|
+
and make sure the tests are green.
|
data/Dockerfile
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
# $ docker build . -t csd
|
4
4
|
# $ docker run -v $(pwd):/app -ti csd rake test
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
FROM circleci/ruby:2.7.2-node-browsers
|
6
|
+
FROM jetthoughts/cimg-ruby:3.1-chrome
|
9
7
|
|
10
8
|
RUN \
|
11
9
|
# Install dependencies
|
@@ -47,6 +45,7 @@ RUN sudo /app/bin/install-vips
|
|
47
45
|
ADD ./lib/capybara/screenshot/diff/version.rb /app/lib/capybara/screenshot/diff/
|
48
46
|
ADD ./capybara-screenshot-diff.gemspec /app/
|
49
47
|
ADD ./gems.rb /app/
|
48
|
+
ADD ./Rakefile /app/
|
50
49
|
|
51
50
|
RUN bundle install
|
52
51
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[![
|
1
|
+
[![Test](https://github.com/donv/capybara-screenshot-diff/actions/workflows/test.yml/badge.svg)](https://github.com/donv/capybara-screenshot-diff/actions/workflows/test.yml)
|
2
2
|
|
3
3
|
# Capybara::Screenshot::Diff
|
4
4
|
|
@@ -40,14 +40,14 @@ In your test class, include the `Capybara::Screenshot::Diff` module:
|
|
40
40
|
```ruby
|
41
41
|
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
42
42
|
include Capybara::Screenshot::Diff
|
43
|
-
...
|
43
|
+
# ...
|
44
44
|
end
|
45
45
|
```
|
46
46
|
|
47
|
-
###
|
47
|
+
### RSpec
|
48
48
|
|
49
49
|
```ruby
|
50
|
-
describe 'Permissions admin', :
|
50
|
+
describe 'Permissions admin', type: :feature, js: true do
|
51
51
|
|
52
52
|
include Capybara::Screenshot::Diff
|
53
53
|
|
@@ -64,7 +64,7 @@ But it's better to include it within your *_helper.rb file so that it can used a
|
|
64
64
|
require 'capybara/screenshot/diff'
|
65
65
|
|
66
66
|
RSpec.configure do |config|
|
67
|
-
|
67
|
+
config.include Capybara::Screenshot::Diff
|
68
68
|
end
|
69
69
|
```
|
70
70
|
|
@@ -97,8 +97,8 @@ doc
|
|
97
97
|
```
|
98
98
|
|
99
99
|
To store the screen shot history, add the `doc/screenshots` directory to your
|
100
|
-
|
101
|
-
|
100
|
+
version control system (git, svn, etc).
|
101
|
+
|
102
102
|
Screen shots are compared to the previously COMMITTED version of the same screen shot.
|
103
103
|
|
104
104
|
### Screenshot groups
|
@@ -186,20 +186,14 @@ end
|
|
186
186
|
test.
|
187
187
|
|
188
188
|
|
189
|
-
|
190
189
|
### Capturing one area instead of the whole page
|
191
190
|
|
191
|
+
You can crop images before comparison to be run, by providing region to crop as `[left, top, right, bottom]` or by css selector like `body .tag`
|
192
|
+
|
192
193
|
```ruby
|
193
194
|
test 'the cool' do
|
194
195
|
visit '/feature'
|
195
|
-
screenshot 'cool_element', crop:
|
196
|
-
end
|
197
|
-
|
198
|
-
private
|
199
|
-
|
200
|
-
def bounds(selector)
|
201
|
-
element = evaluate_script("document.querySelector('#{selector}').getBoundingClientRect()")
|
202
|
-
[element['left'], element['top'], element['right'], element['bottom']]
|
196
|
+
screenshot 'cool_element', crop: '#my_element'
|
203
197
|
end
|
204
198
|
```
|
205
199
|
|
@@ -305,7 +299,7 @@ Capybara::Screenshot::Diff.enabled = ENV['COMPARE_SCREENSHOTS']
|
|
305
299
|
|
306
300
|
By default, `Capybara::Screenshot::Diff` saves screenshots to a
|
307
301
|
`doc/screenshots` folder, relative to either `Rails.root` (if you're in Rails),
|
308
|
-
|
302
|
+
or your current directory otherwise.
|
309
303
|
|
310
304
|
If you want to change where screenshots are saved to, then there are two
|
311
305
|
configuration options that that are relevant.
|
@@ -370,7 +364,6 @@ Capybara::Screenshot.hide_caret = true
|
|
370
364
|
This will make the cursor (caret) transparent (invisible), so the blinking does not delay the screen shot.
|
371
365
|
|
372
366
|
|
373
|
-
|
374
367
|
### Removing focus from the active element
|
375
368
|
|
376
369
|
Another way to avoid the cursor blinking is to set the `blur_active_element` option:
|
@@ -428,7 +421,7 @@ Capybara::Screenshot::Diff.shift_distance_limit = 1
|
|
428
421
|
this will impact performance **severely** if a match cannot be found.
|
429
422
|
|
430
423
|
If `shift_distance_limit` is `nil` shift distance is not measured. If `shift_distance_limit` is set,
|
431
|
-
even to `0`, shift
|
424
|
+
even to `0`, shift distance is measured and reported on image differences.
|
432
425
|
|
433
426
|
### Allowed difference size
|
434
427
|
|
@@ -452,25 +445,26 @@ Capybara::Screenshot::Diff.area_size_limit = 42
|
|
452
445
|
### Skipping an area
|
453
446
|
|
454
447
|
Sometimes you have expected change that you want to ignore.
|
455
|
-
You can use the `skip_area` option
|
448
|
+
You can use the `skip_area` option with `[left, top, right, bottom]`
|
449
|
+
or css selector like `'#footer'` or `'.container .skipped_element'` to the `screenshot` method to ignore an area:
|
456
450
|
|
457
451
|
```ruby
|
458
452
|
test 'unstable area' do
|
459
453
|
visit '/'
|
460
|
-
screenshot 'index', skip_area: [17, 6, 27, 16]
|
454
|
+
screenshot 'index', skip_area: [[17, 6, 27, 16], '.container .skipped_element', '#footer']
|
461
455
|
end
|
462
456
|
```
|
463
457
|
|
464
|
-
The arguments are [
|
458
|
+
The arguments are `[left, top, right, bottom]` for the area you want to ignore. You can also set this globally:
|
465
459
|
|
466
460
|
```ruby
|
467
461
|
Capybara::Screenshot::Diff.skip_area = [0, 0, 64, 48]
|
468
462
|
```
|
469
463
|
|
470
|
-
If you need to ignore multiple areas
|
464
|
+
If you need to ignore multiple areas:
|
471
465
|
|
472
466
|
```ruby
|
473
|
-
screenshot 'index', skip_area: [[0, 0, 64, 48], [17, 6, 27, 16]]
|
467
|
+
screenshot 'index', skip_area: [[0, 0, 64, 48], [17, 6, 27, 16], 'css_selector .element']
|
474
468
|
```
|
475
469
|
|
476
470
|
### Available Image Processing Drivers
|
@@ -479,7 +473,7 @@ There are several image processing supported by this gem.
|
|
479
473
|
There are several options to setup active driver: `:auto`, `:chunky_png` and `:vips`.
|
480
474
|
|
481
475
|
* `:auto` - will try to load `:vips` if there is gem `ruby-vips`, in other cases will load `:chunky_png`
|
482
|
-
* `:chunky_png` and `:vips` will load correspondent driver
|
476
|
+
* `:chunky_png` and `:vips` will load correspondent driver
|
483
477
|
|
484
478
|
### Enable VIPS image processing
|
485
479
|
|
@@ -488,8 +482,8 @@ and could be enabled by adding `ruby-vips` to `Gemfile`.
|
|
488
482
|
|
489
483
|
If need to setup explicitly Vips driver, there are several ways to do this:
|
490
484
|
|
491
|
-
|
492
|
-
|
485
|
+
* Globally: `Capybara::Screenshot::Diff.driver = :vips`
|
486
|
+
* Per screenshot option: `screenshot 'index', driver: :vips`
|
493
487
|
|
494
488
|
With enabled VIPS there are new alternatives to process differences, which easier to find and support.
|
495
489
|
For example, `shift_distance_limit` is very heavy operation. Instead better to use `median_filter_window_size`.
|
@@ -532,6 +526,24 @@ test 'unstable area' do
|
|
532
526
|
end
|
533
527
|
```
|
534
528
|
|
529
|
+
### Skipping stack frames in the error output
|
530
|
+
|
531
|
+
If you would like to override the `screenshot` method or for some other reason would like to skip stack
|
532
|
+
frames when reporting image differences, you can use the `skip_stack_frames` option:
|
533
|
+
|
534
|
+
```ruby
|
535
|
+
test 'test visiting the index' do
|
536
|
+
visit root_path
|
537
|
+
screenshot :index
|
538
|
+
end
|
539
|
+
|
540
|
+
private
|
541
|
+
|
542
|
+
def screenshot(name, **options)
|
543
|
+
super(name, skip_stack_frames: 1, **options)
|
544
|
+
end
|
545
|
+
```
|
546
|
+
|
535
547
|
## Development
|
536
548
|
|
537
549
|
After checking out the repo, run `bin/setup` to install dependencies.
|
data/bin/install-vips
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = "Track your GUI changes with diff assertions"
|
13
13
|
spec.description = "Save screen shots and track changes with graphical diff"
|
14
14
|
spec.homepage = "https://github.com/donv/capybara-screenshot-diff"
|
15
|
-
spec.required_ruby_version = ">= 2.
|
15
|
+
spec.required_ruby_version = defined?(JRUBY_VERSION) ? ">= 2.6.0" : ">= 2.7.0"
|
16
16
|
spec.license = "MIT"
|
17
17
|
spec.metadata["allowed_push_host"] = "https://rubygems.org/"
|
18
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_runtime_dependency "actionpack", ">=
|
23
|
+
spec.add_runtime_dependency "actionpack", ">= 6.0", "< 8"
|
24
24
|
spec.add_runtime_dependency "capybara", ">= 2", "< 4"
|
25
25
|
spec.add_runtime_dependency "chunky_png", "~> 1.3"
|
26
26
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "region"
|
4
|
+
|
5
|
+
module Capybara
|
6
|
+
module Screenshot
|
7
|
+
module BrowserHelpers
|
8
|
+
def current_capybara_driver_class
|
9
|
+
Capybara.current_session.driver.class
|
10
|
+
end
|
11
|
+
|
12
|
+
def selenium?
|
13
|
+
current_capybara_driver_class <= Capybara::Selenium::Driver
|
14
|
+
end
|
15
|
+
|
16
|
+
def window_size_is_wrong?
|
17
|
+
selenium? &&
|
18
|
+
Screenshot.window_size &&
|
19
|
+
page.driver.browser.manage.window.size != ::Selenium::WebDriver::Dimension.new(*Screenshot.window_size)
|
20
|
+
end
|
21
|
+
|
22
|
+
def rect_for(css_selector)
|
23
|
+
all_visible_regions_for(css_selector).first
|
24
|
+
end
|
25
|
+
|
26
|
+
def bounds_for_css(*css_selectors)
|
27
|
+
css_selectors.reduce([]) do |regions, selector|
|
28
|
+
regions.concat(all_visible_regions_for(selector))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
IMAGE_WAIT_SCRIPT = <<~JS
|
33
|
+
function pending_image() {
|
34
|
+
var images = document.images;
|
35
|
+
for (var i = 0; i < images.length; i++) {
|
36
|
+
if (!images[i].complete) {
|
37
|
+
return images[i].src;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
return false;
|
41
|
+
}()
|
42
|
+
JS
|
43
|
+
|
44
|
+
def pending_image_to_load
|
45
|
+
evaluate_script IMAGE_WAIT_SCRIPT
|
46
|
+
end
|
47
|
+
|
48
|
+
HIDE_CARET_SCRIPT = <<~JS
|
49
|
+
if (!document.getElementById('csdHideCaretStyle')) {
|
50
|
+
let style = document.createElement('style');
|
51
|
+
style.setAttribute('id', 'csdHideCaretStyle');
|
52
|
+
document.head.appendChild(style);
|
53
|
+
let styleSheet = style.sheet;
|
54
|
+
styleSheet.insertRule("* { caret-color: transparent !important; }", 0);
|
55
|
+
}
|
56
|
+
JS
|
57
|
+
|
58
|
+
def hide_caret
|
59
|
+
execute_script(HIDE_CARET_SCRIPT)
|
60
|
+
end
|
61
|
+
|
62
|
+
FIND_ACTIVE_ELEMENT_SCRIPT = <<~JS
|
63
|
+
function activeElement(){
|
64
|
+
const ae = document.activeElement;
|
65
|
+
if (ae.nodeName === "INPUT" || ae.nodeName === "TEXTAREA") {
|
66
|
+
ae.blur();
|
67
|
+
return ae;
|
68
|
+
}
|
69
|
+
return null;
|
70
|
+
}();
|
71
|
+
JS
|
72
|
+
|
73
|
+
def blur_from_focused_element
|
74
|
+
page.evaluate_script(FIND_ACTIVE_ELEMENT_SCRIPT)
|
75
|
+
end
|
76
|
+
|
77
|
+
GET_BOUNDING_CLIENT_RECT_SCRIPT = <<~JS
|
78
|
+
[
|
79
|
+
this.getBoundingClientRect().left,
|
80
|
+
this.getBoundingClientRect().top,
|
81
|
+
this.getBoundingClientRect().right,
|
82
|
+
this.getBoundingClientRect().bottom
|
83
|
+
]
|
84
|
+
JS
|
85
|
+
|
86
|
+
def all_visible_regions_for(selector)
|
87
|
+
all(selector, visible: true).map(&method(:region_for))
|
88
|
+
end
|
89
|
+
|
90
|
+
def region_for(element)
|
91
|
+
element.evaluate_script(GET_BOUNDING_CLIENT_RECT_SCRIPT).map { |point| point.negative? ? 0 : point.to_i }
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def create_output_directory_for(file_name)
|
97
|
+
FileUtils.mkdir_p File.dirname(file_name)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -12,6 +12,7 @@ module Capybara
|
|
12
12
|
include ChunkyPNG::Color
|
13
13
|
|
14
14
|
attr_reader :new_file_name, :old_file_name
|
15
|
+
attr_accessor :skip_area, :color_distance_limit, :shift_distance_limit
|
15
16
|
|
16
17
|
def initialize(new_file_name, old_file_name = nil, options = {})
|
17
18
|
options = old_file_name if old_file_name.is_a?(Hash)
|
@@ -69,7 +70,7 @@ module Capybara
|
|
69
70
|
return nil, nil if new_image.pixels == old_image.pixels
|
70
71
|
|
71
72
|
if fast_fail && !(color_distance_limit || shift_distance_limit || area_size_limit)
|
72
|
-
return
|
73
|
+
return build_region_for_whole_image(new_image), nil
|
73
74
|
end
|
74
75
|
|
75
76
|
region = find_top(old_image, new_image)
|
@@ -90,12 +91,6 @@ module Capybara
|
|
90
91
|
image.width
|
91
92
|
end
|
92
93
|
|
93
|
-
def size(region)
|
94
|
-
return 0 unless region
|
95
|
-
|
96
|
-
(region[2] - region[0] + 1) * (region[3] - region[1] + 1)
|
97
|
-
end
|
98
|
-
|
99
94
|
def max_color_distance
|
100
95
|
calculate_metrics unless @max_color_distance
|
101
96
|
@max_color_distance
|
@@ -114,8 +109,8 @@ module Capybara
|
|
114
109
|
log.merge!(max_shift_distance: max_shift_distance) if max_shift_distance
|
115
110
|
end
|
116
111
|
|
117
|
-
def crop(
|
118
|
-
i.crop(*
|
112
|
+
def crop(region, i)
|
113
|
+
i.crop(*region.to_top_left_corner_coordinates)
|
119
114
|
end
|
120
115
|
|
121
116
|
def from_file(filename)
|
@@ -183,20 +178,29 @@ module Capybara
|
|
183
178
|
true
|
184
179
|
end
|
185
180
|
|
186
|
-
def draw_rectangles(images,
|
181
|
+
def draw_rectangles(images, region, (r, g, b))
|
182
|
+
border_color = ChunkyPNG::Color.rgb(r, g, b)
|
183
|
+
border_shadow = ChunkyPNG::Color.rgba(r, g, b, 100)
|
184
|
+
|
187
185
|
images.map do |image|
|
188
186
|
new_img = image.dup
|
189
|
-
new_img.rect(left - 1, top - 1, right + 1, bottom + 1,
|
187
|
+
new_img.rect(region.left - 1, region.top - 1, region.right + 1, region.bottom + 1, border_color)
|
188
|
+
new_img.rect(region.left, region.top, region.right, region.bottom, border_shadow)
|
190
189
|
new_img
|
191
190
|
end
|
192
191
|
end
|
193
192
|
|
194
193
|
private
|
195
194
|
|
196
|
-
def
|
197
|
-
|
195
|
+
def build_region_for_whole_image(new_image)
|
196
|
+
Region.from_edge_coordinates(0, 0, width_for(new_image), height_for(new_image))
|
197
|
+
end
|
198
|
+
|
199
|
+
def find_diff_rectangle(org_img, new_img, area_coordinates)
|
200
|
+
left, top, right, bottom = find_left_right_and_top(org_img, new_img, area_coordinates)
|
198
201
|
bottom = find_bottom(org_img, new_img, left, right, bottom)
|
199
|
-
|
202
|
+
|
203
|
+
Region.from_edge_coordinates(left, top, right, bottom)
|
200
204
|
end
|
201
205
|
|
202
206
|
def find_top(old_img, new_img)
|
@@ -209,10 +213,13 @@ module Capybara
|
|
209
213
|
end
|
210
214
|
|
211
215
|
def find_left_right_and_top(old_img, new_img, region)
|
216
|
+
region = region.is_a?(Region) ? region.to_edge_coordinates : region
|
217
|
+
|
212
218
|
left = region[0] || old_img.width - 1
|
213
219
|
top = region[1]
|
214
220
|
right = region[2] || 0
|
215
221
|
bottom = region[3]
|
222
|
+
|
216
223
|
old_img.height.times do |y|
|
217
224
|
(0...left).find do |x|
|
218
225
|
next if same_color?(old_img, new_img, x, y)
|
@@ -230,6 +237,7 @@ module Capybara
|
|
230
237
|
end
|
231
238
|
end
|
232
239
|
end
|
240
|
+
|
233
241
|
[left, top, right, bottom]
|
234
242
|
end
|
235
243
|
|
@@ -241,13 +249,12 @@ module Capybara
|
|
241
249
|
end
|
242
250
|
end
|
243
251
|
end
|
252
|
+
|
244
253
|
bottom
|
245
254
|
end
|
246
255
|
|
247
256
|
def same_color?(old_img, new_img, x, y)
|
248
|
-
|
249
|
-
return true if skip_start_x <= x && x <= skip_end_x && skip_start_y <= y && y <= skip_end_y
|
250
|
-
end
|
257
|
+
return true if skipped_region?(x, y)
|
251
258
|
|
252
259
|
color_distance =
|
253
260
|
color_distance_at(new_img, old_img, x, y, shift_distance_limit: @shift_distance_limit)
|
@@ -266,6 +273,12 @@ module Capybara
|
|
266
273
|
color_matches
|
267
274
|
end
|
268
275
|
|
276
|
+
def skipped_region?(x, y)
|
277
|
+
return false unless @skip_area
|
278
|
+
|
279
|
+
@skip_area.any? { |region| region.cover?(x, y) }
|
280
|
+
end
|
281
|
+
|
269
282
|
def color_distance_at(new_img, old_img, x, y, shift_distance_limit:)
|
270
283
|
org_color = old_img[x, y]
|
271
284
|
if shift_distance_limit
|