Skip to content

Chromium 150 hangs on startup in CI (ProcessTimeoutError); Chrome for Testing 150 works locally with Ferrum 0.17.2 #601

Description

@vincethewalker2015

Description

Summary

System Chromium 150 on our GitLab CI runner does not produce a DevTools websocket URL when started via Ferrum/Cuprite. This raises Ferrum::ProcessTimeoutError and, under parallel system specs, eventually causes the CI job to hit its 1 hour timeout.

The same Ferrum configuration works with:

  • Chrome for Testing 148 / 149 (CI workaround — pinned download)
  • Chrome for Testing 150.0.7871.115 locally (linux/amd64, 4 parallel workers, ~870 system spec examples, 0 failures, ~9 minutes)

This does not look like a missing process_timeout setting. Chromium 150 appears to hang on startup in our CI environment when using the system browser binary.

Error

Ferrum::ProcessTimeoutError:
  Browser did not produce websocket url within 30 seconds, try to increase `:process_timeout`.

When running parallel system specs without a Chrome pin, workers stall after printing seeds. Failures cluster in the spec files assigned to a single hung worker (typical of one browser never starting). The job is eventually killed:

4 processes for 65 specs, ~ 16 specs per process

Randomized with seed 52070
... (long silence, no example output) ...

19 examples, 18 failures

Failed examples:
rspec ./spec/system/example_feature_spec.rb:42 # ExampleFeature does something
rspec ./spec/system/example_feature_spec.rb:58 # ExampleFeature does something else
... (remaining failures all in the same spec file — same parallel worker batch)

WARNING: step_script could not run to completion because the timeout was exceeded.
ERROR: Job failed: execution took longer than 1h0m0s seconds

The individual assertion messages are irrelevant here — every example in that worker’s batch fails because the browser never connects. This is not an application regression.

Secondary noise after the job is killed (not the root cause):

/usr/local/bundle/gems/parallel_tests-5.7.0/lib/parallel_tests/pids.rb:46:in 'IO.read':
  No such file or directory @ rb_sysopen - /tmp/parallel_tests-pidfile... (Errno::ENOENT)

Steps to reproduce

Failing case (CI)

  1. Use a Debian-based linux/amd64 CI image with system Chromium 150, e.g. chromium --version150.0.7871.46.
  2. Configure Ferrum/Cuprite with headless mode and container flags (no-sandbox, disable-gpu, disable-dev-shm-usage).
  3. Point browser_path at /usr/bin/chromium (no Chrome-for-Testing override).
  4. Run parallel browser specs (we use parallel_rspec with 4 workers).

Expected: Chromium starts and Ferrum receives a DevTools websocket URL.

Actual: Browser startup hangs; ProcessTimeoutError after process_timeout; parallel workers fail in batches; job may run until the CI timeout.

Passing case (local)

  1. linux/amd64 container.
  2. Chrome for Testing 150.0.7871.115 at /opt/chrome-linux64/chrome.
  3. Ferrum 0.17.2, Cuprite 0.17, same browser flags.
  4. CI=true, SYSTEM_WORKERS=4, full parallel system suite.

Result: ~870 examples, 0 failures, ~8m 39s.

Workaround (CI)

Download an older Chrome for Testing build and set BROWSER_PATH:

CHROME_VERSION=149.0.7827.155   # 148.x also works
curl -fsSL "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VERSION}/linux64/chrome-linux64.zip" -o /tmp/chrome.zip
unzip -q -o /tmp/chrome.zip -d /opt
chmod +x /opt/chrome-linux64/chrome
export BROWSER_PATH=/opt/chrome-linux64/chrome

Additional mitigations that helped but did not fix Chromium 150 on CI:

  • CUPRITE_PROCESS_TIMEOUT=60
  • SYSTEM_WORKERS=2

Environment

Component Version
Ferrum 0.17.2 (also seen on 0.17.1)
Cuprite 0.17
Ruby 4.0
parallel_tests 5.7.0
Capybara 3.40.0
OS Debian, linux/amd64
CI image Private GitLab CI runner, Debian-based linux/amd64 builder image with system Chromium 150

Chrome / Chromium versions tested

Browser Version Source Result
Chromium 150.0.7871.46 System (/usr/bin/chromium) Fails in CI
Chrome for Testing 150.0.7871.115 Downloaded binary Passes locally
Chrome for Testing 149.0.7827.155 Downloaded binary Passes in CI (current workaround)
Chrome for Testing 148.0.7778.215 Downloaded binary Passes in CI

Configuration

Ferrum options used via Cuprite:

cuprite_options = {
  window_size: [1200, 800],
  browser_options: {
    'no-sandbox' => true,
    'disable-gpu' => true,
    'disable-dev-shm-usage' => true,
    'disable-background-timer-throttling' => true,
    'disable-backgrounding-occluded-windows' => true,
    'disable-renderer-backgrounding' => true,
    'force-color-profile' => 'srgb',
    'disable-ipc-flooding-protection' => true
  },
  pending_connection_errors: false,
  process_timeout: Integer(ENV.fetch('CUPRITE_PROCESS_TIMEOUT', 30)),
  headless: true
}

cuprite_options[:browser_path] = browser_path if browser_path

JS system specs also retry up to 3 times via rspec-retry, which can make hangs appear as long silent periods before failures.


Minimal reproduction

#!/usr/bin/env ruby
# frozen_string_literal: true

require "ferrum"

browser_path = ENV.fetch("BROWSER_PATH", "/usr/bin/chromium")

puts "Using browser: #{browser_path}"
puts `#{browser_path} --version`

browser = Ferrum::Browser.new(
  headless: true,
  browser_path: browser_path,
  process_timeout: 60,
  browser_options: {
    "no-sandbox" => nil,
    "disable-gpu" => nil,
    "disable-dev-shm-usage" => nil
  }
)

puts "Browser started"
puts "Version: #{browser.version}"
browser.go_to("about:blank")
puts "OK"
browser.quit

Run in CI:

# Fails
BROWSER_PATH=/usr/bin/chromium ruby repro.rb

# Works (example)
CHROME_VERSION=149.0.7827.155
curl -fsSL "https://storage.googleapis.com/chrome-for-testing-public/${CHROME_VERSION}/linux64/chrome-linux64.zip" -o /tmp/chrome.zip
unzip -q -o /tmp/chrome.zip -d /opt
BROWSER_PATH=/opt/chrome-linux64/chrome ruby repro.rb

What we have ruled out

  • Increasing process_timeout to 60 seconds does not fix system Chromium 150 in CI.
  • Upgrading Ferrum from 0.17.1 to 0.17.2 does not fix system Chromium 150 in CI.
  • Application regressions are unlikely: the same suite passes locally on Chrome 150 with 0 failures.
  • Parallel test databases are set up correctly (parallel:create, parallel:load_schema).

Questions for maintainers

  1. Is there a known incompatibility between Ferrum 0.17.x and Chromium 150 on Debian in containerised CI?
  2. Could Ferrum surface Chrome stderr when startup succeeds but no websocket URL is returned?
  3. Is the difference between system Chromium 150 and Chrome for Testing 150 a supported/expected distinction?

Related issues


Additional context

We are happy to test patches. The explicit Ferrum::ProcessTimeoutError line is intermittent in archived logs because the latest CI failure ended with a 1-hour job timeout after workers hung, but this matches the failure mode seen when using system Chromium 150 without a Chrome-for-Testing pin.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions