I am having the issue that phantomjs doesn't render the page correctly when I am running the tests. Please see the attached picture .
Feature Helper Code:
require 'rails_helper'
require 'capybara-screenshot/rspec'
require 'capybara/dsl'
require 'capybara/poltergeist'
Dir[Rails.root.join('spec/features/support/**/*.rb')].each { |f| require f }
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {
js_errors: false,
phantomjs_options: ['--ignore-ssl-errors=yes', '--ssl-protocol=any'],
debug: false,
:timeout => 120,
window_size: [1600, 1200],
# timeout: 5.minutes,
extensions: [
Rails.root.join('spec/features/support/phantomjs/disable_animations.js')
]
})
end
RSpec.configure do |config|
config.include Auth
config.include General
end
Capybara.configure do |config|
config.default_selector = :css
config.javascript_driver = :poltergeist
# config.javascript_driver = :poltergeist_debug
config.server_host = 'foo.xxx.localhost'
Capybara.server_port = 3001
config.default_max_wait_time = 10
end
The latest release versions of PhantomJS (2.1.x) are basically equivalent to a 6-7 year old version of Safari. As such they don't support a lot of modern CSS/JS. Therefore, the most likely reason for incorrect rendering is use of unsupported features in your page. If it's unsupported JS causing your issue then enabling js_errors and/or debug in your driver registration could possibly show that. If it's the use of unsupported CSS (CSS Grid for instance) then no error will be shown and the rendering will just be wrong.
If you need 100% correct rendering and aren't going to modify your app to support old browsers then you probably want to change from using Poltergeist/PhantomJS to the selenium driver with Chrome (in headless mode if wanted).
Related
A Rails app that uses remote testing to test a CakePHP app running on a Vagrant Ubuntu VM.
My OS is macOS High Sierra.
'rspec/rails'
'capybara/rails'
'capybara/mechanize'
'capybara/poltergeist'
'phantomjs'
If I run rspec ./spec/features/my_tests_folder/,
the first 2 tests in the folder always pass and the rest always end up with Capybara::Poltergeist::TimeoutError:.
If I run any of the tests in that folder individually, they ALL pass ALWAYS.
There are 7 test files total. They each have 1 feature with 1 scenario. All are js: true.
I have tried increasing :timeout in Capybara.register_driver and increasing default_max_wait_time in Capybara.configure. Neither changed the outcome.
I've also played around with Capybara.reset! after and before each test. It didn't seem to matter, either.
When I ran this with config.order = :random, sometimes 5 out of 7 had the erros, sometimes only 2 out of 7. But, there were always some errors and some passing. Also, every test was in the errors group at least once.
I'm running out of ideas. What could cause something like this?
UPDATE (to include Capybara and Poltergeist configs and example of a failing test):
Configs in rails_helper.rb:
Capybara.register_driver :poltergeist do |app|
options = {
:timeout => 90, # default is 30
:js_errors => false,
:phantomjs => Phantomjs.path,
# :debug => true
}
Capybara::Poltergeist::Driver.new(app, options)
end
Capybara.register_driver :mechanize do |app|
driver = Capybara::Mechanize::Driver.new(app)
driver.configure do |agent|
agent.user_agent_alias = 'Mac Safari'
end
driver
end
Capybara.configure do |config|
config.run_server = false
config.app_host = "http://my_vm_domain.com"
config.javascript_driver = :poltergeist
config.default_driver = :mechanize
config.default_max_wait_time = 10 # default is 2
end
Example of failing test (not failing, but getting Capybara::Poltergeist::TimeoutError:):
require 'rails_helper'
feature 'agente visualiza estoques de um passeio', js: true do
scenario 'com sucesso' do
agente_log_in
visit '/roteiro/show/723'
find(:partial_href, 'new_passeio/723').click
select 'Passeio Teste', from: 'passeio_produto'
fill_in 'passeio_data', with: '11/11/2017'
within('button#estoque_controls_0') do
within('div#estoque_0_hora') do
expect(page).to have_content('07:30')
end
within('span#estoque_0_vagas') do
expect(page).to have_content('3')
end
end
within('button#estoque_controls_1') do
within('div#estoque_1_hora') do
expect(page).to have_content('10:00')
end
within('span#estoque_1_vagas') do
expect(page).to have_content('5')
end
end
end
end
Code from agente_log_in.rb in support folder:
def agente_log_in
Capybara.app_host = "http://my_vm_domain.com"
visit '/usuario/logout'
visit '/'
fill_in 'data[AdmUsuario][usuario]', with: 'agente'
fill_in 'data[AdmUsuario][senha]', with: 'pa$$w0rd'
click_on 'Entrar'
end
Code for that :partial_href find:
module Selectors
Capybara.add_selector(:partial_href) do
xpath {|href| XPath.descendant[XPath.attr(:href).contains(href)] }
end
end
Everything is fine with the other tests that are in the app's other folders. They're also fine if I run the tests in this folder individually. The problem only seems to happen when I run THIS specific folder as a whole.
After including the extra information requested by Thomas Walpole, I continued searching and studying possibilities.
I eventually came across poltergeist's issue #781 on GitHub, which describes a situation very similar to mine, and eventually presents a wait_for_ajax solution.
Before implementing it in my project, I read more about waiting for Ajax and found this post very helpful, too.
In the end, I chose jasonfb's code from GitHub because it seemed more thorough and informative.
It worked like a charm! My tests now pass consistently. I was even able to remove customization for :timeout and default_max_wait_time.
The CakePHP app in question is very js heavy and the specific part that this folder tests is particularly full of Ajax requests.
Previously, I had Capybara 2.5, and Poltergeist page.save_screenshot worked just fine. But, recently, I've just upgraded my Capybara to 2.15.4, and that caused Poltergeist page.save_screenshot not to work anymore. The file is not created.
Here is my feature spec:
feature 'create', js: true do
before do
visit root_path
end
scenario 'valid' do
page.save_screenshot('test.png')
end
end
spec_helper.rb:
require 'capybara/poltergeist'
Capybara.register_driver :poltergeist do |app|
options = {
js_errors: false,
phantomjs_options: ['--load-images=false', '--ignore-ssl-errors=yes', '--ssl-protocol=any'],
timeout: 60,
debug: true
}
Capybara::Poltergeist::Driver.new(app, options)
end
Capybara.javascript_driver = :poltergeist
My current environment:
Ruby 2.3.3
Capybara 2.15.4
Poltergeist 1.9.0
PhantomJS 2.1.1
You've update Capybara, but not updated Poltergeist. There was an update in Capybara 2.7 where Capybara.save_and_open_page_path was deprecated in favor of Capybara.save_path with slightly different behavior around relative paths. Update Poltergeist as well and your issue will probably go away.
i am trying to run a feature spec with poltergeist and capybara.i see
application javascript is not found error
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
Capybara.default_selector = :css
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, :window_size => [1920, 1080], :phantomjs_logger => nil, :js_errors => false)
end
It sounds like your asset pipeline isn't working correctly in your test environment. This would have nothing to do with Capybara or your driver configuration. Check your config/environements/test.rb to make sure you haven't turned off serving of assets, and try deleting everything in public/assets to see if that will force the tests to rebuild the required assets.
My setup is using poltergeist as the Capybara driver for all my tests, both JS and non-JS.
# spec/rails_helper.rb
require "capybara/poltergeist"
# ...
# ...
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, js_errors: true)
end
Capybara.configure do |config|
config.ignore_hidden_elements = true
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
end
I have some tests where I confirm that certain features on my app are still working even with javascript disabled. For those tests, I of course disable javascript with js: false.
describe "accessibility" do
describe "JavaScript disabled", js: false do
before(:each) { visit root_path }
it "user can still log in" do
# ...
end
end
end
However, I'm noticing that these js:false tests still use JavaScript. I can confirm this by printing debug statements to the console log in JavaScript.
Is there a way to disable JavaScript when using poltergeist? Or is it always enabled? Is it even valid to use poltergeist as a non-JS driver?
Thanks!
No, there doesn't seem to be a way to use poltergeist without Javascript (unless you modify poltergeist yourself). According to this Github issue it would require support in phantomjs, which is available in a patch but not in master.
I have a large test suite that is using poltergeist and capybara. I keep getting the following error:
One or more errors were raised in the Javascript code on the page. If you don't care about
these errors, you can ignore them by setting js_errors: false in your Poltergeist
configuration (see documentation for details).
I am pretty sure I have set js_errors: false but I am still getting the errors. I realize that the optimal solution is to fix the JS but I am inheriting legacy code and fixing the errors is out of scope for my role. My spec helper file looks like this:
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {js_errors: false})
end
Capybara.current_driver = :poltergeist
Capybara.configure do |config|
config.match = :one
config.exact_options = true
config.ignore_hidden_elements = true
config.visible_text_only = true
end
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.infer_base_class_for_anonymous_controllers = false
config.order = "random"
end
I am confused as to where to go or if I am ignoring the JS errors appropriately. Let me know if there is any other information I may have overlooked or neglected to include. Thanks for your time.
I am not sure why your code doesn't work. I just had a similar JS error and did the following (as mentioned on this page (search for js_errors)) -- and basically what Leonardo Galani suggested (I upvoted Leonardo's answer to take it from -1 to 0):
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
options = {js_errors: false}
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, options)
end
I also tested this style, and it worked as well:
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, {js_errors: false})
end
FWIW: My error (in Cucumber test) looked like this:
Capybara::Poltergeist::JavascriptError: One or more errors were raised in the
Javascript code on the page. If you don't care about these errors, you can ignore
them by setting js_errors: false in your Poltergeist configuration (see
documentation for details).
TypeError: Unable to delete property.
TypeError: Unable to delete property.
at :84
at http://maps.gstatic.com/cat_js/maps-api-v3/api/js/17/20/%7Bmain,geometry%7D.js:19 in Ke
at http://maps.gstatic.com/cat_js/maps-api-v3/api/js/17/20/%7Bmain,geometry%7D.js:19 in Ke
at http://maps.gstatic.com/cat_js/maps-api-v3/api/js/17/20/%7Bmain,geometry%7D.js:18
#Leonardo Galani
According to the ruby style guide, your syntax comment isn't true. So the answer could be {js_errors: false} too.
https://github.com/bbatsov/ruby-style-guide#hash-literals
I had the same issue, js_errors: false did not solve the problem, but phantomjs_logger: "/dev/null" yes!