Selenium: A hung chromedriver is never killed while Timecop freezes the time

Posted . Visible to the public.

When Selenium stops chromedriver, it sends SIGTERM and polls until the process exits or a timeout passes, and only then sends SIGKILL.

class Selenium::WebDriver::ChildProcess
  def poll_for_exit
    end_time = Time.now + timeout
    sleep POLL_INTERVAL until exited? || Time.now > end_time
  end
end

Under Timecop.freeze, Time.now never reaches end_time. So a chromedriver that doesn't react to SIGTERM (e.g. a hung browser) is never killed, and the test process hangs until your CI job times out.

Use this monkey patch to fix the polling mechanism whenever browsers are stopped inside a frozen example:

# spec/support/selenium_child_process.rb

# Selenium waits for its driver processes to exit on the wall clock, which stands still while Timecop freezes the
# time. A chromedriver that doesn't exit would hang the run instead of being killed after the timeout.
module SeleniumChildProcessRealTime
  def poll_for_exit(timeout)
    Timecop.return { super }
  end
end

Selenium::WebDriver::ChildProcess.prepend(SeleniumChildProcessRealTime)
Profile picture of Michael Leimstädtner
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted by Michael Leimstädtner to makandra dev (2026-11-05 13:21)