percy-capybara 4.3.0 → 5.0.0.pre.2
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/release-drafter.yml +31 -0
- data/.github/workflows/changelog.yml +11 -0
- data/.github/workflows/lint.yml +22 -0
- data/.github/workflows/release.yml +22 -0
- data/.github/workflows/test.yml +26 -0
- data/.rubocop.yml +4 -5
- data/Gemfile +3 -0
- data/LICENSE +1 -1
- data/Makefile +3 -0
- data/README.md +98 -4
- data/lib/percy/capybara.rb +111 -0
- data/lib/percy/version.rb +3 -0
- data/percy-capybara.gemspec +7 -7
- data/spec/fixture/index.html +1 -0
- data/spec/lib/percy/percy_capybara_spec.rb +103 -0
- data/spec/spec_helper.rb +22 -4
- metadata +48 -35
- data/.circleci/config.yml +0 -38
- data/CHANGELOG.md +0 -1
- data/DEVELOPING.md +0 -26
- data/RELEASING.md +0 -23
- data/lib/environment.rb +0 -38
- data/lib/percy.rb +0 -143
- data/lib/version.rb +0 -3
- data/package.json +0 -6
- data/spec/lib/percy/environment_spec.rb +0 -26
- data/spec/lib/percy/percy_spec.rb +0 -72
- data/yarn.lock +0 -2132
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
LABEL = PercyCapybara::PERCY_LABEL
|
|
2
|
+
|
|
3
|
+
RSpec.describe PercyCapybara, type: :feature do
|
|
4
|
+
before(:each) do
|
|
5
|
+
WebMock.disable_net_connect!(allow: '127.0.0.1', disallow: 'localhost')
|
|
6
|
+
page.__percy_clear_cache!
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe 'snapshot', type: :feature do
|
|
10
|
+
it 'disables when healthcheck version is incorrect' do
|
|
11
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/healthcheck")
|
|
12
|
+
.to_return(status: 200, body: '', headers: {'x-percy-core-version': '0.1.0'})
|
|
13
|
+
|
|
14
|
+
expect { page.percy_snapshot('Name') }
|
|
15
|
+
.to output("#{LABEL} Unsupported Percy CLI version, 0.1.0\n").to_stdout
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'disables when healthcheck version is missing' do
|
|
19
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/healthcheck")
|
|
20
|
+
.to_return(status: 200, body: '', headers: {})
|
|
21
|
+
|
|
22
|
+
expect { page.percy_snapshot('Name') }
|
|
23
|
+
.to output(
|
|
24
|
+
"#{LABEL} You may be using @percy/agent which" \
|
|
25
|
+
' is no longer supported by this SDK. Please uninstall' \
|
|
26
|
+
' @percy/agent and install @percy/cli instead.' \
|
|
27
|
+
" https://docs.percy.io/docs/migrating-to-percy-cli\n",
|
|
28
|
+
).to_stdout
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'disables when healthcheck fails' do
|
|
32
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/healthcheck")
|
|
33
|
+
.to_return(status: 500, body: '', headers: {})
|
|
34
|
+
|
|
35
|
+
expect { page.percy_snapshot('Name') }
|
|
36
|
+
.to output("#{LABEL} Percy is not running, disabling snapshots\n").to_stdout
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'disables when healthcheck fails to connect' do
|
|
40
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/healthcheck")
|
|
41
|
+
.to_raise(StandardError)
|
|
42
|
+
|
|
43
|
+
expect { page.percy_snapshot('Name') }
|
|
44
|
+
.to output("#{LABEL} Percy is not running, disabling snapshots\n").to_stdout
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'throws an error when name is not provided' do
|
|
48
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/healthcheck")
|
|
49
|
+
.to_return(status: 500, body: '', headers: {})
|
|
50
|
+
|
|
51
|
+
expect { page.percy_snapshot }.to raise_error(ArgumentError)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'logs an error when sending a snapshot fails' do
|
|
55
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/healthcheck")
|
|
56
|
+
.to_return(status: 200, body: '', headers: {'x-percy-core-version': '1.0.0'})
|
|
57
|
+
|
|
58
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/dom.js")
|
|
59
|
+
.to_return(
|
|
60
|
+
status: 200,
|
|
61
|
+
body: 'window.PercyDOM = { serialize: () => document.documentElement.outerHTML };',
|
|
62
|
+
headers: {},
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
stub_request(:post, 'http://localhost:5338/percy/snapshot')
|
|
66
|
+
.to_return(status: 200, body: '', headers: {})
|
|
67
|
+
|
|
68
|
+
expect { page.percy_snapshot('Name') }
|
|
69
|
+
.to output("#{LABEL} Could not take DOM snapshot 'Name'\n").to_stdout
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'sends snapshots to the local server' do
|
|
73
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/healthcheck")
|
|
74
|
+
.to_return(status: 200, body: '', headers: {'x-percy-core-version': '1.0.0'})
|
|
75
|
+
|
|
76
|
+
stub_request(:get, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/dom.js")
|
|
77
|
+
.to_return(
|
|
78
|
+
status: 200,
|
|
79
|
+
body: 'window.PercyDOM = { serialize: () => document.documentElement.outerHTML };',
|
|
80
|
+
headers: {},
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
stub_request(:post, 'http://localhost:5338/percy/snapshot')
|
|
84
|
+
.to_return(status: 200, body: '{"success": "true" }', headers: {})
|
|
85
|
+
|
|
86
|
+
visit 'index.html'
|
|
87
|
+
page.percy_snapshot('Name')
|
|
88
|
+
|
|
89
|
+
expect(WebMock)
|
|
90
|
+
.to have_requested(:post, "#{PercyCapybara::PERCY_SERVER_ADDRESS}/percy/snapshot")
|
|
91
|
+
.with(
|
|
92
|
+
body: {
|
|
93
|
+
name: 'Name',
|
|
94
|
+
url: 'http://127.0.0.1:3003/index.html',
|
|
95
|
+
dom_snapshot:
|
|
96
|
+
"<html><head><title>I am a page</title></head><body>Snapshot me\n</body></html>",
|
|
97
|
+
client_info: "percy-capybara/#{PercyCapybara::VERSION}",
|
|
98
|
+
environment_info: "capybara/#{Capybara::VERSION} ruby/#{RUBY_VERSION}",
|
|
99
|
+
}.to_json,
|
|
100
|
+
).once
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
# This must be required & started before any app code (for proper coverage)
|
|
2
|
+
require 'simplecov'
|
|
3
|
+
SimpleCov.start
|
|
4
|
+
SimpleCov.minimum_coverage 100
|
|
5
|
+
|
|
1
6
|
require 'capybara/rspec'
|
|
2
|
-
require '
|
|
3
|
-
require 'percy'
|
|
7
|
+
require 'webmock/rspec'
|
|
8
|
+
require 'percy/capybara'
|
|
4
9
|
|
|
5
10
|
RSpec.configure do |config|
|
|
6
11
|
config.expect_with :rspec do |expectations|
|
|
@@ -28,6 +33,19 @@ RSpec.configure do |config|
|
|
|
28
33
|
Kernel.srand config.seed
|
|
29
34
|
|
|
30
35
|
# See https://github.com/teamcapybara/capybara#selecting-the-driver for other options
|
|
31
|
-
Capybara.default_driver = :
|
|
32
|
-
Capybara.javascript_driver = :
|
|
36
|
+
Capybara.default_driver = :selenium_headless
|
|
37
|
+
Capybara.javascript_driver = :selenium_headless
|
|
38
|
+
|
|
39
|
+
# Setup for Capybara to test static files served by Rack
|
|
40
|
+
Capybara.server_port = 3003
|
|
41
|
+
Capybara.server = :puma, { Silent: true }
|
|
42
|
+
Capybara.app = Rack::File.new(File.join(File.dirname(__FILE__), 'fixture'))
|
|
33
43
|
end
|
|
44
|
+
|
|
45
|
+
## Add cache clearing methods for tests
|
|
46
|
+
Capybara::Session.class_eval {
|
|
47
|
+
def __percy_clear_cache!
|
|
48
|
+
@percy_dom = nil
|
|
49
|
+
@percy_enabled = nil
|
|
50
|
+
end
|
|
51
|
+
}
|
metadata
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: percy-capybara
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 5.0.0.pre.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Perceptual Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-05-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: capybara
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '3'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: selenium-webdriver
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 4.0.0.beta1
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 4.0.0.beta1
|
|
13
41
|
- !ruby/object:Gem::Dependency
|
|
14
42
|
name: bundler
|
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -66,20 +94,6 @@ dependencies:
|
|
|
66
94
|
- - "~>"
|
|
67
95
|
- !ruby/object:Gem::Version
|
|
68
96
|
version: '3.31'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: selenium-webdriver
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: percy-style
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -101,28 +115,28 @@ executables: []
|
|
|
101
115
|
extensions: []
|
|
102
116
|
extra_rdoc_files: []
|
|
103
117
|
files:
|
|
104
|
-
- ".
|
|
118
|
+
- ".github/dependabot.yml"
|
|
119
|
+
- ".github/release-drafter.yml"
|
|
120
|
+
- ".github/workflows/changelog.yml"
|
|
121
|
+
- ".github/workflows/lint.yml"
|
|
122
|
+
- ".github/workflows/release.yml"
|
|
123
|
+
- ".github/workflows/test.yml"
|
|
105
124
|
- ".gitignore"
|
|
106
125
|
- ".rspec"
|
|
107
126
|
- ".rubocop.yml"
|
|
108
127
|
- ".yardopts"
|
|
109
|
-
- CHANGELOG.md
|
|
110
|
-
- DEVELOPING.md
|
|
111
128
|
- Gemfile
|
|
112
129
|
- Guardfile
|
|
113
130
|
- LICENSE
|
|
131
|
+
- Makefile
|
|
114
132
|
- README.md
|
|
115
|
-
- RELEASING.md
|
|
116
133
|
- Rakefile
|
|
117
|
-
- lib/
|
|
118
|
-
- lib/percy.rb
|
|
119
|
-
- lib/version.rb
|
|
120
|
-
- package.json
|
|
134
|
+
- lib/percy/capybara.rb
|
|
135
|
+
- lib/percy/version.rb
|
|
121
136
|
- percy-capybara.gemspec
|
|
122
|
-
- spec/
|
|
123
|
-
- spec/lib/percy/
|
|
137
|
+
- spec/fixture/index.html
|
|
138
|
+
- spec/lib/percy/percy_capybara_spec.rb
|
|
124
139
|
- spec/spec_helper.rb
|
|
125
|
-
- yarn.lock
|
|
126
140
|
homepage: ''
|
|
127
141
|
licenses:
|
|
128
142
|
- MIT
|
|
@@ -137,19 +151,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
137
151
|
requirements:
|
|
138
152
|
- - ">="
|
|
139
153
|
- !ruby/object:Gem::Version
|
|
140
|
-
version:
|
|
154
|
+
version: 2.3.0
|
|
141
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
156
|
requirements:
|
|
143
|
-
- - "
|
|
157
|
+
- - ">"
|
|
144
158
|
- !ruby/object:Gem::Version
|
|
145
|
-
version:
|
|
159
|
+
version: 1.3.1
|
|
146
160
|
requirements: []
|
|
147
|
-
|
|
148
|
-
rubygems_version: 2.7.10
|
|
161
|
+
rubygems_version: 3.0.3
|
|
149
162
|
signing_key:
|
|
150
163
|
specification_version: 4
|
|
151
|
-
summary: Percy
|
|
164
|
+
summary: Percy visual testing for Capybara
|
|
152
165
|
test_files:
|
|
153
|
-
- spec/
|
|
154
|
-
- spec/lib/percy/
|
|
166
|
+
- spec/fixture/index.html
|
|
167
|
+
- spec/lib/percy/percy_capybara_spec.rb
|
|
155
168
|
- spec/spec_helper.rb
|
data/.circleci/config.yml
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
version: 2.1
|
|
2
|
-
|
|
3
|
-
default_steps: &default_steps
|
|
4
|
-
steps:
|
|
5
|
-
- checkout
|
|
6
|
-
- run: sudo gem update --system
|
|
7
|
-
- run: ruby -v
|
|
8
|
-
- run: yarn
|
|
9
|
-
- run: bundle install
|
|
10
|
-
- run: yarn percy exec -- bundle exec rspec
|
|
11
|
-
- run: bundle exec rubocop -D
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
ruby_latest_with_percy:
|
|
15
|
-
# This is the one environment where we'll capture and upload snapshots in CI.
|
|
16
|
-
docker:
|
|
17
|
-
- image: circleci/ruby:latest-node-browsers
|
|
18
|
-
<<: *default_steps
|
|
19
|
-
ruby_25:
|
|
20
|
-
docker:
|
|
21
|
-
- image: circleci/ruby:2.5-node-browsers
|
|
22
|
-
environment:
|
|
23
|
-
PERCY_ENABLE: 0
|
|
24
|
-
<<: *default_steps
|
|
25
|
-
ruby_24:
|
|
26
|
-
docker:
|
|
27
|
-
- image: circleci/ruby:2.4-node-browsers
|
|
28
|
-
environment:
|
|
29
|
-
PERCY_ENABLE: 0
|
|
30
|
-
<<: *default_steps
|
|
31
|
-
|
|
32
|
-
workflows:
|
|
33
|
-
version: 2
|
|
34
|
-
test:
|
|
35
|
-
jobs:
|
|
36
|
-
- ruby_latest_with_percy
|
|
37
|
-
- ruby_25
|
|
38
|
-
- ruby_24
|
data/CHANGELOG.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
See [releases](https://github.com/percy/percy-capybara/releases).
|
data/DEVELOPING.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# Developing percy-capybara
|
|
2
|
-
|
|
3
|
-
You'll need:
|
|
4
|
-
* [Ruby](https://www.ruby-lang.org)
|
|
5
|
-
* [Bundler](https://bundler.io/)
|
|
6
|
-
* [npm](https://www.npmjs.com/), to manage our dependency on [`@percy/agent`](https://www.npmjs.com/package/@percy/agent)
|
|
7
|
-
|
|
8
|
-
To install dependencies:
|
|
9
|
-
```bash
|
|
10
|
-
$ bundle install
|
|
11
|
-
$ npm install
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
To run our test suite and create snapshots:
|
|
15
|
-
```bash
|
|
16
|
-
$ bundle exec rake snapshots
|
|
17
|
-
```
|
|
18
|
-
(You'll need a `PERCY_TOKEN` in your environment for snapshots to be uploaded to Percy for diffing.)
|
|
19
|
-
|
|
20
|
-
If you want to run the test suite without uploading snapshots, you can run:
|
|
21
|
-
```bash
|
|
22
|
-
$ bundle exec rspec
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
For instructions on releasing, and on updating the vendored version of `percy-agent.js` in this repository, please refer to the [RELEASING](RELEASING.md) doc.
|
|
26
|
-
|
data/RELEASING.md
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Releasing
|
|
2
|
-
|
|
3
|
-
1. `git checkout master`
|
|
4
|
-
1. `git pull origin master`
|
|
5
|
-
1. `git checkout -b X.X.X`
|
|
6
|
-
1. Update version.rb file accordingly.
|
|
7
|
-
1. Commit and push the version update
|
|
8
|
-
1. Tag the release: `git tag vX.X.X`
|
|
9
|
-
1. Push changes: `git push --tags`
|
|
10
|
-
1. Ensure tests have passed on that tag
|
|
11
|
-
1. Open up a pull request titled with the new version number
|
|
12
|
-
1. Merge approved pull request
|
|
13
|
-
1. Draft and publish a [new release on github](https://github.com/percy/percy-capybara/releases)
|
|
14
|
-
1. Build and publish:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
bundle exec rake build
|
|
18
|
-
gem push pkg/percy-capybara-X.XX.XX.gem
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
* Announce the new release,
|
|
22
|
-
making sure to say "thank you" to the contributors
|
|
23
|
-
who helped shape this version!
|
data/lib/environment.rb
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
require_relative './version'
|
|
2
|
-
|
|
3
|
-
module Percy
|
|
4
|
-
def self.client_info
|
|
5
|
-
"percy-capybara/#{VERSION}"
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def self.environment_info
|
|
9
|
-
env_strings = [
|
|
10
|
-
"rails/#{self._rails_version}",
|
|
11
|
-
"sinatra/#{self._sinatra_version}",
|
|
12
|
-
"capybara/#{self.capybara_version}",
|
|
13
|
-
"ember-cli-rails/#{self._ember_cli_rails_version}",
|
|
14
|
-
].reject do |info|
|
|
15
|
-
info =~ /\/$/ # reject if version is empty
|
|
16
|
-
end
|
|
17
|
-
env_strings.empty? ? 'unknown' : env_strings.join('; ')
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def self.capybara_version
|
|
21
|
-
Capybara::VERSION if defined? Capybara
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def self._ember_cli_rails_version
|
|
25
|
-
return unless defined? EmberCli
|
|
26
|
-
|
|
27
|
-
require 'ember_cli/version'
|
|
28
|
-
EmberCli::VERSION
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def self._rails_version
|
|
32
|
-
Rails.version if defined? Rails
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def self._sinatra_version
|
|
36
|
-
Sinatra::VERSION if defined? Sinatra
|
|
37
|
-
end
|
|
38
|
-
end
|
data/lib/percy.rb
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
require 'logger'
|
|
2
|
-
require 'net/http'
|
|
3
|
-
require 'uri'
|
|
4
|
-
require 'json'
|
|
5
|
-
require 'environment'
|
|
6
|
-
|
|
7
|
-
module Percy
|
|
8
|
-
# Takes a snapshot of the given page HTML and its assets.
|
|
9
|
-
#
|
|
10
|
-
# See https://docs.percy.io/v1/docs/configuration for detailed documentation on
|
|
11
|
-
# snapshot options.
|
|
12
|
-
#
|
|
13
|
-
# @param [Capybara::Session] page The Capybara page to snapshot.
|
|
14
|
-
# @param [Hash] options
|
|
15
|
-
# @option options [String] :name A unique name for the current page that identifies
|
|
16
|
-
# it across builds. By default this is the URL of the page, but can be customized if the
|
|
17
|
-
# URL does not entirely identify the current state.
|
|
18
|
-
# @option options [Array(Number)] :widths Widths, in pixels, that you'd like to capture for
|
|
19
|
-
# this snapshot.
|
|
20
|
-
def self.snapshot(page, options = {})
|
|
21
|
-
return unless self._is_agent_running?
|
|
22
|
-
|
|
23
|
-
if !options.has_key?(:name)
|
|
24
|
-
options[:name] = page.current_url
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
domSnapshot = self._make_dom_snapshot(page, self._keys_to_json(options))
|
|
28
|
-
return unless domSnapshot
|
|
29
|
-
|
|
30
|
-
body = {
|
|
31
|
-
url: page.current_url,
|
|
32
|
-
domSnapshot: domSnapshot,
|
|
33
|
-
clientInfo: Percy.client_info,
|
|
34
|
-
environmentInfo: Percy.environment_info,
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
body = body.merge(self._keys_to_json(options))
|
|
38
|
-
|
|
39
|
-
if self._is_debug?
|
|
40
|
-
self._logger.info { "passed snapshot options: #{options}" }
|
|
41
|
-
self._logger.info { "snapshot object to POST: #{body}" }
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
self._post_snapshot_to_agent(body)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
|
|
49
|
-
AGENT_HOST = 'localhost'
|
|
50
|
-
# Technically, the port is configurable when you run the agent. One day we might want
|
|
51
|
-
# to make the port configurable in this SDK as well.
|
|
52
|
-
AGENT_PORT = 5338
|
|
53
|
-
AGENT_JS_PATH= '/percy-agent.js'
|
|
54
|
-
|
|
55
|
-
def self._logger
|
|
56
|
-
unless defined?(@logger)
|
|
57
|
-
@logger = Logger.new(STDOUT)
|
|
58
|
-
@logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
|
59
|
-
"[percy] #{msg} \n"
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
return @logger
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def self._get_agent_js
|
|
66
|
-
begin
|
|
67
|
-
return Net::HTTP.get(AGENT_HOST, AGENT_JS_PATH, AGENT_PORT)
|
|
68
|
-
rescue => e
|
|
69
|
-
self._logger.error { "Could not load #{AGENT_JS_PATH}. Error: #{e}" }
|
|
70
|
-
return nil
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def self._make_dom_snapshot(page, options)
|
|
75
|
-
agent_js = self._get_agent_js
|
|
76
|
-
return unless agent_js
|
|
77
|
-
|
|
78
|
-
begin
|
|
79
|
-
page.execute_script(agent_js)
|
|
80
|
-
dom_snapshot_js = "new window.PercyAgent({ handleAgentCommunication: false }).domSnapshot(document, #{options.to_json})"
|
|
81
|
-
|
|
82
|
-
if self._is_capybara?
|
|
83
|
-
dom_snapshot = page.evaluate_script(dom_snapshot_js)
|
|
84
|
-
else
|
|
85
|
-
dom_snapshot = page.execute_script(dom_snapshot_js)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
return dom_snapshot
|
|
89
|
-
rescue => e
|
|
90
|
-
self._logger.error { "DOM snapshotting failed. Error: #{e}" }
|
|
91
|
-
return nil
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def self._post_snapshot_to_agent(body)
|
|
96
|
-
http = Net::HTTP.new(AGENT_HOST, AGENT_PORT)
|
|
97
|
-
request = Net::HTTP::Post.new('/percy/snapshot', { 'Content-Type': 'application/json' })
|
|
98
|
-
request.body = body.to_json
|
|
99
|
-
|
|
100
|
-
begin
|
|
101
|
-
response = http.request(request)
|
|
102
|
-
rescue => e
|
|
103
|
-
self._logger.error { "Percy rejected snapshot request. Error: #{e}" }
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def self._is_agent_running?
|
|
108
|
-
begin
|
|
109
|
-
Net::HTTP.get(AGENT_HOST, '/percy/healthcheck', AGENT_PORT)
|
|
110
|
-
return true
|
|
111
|
-
rescue => e
|
|
112
|
-
if self._is_debug?
|
|
113
|
-
self._logger.error { "Healthcheck failed, Percy is not running: #{e}" }
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
return false
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# For Ruby style, require snake_case args but transform them into camelCase for percy-agent.
|
|
121
|
-
def self._keys_to_json(options)
|
|
122
|
-
{
|
|
123
|
-
enable_javascript: :enableJavaScript,
|
|
124
|
-
min_height: :minHeight,
|
|
125
|
-
percy_css: :percyCSS,
|
|
126
|
-
request_headers: :requestHeaders,
|
|
127
|
-
}.each do |ruby_key, json_key|
|
|
128
|
-
if options.has_key? ruby_key
|
|
129
|
-
options[json_key] = options[ruby_key]
|
|
130
|
-
options.delete(ruby_key)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
return options
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def self._is_debug?
|
|
137
|
-
ENV['LOG_LEVEL'] == 'debug'
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def self._is_capybara?
|
|
141
|
-
Percy.capybara_version.length > 0
|
|
142
|
-
end
|
|
143
|
-
end
|