# rubocop:disable RSpec/MultipleDescribes
RSpec.describe Percy, type: :feature do
dom_string = "
I am a pageSnapshot me\n"
fetch_script_string = 'window.PercyDOM = {' \
'serialize: () => {' \
'return {' \
'html: document.documentElement.outerHTML,' \
'cookies: ""' \
'}' \
'},' \
'waitForResize: () => {' \
'if(!window.resizeCount) {' \
'window.addEventListener(\'resize\', () => window.resizeCount++)' \
'}' \
'window.resizeCount = 0;' \
'}};'
before(:each) do
WebMock.disable_net_connect!(allow: '127.0.0.1', disallow: 'localhost')
stub_request(:post, 'http://localhost:5338/percy/log').to_raise(StandardError)
Percy._clear_cache!
end
describe 'snapshot', type: :feature, js: true do
it 'disables when healthcheck version is incorrect' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_return(status: 200, body: '', headers: {'x-percy-core-version': '0.1.0'})
expect { Percy.snapshot(page, 'Name') }
.to output("#{Percy::LABEL} Unsupported Percy CLI version, 0.1.0\n").to_stdout
end
it 'disables when healthcheck version is missing' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_return(status: 200, body: '', headers: {})
expect { Percy.snapshot(page, 'Name') }
.to output(
"#{Percy::LABEL} You may be using @percy/agent which" \
' is no longer supported by this SDK. Please uninstall' \
' @percy/agent and install @percy/cli instead.' \
" https://www.browserstack.com/docs/percy/migration/migrate-to-cli\n",
).to_stdout
end
it 'disables when healthcheck fails' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_return(status: 500, body: '', headers: {})
expect { Percy.snapshot(page, 'Name') }
.to output("#{Percy::LABEL} Percy is not running, disabling snapshots\n").to_stdout
end
it 'disables when healthcheck fails to connect' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_raise(StandardError)
expect { Percy.snapshot(page, 'Name') }
.to output("#{Percy::LABEL} Percy is not running, disabling snapshots\n").to_stdout
end
it 'throws an error when driver is not provided' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_return(status: 500, body: '', headers: {})
expect { Percy.snapshot }.to raise_error(ArgumentError)
end
it 'throws an error when name is not provided' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_return(status: 500, body: '', headers: {})
expect { Percy.snapshot(page) }.to raise_error(ArgumentError)
end
it 'logs an error when sending a snapshot fails' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_return(status: 200, body: '{"success": "true" }',
headers: {'x-percy-core-version': '1.0.0'},)
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/dom.js")
.to_return(
status: 200,
body: fetch_script_string,
headers: {},
)
stub_request(:post, 'http://localhost:5338/percy/snapshot')
.to_return(status: 200, body: '', headers: {})
expect { Percy.snapshot(page, 'Name') }
.to output("#{Percy::LABEL} Could not take DOM snapshot 'Name'\n").to_stdout
end
it 'sends snapshots to the local server' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_return(status: 200, body: '{"success": "true" }', headers: {
'x-percy-core-version': '1.0.0',
},)
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/dom.js")
.to_return(
status: 200,
body: fetch_script_string,
headers: {},
)
stub_request(:post, 'http://localhost:5338/percy/snapshot')
.to_return(status: 200, body: '{"success": "true" }', headers: {})
visit 'index.html'
data = Percy.snapshot(page, 'Name', widths: [944])
expect(WebMock).to have_requested(:post, "#{Percy::PERCY_SERVER_ADDRESS}/percy/snapshot")
.with(
body: {
name: 'Name',
url: 'http://127.0.0.1:3003/index.html',
dom_snapshot:
{"cookies": [], "html": dom_string},
client_info: "percy-selenium-ruby/#{Percy::VERSION}",
environment_info: "selenium/#{Selenium::WebDriver::VERSION} ruby/#{RUBY_VERSION}",
widths: [944],
}.to_json,
).once
expect(data).to eq(nil)
end
it 'sends multiple dom snapshots to the local server' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck").to_return(
status: 200,
body: '{"success": "true", "widths": { "mobile": [390], "config": [765, 1280]} }',
headers: {
'x-percy-core-version': '1.0.0',
'config': {}, 'widths': {'mobile': [375], 'config': [765, 1280]},
},
)
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/dom.js")
.to_return(
status: 200,
body: fetch_script_string,
headers: {},
)
stub_request(:post, 'http://localhost:5338/percy/snapshot')
.to_return(status: 200, body: '{"success": "true" }', headers: {})
visit 'index.html'
data = Percy.snapshot(page, 'Name', {responsive_snapshot_capture: true})
expect(WebMock).to have_requested(:post, "#{Percy::PERCY_SERVER_ADDRESS}/percy/snapshot")
.with(
body: {
name: 'Name',
url: 'http://127.0.0.1:3003/index.html',
dom_snapshot: [
{'cookies': [], 'html': dom_string, 'width': 390},
{'cookies': [], 'html': dom_string, 'width': 765},
{'cookies': [], 'html': dom_string, 'width': 1280},
],
client_info: "percy-selenium-ruby/#{Percy::VERSION}",
environment_info: "selenium/#{Selenium::WebDriver::VERSION} ruby/#{RUBY_VERSION}",
responsive_snapshot_capture: true,
}.to_json,
).once
expect(data).to eq(nil)
end
it 'sends multiple dom snapshots to the local server using selenium' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck").to_return(
status: 200,
body: '{"success": "true", "widths": { "mobile": [390], "config": [765, 1280]} }',
headers: {
'x-percy-core-version': '1.0.0',
'config': {}, 'widths': {'mobile': [375], 'config': [765, 1280]},
},
)
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/dom.js")
.to_return(
status: 200,
body: fetch_script_string,
headers: {},
)
stub_request(:post, 'http://localhost:5338/percy/snapshot')
.to_return(status: 200, body: '{"success": "true" }', headers: {})
driver = Selenium::WebDriver.for :firefox
driver.navigate.to 'http://localhost:5338/test/snapshot'
driver.manage.add_cookie({name: 'cookie-name', value: 'cookie-value'})
data = Percy.snapshot(driver, 'Name', {responsive_snapshot_capture: true})
expected_cookie = {name: 'cookie-name', value: 'cookie-value', path: '/',
domain: 'localhost', "expires": nil, "same_site": 'Lax',
"http_only": false, "secure": false,}
expected_dom = 'Snapshot Me!
'
expect(WebMock).to have_requested(:post, "#{Percy::PERCY_SERVER_ADDRESS}/percy/snapshot")
.with(
body: {
name: 'Name',
url: 'http://localhost:5338/test/snapshot',
dom_snapshot: [
{'cookies': [expected_cookie], 'html': expected_dom, 'width': 390},
{'cookies': [expected_cookie], 'html': expected_dom, 'width': 765},
{'cookies': [expected_cookie], 'html': expected_dom, 'width': 1280},
],
client_info: "percy-selenium-ruby/#{Percy::VERSION}",
environment_info: "selenium/#{Selenium::WebDriver::VERSION} ruby/#{RUBY_VERSION}",
responsive_snapshot_capture: true,
}.to_json,
).once
expect(data).to eq(nil)
end
it 'sends snapshots for sync' do
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/healthcheck")
.to_return(status: 200, body: '{"success": "true" }',
headers: {'x-percy-core-version': '1.0.0'},)
stub_request(:get, "#{Percy::PERCY_SERVER_ADDRESS}/percy/dom.js")
.to_return(
status: 200,
body: fetch_script_string,
headers: {},
)
stub_request(:post, 'http://localhost:5338/percy/snapshot')
.to_return(status: 200, body: '{"success": "true", "data": "sync_data" }', headers: {})
visit 'index.html'
data = Percy.snapshot(page, 'Name', {sync: true})
expect(WebMock).to have_requested(:post, "#{Percy::PERCY_SERVER_ADDRESS}/percy/snapshot")
.with(
body: {
name: 'Name',
url: 'http://127.0.0.1:3003/index.html',
dom_snapshot:
{'cookies' => [], 'html' => dom_string},
client_info: "percy-selenium-ruby/#{Percy::VERSION}",
environment_info: "selenium/#{Selenium::WebDriver::VERSION} ruby/#{RUBY_VERSION}",
sync: true,
}.to_json,
).once
expect(data).to eq('sync_data')
end
end
end
RSpec.describe Percy, type: :feature do
before(:each) do
WebMock.reset!
WebMock.allow_net_connect!
Percy._clear_cache!
end
describe 'integration', type: :feature do
it 'sends snapshots to percy server' do
visit 'index.html'
Percy.snapshot(page, 'Name', widths: [375])
sleep 5 # wait for percy server to process
resp = Net::HTTP.get_response(URI("#{Percy::PERCY_SERVER_ADDRESS}/test/requests"))
requests = JSON.parse(resp.body)['requests']
healthcheck = requests[0]
expect(healthcheck['url']).to eq('/percy/healthcheck')
snap = requests[2]['body']
expect(snap['name']).to eq('Name')
expect(snap['url']).to eq('http://127.0.0.1:3003/index.html')
expect(snap['client_info']).to include('percy-selenium-ruby')
expect(snap['environment_info']).to include('selenium')
expect(snap['widths']).to eq([375])
end
end
end
# rubocop:enable RSpec/MultipleDescribes