percy-capybara 0.6.1 → 0.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/lib/percy/capybara/client.rb +18 -0
- data/lib/percy/capybara/client/builds.rb +16 -3
- data/lib/percy/capybara/client/snapshots.rb +14 -9
- data/lib/percy/capybara/version.rb +1 -1
- data/spec/lib/percy/capybara/client/builds_spec.rb +86 -35
- data/spec/lib/percy/capybara/client/snapshots_spec.rb +11 -0
- data/spec/lib/percy/capybara/client_spec.rb +46 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c71d17b90a56a54122b7ab3ca6b6ba5d191afc1
|
4
|
+
data.tar.gz: 59ae7c7476a3bf8ad24df13fcd5c645762d7a7fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d7c169bcadc15579454c9f433a7de8e044213e5679fead6d6fef24798ee52b71f5bf8686add411fbb443bf0ca55c513c3c3b5e68562bc945ff0662e31c5871b
|
7
|
+
data.tar.gz: 1dab69ac68f0c303d658932ced422b3655a59c6c084c53cebbbe14c667c38aad777c1334b84330e4de3cc5892aa5e1965a044e48e03e16fa1cd4afdb4864b08d
|
@@ -38,6 +38,24 @@ module Percy
|
|
38
38
|
@enabled ||= !Percy::Client::Environment.current_ci.nil?
|
39
39
|
end
|
40
40
|
|
41
|
+
def rescue_connection_failures(&block)
|
42
|
+
raise ArgumentError.new('block is requried') if !block_given?
|
43
|
+
begin
|
44
|
+
block.call
|
45
|
+
rescue Percy::Client::HttpError,
|
46
|
+
Percy::Client::ConnectionFailed,
|
47
|
+
Percy::Client::TimeoutError => e
|
48
|
+
Percy.logger.error(e)
|
49
|
+
@enabled = false
|
50
|
+
@failed = true
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def failed?
|
56
|
+
return !!@failed
|
57
|
+
end
|
58
|
+
|
41
59
|
def initialize_loader(options = {})
|
42
60
|
if sprockets_environment && sprockets_options
|
43
61
|
Percy.logger.debug { 'Using sprockets_loader to discover assets.' }
|
@@ -15,8 +15,14 @@ module Percy
|
|
15
15
|
build_resources.each { |br| Percy.logger.debug { "Build resource: #{br.resource_url}" } }
|
16
16
|
Percy.logger.debug { "All build resources loaded (#{Time.now - start}s)" }
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
rescue_connection_failures do
|
19
|
+
@current_build = client.create_build(client.config.repo, options)
|
20
|
+
_upload_missing_build_resources(build_resources) if !build_resources.empty?
|
21
|
+
end
|
22
|
+
if failed?
|
23
|
+
Percy.logger.error { "Percy build failed! Check log above for errors." }
|
24
|
+
return
|
25
|
+
end
|
20
26
|
@current_build
|
21
27
|
end
|
22
28
|
|
@@ -35,7 +41,14 @@ module Percy
|
|
35
41
|
raise Percy::Capybara::Client::BuildNotInitializedError.new(
|
36
42
|
'Failed to finalize build because no build has been initialized.')
|
37
43
|
end
|
38
|
-
|
44
|
+
result = rescue_connection_failures do
|
45
|
+
client.finalize_build(current_build['data']['id'])
|
46
|
+
end
|
47
|
+
if failed?
|
48
|
+
Percy.logger.error { "Percy build failed! Check log above for errors." }
|
49
|
+
return
|
50
|
+
end
|
51
|
+
result
|
39
52
|
end
|
40
53
|
|
41
54
|
# @private
|
@@ -58,16 +58,21 @@ module Percy
|
|
58
58
|
|
59
59
|
# Create the snapshot and upload any missing snapshot resources.
|
60
60
|
start = Time.now
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# Finalize the snapshot.
|
69
|
-
client.finalize_snapshot(snapshot['data']['id'])
|
61
|
+
rescue_connection_failures do
|
62
|
+
snapshot = client.create_snapshot(current_build_id, resources, name: name)
|
63
|
+
snapshot['data']['relationships']['missing-resources']['data'].each do |missing_resource|
|
64
|
+
sha = missing_resource['id']
|
65
|
+
client.upload_resource(current_build_id, resource_map[sha].content)
|
66
|
+
end
|
67
|
+
Percy.logger.debug { "All snapshot resources uploaded (#{Time.now - start}s)" }
|
70
68
|
|
69
|
+
# Finalize the snapshot.
|
70
|
+
client.finalize_snapshot(snapshot['data']['id'])
|
71
|
+
end
|
72
|
+
if failed?
|
73
|
+
Percy.logger.error { "Percy build failed! Check log above for errors." }
|
74
|
+
return
|
75
|
+
end
|
71
76
|
true
|
72
77
|
end
|
73
78
|
end
|
@@ -2,7 +2,9 @@ RSpec.describe Percy::Capybara::Client::Builds do
|
|
2
2
|
let(:enabled) { true }
|
3
3
|
let(:capybara_client) { Percy::Capybara::Client.new(enabled: enabled) }
|
4
4
|
|
5
|
-
describe '#initialize_build' do
|
5
|
+
describe '#initialize_build', type: :feature, js: true do
|
6
|
+
before(:each) { setup_sprockets(capybara_client) }
|
7
|
+
|
6
8
|
context 'percy is not enabled' do
|
7
9
|
let(:enabled) { false }
|
8
10
|
it 'returns nil if not enabled' do
|
@@ -20,6 +22,77 @@ RSpec.describe Percy::Capybara::Client::Builds do
|
|
20
22
|
.to_return(status: 201, body: mock_response.to_json)
|
21
23
|
expect(capybara_client.initialize_build).to eq(mock_response)
|
22
24
|
end
|
25
|
+
it 'uploads missing build resources' do
|
26
|
+
visit '/'
|
27
|
+
loader = capybara_client.initialize_loader(page: page)
|
28
|
+
mock_response = {
|
29
|
+
'data' => {
|
30
|
+
'id' => '123',
|
31
|
+
'type' => 'builds',
|
32
|
+
'relationships' => {
|
33
|
+
'self' => "/api/v1/snapshots/123",
|
34
|
+
'missing-resources' => {
|
35
|
+
'data' => [
|
36
|
+
{
|
37
|
+
'type' => 'resources',
|
38
|
+
'id' => loader.build_resources.first.sha,
|
39
|
+
},
|
40
|
+
],
|
41
|
+
},
|
42
|
+
},
|
43
|
+
},
|
44
|
+
}
|
45
|
+
# Stub create build.
|
46
|
+
build_stub = stub_request(:post, 'https://percy.io/api/v1/repos/percy/percy-capybara/builds/')
|
47
|
+
.to_return(status: 201, body: mock_response.to_json)
|
48
|
+
|
49
|
+
# Stub resource upload.
|
50
|
+
resources_stub = stub_request(:post, "https://percy.io/api/v1/builds/123/resources/")
|
51
|
+
.to_return(status: 201, body: {success: true}.to_json)
|
52
|
+
capybara_client.initialize_build
|
53
|
+
|
54
|
+
expect(resources_stub).to have_been_requested
|
55
|
+
expect(build_stub).to have_been_requested
|
56
|
+
end
|
57
|
+
it 'safely handles connection errors when creating build' do
|
58
|
+
expect(capybara_client.client).to receive(:create_build)
|
59
|
+
.and_raise(Percy::Client::ConnectionFailed)
|
60
|
+
expect(capybara_client.initialize_build).to eq(nil)
|
61
|
+
expect(capybara_client.failed?).to eq(true)
|
62
|
+
end
|
63
|
+
it 'safely handles connection errors when uploading missing build_resources' do
|
64
|
+
visit '/'
|
65
|
+
loader = capybara_client.initialize_loader(page: page)
|
66
|
+
mock_response = {
|
67
|
+
'data' => {
|
68
|
+
'id' => '123',
|
69
|
+
'type' => 'builds',
|
70
|
+
'relationships' => {
|
71
|
+
'self' => "/api/v1/snapshots/123",
|
72
|
+
'missing-resources' => {
|
73
|
+
'data' => [
|
74
|
+
{
|
75
|
+
'type' => 'resources',
|
76
|
+
'id' => loader.build_resources.first.sha,
|
77
|
+
},
|
78
|
+
],
|
79
|
+
},
|
80
|
+
},
|
81
|
+
},
|
82
|
+
}
|
83
|
+
# Stub create build.
|
84
|
+
build_stub = stub_request(:post, 'https://percy.io/api/v1/repos/percy/percy-capybara/builds/')
|
85
|
+
.to_return(status: 201, body: mock_response.to_json)
|
86
|
+
|
87
|
+
# Stub resource upload.
|
88
|
+
expect(capybara_client.client).to receive(:upload_resource)
|
89
|
+
.and_raise(Percy::Client::ConnectionFailed)
|
90
|
+
|
91
|
+
result = capybara_client.initialize_build
|
92
|
+
expect(capybara_client.initialize_build).to eq(nil)
|
93
|
+
expect(capybara_client.failed?).to eq(true)
|
94
|
+
expect(build_stub).to have_been_requested
|
95
|
+
end
|
23
96
|
end
|
24
97
|
describe '#current_build' do
|
25
98
|
it 'returns nil if no build has been initialized' do
|
@@ -42,10 +115,10 @@ RSpec.describe Percy::Capybara::Client::Builds do
|
|
42
115
|
describe '#build_initialized?' do
|
43
116
|
it 'is false before a build is initialized and true afterward' do
|
44
117
|
expect(capybara_client.client).to receive(:create_build).and_return(double('build'))
|
45
|
-
expect(capybara_client.build_initialized?).to
|
118
|
+
expect(capybara_client.build_initialized?).to eq(false)
|
46
119
|
|
47
120
|
capybara_client.initialize_build
|
48
|
-
expect(capybara_client.build_initialized?).to
|
121
|
+
expect(capybara_client.build_initialized?).to eq(true)
|
49
122
|
end
|
50
123
|
end
|
51
124
|
describe '#finalize_current_build' do
|
@@ -62,6 +135,16 @@ RSpec.describe Percy::Capybara::Client::Builds do
|
|
62
135
|
capybara_client.finalize_current_build
|
63
136
|
end.to raise_error(Percy::Capybara::Client::BuildNotInitializedError)
|
64
137
|
end
|
138
|
+
it 'safely handles connection errors' do
|
139
|
+
build_data = {'data' => {'id' => 123}}
|
140
|
+
expect(capybara_client.client).to receive(:create_build).and_return(build_data)
|
141
|
+
capybara_client.initialize_build
|
142
|
+
|
143
|
+
expect(capybara_client.client).to receive(:finalize_build)
|
144
|
+
.and_raise(Percy::Client::ConnectionFailed)
|
145
|
+
expect(capybara_client.finalize_current_build).to eq(nil)
|
146
|
+
expect(capybara_client.failed?).to eq(true)
|
147
|
+
end
|
65
148
|
end
|
66
149
|
describe '#_upload_missing_build_resources', type: :feature, js: true do
|
67
150
|
before(:each) { setup_sprockets(capybara_client) }
|
@@ -80,38 +163,6 @@ RSpec.describe Percy::Capybara::Client::Builds do
|
|
80
163
|
loader = capybara_client.initialize_loader
|
81
164
|
expect(capybara_client.send(:_upload_missing_build_resources, loader.build_resources)).to eq(0)
|
82
165
|
end
|
83
|
-
it 'uploads missing resources and returns the number uploaded' do
|
84
|
-
visit '/'
|
85
|
-
loader = capybara_client.initialize_loader(page: page)
|
86
|
-
|
87
|
-
mock_response = {
|
88
|
-
'data' => {
|
89
|
-
'id' => '123',
|
90
|
-
'type' => 'builds',
|
91
|
-
'relationships' => {
|
92
|
-
'self' => "/api/v1/snapshots/123",
|
93
|
-
'missing-resources' => {
|
94
|
-
'data' => [
|
95
|
-
{
|
96
|
-
'type' => 'resources',
|
97
|
-
'id' => loader.build_resources.first.sha,
|
98
|
-
},
|
99
|
-
],
|
100
|
-
},
|
101
|
-
},
|
102
|
-
},
|
103
|
-
}
|
104
|
-
# Stub create build.
|
105
|
-
stub_request(:post, 'https://percy.io/api/v1/repos/percy/percy-capybara/builds/')
|
106
|
-
.to_return(status: 201, body: mock_response.to_json)
|
107
|
-
|
108
|
-
# Stub resource upload.
|
109
|
-
stub_request(:post, "https://percy.io/api/v1/builds/123/resources/")
|
110
|
-
.to_return(status: 201, body: {success: true}.to_json)
|
111
|
-
capybara_client.initialize_build
|
112
|
-
result = capybara_client.send(:_upload_missing_build_resources, loader.build_resources)
|
113
|
-
expect(result).to eq(1)
|
114
|
-
end
|
115
166
|
end
|
116
167
|
|
117
168
|
end
|
@@ -73,6 +73,17 @@ RSpec.describe Percy::Capybara::Client::Snapshots, type: :feature do
|
|
73
73
|
remove_request_stub(build_resource_stub)
|
74
74
|
expect(capybara_client.snapshot(page)).to eq(true)
|
75
75
|
end
|
76
|
+
it 'safely handles connection errors' do
|
77
|
+
visit '/'
|
78
|
+
build_data = {'data' => {'id' => 123}}
|
79
|
+
expect(capybara_client.client).to receive(:create_build).and_return(build_data)
|
80
|
+
capybara_client.initialize_build
|
81
|
+
|
82
|
+
expect(capybara_client.client).to receive(:create_snapshot)
|
83
|
+
.and_raise(Percy::Client::ConnectionFailed)
|
84
|
+
expect(capybara_client.snapshot(page)).to eq(nil)
|
85
|
+
expect(capybara_client.failed?).to eq(true)
|
86
|
+
end
|
76
87
|
end
|
77
88
|
end
|
78
89
|
end
|
@@ -17,15 +17,58 @@ RSpec.describe Percy::Capybara::Client do
|
|
17
17
|
context 'in supported CI environment' do
|
18
18
|
it 'is true' do
|
19
19
|
ENV['TRAVIS_BUILD_ID'] = '123'
|
20
|
-
expect(Percy::Capybara::Client.new.enabled?).to
|
20
|
+
expect(Percy::Capybara::Client.new.enabled?).to eq(true)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
it 'is false by default for local dev environments or unknown CI environments' do
|
24
|
-
expect(Percy::Capybara::Client.new.enabled?).to
|
24
|
+
expect(Percy::Capybara::Client.new.enabled?).to eq(false)
|
25
25
|
end
|
26
26
|
it 'is true if PERCY_ENABLE=1 is set' do
|
27
27
|
ENV['PERCY_ENABLE'] = '1'
|
28
|
-
expect(Percy::Capybara::Client.new.enabled?).to
|
28
|
+
expect(Percy::Capybara::Client.new.enabled?).to eq(true)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
describe '#failed?' do
|
32
|
+
it 'is false by default' do
|
33
|
+
expect(Percy::Capybara::Client.new.failed?).to eq(false)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
describe '#rescue_connection_failures' do
|
37
|
+
let(:capybara_client) { Percy::Capybara::Client.new(enabled: true) }
|
38
|
+
it 'returns block result on success' do
|
39
|
+
result = capybara_client.rescue_connection_failures do
|
40
|
+
true
|
41
|
+
end
|
42
|
+
expect(result).to eq(true)
|
43
|
+
expect(capybara_client.enabled?).to eq(true)
|
44
|
+
expect(capybara_client.failed?).to eq(false)
|
45
|
+
end
|
46
|
+
it 'makes block safe from HttpError' do
|
47
|
+
result = capybara_client.rescue_connection_failures do
|
48
|
+
raise Percy::Client::HttpError.new(500, 'POST', '', '')
|
49
|
+
end
|
50
|
+
expect(result).to eq(nil)
|
51
|
+
expect(capybara_client.enabled?).to eq(false)
|
52
|
+
expect(capybara_client.failed?).to eq(true)
|
53
|
+
end
|
54
|
+
it 'makes block safe from ConnectionFailed' do
|
55
|
+
result = capybara_client.rescue_connection_failures do
|
56
|
+
raise Percy::Client::ConnectionFailed
|
57
|
+
end
|
58
|
+
expect(result).to eq(nil)
|
59
|
+
expect(capybara_client.enabled?).to eq(false)
|
60
|
+
expect(capybara_client.failed?).to eq(true)
|
61
|
+
end
|
62
|
+
it 'makes block safe from TimeoutError' do
|
63
|
+
result = capybara_client.rescue_connection_failures do
|
64
|
+
raise Percy::Client::TimeoutError
|
65
|
+
end
|
66
|
+
expect(result).to eq(nil)
|
67
|
+
expect(capybara_client.enabled?).to eq(false)
|
68
|
+
expect(capybara_client.failed?).to eq(true)
|
69
|
+
end
|
70
|
+
it 'requires a block' do
|
71
|
+
expect { capybara_client.rescue_connection_failures }.to raise_error(ArgumentError)
|
29
72
|
end
|
30
73
|
end
|
31
74
|
describe '#initialize_loader' do
|
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: 0.
|
4
|
+
version: 0.7.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: 2015-10-
|
11
|
+
date: 2015-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: percy-client
|