percy-capybara 2.3.6 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/percy/capybara.rb +3 -2
- data/lib/percy/capybara/client.rb +29 -8
- data/lib/percy/capybara/loaders/filesystem_loader.rb +59 -0
- data/lib/percy/capybara/loaders/sprockets_loader.rb +1 -1
- data/lib/percy/capybara/version.rb +1 -1
- data/spec/lib/percy/capybara/client_spec.rb +31 -2
- data/spec/lib/percy/capybara/loaders/filesystem_loader_spec.rb +113 -0
- data/spec/lib/percy/capybara_spec.rb +11 -4
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb10aec66c3c56197c20d065c40d832e877a6f6c
|
4
|
+
data.tar.gz: c0ceaad44d882dd332bc311f9487254ebddd629e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c77f2d2408b130ae4ddc0da23a4dc57ab2cfb17eeb7d0f70f95856bfd4b5f0d48c55f9098c002c5ff43e233621ab7329034b089dbb8943e132f15b1698a58d8
|
7
|
+
data.tar.gz: 61edd95f68244f5d7b63d169a9da0b95be1743c5ebfeaf96f9f226721467ec059f38d76722bd4b53e4dccf7ee562de2e818fd36647d6e40f0ee8d69df223a310
|
data/lib/percy/capybara.rb
CHANGED
@@ -53,8 +53,9 @@ module Percy
|
|
53
53
|
capybara_client.disable!
|
54
54
|
end
|
55
55
|
|
56
|
-
def self.use_loader(loader)
|
57
|
-
capybara_client.
|
56
|
+
def self.use_loader(loader, options = {})
|
57
|
+
capybara_client.loader = loader
|
58
|
+
capybara_client.loader_options = options
|
58
59
|
end
|
59
60
|
end
|
60
61
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'percy/capybara/client/builds'
|
2
2
|
require 'percy/capybara/client/snapshots'
|
3
|
+
require 'percy/capybara/loaders/filesystem_loader'
|
3
4
|
require 'percy/capybara/loaders/native_loader'
|
4
5
|
require 'percy/capybara/loaders/sprockets_loader'
|
5
6
|
|
@@ -17,7 +18,8 @@ module Percy
|
|
17
18
|
|
18
19
|
attr_accessor :sprockets_environment
|
19
20
|
attr_accessor :sprockets_options
|
20
|
-
attr_accessor :
|
21
|
+
attr_accessor :loader
|
22
|
+
attr_accessor :loader_options
|
21
23
|
|
22
24
|
def initialize(options = {})
|
23
25
|
@failed = false
|
@@ -25,6 +27,8 @@ module Percy
|
|
25
27
|
@client = options[:client] || Percy.client
|
26
28
|
@enabled = options[:enabled]
|
27
29
|
|
30
|
+
@loader_options = options[:loader_options] || {}
|
31
|
+
|
28
32
|
if defined?(Rails)
|
29
33
|
@sprockets_environment = options[:sprockets_environment] || Rails.application.assets
|
30
34
|
@sprockets_options = options[:sprockets_options] || Rails.application.config.assets
|
@@ -80,17 +84,34 @@ module Percy
|
|
80
84
|
end
|
81
85
|
|
82
86
|
def initialize_loader(options = {})
|
83
|
-
|
84
|
-
|
85
|
-
|
87
|
+
merged_options = loader_options.merge(options)
|
88
|
+
if loader
|
89
|
+
case loader
|
90
|
+
when :filesystem
|
91
|
+
Percy.logger.debug { 'Using filesystem_loader to discover assets.' }
|
92
|
+
Percy::Capybara::Loaders::FilesystemLoader.new(merged_options)
|
93
|
+
when :native
|
94
|
+
Percy.logger.debug { 'Using native_loader to discover assets (slow).' }
|
95
|
+
Percy::Capybara::Loaders::NativeLoader.new(merged_options)
|
96
|
+
else
|
97
|
+
Percy.logger.debug { 'Using a custom loader to discover assets.' }
|
98
|
+
loader.new(merged_options)
|
99
|
+
end
|
86
100
|
elsif sprockets_environment && sprockets_options
|
87
101
|
Percy.logger.debug { 'Using sprockets_loader to discover assets.' }
|
88
|
-
|
89
|
-
|
90
|
-
Percy::Capybara::Loaders::SprocketsLoader.new(
|
102
|
+
merged_options[:sprockets_environment] = sprockets_environment
|
103
|
+
merged_options[:sprockets_options] = sprockets_options
|
104
|
+
Percy::Capybara::Loaders::SprocketsLoader.new(merged_options)
|
91
105
|
else
|
106
|
+
unless @warned_about_native_loader
|
107
|
+
Percy.logger.warn \
|
108
|
+
'[DEPRECATED] The native_loader is deprecated and will be opt-in in a future release. ' +
|
109
|
+
'You should move to the faster, more reliable filesystem_loader. See the docs for ' +
|
110
|
+
'Non-Rails frameworks: https://percy.io/docs/clients/ruby/capybara '
|
111
|
+
@warned_about_native_loader = true
|
112
|
+
end
|
92
113
|
Percy.logger.debug { 'Using native_loader to discover assets (slower).' }
|
93
|
-
Percy::Capybara::Loaders::NativeLoader.new(
|
114
|
+
Percy::Capybara::Loaders::NativeLoader.new(merged_options)
|
94
115
|
end
|
95
116
|
end
|
96
117
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'percy/capybara/loaders/base_loader'
|
2
|
+
require 'digest'
|
3
|
+
require 'find'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
module Percy
|
7
|
+
module Capybara
|
8
|
+
module Loaders
|
9
|
+
|
10
|
+
# Resource loader that looks for resources in the specified folder.
|
11
|
+
class FilesystemLoader < BaseLoader
|
12
|
+
SKIP_RESOURCE_EXTENSIONS = [
|
13
|
+
'.map', # Ignore source maps.
|
14
|
+
'.gz', # Ignore gzipped files.
|
15
|
+
]
|
16
|
+
MAX_FILESIZE_BYTES = 15 * 1024**2 # 15 MB.
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
# @assets_dir should point to a _compiled_ static assets directory, not source assets.
|
20
|
+
@assets_dir = options[:assets_dir]
|
21
|
+
@base_url = options[:base_url] || ''
|
22
|
+
|
23
|
+
raise ArgumentError.new('assets_dir is required') if @assets_dir.nil? || @assets_dir == ''
|
24
|
+
if !Pathname.new(@assets_dir).absolute?
|
25
|
+
raise ArgumentError.new("assets_dir needs to be an absolute path. Received: #{@assets_dir}")
|
26
|
+
end
|
27
|
+
if !Dir.exist?(@assets_dir)
|
28
|
+
raise ArgumentError.new("assets_dir provided was not found. Received: #{@assets_dir}")
|
29
|
+
end
|
30
|
+
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
def snapshot_resources
|
35
|
+
[root_html_resource]
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_resources
|
39
|
+
resources = []
|
40
|
+
Find.find(@assets_dir).each do |path|
|
41
|
+
# Skip directories.
|
42
|
+
next if !FileTest.file?(path)
|
43
|
+
# Skip certain extensions.
|
44
|
+
next if SKIP_RESOURCE_EXTENSIONS.include?(File.extname(path))
|
45
|
+
# Skip large files, these are hopefully downloads and not used in page rendering.
|
46
|
+
next if File.size(path) > MAX_FILESIZE_BYTES
|
47
|
+
|
48
|
+
# Replace the assets_dir with the base_url to generate the resource_url
|
49
|
+
resource_url = path.sub(@assets_dir, @base_url)
|
50
|
+
|
51
|
+
sha = Digest::SHA256.hexdigest(File.read(path))
|
52
|
+
resources << Percy::Client::Resource.new(resource_url, sha: sha, path: path)
|
53
|
+
end
|
54
|
+
resources
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -47,7 +47,7 @@ module Percy
|
|
47
47
|
|
48
48
|
if defined?(ActionController)
|
49
49
|
# Ask Rails where this asset is (this handles asset_hosts, digest paths, etc.).
|
50
|
-
resource_url = ActionController::Base.helpers.
|
50
|
+
resource_url = ActionController::Base.helpers.assets_dir(logical_path)
|
51
51
|
else
|
52
52
|
# TODO: more robust support for Sprockets usage outside Rails, ie Sinatra.
|
53
53
|
# How do we find the correct path in that case?
|
@@ -94,10 +94,27 @@ RSpec.describe Percy::Capybara::Client do
|
|
94
94
|
describe '#initialize_loader' do
|
95
95
|
let(:capybara_client) { Percy::Capybara::Client.new }
|
96
96
|
|
97
|
-
context 'when
|
97
|
+
context 'when loader has been set to :native' do
|
98
|
+
it 'returns a NativeLoader' do
|
99
|
+
capybara_client.loader = :native
|
100
|
+
loader = capybara_client.initialize_loader
|
101
|
+
expect(loader.class).to eq(Percy::Capybara::Loaders::NativeLoader)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when loader has been set to :filesystem' do
|
106
|
+
it 'returns a FilesystemLoader' do
|
107
|
+
capybara_client.loader = :filesystem
|
108
|
+
capybara_client.loader_options = {assets_dir: '/', base_url: '/'}
|
109
|
+
loader = capybara_client.initialize_loader
|
110
|
+
expect(loader.class).to eq(Percy::Capybara::Loaders::FilesystemLoader)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when loader has been set to a class' do
|
98
115
|
it 'returns an instance of the clients custom loader' do
|
99
116
|
class DummyLoader < Percy::Capybara::Loaders::NativeLoader; end
|
100
|
-
capybara_client.
|
117
|
+
capybara_client.loader = DummyLoader
|
101
118
|
loader = capybara_client.initialize_loader
|
102
119
|
expect(loader.class).to eq(DummyLoader)
|
103
120
|
end
|
@@ -117,5 +134,17 @@ RSpec.describe Percy::Capybara::Client do
|
|
117
134
|
expect(capybara_client.initialize_loader.class).to eq(Percy::Capybara::Loaders::NativeLoader)
|
118
135
|
end
|
119
136
|
end
|
137
|
+
|
138
|
+
context 'when loader_options are set' do
|
139
|
+
let(:loader_class) { Percy::Capybara::Loaders::FilesystemLoader }
|
140
|
+
let(:options) { {assets_dir: 'xyz'} }
|
141
|
+
|
142
|
+
it 'initializes the loader with them' do
|
143
|
+
capybara_client.loader = :filesystem
|
144
|
+
capybara_client.loader_options = options
|
145
|
+
expect(loader_class).to receive(:new).with(options).once
|
146
|
+
capybara_client.initialize_loader
|
147
|
+
end
|
148
|
+
end
|
120
149
|
end
|
121
150
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
RSpec.describe Percy::Capybara::Loaders::FilesystemLoader do
|
2
|
+
let(:fake_page) { OpenStruct.new(current_url: 'http://localhost/foo') }
|
3
|
+
let(:assets_dir) { File.expand_path('../../client/testdata', __FILE__) }
|
4
|
+
let(:base_url) { '/url-prefix' }
|
5
|
+
let(:loader) { described_class.new(base_url: base_url, assets_dir: assets_dir, page: fake_page) }
|
6
|
+
|
7
|
+
describe 'initialize' do
|
8
|
+
context 'assets_dir not specified' do
|
9
|
+
let(:assets_dir) { nil }
|
10
|
+
it 'raises an error' do
|
11
|
+
expect { loader }.to raise_error(ArgumentError)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
context 'assets_dir is not an absolute path' do
|
15
|
+
let(:assets_dir) { '../../client/testdata' }
|
16
|
+
it 'raises an error' do
|
17
|
+
expect { loader }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
context 'assets_dir doesn\'t exist' do
|
21
|
+
let(:assets_dir) { File.expand_path("../../client/testdata-doesnt-exist", __FILE__) }
|
22
|
+
it 'raises an error' do
|
23
|
+
expect { loader }.to raise_error(ArgumentError)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#snapshot_resources', type: :feature, js: true do
|
29
|
+
it 'returns the root HTML' do
|
30
|
+
visit '/'
|
31
|
+
loader = described_class.new(base_url: base_url, assets_dir: assets_dir, page: page)
|
32
|
+
expect(loader.snapshot_resources.collect(&:resource_url)).to match_array(['/'])
|
33
|
+
end
|
34
|
+
it 'returns the visited html resource' do
|
35
|
+
visit '/test-css.html'
|
36
|
+
loader = described_class.new(base_url: base_url, assets_dir: assets_dir, page: page)
|
37
|
+
resource_urls = loader.snapshot_resources.collect(&:resource_url)
|
38
|
+
expect(resource_urls).to match_array(['/test-css.html'])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#build_resources' do
|
43
|
+
context 'assets_dir including all test files' do
|
44
|
+
it 'returns all included assets as resources' do
|
45
|
+
actual_paths = loader.build_resources.collect { |resource| resource.path.gsub(assets_dir, '') }
|
46
|
+
expected_paths = [
|
47
|
+
'/assets/css/digested-f3420c6aee71c137a3ca39727052811bae84b2f37d898f4db242e20656a1579e.css',
|
48
|
+
'/css/base.css',
|
49
|
+
'/css/digested.css',
|
50
|
+
'/css/imports.css',
|
51
|
+
'/css/level0-imports.css',
|
52
|
+
'/css/level1-imports.css',
|
53
|
+
'/css/level2-imports.css',
|
54
|
+
'/css/simple-imports.css',
|
55
|
+
'/iframe.html',
|
56
|
+
'/images/bg-relative-to-root.png',
|
57
|
+
'/images/bg-relative.png',
|
58
|
+
'/images/bg-stacked.png',
|
59
|
+
'/images/img-relative-to-root.png',
|
60
|
+
'/images/img-relative.png',
|
61
|
+
'/images/percy.svg',
|
62
|
+
'/images/srcset-base.png',
|
63
|
+
'/images/srcset-first.png',
|
64
|
+
'/images/srcset-second.png',
|
65
|
+
'/index.html',
|
66
|
+
'/js/base.js',
|
67
|
+
'/public/percy-from-public.svg',
|
68
|
+
'/test-css.html',
|
69
|
+
'/test-iframe.html',
|
70
|
+
'/test-images.html',
|
71
|
+
'/test-localtest-me-images.html',
|
72
|
+
]
|
73
|
+
expect(actual_paths).to eq(expected_paths)
|
74
|
+
|
75
|
+
expected_urls = loader.build_resources.collect { |resource| resource.resource_url }
|
76
|
+
actual_urls = [
|
77
|
+
'/url-prefix/assets/css/digested-f3420c6aee71c137a3ca39727052811bae84b2f37d898f4db242e20656a1579e.css',
|
78
|
+
'/url-prefix/css/base.css',
|
79
|
+
'/url-prefix/css/digested.css',
|
80
|
+
'/url-prefix/css/imports.css',
|
81
|
+
'/url-prefix/css/level0-imports.css',
|
82
|
+
'/url-prefix/css/level1-imports.css',
|
83
|
+
'/url-prefix/css/level2-imports.css',
|
84
|
+
'/url-prefix/css/simple-imports.css',
|
85
|
+
'/url-prefix/iframe.html',
|
86
|
+
'/url-prefix/images/bg-relative-to-root.png',
|
87
|
+
'/url-prefix/images/bg-relative.png',
|
88
|
+
'/url-prefix/images/bg-stacked.png',
|
89
|
+
'/url-prefix/images/img-relative-to-root.png',
|
90
|
+
'/url-prefix/images/img-relative.png',
|
91
|
+
'/url-prefix/images/percy.svg',
|
92
|
+
'/url-prefix/images/srcset-base.png',
|
93
|
+
'/url-prefix/images/srcset-first.png',
|
94
|
+
'/url-prefix/images/srcset-second.png',
|
95
|
+
'/url-prefix/index.html',
|
96
|
+
'/url-prefix/js/base.js',
|
97
|
+
'/url-prefix/public/percy-from-public.svg',
|
98
|
+
'/url-prefix/test-css.html',
|
99
|
+
'/url-prefix/test-iframe.html',
|
100
|
+
'/url-prefix/test-images.html',
|
101
|
+
'/url-prefix/test-localtest-me-images.html',
|
102
|
+
]
|
103
|
+
expect(actual_urls).to eq(expected_urls)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
context 'assets_dir with only skippable resources' do
|
107
|
+
let(:assets_dir) { File.expand_path('../../client/testdata/assets/images', __FILE__) }
|
108
|
+
it 'returns an empty list' do
|
109
|
+
expect(loader.build_resources).to eq([])
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -70,7 +70,7 @@ RSpec.describe Percy::Capybara do
|
|
70
70
|
end
|
71
71
|
describe '#disable!' do
|
72
72
|
it 'sets the current capybara_client to disabled' do
|
73
|
-
capybara_client = Percy::Capybara::Client.new(enabled:true)
|
73
|
+
capybara_client = Percy::Capybara::Client.new(enabled: true)
|
74
74
|
expect(Percy::Capybara).to receive(:capybara_client)
|
75
75
|
.and_return(capybara_client).exactly(3).times
|
76
76
|
expect(Percy::Capybara.capybara_client.enabled?).to eq(true)
|
@@ -81,10 +81,17 @@ RSpec.describe Percy::Capybara do
|
|
81
81
|
describe '#use_loader' do
|
82
82
|
class DummyLoader < Percy::Capybara::Loaders::NativeLoader; end
|
83
83
|
|
84
|
-
it 'sets the current capybara
|
85
|
-
expect(Percy::Capybara.capybara_client.
|
84
|
+
it 'sets the current capybara client\'s loader' do
|
85
|
+
expect(Percy::Capybara.capybara_client.loader).to_not be
|
86
86
|
Percy::Capybara.use_loader(DummyLoader)
|
87
|
-
expect(Percy::Capybara.capybara_client.
|
87
|
+
expect(Percy::Capybara.capybara_client.loader).to be
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'sets the current capybara client\'s loader options' do
|
91
|
+
expect(Percy::Capybara.capybara_client.loader_options).to eq({})
|
92
|
+
Percy::Capybara.use_loader(DummyLoader, {test_option: 3})
|
93
|
+
expect(Percy::Capybara.capybara_client.loader_options).to be
|
94
|
+
expect(Percy::Capybara.capybara_client.loader_options[:test_option]).to eq(3)
|
88
95
|
end
|
89
96
|
end
|
90
97
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: percy-capybara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Perceptual Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: percy-client
|
@@ -187,6 +187,7 @@ files:
|
|
187
187
|
- lib/percy/capybara/client/snapshots.rb
|
188
188
|
- lib/percy/capybara/httpfetcher.rb
|
189
189
|
- lib/percy/capybara/loaders/base_loader.rb
|
190
|
+
- lib/percy/capybara/loaders/filesystem_loader.rb
|
190
191
|
- lib/percy/capybara/loaders/native_loader.rb
|
191
192
|
- lib/percy/capybara/loaders/sprockets_loader.rb
|
192
193
|
- lib/percy/capybara/rspec.rb
|
@@ -225,6 +226,7 @@ files:
|
|
225
226
|
- spec/lib/percy/capybara/client_spec.rb
|
226
227
|
- spec/lib/percy/capybara/httpfetcher_spec.rb
|
227
228
|
- spec/lib/percy/capybara/loaders/base_loader_spec.rb
|
229
|
+
- spec/lib/percy/capybara/loaders/filesystem_loader_spec.rb
|
228
230
|
- spec/lib/percy/capybara/loaders/native_loader_spec.rb
|
229
231
|
- spec/lib/percy/capybara/loaders/sprockets_loader_spec.rb
|
230
232
|
- spec/lib/percy/capybara_spec.rb
|
@@ -250,7 +252,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
252
|
version: '0'
|
251
253
|
requirements: []
|
252
254
|
rubyforge_project:
|
253
|
-
rubygems_version: 2.
|
255
|
+
rubygems_version: 2.6.7
|
254
256
|
signing_key:
|
255
257
|
specification_version: 4
|
256
258
|
summary: Percy::Capybara
|
@@ -288,6 +290,7 @@ test_files:
|
|
288
290
|
- spec/lib/percy/capybara/client_spec.rb
|
289
291
|
- spec/lib/percy/capybara/httpfetcher_spec.rb
|
290
292
|
- spec/lib/percy/capybara/loaders/base_loader_spec.rb
|
293
|
+
- spec/lib/percy/capybara/loaders/filesystem_loader_spec.rb
|
291
294
|
- spec/lib/percy/capybara/loaders/native_loader_spec.rb
|
292
295
|
- spec/lib/percy/capybara/loaders/sprockets_loader_spec.rb
|
293
296
|
- spec/lib/percy/capybara_spec.rb
|