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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c4cc56770f66ae733c1b919f38301d17b7910c2
4
- data.tar.gz: 0698249b05a20484631589ba84c68440e30b8844
3
+ metadata.gz: 1c71d17b90a56a54122b7ab3ca6b6ba5d191afc1
4
+ data.tar.gz: 59ae7c7476a3bf8ad24df13fcd5c645762d7a7fa
5
5
  SHA512:
6
- metadata.gz: 8c577cb415023e6ab72549983e00f9db56a228a796648775820debb839bee6cf232ff4fffd4ed36225d6ab18491da6d781aee638b10ea70e6022d0e33050bf93
7
- data.tar.gz: cfb935770d5bb6d5e7223045584a0a337debe8d6f14705b8bd25459eb713691b3bacb08c792c14d8474d9b05dc8e593c68feb6a77eaecdfcfa1335a0d3ee95fc
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
- @current_build = client.create_build(client.config.repo, options)
19
- _upload_missing_build_resources(build_resources) if !build_resources.empty?
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
- client.finalize_build(current_build['data']['id'])
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
- snapshot = client.create_snapshot(current_build_id, resources, name: name)
62
- snapshot['data']['relationships']['missing-resources']['data'].each do |missing_resource|
63
- sha = missing_resource['id']
64
- client.upload_resource(current_build_id, resource_map[sha].content)
65
- end
66
- Percy.logger.debug { "All snapshot resources uploaded (#{Time.now - start}s)" }
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
@@ -1,5 +1,5 @@
1
1
  module Percy
2
2
  module Capybara
3
- VERSION = '0.6.1'
3
+ VERSION = '0.7.0'
4
4
  end
5
5
  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 be_falsey
118
+ expect(capybara_client.build_initialized?).to eq(false)
46
119
 
47
120
  capybara_client.initialize_build
48
- expect(capybara_client.build_initialized?).to be_truthy
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 be_truthy
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 be_falsey
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 be_truthy
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.6.1
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-12 00:00:00.000000000 Z
11
+ date: 2015-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: percy-client