From 25829631ce5a8376817a78a081af42daab57e890 Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Sat, 28 Feb 2026 14:31:05 +0300 Subject: [PATCH 01/10] feat: pending_connection_errors are false now in ferrum by default --- lib/capybara/cuprite/driver.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/capybara/cuprite/driver.rb b/lib/capybara/cuprite/driver.rb index 30e7430..cc8bef0 100644 --- a/lib/capybara/cuprite/driver.rb +++ b/lib/capybara/cuprite/driver.rb @@ -35,6 +35,8 @@ def initialize(app, options = {}) @screen_size ||= DEFAULT_MAXIMIZE_SCREEN_SIZE @options[:save_path] ||= File.expand_path(Capybara.save_path) if Capybara.save_path + @options[:pending_connection_errors] = true unless @options.key?(:pending_connection_errors) + # It's set for debug() to make devtools tab open correctly. @options[:browser_options] ||= {} unless @options[:browser_options][:"remote-allow-origins"] From ee3ed5e5d398e0e2255af605e4ae58601be6b7bf Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Mon, 9 Mar 2026 10:53:35 +0300 Subject: [PATCH 02/10] fix: some of the drag_to specs are passing now after adding scroll_into_view --- lib/capybara/cuprite/browser.rb | 1 + spec/spec_helper.rb | 37 ++++++++++++++------------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/lib/capybara/cuprite/browser.rb b/lib/capybara/cuprite/browser.rb index d7ce914..9d04f44 100644 --- a/lib/capybara/cuprite/browser.rb +++ b/lib/capybara/cuprite/browser.rb @@ -140,6 +140,7 @@ def source end def drag(node, other, steps, delay = nil, scroll = true) + node.scroll_into_view if scroll x1, y1 = node.find_position mouse.move(x: x1, y: y1) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index bcc30d6..789d743 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -36,26 +36,21 @@ module TestSessions RSpec.configure do |config| config.define_derived_metadata do |metadata| regexes = <<~REGEXP.split("\n").map { |s| Regexp.quote(s.strip) }.join("|") - node #drag_to should work with jsTree - node #drag_to should drag and drop an object - node #drag_to should drag and drop if scrolling is needed - node #drag_to should drag a link - node #drag_to should work with Dragula - node #drag_to HTML5 should work with SortableJS - node #drag_to HTML5 should HTML5 drag and drop an object - node #drag_to HTML5 should set clientX/Y in dragover events - node #drag_to HTML5 should not HTML5 drag and drop on a non HTML5 drop element - node #drag_to HTML5 should HTML5 drag and drop when scrolling needed - node #drag_to HTML5 should drag HTML5 default draggable elements - node #drag_to HTML5 should drag HTML5 default draggable element child - node #drag_to should simulate a single held down modifier key - node #drag_to should simulate multiple held down modifier keys - node #drag_to should support key aliases - node #drag_to HTML5 should preserve clientX/Y from last dragover event - node #drag_to HTML5 should simulate a single held down modifier key - node #drag_to HTML5 should simulate multiple held down modifier keys - node #drag_to HTML5 should support key aliases - node #drag_to HTML5 should trigger a dragenter event, before the first dragover event + #drag_to should simulate a single held down modifier key + #drag_to should simulate multiple held down modifier keys + #drag_to should support key aliases + #drag_to HTML5 should HTML5 drag and drop an object + #drag_to HTML5 should HTML5 drag and drop an object child + #drag_to HTML5 should set clientX/Y in dragover events + #drag_to HTML5 should preserve clientX/Y from last dragover event + #drag_to HTML5 should HTML5 drag and drop when scrolling needed + #drag_to HTML5 should drag HTML5 default draggable elements + #drag_to HTML5 should work with SortableJS + #drag_to HTML5 should drag HTML5 default draggable element child + #drag_to HTML5 should simulate a single held down modifier key + #drag_to HTML5 should simulate multiple held down modifier keys + #drag_to HTML5 should support key aliases + #drag_to HTML5 should trigger a dragenter event, before the first dragover event node Element#drop can drop a file node Element#drop can drop multiple files node Element#drop can drop strings @@ -68,6 +63,7 @@ module TestSessions node #set should submit single text input forms if ended with #fill_in should fill in a color field #fill_in should handle carriage returns with line feeds in a textarea correctly + #fill_in should fill in a textarea in a reasonable time by default #has_field with valid should be false if field is invalid #find with spatial filters should find an element above another element #find with spatial filters should find an element below another element @@ -77,7 +73,6 @@ module TestSessions #find with spatial filters should find an element "near" another element #has_css? with spatial requirements accepts spatial options #has_css? with spatial requirements supports spatial sugar - #fill_in should fill in a textarea in a reasonable time by default #has_element? should be true if the given element is on the page #assert_matches_style should raise error if the elements style doesn't contain the given properties #has_css? :style option should support Hash From fbfc56e760c8386061da0a478b30dba415078001 Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Mon, 9 Mar 2026 10:57:45 +0300 Subject: [PATCH 03/10] fix: linter --- lib/capybara/cuprite/page.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/capybara/cuprite/page.rb b/lib/capybara/cuprite/page.rb index f3e2bf3..2b21a86 100644 --- a/lib/capybara/cuprite/page.rb +++ b/lib/capybara/cuprite/page.rb @@ -15,6 +15,7 @@ class Page < Ferrum::Page TRIGGER_CLICK_WAIT = ENV.fetch("CUPRITE_TRIGGER_CLICK_WAIT", 0.1).to_f extend Forwardable + delegate %i[at_css at_xpath css xpath current_url current_title body execution_id execution_id! evaluate evaluate_on evaluate_async execute] => :active_frame From 726fe75affa079e02e7b75a4d4d2c3e7731c1ed2 Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Sat, 21 Mar 2026 08:52:17 +0300 Subject: [PATCH 04/10] ci: update Ruby versions and enable Chrome dockerization in test workflow --- .github/workflows/tests.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7e55d6f..85892e9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,11 +11,12 @@ jobs: strategy: fail-fast: false matrix: - ruby: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4"] + ruby: ["3.1", "3.2", "3.3", "3.4", "4.0"] runs-on: ubuntu-latest env: FERRUM_PROCESS_TIMEOUT: 25 FERRUM_DEFAULT_TIMEOUT: 15 + FERRUM_CHROME_DOCKERIZE: true steps: - name: Checkout code uses: actions/checkout@v4 @@ -31,11 +32,6 @@ jobs: with: chrome-version: stable - - name: Fix GA Chrome Permissions - run: | - sudo chown root:root /opt/hostedtoolcache/setup-chrome/chromium/stable/x64/chrome-sandbox - sudo chmod 4755 /opt/hostedtoolcache/setup-chrome/chromium/stable/x64/chrome-sandbox - - name: Run tests run: | mkdir -p /tmp/cuprite From 2cfd9ef74e9427cdb47c27886576540be6e52c4f Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Sat, 21 Mar 2026 09:08:26 +0300 Subject: [PATCH 05/10] chore: update Gemfile platforms for byebug and add ostruct dependency --- Gemfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index b936ae2..5e1283b 100644 --- a/Gemfile +++ b/Gemfile @@ -2,10 +2,11 @@ source "https://rubygems.org" -gem "byebug", "~> 11.1", platforms: %i[mri mingw x64_mingw] +gem "byebug", "~> 11.1", platforms: %i[mri windows] gem "chunky_png", "~> 1.4" gem "image_size", "~> 3.0" gem "launchy", "~> 2.5" +gem "ostruct" gem "pdf-reader", "~> 2.12" gem "puma", ">= 5.6.7" gem "rake", "~> 13.0" From e93306a4795297f3dfaa207754b0202c2e7e2419 Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Mon, 23 Mar 2026 11:33:26 +0300 Subject: [PATCH 06/10] fix: linter matrix --- .github/workflows/linter.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 4f7646f..f9c375e 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,5 +1,9 @@ name: Linter -on: [push] +on: + push: + branches: + - main + pull_request: jobs: linters: @@ -7,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ 2.7, "3.0" ] + ruby: ["3.1", "4.0"] runs-on: ubuntu-latest steps: - name: Checkout code From ae8abc983b6ec4a2e095ff3f358587f77b6e0398 Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Mon, 23 Mar 2026 16:26:48 +0300 Subject: [PATCH 07/10] fix: skip response_headers as it's also skipped in capybara test, and only passing for rack-test --- spec/features/session_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/session_spec.rb b/spec/features/session_spec.rb index 96a5b78..0332050 100644 --- a/spec/features/session_spec.rb +++ b/spec/features/session_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -Capybara::SpecHelper.run_specs TestSessions::Cuprite, "Cuprite" +Capybara::SpecHelper.run_specs TestSessions::Cuprite, "Cuprite", capybara_skip: %i[response_headers] describe Capybara::Session do context "with cuprite driver" do From 75870fe95e7f99b09decbe7940dc2c5b9dfe2664 Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Mon, 23 Mar 2026 16:35:48 +0300 Subject: [PATCH 08/10] chore: add logger for ruby 4.0 --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 5e1283b..73412cd 100644 --- a/Gemfile +++ b/Gemfile @@ -6,6 +6,7 @@ gem "byebug", "~> 11.1", platforms: %i[mri windows] gem "chunky_png", "~> 1.4" gem "image_size", "~> 3.0" gem "launchy", "~> 2.5" +gem "logger" gem "ostruct" gem "pdf-reader", "~> 2.12" gem "puma", ">= 5.6.7" From 6c48e8afec87c79a6ad2a8522a8fafedffafef8e Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Mon, 23 Mar 2026 16:37:47 +0300 Subject: [PATCH 09/10] chore: bump ruby --- .rubocop.yml | 2 +- cuprite.gemspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 8788f4c..9bbdd62 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,5 @@ AllCops: - TargetRubyVersion: 2.7 + TargetRubyVersion: 3.1 NewCops: enable SuggestExtensions: false diff --git a/cuprite.gemspec b/cuprite.gemspec index 3052d53..2df2a1e 100644 --- a/cuprite.gemspec +++ b/cuprite.gemspec @@ -22,7 +22,7 @@ Gem::Specification.new do |s| "rubygems_mfa_required" => "true" } - s.required_ruby_version = ">= 2.7.0" + s.required_ruby_version = ">= 3.1" s.add_dependency "capybara", "~> 3.0" s.add_dependency "ferrum", "~> 0.17.0" From d3e31bc14c6dd19c8fe04acff5086acc0f7498e9 Mon Sep 17 00:00:00 2001 From: Dmitry Vorotilin Date: Mon, 23 Mar 2026 16:39:02 +0300 Subject: [PATCH 10/10] fix: lint --- .rubocop.yml | 2 +- spec/support/test_app.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9bbdd62..834d5ec 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -57,5 +57,5 @@ Metrics/ModuleLength: Metrics/PerceivedComplexity: Max: 14 -require: +plugins: - rubocop-rake diff --git a/spec/support/test_app.rb b/spec/support/test_app.rb index c93b735..a77b170 100644 --- a/spec/support/test_app.rb +++ b/spec/support/test_app.rb @@ -6,8 +6,8 @@ class TestApp configure do set :protection, except: :frame_options end - CUPRITE_VIEWS = "#{File.dirname(__FILE__)}/views" - CUPRITE_PUBLIC = "#{File.dirname(__FILE__)}/public" + CUPRITE_VIEWS = "#{File.dirname(__FILE__)}/views".freeze + CUPRITE_PUBLIC = "#{File.dirname(__FILE__)}/public".freeze set :erb, layout: File.read("#{CUPRITE_VIEWS}/layout.erb")