Poltergeist throws JS errors when js_errors: false - capybara

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!

Related

Phantomjs does not load the CSS/JS correctly

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).

Disabling JavaScript when using Poltergeist and Capybara's default driver

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.

Spork & Rails 3.1 engine: helpers are not reloaded

I'm developing a Rails 3.1 engine and want to test it. I use RSpec for this, and everything works nicely, but when trying to use Spork, I have the problem that my helpers are not correctly reloaded.
I read a lot about a similar problem with models, and I came up with the following possible fix:
# my_engine/spec/spec_helper.rb
ActiveSupport::Dependencies.clear
ActiveRecord::Base.instantiate_observers
Dir[File.join(File.dirname(__FILE__), '..', 'app', 'helpers', '*.rb')].each do |file|
require file
end
# my_engine/spec/dummy/config/environments/test.rb
Dummy::Application.configure do
# ...
config.cache_classes = !(ENV['DRB'] == 'true') # Ensure that classes aren't cached when using Spork.
# ...
end
This works as far as it definitely is reloading ever helper file (I added a breakpoint to check this), but the changes are not reflected within the tests, only a restart of Spork does. Maybe it's because helpers are modules, and the tests don't rely on the module but on the classes that implement the modules, so the modules are properly reloaded but not properly mixed in??
At the time being, I'm just putting all intitializer code into the each_run block:
# Configure Rails Environment
ENV["RAILS_ENV"] = "test"
require File.expand_path("../dummy/config/environment.rb", __FILE__)
require 'rspec/rails'
Rails.backtrace_cleaner.remove_silencers!
# Load support files
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
RSpec.configure do |config|
config.use_transactional_fixtures = true
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
end
I have done a lot of research about this topic, and I've written about in these two blog posts:
How to Develop Rails 3.1 Engines with Ease: Part I – The engine
How to Develop Rails 3.1 Engines with Ease: Part II – The gem
Regarding especially to my question above: I can imagine that it didn't work because I didn't require 'rspec/autorun' in the Spork.prefork block, but I'm not completely sure.
Here's the spec_helper.rb for my current engine (which successfully reloads everything as needed):
require 'rubygems'
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../dummy/config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.use_transactional_fixtures = true
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.infer_base_class_for_anonymous_controllers = false
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
end
end
Spork.each_run do
# This code will be run each time you run your specs.
end

RSpec - shared DB conn. & transactional fixtures not working

I tried to follow José Valim's advice on faster test suites, but to no avail.
I use Spork and put the AR monkey patch in the Spork.each_run block (see the spec helper below).
However, my request specs fail because the database is not cleaned between runs - specifically, I get errors such as expected 1 record, got X when doing assertions like Model.should have(1).record.
Update
The problem lies with request specs using Javascript. See the following spec - it fails when I use js: true, but not if I remove that (I use RSpec's config.treat_symbols_as_metadata_keys_with_true_values = true, fwiw.)
# encoding: UTF-8
require 'spec_helper'
feature "Create a shift", :js do
scenario %q(
In order to plan the workload
As a coordinator
I want to schedule shifts
And I want to see when they're scheduled for
) do
visit shifts_path
click_link "new_shift_#{Date.current}"
fill_in 'shift_note', with: 'Casper - luk'
click_link_or_button 'submit'
Shift.should have(1).record
Shift.last.begins_at.should == Date.current
page.should have_selector("ol[data-date=\"#{Date.current}\"] li#shift_#{Shift.last.id}")
end
end
I can tell it's related to the DB not being cleaned, because it fails the first time (expected 1 record, got 0), passes the second time (because there's 1 record in the DB) and then fails again on any subsequent runs (expected 1 record, got 2 etc.)
I'm trying to avoid using a gem like DatabaseCleaner, to keep dependencies as few as possible, and to avoid a speed decrease in the test suite.
Any help/info/pointers are greatly appreciated!
Relevant info:
Rails 3.2.2
RSpec 2.9.0
Capybara 1.1.2
Capybara-webkit 0.11.0
FactoryGirl 2.6.4
Spork 0.9.0
Guard 1.0.1
Guard-spork 0.5.2
on a Macbook Air, OS X 10.7.3 (if that's relevant)
And my spec helper:
# encoding: UTF-8
require 'rubygems'
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rspec'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :rspec
config.use_transactional_fixtures = true
config.treat_symbols_as_metadata_keys_with_true_values = true
config.infer_base_class_for_anonymous_controllers = false
config.include Factory::Syntax::Methods
Capybara.javascript_driver = :webkit
Rails.logger.level = 4 # speed - http://blog.plataformatec.com.br/tag/capybara/
end
end
Spork.each_run do
require 'factory_girl_rails'
class ActiveRecord::Base
mattr_accessor :shared_connection
##shared_connection = nil
def self.connection
##shared_connection || retrieve_connection
end
end
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
end
After much investigating, the problem seems to be with specs using JS in general, and not really the AR monkey patch.
I've re-phrased the problem in a new question here: RSpec+Capybara request specs w/ JS not working

How to set the ignore_ssl_errors option for Capybara Webkit in spec_helper.rb

In my spec_helper file I have:
Capybara.javascript_driver = :webkit
capybara_webkit now has a ignore_ssl_errors option that I want to use. How do I specify that in my spec_helper?
Here's how to register the :webkit driver with the :ignore_ssl_errors option.
Capybara.register_driver :webkit do |app|
Capybara::Driver::Webkit.new(app, :ignore_ssl_errors => true)
end
As of writing (capybara-webkit 1.7.1), the configuration seems to have been simplified:
Capybara::Webkit.configure do |config|
config.ignore_ssl_errors
end
(source)
Somehow the above register_driver examples don't work with Capybara 1.1.4. The example below is taken from the capybara browser_spec.rb.
Capybara.register_driver :webkit_ignore_ssl do |app|
browser = Capybara::Webkit::Browser.new(Capybara::Webkit::Connection.new).tap do |browser|
browser.ignore_ssl_errors
end
Capybara::Webkit::Driver.new(app, :browser => browser)
end
Capybara.javascript_driver = :webkit_ignore_ssl
As #hjblok says, the interface has changed in recent versions of capybara-webkit. You can simplify the solution slightly:
Capybara.register_driver :webkit_ignore_ssl do |app|
Capybara::Webkit::Driver.new(app).tap {|d| d.browser.ignore_ssl_errors }
end
Capybara.javascript_driver = :webkit_ignore_ssl
When createing a new webkit Object you can use this to ignore the ssl errors
Capybara::Driver::Webkit.new({ :ignore_ssl_errors => true})

Resources