mirror of
https://github.com/teampoltergeist/poltergeist.git
synced 2022-11-09 12:05:00 -05:00

If the click event is fired on the target element, then the caret position that was previously set by, e.g., send_keys(:Left) is lost. This addresses that by first checking if the target element already contains the current selection, meaning we have focus within the target element and don't need to first give it focus. Fixes #493.
854 lines
26 KiB
Ruby
854 lines
26 KiB
Ruby
require 'spec_helper'
|
|
require 'image_size'
|
|
require 'pdf/reader'
|
|
|
|
module Capybara::Poltergeist
|
|
describe Driver do
|
|
before do
|
|
@session = TestSessions::Poltergeist
|
|
@driver = @session.driver
|
|
end
|
|
|
|
after do
|
|
@driver.reset!
|
|
end
|
|
|
|
def session_url(path)
|
|
server = @session.server
|
|
"http://#{server.host}:#{server.port}#{path}"
|
|
end
|
|
|
|
it 'supports a custom phantomjs path' do
|
|
begin
|
|
file = POLTERGEIST_ROOT + '/spec/support/custom_phantomjs_called'
|
|
path = POLTERGEIST_ROOT + '/spec/support/custom_phantomjs'
|
|
|
|
FileUtils.rm_f file
|
|
|
|
driver = Capybara::Poltergeist::Driver.new(nil, :phantomjs => path)
|
|
driver.browser
|
|
|
|
# If the correct custom path is called, it will touch the file.
|
|
# We allow at least 10 secs for this to happen before failing.
|
|
|
|
tries = 0
|
|
until File.exist?(file) || tries == 100
|
|
sleep 0.1
|
|
tries += 1
|
|
end
|
|
|
|
expect(File.exist?(file)).to be_true
|
|
ensure
|
|
driver.quit if driver
|
|
end
|
|
end
|
|
|
|
it 'supports capturing console.log' do
|
|
begin
|
|
output = StringIO.new
|
|
Capybara.register_driver :poltergeist_with_logger do |app|
|
|
Capybara::Poltergeist::Driver.new(app, :phantomjs_logger => output)
|
|
end
|
|
|
|
session = Capybara::Session.new(:poltergeist_with_logger, TestApp)
|
|
session.visit('/poltergeist/console_log')
|
|
expect(output.string).to include('Hello world')
|
|
ensure
|
|
session.driver.quit
|
|
end
|
|
end
|
|
|
|
it 'raises an error and restarts the client if the client dies while executing a command' do
|
|
expect { @driver.browser.command('exit') }.to raise_error(DeadClient)
|
|
@session.visit('/')
|
|
expect(@driver.html).to include('Hello world')
|
|
end
|
|
|
|
it 'quits silently before visit call' do
|
|
driver = Capybara::Poltergeist::Driver.new(nil)
|
|
expect { driver.quit }.not_to raise_error
|
|
end
|
|
|
|
it 'has a viewport size of 1024x768 by default' do
|
|
@session.visit('/')
|
|
expect(
|
|
@driver.evaluate_script('[window.innerWidth, window.innerHeight]')
|
|
).to eq([1024, 768])
|
|
end
|
|
|
|
it 'allows the viewport to be resized' do
|
|
@session.visit('/')
|
|
@driver.resize(200, 400)
|
|
expect(
|
|
@driver.evaluate_script('[window.innerWidth, window.innerHeight]')
|
|
).to eq([200, 400])
|
|
end
|
|
|
|
it 'allows the page to be scrolled' do
|
|
@session.visit('/poltergeist/long_page')
|
|
@driver.resize(10, 10)
|
|
@driver.scroll_to(200, 100)
|
|
expect(
|
|
@driver.evaluate_script('[window.scrollX, window.scrollY]')
|
|
).to eq([200, 100])
|
|
end
|
|
|
|
it 'supports specifying viewport size with an option' do
|
|
begin
|
|
Capybara.register_driver :poltergeist_with_custom_window_size do |app|
|
|
Capybara::Poltergeist::Driver.new(
|
|
app,
|
|
:logger => TestSessions.logger,
|
|
:window_size => [800, 600]
|
|
)
|
|
end
|
|
driver = Capybara::Session.new(:poltergeist_with_custom_window_size, TestApp).driver
|
|
driver.visit(session_url '/')
|
|
expect(
|
|
driver.evaluate_script('[window.innerWidth, window.innerHeight]')
|
|
).to eq([800, 600])
|
|
ensure
|
|
driver.quit if driver
|
|
end
|
|
end
|
|
|
|
shared_examples 'render screen' do
|
|
it 'supports rendering the whole of a page that goes outside the viewport' do
|
|
@session.visit('/poltergeist/long_page')
|
|
|
|
create_screenshot file
|
|
File.open(file, 'rb') do |f|
|
|
expect(ImageSize.new(f.read).size).to eq(
|
|
@driver.evaluate_script('[window.innerWidth, window.innerHeight]')
|
|
)
|
|
end
|
|
|
|
create_screenshot file, full: true
|
|
File.open(file, 'rb') do |f|
|
|
expect(ImageSize.new(f.read).size).to eq(
|
|
@driver.evaluate_script('[document.documentElement.clientWidth, document.documentElement.clientHeight]')
|
|
)
|
|
end
|
|
end
|
|
|
|
it 'supports rendering the entire window when documentElement has no height' do
|
|
@session.visit('/poltergeist/fixed_positioning')
|
|
|
|
create_screenshot file, full: true
|
|
File.open(file, 'rb') do |f|
|
|
expect(ImageSize.new(f.read).size).to eq(
|
|
@driver.evaluate_script('[window.innerWidth, window.innerHeight]')
|
|
)
|
|
end
|
|
end
|
|
|
|
it 'supports rendering just the selected element' do
|
|
@session.visit('/poltergeist/long_page')
|
|
|
|
create_screenshot file, selector: '#penultimate'
|
|
|
|
File.open(file, 'rb') do |f|
|
|
size = @driver.evaluate_script <<-EOS
|
|
function() {
|
|
var ele = document.getElementById('penultimate');
|
|
var rect = ele.getBoundingClientRect();
|
|
return [rect.width, rect.height];
|
|
}();
|
|
EOS
|
|
expect(ImageSize.new(f.read).size).to eq(size)
|
|
end
|
|
end
|
|
|
|
it 'ignores :selector in #save_screenshot if :full => true' do
|
|
@session.visit('/poltergeist/long_page')
|
|
@driver.browser.should_receive(:warn).with(/Ignoring :selector/)
|
|
|
|
create_screenshot file, full: true, selector: '#penultimate'
|
|
|
|
File.open(file, 'rb') do |f|
|
|
expect(ImageSize.new(f.read).size).to eq(
|
|
@driver.evaluate_script('[document.documentElement.clientWidth, document.documentElement.clientHeight]')
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#save_screenshot' do
|
|
let(:format) { :png }
|
|
let(:file) { POLTERGEIST_ROOT + "/spec/tmp/screenshot.#{format}" }
|
|
|
|
def create_screenshot(file, *args)
|
|
@driver.save_screenshot(file, *args)
|
|
end
|
|
|
|
it 'supports rendering the page' do
|
|
FileUtils.rm_f file
|
|
@session.visit('/')
|
|
|
|
@driver.save_screenshot(file)
|
|
|
|
expect(File.exist?(file)).to be_true
|
|
end
|
|
|
|
it 'supports rendering the page with a nonstring path' do
|
|
FileUtils.rm_f file
|
|
@session.visit('/')
|
|
|
|
@driver.save_screenshot(Pathname(file))
|
|
|
|
expect(File.exist?(file)).to be_true
|
|
end
|
|
|
|
|
|
shared_examples 'when #zoom_factor= is set' do
|
|
let(:format) {:xbm}
|
|
it 'changes image dimensions' do
|
|
@session.visit('/poltergeist/zoom_test')
|
|
|
|
black_pixels_count = ->(file) {
|
|
File.read(file).to_s[/{.*}/m][1...-1].split(/\W/).map{|n| n.hex.to_s(2).count('1')}.reduce(:+)
|
|
}
|
|
@driver.save_screenshot(file)
|
|
before = black_pixels_count[file]
|
|
|
|
@driver.zoom_factor = zoom_factor
|
|
@driver.save_screenshot(file)
|
|
after = black_pixels_count[file]
|
|
|
|
expect(after.to_f/before.to_f).to eq(zoom_factor**2)
|
|
end
|
|
end
|
|
|
|
context 'zoom in' do
|
|
let(:zoom_factor) { 2 }
|
|
include_examples 'when #zoom_factor= is set'
|
|
end
|
|
|
|
context 'zoom out' do
|
|
let(:zoom_factor) { 0.5 }
|
|
include_examples 'when #zoom_factor= is set'
|
|
end
|
|
|
|
context 'when #paper_size= is set' do
|
|
let(:format) { :pdf }
|
|
|
|
it 'changes pdf size' do
|
|
@session.visit('/poltergeist/long_page')
|
|
@driver.paper_size = { width: '1in', height: '1in' }
|
|
|
|
@driver.save_screenshot(file)
|
|
|
|
reader = PDF::Reader.new(file)
|
|
reader.pages.each do |page|
|
|
bbox = page.attributes[:MediaBox]
|
|
width = (bbox[2] - bbox[0]) / 72
|
|
expect(width).to eq(1)
|
|
end
|
|
end
|
|
end
|
|
|
|
include_examples 'render screen'
|
|
end
|
|
|
|
describe '#render_base64' do
|
|
let(:file) { POLTERGEIST_ROOT + "/spec/tmp/screenshot.#{format}" }
|
|
|
|
def create_screenshot(file, *args)
|
|
image = @driver.render_base64(format, *args)
|
|
File.open(file, 'wb') { |f| f.write Base64.decode64(image) }
|
|
end
|
|
|
|
it 'supports rendering the page in base64' do
|
|
@session.visit('/')
|
|
|
|
screenshot = @driver.render_base64
|
|
|
|
expect(screenshot.length).to be > 100
|
|
end
|
|
|
|
context 'png' do
|
|
let(:format) { :png }
|
|
include_examples 'render screen'
|
|
end
|
|
|
|
context 'jpeg' do
|
|
let(:format) { :jpeg }
|
|
include_examples 'render screen'
|
|
end
|
|
end
|
|
|
|
context 'setting headers' do
|
|
it 'allows headers to be set' do
|
|
@driver.headers = {
|
|
"Cookie" => "foo=bar",
|
|
"Host" => "foo.com"
|
|
}
|
|
@session.visit('/poltergeist/headers')
|
|
expect(@driver.body).to include('COOKIE: foo=bar')
|
|
expect(@driver.body).to include('HOST: foo.com')
|
|
end
|
|
|
|
it 'allows headers to be read' do
|
|
expect(@driver.headers).to eq({})
|
|
@driver.headers = { 'User-Agent' => 'PhantomJS', 'Host' => 'foo.com' }
|
|
expect(@driver.headers).to eq('User-Agent' => 'PhantomJS', 'Host' => 'foo.com')
|
|
end
|
|
|
|
it 'supports User-Agent' do
|
|
@driver.headers = { 'User-Agent' => 'foo' }
|
|
@session.visit '/'
|
|
expect(@driver.evaluate_script('window.navigator.userAgent')).to eq('foo')
|
|
end
|
|
|
|
it 'sets headers for all HTTP requests' do
|
|
@driver.headers = { 'X-Omg' => 'wat' }
|
|
@session.visit '/'
|
|
@driver.execute_script <<-JS
|
|
var request = new XMLHttpRequest();
|
|
request.open('GET', '/poltergeist/headers', false);
|
|
request.send();
|
|
|
|
if (request.status === 200) {
|
|
document.body.innerHTML = request.responseText;
|
|
}
|
|
JS
|
|
expect(@driver.body).to include('X_OMG: wat')
|
|
end
|
|
|
|
it 'adds new headers' do
|
|
@driver.headers = { 'User-Agent' => 'PhantomJS', 'Host' => 'foo.com' }
|
|
@driver.add_headers('User-Agent' => 'Poltergeist', 'Appended' => 'true')
|
|
@session.visit('/poltergeist/headers')
|
|
expect(@driver.body).to include('USER_AGENT: Poltergeist')
|
|
expect(@driver.body).to include('HOST: foo.com')
|
|
expect(@driver.body).to include('APPENDED: true')
|
|
end
|
|
|
|
it 'sets headers on the initial request' do
|
|
@driver.headers = { 'PermanentA' => 'a' }
|
|
@driver.add_headers('PermanentB' => 'b')
|
|
@driver.add_header('Referer', 'http://google.com', :permanent => false)
|
|
@driver.add_header('TempA', 'a', :permanent => false)
|
|
|
|
@session.visit('/poltergeist/headers_with_ajax')
|
|
initial_request = @session.find(:css, '#initial_request').text
|
|
ajax_request = @session.find(:css, '#ajax_request').text
|
|
|
|
expect(initial_request).to include('PERMANENTA: a')
|
|
expect(initial_request).to include('PERMANENTB: b')
|
|
expect(initial_request).to include('REFERER: http://google.com')
|
|
expect(initial_request).to include('TEMPA: a')
|
|
|
|
expect(ajax_request).to include('PERMANENTA: a')
|
|
expect(ajax_request).to include('PERMANENTB: b')
|
|
expect(ajax_request).to_not include('REFERER: http://google.com')
|
|
expect(ajax_request).to_not include('TEMPA: a')
|
|
end
|
|
end
|
|
|
|
it 'supports clicking precise coordinates' do
|
|
@session.visit('/poltergeist/click_coordinates')
|
|
@driver.click(100, 150)
|
|
expect(@driver.body).to include('x: 100, y: 150')
|
|
end
|
|
|
|
it 'supports executing multiple lines of javascript' do
|
|
@driver.execute_script <<-JS
|
|
var a = 1
|
|
var b = 2
|
|
window.result = a + b
|
|
JS
|
|
expect(@driver.evaluate_script("result")).to eq(3)
|
|
end
|
|
|
|
it 'operates a timeout when communicating with phantomjs' do
|
|
begin
|
|
prev_timeout = @driver.timeout
|
|
@driver.timeout = 0.001
|
|
expect { @driver.browser.command 'noop' }.to raise_error(TimeoutError)
|
|
ensure
|
|
@driver.timeout = prev_timeout
|
|
end
|
|
end
|
|
|
|
unless Capybara::Poltergeist.windows?
|
|
# Not sure how to do this on Windows, so skipping
|
|
it 'supports quitting the session' do
|
|
driver = Capybara::Poltergeist::Driver.new(nil)
|
|
pid = driver.client_pid
|
|
|
|
expect(Process.kill(0, pid)).to eq(1)
|
|
driver.quit
|
|
|
|
begin
|
|
Process.kill(0, pid)
|
|
rescue Errno::ESRCH
|
|
else
|
|
raise "process is still alive"
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'extending browser javascript' do
|
|
before do
|
|
@extended_driver = Capybara::Poltergeist::Driver.new(
|
|
@session.app,
|
|
:logger => TestSessions.logger,
|
|
:inspector => (ENV['DEBUG'] != nil),
|
|
:extensions => %W% #{File.expand_path '../../support/geolocation.js', __FILE__ } %
|
|
)
|
|
end
|
|
|
|
it 'supports extending the phantomjs world' do
|
|
begin
|
|
@extended_driver.visit session_url("/poltergeist/requiring_custom_extension")
|
|
expect(@extended_driver.body).
|
|
to include(%Q%Location: <span id="location">1,-1</span>%)
|
|
expect(
|
|
@extended_driver.evaluate_script("document.getElementById('location').innerHTML")
|
|
).to eq('1,-1')
|
|
expect(
|
|
@extended_driver.evaluate_script('navigator.geolocation')
|
|
).to_not eq(nil)
|
|
ensure
|
|
@extended_driver.quit
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'javascript errors' do
|
|
it 'propagates a Javascript error inside Poltergeist to a ruby exception' do
|
|
expect { @driver.browser.command 'browser_error' }.to raise_error(BrowserError)
|
|
|
|
begin
|
|
@driver.browser.command 'browser_error'
|
|
rescue BrowserError => e
|
|
expect(e.message).to include("Error: zomg")
|
|
expect(e.message).to include("compiled/browser.js")
|
|
else
|
|
raise "BrowserError expected"
|
|
end
|
|
end
|
|
|
|
it 'propagates an asynchronous Javascript error on the page to a ruby exception' do
|
|
@driver.execute_script "setTimeout(function() { omg }, 0)"
|
|
sleep 0.01
|
|
expect { @driver.execute_script "" }.to raise_error(JavascriptError)
|
|
|
|
begin
|
|
@driver.execute_script "setTimeout(function() { omg }, 0)"
|
|
sleep 0.01
|
|
@driver.execute_script ""
|
|
rescue JavascriptError => e
|
|
expect(e.message).to include("omg")
|
|
expect(e.message).to include("ReferenceError")
|
|
else
|
|
raise "expected JavascriptError"
|
|
end
|
|
end
|
|
|
|
it 'propagates a synchronous Javascript error on the page to a ruby exception' do
|
|
expect { @driver.execute_script "omg" }.to raise_error(JavascriptError)
|
|
|
|
begin
|
|
@driver.execute_script "omg"
|
|
rescue JavascriptError => e
|
|
expect(e.message).to include("omg")
|
|
expect(e.message).to include("ReferenceError")
|
|
else
|
|
raise "expected JavascriptError"
|
|
end
|
|
end
|
|
|
|
it "doesn't re-raise a Javascript error if it's rescued" do
|
|
begin
|
|
@driver.execute_script "setTimeout(function() { omg }, 0)"
|
|
sleep 0.01
|
|
@driver.execute_script ""
|
|
rescue JavascriptError
|
|
else
|
|
raise "expected JavascriptError"
|
|
end
|
|
|
|
# should not raise again
|
|
expect(@driver.evaluate_script("1+1")).to eq(2)
|
|
end
|
|
|
|
it 'propagates a Javascript error during page load to a ruby exception' do
|
|
expect { @session.visit "/poltergeist/js_error" }.to raise_error(JavascriptError)
|
|
end
|
|
|
|
it "doesn't propagate a Javascript error to ruby if error raising disabled" do
|
|
begin
|
|
driver = Capybara::Poltergeist::Driver.new(@session.app, :js_errors => false, logger: TestSessions.logger)
|
|
driver.visit session_url("/poltergeist/js_error")
|
|
driver.execute_script "setTimeout(function() { omg }, 0)"
|
|
sleep 0.1
|
|
expect(driver.body).to include("hello")
|
|
ensure
|
|
driver.quit if driver
|
|
end
|
|
end
|
|
end
|
|
|
|
context "phantomjs {'status': 'fail'} responses" do
|
|
before { @port = @session.server.port }
|
|
it "Do not occur when DNS correct" do
|
|
expect { @session.visit("http://localhost:#{@port}/") }.not_to raise_error
|
|
end
|
|
|
|
it "Should handle when DNS incorrect" do
|
|
expect { @session.visit("http://nope:#{@port}/") }.to raise_error(StatusFailError)
|
|
end
|
|
it "Should have a descriptive message when DNS incorrect" do
|
|
begin
|
|
@session.visit("http://nope:#{@port}/")
|
|
rescue StatusFailError => e
|
|
expect(e.message).to include("Request failed to reach server, check DNS and/or server status")
|
|
else
|
|
raise "expected StatusFailError"
|
|
end
|
|
end
|
|
end
|
|
|
|
context "network traffic" do
|
|
before do
|
|
@driver.restart
|
|
end
|
|
|
|
it "keeps track of network traffic" do
|
|
@session.visit('/poltergeist/with_js')
|
|
urls = @driver.network_traffic.map(&:url)
|
|
|
|
expect(urls.grep(%r{/poltergeist/jquery-1.6.2.min.js$}).size).to eq(1)
|
|
expect(urls.grep(%r{/poltergeist/jquery-ui-1.8.14.min.js$}).size).to eq(1)
|
|
expect(urls.grep(%r{/poltergeist/test.js$}).size).to eq(1)
|
|
end
|
|
|
|
it "captures responses" do
|
|
@session.visit('/poltergeist/with_js')
|
|
request = @driver.network_traffic.last
|
|
|
|
expect(request.response_parts.last.status).to eq(200)
|
|
end
|
|
|
|
it "keeps a running list between multiple web page views" do
|
|
@session.visit('/poltergeist/with_js')
|
|
expect(@driver.network_traffic.length).to eq(4)
|
|
|
|
@session.visit('/poltergeist/with_js')
|
|
expect(@driver.network_traffic.length).to eq(8)
|
|
end
|
|
|
|
it "gets cleared on restart" do
|
|
@session.visit('/poltergeist/with_js')
|
|
expect(@driver.network_traffic.length).to eq(4)
|
|
|
|
@driver.restart
|
|
|
|
@session.visit('/poltergeist/with_js')
|
|
expect(@driver.network_traffic.length).to eq(4)
|
|
end
|
|
|
|
it "gets cleared when being cleared" do
|
|
@session.visit('/poltergeist/with_js')
|
|
expect(@driver.network_traffic.length).to eq(4)
|
|
|
|
@driver.clear_network_traffic
|
|
|
|
expect(@driver.network_traffic.length).to eq(0)
|
|
end
|
|
end
|
|
|
|
context 'status code support' do
|
|
it 'determines status from the simple response' do
|
|
@session.visit('/poltergeist/status/500')
|
|
expect(@driver.status_code).to eq(500)
|
|
end
|
|
|
|
it 'determines status code when the page has a few resources' do
|
|
@session.visit('/poltergeist/with_different_resources')
|
|
expect(@driver.status_code).to eq(200)
|
|
end
|
|
|
|
it 'determines status code even after redirect' do
|
|
@session.visit('/poltergeist/redirect')
|
|
expect(@driver.status_code).to eq(200)
|
|
end
|
|
end
|
|
|
|
context 'cookies support' do
|
|
it 'returns set cookies' do
|
|
@session.visit('/set_cookie')
|
|
|
|
cookie = @driver.cookies['capybara']
|
|
expect(cookie.name).to eq('capybara')
|
|
expect(cookie.value).to eq('test_cookie')
|
|
expect(cookie.domain).to eq('127.0.0.1')
|
|
expect(cookie.path).to eq('/')
|
|
expect(cookie.secure?).to be_false
|
|
expect(cookie.httponly?).to be_false
|
|
expect(cookie.expires).to be_nil
|
|
end
|
|
|
|
it 'can set cookies' do
|
|
@driver.set_cookie 'capybara', 'omg'
|
|
@session.visit('/get_cookie')
|
|
expect(@driver.body).to include('omg')
|
|
end
|
|
|
|
it 'can set cookies when a space exists in the url' do
|
|
@session.visit '/poltergeist/arbitrary_path/200/foo bar'
|
|
@driver.set_cookie 'capybara', 'omg'
|
|
end
|
|
|
|
it 'can set cookies with custom settings' do
|
|
@driver.set_cookie 'capybara', 'omg', :path => '/poltergeist'
|
|
|
|
@session.visit('/get_cookie')
|
|
expect(@driver.body).to_not include('omg')
|
|
|
|
@session.visit('/poltergeist/get_cookie')
|
|
expect(@driver.body).to include('omg')
|
|
|
|
expect(@driver.cookies['capybara'].path).to eq('/poltergeist')
|
|
end
|
|
|
|
it 'can remove a cookie' do
|
|
@session.visit('/set_cookie')
|
|
|
|
@session.visit('/get_cookie')
|
|
expect(@driver.body).to include('test_cookie')
|
|
|
|
@driver.remove_cookie 'capybara'
|
|
|
|
@session.visit('/get_cookie')
|
|
expect(@driver.body).to_not include('test_cookie')
|
|
end
|
|
|
|
it 'can set cookies with an expires time' do
|
|
time = Time.at(Time.now.to_i + 10000)
|
|
@session.visit '/'
|
|
@driver.set_cookie 'foo', 'bar', :expires => time
|
|
expect(@driver.cookies['foo'].expires).to eq(time)
|
|
end
|
|
|
|
it 'can set cookies for given domain' do
|
|
port = @session.server.port
|
|
@driver.set_cookie 'capybara', '127.0.0.1'
|
|
@driver.set_cookie 'capybara', 'localhost', :domain => 'localhost'
|
|
|
|
@session.visit("http://localhost:#{port}/poltergeist/get_cookie")
|
|
expect(@driver.body).to include('localhost')
|
|
|
|
@session.visit("http://127.0.0.1:#{port}/poltergeist/get_cookie")
|
|
expect(@driver.body).to include('127.0.0.1')
|
|
end
|
|
|
|
it 'can enable and disable cookies' do
|
|
@driver.cookies_enabled = false
|
|
@session.visit('/set_cookie')
|
|
expect(@driver.cookies).to be_empty
|
|
|
|
@driver.cookies_enabled = true
|
|
@session.visit('/set_cookie')
|
|
expect(@driver.cookies).to_not be_empty
|
|
end
|
|
end
|
|
|
|
it "allows the driver to have a fixed port" do
|
|
begin
|
|
driver = Capybara::Poltergeist::Driver.new(@driver.app, port: 12345)
|
|
driver.visit session_url('/')
|
|
|
|
expect { TCPServer.new("127.0.0.1", 12345) }.to raise_error(Errno::EADDRINUSE)
|
|
ensure
|
|
driver.quit
|
|
end
|
|
end
|
|
|
|
it 'lists the open windows' do
|
|
@session.visit '/'
|
|
|
|
@session.evaluate_script <<-CODE
|
|
window.open('/poltergeist/simple', 'popup')
|
|
CODE
|
|
|
|
@session.evaluate_script <<-CODE
|
|
window.open('/poltergeist/simple', 'popup2')
|
|
CODE
|
|
|
|
@session.within_window 'popup2' do
|
|
expect(@session.html).to include('Test')
|
|
@session.evaluate_script('window.close()')
|
|
end
|
|
|
|
sleep 0.1;
|
|
|
|
expect(@driver.browser.window_handles).to eq(["popup"])
|
|
expect(@driver.window_handles).to eq(["popup"])
|
|
end
|
|
|
|
context 'basic http authentication' do
|
|
it 'denies without credentials' do
|
|
@session.visit '/poltergeist/basic_auth'
|
|
|
|
expect(@session.status_code).to eq(401)
|
|
expect(@session).not_to have_content('Welcome, authenticated client')
|
|
end
|
|
|
|
it 'allows with given credentials' do
|
|
@driver.basic_authorize('login', 'pass')
|
|
|
|
@session.visit '/poltergeist/basic_auth'
|
|
|
|
expect(@session.status_code).to eq(200)
|
|
expect(@session).to have_content('Welcome, authenticated client')
|
|
end
|
|
|
|
it 'allows even overwriting headers' do
|
|
@driver.basic_authorize('login', 'pass')
|
|
@driver.headers = [{ 'Poltergeist' => 'true' }]
|
|
|
|
@session.visit '/poltergeist/basic_auth'
|
|
|
|
expect(@session.status_code).to eq(200)
|
|
expect(@session).to have_content('Welcome, authenticated client')
|
|
end
|
|
|
|
it 'denies with wrong credentials' do
|
|
@driver.basic_authorize('user', 'pass!')
|
|
|
|
@session.visit '/poltergeist/basic_auth'
|
|
|
|
expect(@session.status_code).to eq(401)
|
|
expect(@session).not_to have_content('Welcome, authenticated client')
|
|
end
|
|
|
|
it 'allows on POST request' do
|
|
@driver.basic_authorize('login', 'pass')
|
|
|
|
@session.visit '/poltergeist/basic_auth'
|
|
@session.click_button('Submit')
|
|
|
|
expect(@session.status_code).to eq(200)
|
|
expect(@session).to have_content('Authorized POST request')
|
|
end
|
|
end
|
|
|
|
context 'has ability to send keys' do
|
|
before { @session.visit('/poltergeist/send_keys') }
|
|
|
|
it 'sends keys to empty input' do
|
|
input = @session.find(:css, '#empty_input')
|
|
|
|
input.native.send_keys('Input')
|
|
|
|
expect(input.value).to eq('Input')
|
|
end
|
|
|
|
it 'sends keys to filled input' do
|
|
input = @session.find(:css, '#filled_input')
|
|
|
|
input.native.send_keys(' appended')
|
|
|
|
expect(input.value).to eq('Text appended')
|
|
end
|
|
|
|
it 'sends keys to empty textarea' do
|
|
input = @session.find(:css, '#empty_textarea')
|
|
|
|
input.native.send_keys('Input')
|
|
|
|
expect(input.value).to eq('Input')
|
|
end
|
|
|
|
it 'sends keys to filled textarea' do
|
|
input = @session.find(:css, '#filled_textarea')
|
|
|
|
input.native.send_keys(' appended')
|
|
|
|
expect(input.value).to eq('Description appended')
|
|
end
|
|
|
|
it 'sends keys to empty contenteditable div' do
|
|
input = @session.find(:css, '#empty_div')
|
|
|
|
input.native.send_keys('Input')
|
|
|
|
expect(input.text).to eq('Input')
|
|
end
|
|
|
|
it 'persists focus across calls' do
|
|
input = @session.find(:css, '#empty_div')
|
|
|
|
input.native.send_keys('helo')
|
|
input.native.send_keys(:Left)
|
|
input.native.send_keys('l')
|
|
|
|
expect(input.text).to eq('hello')
|
|
end
|
|
|
|
it 'sends keys to filled contenteditable div' do
|
|
input = @session.find(:css, '#filled_div')
|
|
|
|
input.native.send_keys(' appended')
|
|
|
|
expect(input.text).to eq('Content appended')
|
|
end
|
|
|
|
it 'sends sequences' do
|
|
input = @session.find(:css, '#empty_input')
|
|
|
|
input.native.send_keys(:Shift, 'S', :Alt, 't', 'r', 'i', 'g', :Left, 'n')
|
|
|
|
expect(input.value).to eq('String')
|
|
end
|
|
|
|
it 'submits the form with sequence' do
|
|
input = @session.find(:css, '#without_submit_button input')
|
|
|
|
input.native.send_keys(:Enter)
|
|
|
|
expect(input.value).to eq('Submitted')
|
|
end
|
|
|
|
it 'raises error on modifier' do
|
|
input = @session.find(:css, '#empty_input')
|
|
|
|
expect { input.native.send_keys([:Shift, 's'], 'tring') }
|
|
.to raise_error(Capybara::Poltergeist::Error)
|
|
end
|
|
|
|
it 'has an alias' do
|
|
input = @session.find(:css, '#empty_input')
|
|
|
|
input.native.send_key('S')
|
|
|
|
expect(input.value).to eq('S')
|
|
end
|
|
end
|
|
|
|
context "set" do
|
|
before { @session.visit('/poltergeist/set') }
|
|
|
|
it "sets a contenteditable's content" do
|
|
input = @session.find(:css, '#filled_div')
|
|
input.set('new text')
|
|
expect(input.text).to eq('new text')
|
|
end
|
|
|
|
it "sets multiple contenteditables' content" do
|
|
input = @session.find(:css, '#empty_div')
|
|
input.set('new text')
|
|
|
|
expect(input.text).to eq('new text')
|
|
|
|
input = @session.find(:css, '#filled_div')
|
|
input.set('replacement text')
|
|
|
|
expect(input.text).to eq('replacement text')
|
|
end
|
|
end
|
|
end
|
|
end
|