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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 09d303f9090ad8ce75b13714c58bcec25d711602
4
- data.tar.gz: 108512d47e2d4e67e84cdfa2b9456e5368ac58a2
3
+ metadata.gz: bb10aec66c3c56197c20d065c40d832e877a6f6c
4
+ data.tar.gz: c0ceaad44d882dd332bc311f9487254ebddd629e
5
5
  SHA512:
6
- metadata.gz: 67e7111b3708fbad2de5475ee88e8f74b9f47b25a30b66ba06e32372df70d15ccc8fb3d0e43052eeee3b82d1189209326c292691585c8d20b35a0205913184a2
7
- data.tar.gz: 2dd5b305baaa6f592c84218537f2d1a125b9a78ffbc6d59bfcf1cf442fba38719edc6006494de46ae6bc6134f900f0f8390feb56515f82e988d731fd7104f42d
6
+ metadata.gz: 8c77f2d2408b130ae4ddc0da23a4dc57ab2cfb17eeb7d0f70f95856bfd4b5f0d48c55f9098c002c5ff43e233621ab7329034b089dbb8943e132f15b1698a58d8
7
+ data.tar.gz: 61edd95f68244f5d7b63d169a9da0b95be1743c5ebfeaf96f9f226721467ec059f38d76722bd4b53e4dccf7ee562de2e818fd36647d6e40f0ee8d69df223a310
@@ -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.custom_loader = loader
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 :custom_loader
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
- if custom_loader
84
- Percy.logger.debug { 'Using a custom loader to discover assets.' }
85
- custom_loader.new(options)
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
- options[:sprockets_environment] = sprockets_environment
89
- options[:sprockets_options] = sprockets_options
90
- Percy::Capybara::Loaders::SprocketsLoader.new(options)
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(options)
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.asset_path(logical_path)
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?
@@ -1,5 +1,5 @@
1
1
  module Percy
2
2
  module Capybara
3
- VERSION = '2.3.6'
3
+ VERSION = '2.4.0'
4
4
  end
5
5
  end
@@ -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 a custom loader has been set' do
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.custom_loader = DummyLoader
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 clients custom loader' do
85
- expect(Percy::Capybara.capybara_client.custom_loader).to_not be
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.custom_loader).to be
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.3.6
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-01-26 00:00:00.000000000 Z
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.4.8
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