cucumber/cucumber-rails

@javascript tag fails if DatabaseCleaner is not installed

MikhailMS opened this issue · 5 comments

Summary

Basically the issue here is that if you don't have DatabaseCleaner installed, cucumber-rails would fail with

uninitialized constant Cucumber::Rails::Database::Strategy::DatabaseCleaner (NameError)

Expected Behavior

I'd expect cucumber rails just ignore that DatabaseCleaner is not installed and execute test cases, since in the README of the project it says that DatabaseCleaner is not required for cucumber-rails to run

Current Behavior

As of now I see this error

uninitialized constant Cucumber::Rails::Database::Strategy::DatabaseCleaner (NameError)

I tried to have a look into error stacktrace with -b flag, and got

/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/bundler/gems/cucumber-rails-6a8bc4b8d536/lib/cucumber/rails/database.rb:84:in `before_js'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/bundler/gems/cucumber-rails-6a8bc4b8d536/lib/cucumber/rails/database.rb:103:in `before_js'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/bundler/gems/cucumber-rails-6a8bc4b8d536/lib/cucumber/rails/database.rb:29:in `before_js'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/bundler/gems/cucumber-rails-6a8bc4b8d536/lib/cucumber/rails/hooks/active_record.rb:15:in `block in <top (required)>'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/glue/invoke_in_world.rb:36:in `instance_exec'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/glue/invoke_in_world.rb:36:in `block in cucumber_instance_exec_in'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/glue/invoke_in_world.rb:50:in `cucumber_run_with_backtrace_filtering'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/glue/invoke_in_world.rb:26:in `cucumber_instance_exec_in'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/glue/hook.rb:22:in `invoke'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/runtime/before_hooks.rb:25:in `block (2 levels) in before_hooks'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/action.rb:24:in `execute'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/step.rb:35:in `execute'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/runner.rb:106:in `execute'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/runner.rb:53:in `execute'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/runner.rb:29:in `test_step'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/step.rb:23:in `describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:31:in `block (3 levels) in describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:30:in `each'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:30:in `block (2 levels) in describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/filters/prepare_world.rb:23:in `block in test_case'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/around_hook.rb:21:in `execute'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/runner.rb:106:in `execute'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/runner.rb:53:in `execute'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/runner.rb:36:in `around_hook'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/around_hook.rb:12:in `describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:80:in `block (2 levels) in compose_around_hooks'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:81:in `compose_around_hooks'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:29:in `block in describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/runner.rb:19:in `test_case'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:28:in `describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/filters/prepare_world.rb:11:in `test_case'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:28:in `describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/filter.rb:57:in `test_case'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/filters/retry.rb:18:in `test_case'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:28:in `describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/filters/quit.rb:11:in `test_case'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/case.rb:28:in `describe_to'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/filters/broadcast_test_run_started_event.rb:21:in `block in done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/filters/broadcast_test_run_started_event.rb:20:in `map'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/filters/broadcast_test_run_started_event.rb:20:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/filter.rb:62:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/filter.rb:62:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/filter.rb:62:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/filter.rb:62:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/filter.rb:62:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/filter.rb:62:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/filters/locations_filter.rb:20:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/filter.rb:62:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/test/filters/tag_filter.rb:18:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/compiler.rb:31:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core/gherkin/parser.rb:46:in `done'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core.rb:35:in `parse'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-core-7.1.0/lib/cucumber/core.rb:24:in `compile'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/runtime.rb:79:in `run!'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/lib/cucumber/cli/main.rb:29:in `execute!'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/cucumber-4.1.0/bin/cucumber:9:in `<top (required)>'
/username/.rbenv/versions/2.5.1/bin/cucumber:23:in `load'
/username/.rbenv/versions/2.5.1/bin/cucumber:23:in `<top (required)>'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `load'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `kernel_load'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:28:in `run'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/cli.rb:476:in `exec'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor.rb:399:in `dispatch'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/cli.rb:30:in `dispatch'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/base.rb:476:in `start'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/cli.rb:24:in `start'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/exe/bundle:46:in `block in <top (required)>'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/lib/bundler/friendly_errors.rb:123:in `with_friendly_errors'
/username/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/bundler-2.1.4/exe/bundle:34:in `<top (required)>'
/username/.rbenv/versions/2.5.1/bin/bundle:23:in `load'
/username/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'

Possible Solution

Seems like the problem is in lib/cucumber/rails/database.rb:84:in `before_js', where you sort of check if DatabaseCleaner is available, but still use it in else clause

The hack I put in place rn is

def before_js(strategy)
  **return unless defined?(DatabaseCleaner::VERSION)**

  @original_strategy = if defined?(DatabaseCleaner::VERSION) && Gem::Version.new(DatabaseCleaner::VERSION) >= Gem::Version.new('1.8.0.beta')
                        DatabaseCleaner.cleaners.values.first.strategy # that feels like a nasty hack
                      else
                        DatabaseCleaner.connections.first.strategy # that feels like a nasty hack
                      end
  DatabaseCleaner.strategy = strategy, @options
end

I'm not ruby/rails dev, so there should be a nice solution to it :)

Steps to Reproduce (for bugs)

Not 100% sure, but I believe:

  1. Write any simple cucumber feature with @javascript
  2. Ensure you don't have DatabaseCleaner gem installed
  3. You should get this bug

Context & Motivation

Your Environment

macOS 10.13.6
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
cucumber-rails 2.1.0 & build directly from master branch
Rails 6.0.3.2

I can see the issue here and I'll have a look into this, although We've done some tweaks recently, so what I'll probably do is write an extra test, as I can see whilst we've made some changes in this area, we don't have a direct feature that "just" uses the option you probably want :no_database_cleaner

@MikhailMS can you copy your env.rb file here (Minus all the comments).

@luke-hill
Is it the one from features/support ? If so, it looks like this

#!!env.rb

require "simplecov"
require "simplecov-console"

SimpleCov.start "rails" do
  coverage_dir "log/cucumber/coverage/spec"
  add_filter "app/controllers/admin"
  add_filter "app/dashboards"
  add_filter "factories"
  if ENV["COVERAGE_REPORT"]
    formatter SimpleCov::Formatter::MultiFormatter.new(
      [
        SimpleCov::Formatter::HTMLFormatter,
        SimpleCov::Formatter::Console,
      ]
    )
  end
end

require "cucumber/rails"

ActionController::Base.allow_rescue = false

I've dug into this further, and found out it's configuration related....

However this has also raised the point we don't have documentary tests for this. So I've spent a whole heap of time adding those. I'm also fairly convinced the physical README docs for this aren't great.

I'll push up a PR which improves these things soon. But for now I'm convinced this is no longer a bug @MikhailMS

You need to tell cucumber NOT to use default settings (By default we use database cleaner). So simply setting: Cucumber::Rails::Database.autorun_database_cleaner = false in your env.rb file will be enough. However as mentioned this isn't articulated very well so I'm updating the tests / docs.

Awesome!

It indeed helped

Thank you for getting it resolved :)