capybara-screenshot-diff 1.6.3 → 1.7.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 +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
|
-
[](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
|