[Help Wanted] `binding.irb` during system spec, long browser reload time

Problem

During testing with Capybara, I use binding.irb to pause the process temporarily.

At that time, I modify the code and reload the browser.

The reload time is very long and I would like to know the cause and how to improve it.


:tv: gif about this issue :point_down:

2024-03-29 09.54.39

*The .mov format of the same video can be found in the github readme. (GitHub - kohheepeace/rails_capybara_reload_issue)


I’m not entirely sure what the cause is, but I was wondering if Zeitwerk might be related, so mentioning @fxn

Motivation

I would like to be able to achieve a cypress-like TDD experience, to see code changes instantly during test.

Repo

Environment

  • ruby “3.2.2”
  • rails (7.1.3.2)
  • rspec-core (3.13.0)
  • capybara (3.40.0)

Steps

  1. set config.enable_reloading = true in `config/environments/test.rb
Rails.application.configure do
...
	config.enable_reloading = true
...
end
  1. call binding.irb in system spec

spec/system/example_spec.rb

require 'rails_helper'

RSpec.describe 'example', type: :system do
  before do
    driven_by :selenium, using: :chrome, screen_size: [600, 600]
  end

  describe '#root' do
    it 'works as expected' do
      visit posts_path

      binding.irb # 👈 here
    end
  end
end
  1. change the view code and reload browser.

Thanks ! :smile:

…EDIT… (all of it, sorry)

I think it’s safe to say a binding.irb in a spec file is not affecting this (unless you can show otherwise without it.)

You will probably want to look at and/or share what the development server is doing, and not test logs (if that is what that terminal session is.) Seeing what tests are doing does not help you investigate development issues. But this is probably Zeitwerk related, I am surprised though that the reload would be that long for (I’m assuming a really small codebase.) Maybe make sure you have nothing run amok and eating your CPU?

Hi, thank you for your reply :slight_smile:

I am surprised though that the reload would be that long for (I’m assuming a really small codebase.)

=> Does your environment not slow reload time like this?

My dev stack is …

  • Macbook Air m2 15-inch
  • 24 GB RAM

My current solution

Here is my current solution to this issue. Not perfect but it is ok for me now.

  1. Run test server before running system test
RAILS_ENV=test bin/rails server -p 3001
  1. Setup Capybara for remote server
  Capybara.app_host = 'http://localhost:3001'
  Capybara.run_server = false

Ref: teamcapybara/capybara: Acceptance test framework for web applications (github.com)

  1. In spec/rails_helper.rb
RSpec.configure do |config|
 ...
  config.use_transactional_fixtures = false # 👈 here
...
end

  1. Use database_cleaner gem
RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each, type: :system) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
end

Ref: GitHub - DatabaseCleaner/database_cleaner: Strategies for cleaning databases in Ruby. Can be used to ensure a clean state for testing.

  1. Use gem 'action_mailer_cache_delivery'

Since the thread under test and the execution server are different? (Is that right?),

Ref: ruby on rails - Why are emails not getting in the ActionMailer::Base.deliveries table? - Stack Overflow

ActionMailer::Base.deliveries.last

become unavailable. So, I need to use gem 'action_mailer_cache_delivery'

Doing so solved the debug reloading problem in testing :tada: .

In actual development, we are doing HMR and Full Reload with vite-ruby gem, and the updates are immediately reflected during binding.irb in system spec, which is a pretty good development experience.

We also use the https://github.com/jonleighton/spring-commands-rspec gem.

P.S

When I left the test server running and tried to start the development server as well, a pid error occurred, so now I do the following.

In Procfile.dev

web: bin/rails s -p 3000 --pid tmp/pids/server2.pid
vite: bin/vite dev

I uhh… honestly not sure what to say. I’ve actually never ran/interacted with the server in RAILS_ENV=test. I think I usually have config.cache_classes = true in my test.rb config. Then again… I tend to avoid Capybara so :man_shrugging: Sorry I can’t be more help.

1 Like

I think I usually have config.cache_classes = true in my test.rb config.

=> true ! This is not common way and thanks for taking your time :slight_smile: :+1: