From 06b4fff96a1a8ae76079f0ef7b7bdcd59013e428 Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Sat, 27 Dec 2025 20:41:35 +0100 Subject: [PATCH 1/7] Update to Ruby 4.0.0 --- .github/Dockerfile.base | 2 +- .rubocop.yml | 2 +- .ruby-version | 2 +- Gemfile | 3 ++- Gemfile.lock | 18 +++++++++++------- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/Dockerfile.base b/.github/Dockerfile.base index 5fae1efe..39557d77 100644 --- a/.github/Dockerfile.base +++ b/.github/Dockerfile.base @@ -3,7 +3,7 @@ # call this from rails root: podman build -t mapforge-base -f .github/Dockerfile.base . # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile -ARG RUBY_VERSION=3.4.5 +ARG RUBY_VERSION=4.0.0 FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base LABEL org.opencontainers.image.source="https://github.com/mapforge-org/mapforge" diff --git a/.rubocop.yml b/.rubocop.yml index 437af5cd..e8f37347 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,7 +5,7 @@ inherit_gem: inherit_from: .rubocop_todo.yml AllCops: - TargetRubyVersion: 3.4 + TargetRubyVersion: 4.0 DisplayCopNames: true DisplayStyleGuide: true ExtraDetails: true diff --git a/.ruby-version b/.ruby-version index 4f5e6973..fcdb2e10 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.4.5 +4.0.0 diff --git a/Gemfile b/Gemfile index 25ab22ad..0d820c90 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source "https://rubygems.org" -ruby "3.4.5" +ruby "4.0.0" gem "rails" @@ -59,6 +59,7 @@ gem "rgeo" gem "rgeo-geojson" gem "rgeo-proj4" gem "gpx" +gem "csv" # required by gpx, and not part of Ruby 4.0 standard lib anymore # resolving request IP addresses to coordinates gem "maxminddb" diff --git a/Gemfile.lock b/Gemfile.lock index 4cbd9bf1..fc7aac65 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -125,7 +125,7 @@ GEM connection_pool (3.0.2) cookiejar (0.3.4) crass (1.0.6) - csv (3.3.3) + csv (3.3.5) database_cleaner-core (2.0.1) database_cleaner-mongoid (2.0.1) database_cleaner-core (~> 2.0.0) @@ -220,9 +220,8 @@ GEM i18n (>= 0.7) multi_json request_store (>= 1.0) - gpx (1.2.1) - csv - nokogiri (~> 1.7) + gpx (0.8.3) + nokogiri rake haml (7.1.0) temple (>= 0.8.2) @@ -280,6 +279,7 @@ GEM mini_magick (5.3.1) logger mini_mime (1.1.5) + mini_portile2 (2.8.9) minitest (6.0.0) prism (~> 1.5) mongo (2.21.3) @@ -319,6 +319,9 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.5) + nokogiri (1.18.10) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) nokogiri (1.18.10-x86_64-linux-gnu) racc (~> 1.4) oauth2 (2.0.9) @@ -520,7 +523,7 @@ GEM rubocop-ast (>= 1.44.0, < 2.0) ruby-next-core (1.1.2) ruby-progressbar (1.13.0) - ruby_parser (3.21.1) + ruby_parser (3.22.0) racc (~> 1.5) sexp_processor (~> 4.16) rubycritic (4.11.0) @@ -543,7 +546,7 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 4.0) websocket (~> 1.0) - sexp_processor (4.17.4) + sexp_processor (4.17.5) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -629,6 +632,7 @@ DEPENDENCIES byebug capybara capybara-screenshot + csv database_cleaner-mongoid debug dotenv-rails @@ -690,7 +694,7 @@ DEPENDENCIES yabeda-rails RUBY VERSION - ruby 3.4.5 + ruby 4.0.0p0 BUNDLED WITH 2.7.1 From 54b477d231d588fe929836d36fae82c2fa17fede Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Sat, 27 Dec 2025 20:50:54 +0100 Subject: [PATCH 2/7] no bundler cache --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8152b577..afe37352 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: uses: ruby/setup-ruby@v1 with: # caches by Gemfile.lock checksum - bundler-cache: true + bundler-cache: false - uses: actions/setup-node@v4 with: node-version: 20 From ce5b9db21bc9cb1c15198f2894f671ee6a52ddfe Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Sat, 27 Dec 2025 20:53:37 +0100 Subject: [PATCH 3/7] skip bundler audit --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afe37352..0079ce31 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,8 +44,8 @@ jobs: cache: 'npm' - name: Install npm dependencies run: npm install - - name: Security audit dependencies - run: bin/bundler-audit --update + #- name: Security audit dependencies + # run: bin/bundler-audit --update - name: Security audit application code run: bin/brakeman -q -w2 - name: Lint Ruby files From fc8bfc7791b1c86371a66e4366fac8f648dd0814 Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Sun, 28 Dec 2025 12:23:31 +0100 Subject: [PATCH 4/7] call bundle install --- .github/workflows/ci.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0079ce31..f1f7b8ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,19 +33,21 @@ jobs: sudo chmod +x /usr/bin/mandb - name: Install dependencies run: sudo apt-get install --no-install-recommends -y libproj-dev libimlib2-dev - - name: Install Ruby and gems + - name: Install Ruby uses: ruby/setup-ruby@v1 with: # caches by Gemfile.lock checksum - bundler-cache: false + bundler-cache: true - uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' - name: Install npm dependencies run: npm install - #- name: Security audit dependencies - # run: bin/bundler-audit --update + - name: Install gem dependencies + run: bundle install + - name: Security audit dependencies + run: bin/bundler-audit --update - name: Security audit application code run: bin/brakeman -q -w2 - name: Lint Ruby files From f473d8c7a01b5dc19dc7a82f0b849a0ff5977235 Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Sun, 28 Dec 2025 12:32:22 +0100 Subject: [PATCH 5/7] update bundler --- .github/workflows/ci.yml | 2 -- Gemfile.lock | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1f7b8ca..447fa420 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,8 +44,6 @@ jobs: cache: 'npm' - name: Install npm dependencies run: npm install - - name: Install gem dependencies - run: bundle install - name: Security audit dependencies run: bin/bundler-audit --update - name: Security audit application code diff --git a/Gemfile.lock b/Gemfile.lock index fc7aac65..f084d7be 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -697,4 +697,4 @@ RUBY VERSION ruby 4.0.0p0 BUNDLED WITH - 2.7.1 + 4.0.3 From e7edf471df36c360b1b8ab5552e90296da880878 Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Sun, 28 Dec 2025 12:50:53 +0100 Subject: [PATCH 6/7] use gpx from fork --- .github/workflows/ci.yml | 2 +- Gemfile | 2 +- Gemfile.lock | 18 ++++++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 447fa420..8152b577 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: sudo chmod +x /usr/bin/mandb - name: Install dependencies run: sudo apt-get install --no-install-recommends -y libproj-dev libimlib2-dev - - name: Install Ruby + - name: Install Ruby and gems uses: ruby/setup-ruby@v1 with: # caches by Gemfile.lock checksum diff --git a/Gemfile b/Gemfile index 0d820c90..b89f2bd0 100644 --- a/Gemfile +++ b/Gemfile @@ -58,7 +58,7 @@ gem "rszr" gem "rgeo" gem "rgeo-geojson" gem "rgeo-proj4" -gem "gpx" +gem "gpx", git: "https://github.com/digitaltom/gpx" gem "csv" # required by gpx, and not part of Ruby 4.0 standard lib anymore # resolving request IP addresses to coordinates gem "maxminddb" diff --git a/Gemfile.lock b/Gemfile.lock index f084d7be..daca775a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,12 @@ +GIT + remote: https://github.com/digitaltom/gpx + revision: 2c2dd533da977ce2a45f77a625a8974cf653dd40 + specs: + gpx (1.2.1) + csv + nokogiri (~> 1.7) + rake + GIT remote: https://github.com/ruby/net-pop.git revision: 30d89b359c940610d84ecd1fed0dba4003508fde @@ -220,9 +229,6 @@ GEM i18n (>= 0.7) multi_json request_store (>= 1.0) - gpx (0.8.3) - nokogiri - rake haml (7.1.0) temple (>= 0.8.2) thor @@ -639,7 +645,7 @@ DEPENDENCIES dragonfly factory_bot_rails gon - gpx + gpx! haml hotwire-spark importmap-rails @@ -694,7 +700,7 @@ DEPENDENCIES yabeda-rails RUBY VERSION - ruby 4.0.0p0 + ruby 4.0.0p0 BUNDLED WITH - 4.0.3 + 4.0.3 From 5fb4a16de126a75dfcc3e80accc92aa499f3e6a9 Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Mon, 29 Dec 2025 02:04:36 +0100 Subject: [PATCH 7/7] migrate to cuprit + ferrum web driver --- Gemfile | 6 +-- Gemfile.lock | 47 +++++++-------------- spec/features/feature_details_spec.rb | 11 ++--- spec/features/feature_directions_spec.rb | 4 +- spec/features/feature_edit_spec.rb | 4 +- spec/features/map_layers_spec.rb | 15 ++++--- spec/rails_helper.rb | 53 ++++++++++++------------ spec/support/billy.rb | 34 --------------- spec/support/capybara.rb | 20 +++++---- spec/support/feature_helpers.rb | 19 +++++---- spec/support/mouse_helpers.rb | 29 +++++++++---- 11 files changed, 108 insertions(+), 134 deletions(-) delete mode 100644 spec/support/billy.rb diff --git a/Gemfile b/Gemfile index b89f2bd0..d5a4aa29 100644 --- a/Gemfile +++ b/Gemfile @@ -58,8 +58,7 @@ gem "rszr" gem "rgeo" gem "rgeo-geojson" gem "rgeo-proj4" -gem "gpx", git: "https://github.com/digitaltom/gpx" -gem "csv" # required by gpx, and not part of Ruby 4.0 standard lib anymore +gem "gpx", git: "https://github.com/digitaltom/gpx" # Ruby 4.0 fork # resolving request IP addresses to coordinates gem "maxminddb" @@ -102,6 +101,7 @@ group :test do gem "simplecov" gem "database_cleaner-mongoid" gem "mongoid-rspec" - gem "puffing-billy" + gem "cuprite" + gem "capybara_mock" gem "table_print" end diff --git a/Gemfile.lock b/Gemfile.lock index daca775a..42d583ca 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/digitaltom/gpx - revision: 2c2dd533da977ce2a45f77a625a8974cf653dd40 + revision: 204842fc2a00dca66adb66d7d8148e7580e197bd specs: gpx (1.2.1) csv @@ -126,15 +126,19 @@ GEM capybara-screenshot (1.0.26) capybara (>= 1.0, < 4) launchy + capybara_mock (0.2.0) + rack (>= 2.2.0) childprocess (5.1.0) logger (~> 1.5) coercible (1.0.0) descendants_tracker (~> 0.0.1) concurrent-ruby (1.3.6) connection_pool (3.0.2) - cookiejar (0.3.4) crass (1.0.6) csv (3.3.5) + cuprite (0.17) + capybara (~> 3.0) + ferrum (~> 0.17.0) database_cleaner-core (2.0.1) database_cleaner-mongoid (2.0.1) database_cleaner-core (~> 2.0.0) @@ -186,21 +190,8 @@ GEM dry-inflector (~> 1.0) dry-logic (~> 1.4) zeitwerk (~> 2.6) - em-http-request (1.1.7) - addressable (>= 2.3.4) - cookiejar (!= 0.3.1) - em-socksify (>= 0.3) - eventmachine (>= 1.0.3) - http_parser.rb (>= 0.6.0) - em-socksify (0.3.3) - base64 - eventmachine (>= 1.0.0.beta.4) - em-synchrony (1.0.6) - eventmachine (>= 1.0.0.beta.1) erb (6.0.1) erubi (1.13.1) - eventmachine (1.2.7) - eventmachine_httpserver (0.2.1) factory_bot (6.5.5) activesupport (>= 6.1.0) factory_bot_rails (6.5.1) @@ -212,6 +203,12 @@ GEM logger faraday-net_http (3.4.0) net-http (>= 0.5.0) + ferrum (0.17.1) + addressable (~> 2.5) + base64 (~> 0.2) + concurrent-ruby (~> 1.1) + webrick (~> 1.7) + websocket-driver (~> 0.7) ffi (1.17.0) flay (2.13.3) erubi (~> 1.10) @@ -238,7 +235,6 @@ GEM listen rails (>= 7.0.0) zeitwerk - http_parser.rb (0.8.0) i18n (1.14.7) concurrent-ruby (~> 1.0) ice_nine (0.11.2) @@ -285,7 +281,6 @@ GEM mini_magick (5.3.1) logger mini_mime (1.1.5) - mini_portile2 (2.8.9) minitest (6.0.0) prism (~> 1.5) mongo (2.21.3) @@ -325,10 +320,7 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.5) - nokogiri (1.18.10) - mini_portile2 (~> 2.8.2) - racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-gnu) + nokogiri (1.19.0-x86_64-linux-gnu) racc (~> 1.4) oauth2 (2.0.9) faraday (>= 0.17.3, < 3.0) @@ -371,14 +363,6 @@ GEM date stringio public_suffix (6.0.2) - puffing-billy (4.0.2) - addressable (~> 2.5) - em-http-request (~> 1.1, >= 1.1.0) - em-synchrony - eventmachine (~> 1.2) - eventmachine_httpserver - http_parser.rb (~> 0.8.0) - multi_json puma (7.1.0) nio4r (~> 2.0) puppeteer-ruby (0.45.6) @@ -601,6 +585,7 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) + webrick (1.9.2) websocket (1.2.11) websocket-driver (0.8.0) base64 @@ -638,7 +623,8 @@ DEPENDENCIES byebug capybara capybara-screenshot - csv + capybara_mock + cuprite database_cleaner-mongoid debug dotenv-rails @@ -664,7 +650,6 @@ DEPENDENCIES omniauth-google-oauth2 ostruct parallel_tests - puffing-billy puma puppeteer-ruby rack-cache diff --git a/spec/features/feature_details_spec.rb b/spec/features/feature_details_spec.rb index 528a1b0c..3d3f83e6 100644 --- a/spec/features/feature_details_spec.rb +++ b/spec/features/feature_details_spec.rb @@ -13,17 +13,18 @@ context 'with selected feature' do before do - click_coord('#maplibre-map', 50, 50) + click_center_of_screen expect(page).to have_css('#feature-details-modal') end it 'can enlarge modal with pull-up button', :mobile do - height = find('#feature-details-modal').native.style('height').sub('px', '').to_i - expect(height).to be < 200 + height = element_offset_height('#feature-details-modal') + # initial height is half the screen height + expect(height).to be < 300 find('.modal-pull-button').click sleep(0.3) - height = find('#feature-details-modal').native.style('height').sub('px', '').to_i - expect(height).to be > 150 + height = element_offset_height('#feature-details-modal') + expect(height).to be > 300 end it 'can download feature export' do diff --git a/spec/features/feature_directions_spec.rb b/spec/features/feature_directions_spec.rb index 3a211147..3553c7d4 100644 --- a/spec/features/feature_directions_spec.rb +++ b/spec/features/feature_directions_spec.rb @@ -12,8 +12,8 @@ it 'can create foot track' do find('.mapbox-gl-draw_line').click find('.mapbox-gl-draw_foot').click - click_coord('#maplibre-map', 50, 50) - click_coord('#maplibre-map', 150, 150) + click_coord('#maplibre-map', 250, 250) + click_coord('#maplibre-map', 450, 450) wait_for { Feature.line_string.count }.to eq(1) end end diff --git a/spec/features/feature_edit_spec.rb b/spec/features/feature_edit_spec.rb index 56dda8ac..bce290ba 100644 --- a/spec/features/feature_edit_spec.rb +++ b/spec/features/feature_edit_spec.rb @@ -57,7 +57,7 @@ context 'with selected polygon feature' do before do - click_coord('#maplibre-map', 50, 50) + click_coord('#maplibre-map', 512, 430) expect(page).to have_css('#edit-button-edit') end @@ -101,7 +101,7 @@ context 'with selected point feature' do before do - click_coord('#maplibre-map', 50, 50) + click_coord('#maplibre-map', 512, 430) find('#edit-button-edit').click end diff --git a/spec/features/map_layers_spec.rb b/spec/features/map_layers_spec.rb index 1586eea2..1624a3af 100644 --- a/spec/features/map_layers_spec.rb +++ b/spec/features/map_layers_spec.rb @@ -80,10 +80,15 @@ context 'overpass layer' do before do - proxy.stub('https://overpass-api.de:443/api/interpreter', method: 'post') - .and_return( - headers: { 'Access-Control-Allow-Origin' => '*' }, - text: File.read(Rails.root.join("spec", "fixtures", "files", "overpass.json"))) + overpass_file = File.read(Rails.root.join("spec", "fixtures", "files", "overpass.json")) + # https://github.com/railsware/capybara_mock + CapybaraMock.stub_request( + :post, 'https://overpass-api.de/api/interpreter' + ).to_return( + headers: { 'Access-Control-Allow-Origin' => '*' }, + status: 200, + body: overpass_file + ) map.layers << layer visit map.private_map_path @@ -95,7 +100,7 @@ let(:layer) { create(:layer, :overpass, name: 'opass') } it 'Shows overpass layer' do - expect(page).to have_text('opass') + expect(page).to have_text('opass(1)') end it 'can add overpass layer' do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 7d9c8367..297235f0 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -19,6 +19,7 @@ require 'database_cleaner/mongoid' require 'capybara-screenshot/rspec' require 'mongoid-rspec' +require 'capybara_mock/rspec' # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are @@ -40,7 +41,6 @@ config.use_active_record = false config.include Mongoid::Matchers, type: :model - config.include Features::Helpers, type: :feature config.include FactoryBot::Syntax::Methods config.before(:suite) do @@ -56,37 +56,36 @@ end config.around(:each, :mobile) do |spec| - browser = Capybara.current_session.driver.browser - browser.manage.window.resize_to(290, 523) + page.driver.browser.resize(width: 290, height: 523) spec.run - browser.manage.window.resize_to(1024, 576) + page.driver.browser.resize(width: 1024, height: 860) end # raise on js console errors class JavaScriptError< StandardError; end - RSpec.configure do |config| - config.after(:each, type: :feature) do |spec| - unless spec.metadata[:skip_console_errors] - levels = [ "SEVERE" ] - # "maplibre-gl.js TypeError: Failed to fetch" seems to be caused by - # the js file being cached already - exclude = [ /TypeError: Failed to fetch/, - /The user aborted a request/, - /Failed to load resource/ ] - errors = page.driver.browser.logs.get(:browser).to_a - .select { |e| levels.include?(e.level) && e.message.present? } - .reject { |e| exclude.any? { |ex| e.message =~ ex } } - .map(&:message) - if errors.present? - raise JavaScriptError, errors.join("\n\n") - end - end - if spec.metadata[:print_console_logs] - logs = page.driver.browser.logs.get(:browser).to_a.map(&:message) - puts logs.join("\n\n") - end - end - end + # RSpec.configure do |config| + # config.after(:each, type: :feature) do |spec| + # unless spec.metadata[:skip_console_errors] + # levels = [ "SEVERE" ] + # # "maplibre-gl.js TypeError: Failed to fetch" seems to be caused by + # # the js file being cached already + # exclude = [ /TypeError: Failed to fetch/, + # /The user aborted a request/, + # /Failed to load resource/ ] + # errors = page.driver.browser.logs.get(:browser).to_a + # .select { |e| levels.include?(e.level) && e.message.present? } + # .reject { |e| exclude.any? { |ex| e.message =~ ex } } + # .map(&:message) + # if errors.present? + # raise JavaScriptError, errors.join("\n\n") + # end + # end + # if spec.metadata[:print_console_logs] + # logs = page.driver.browser.logs.get(:browser).to_a.map(&:message) + # puts logs.join("\n\n") + # end + # end + # end # If you enable ActiveRecord support you should uncomment these lines, # note if you'd prefer not to run each example within a transaction, you diff --git a/spec/support/billy.rb b/spec/support/billy.rb deleted file mode 100644 index ab787c47..00000000 --- a/spec/support/billy.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'table_print' # Add this dependency to your gemfile - -# https://github.com/oesmith/puffing-billy?tab=readme-ov-file#params -Billy.configure do |c| - # c.record_requests = true # needed for the table output below - c.non_successful_error_level = :error - c.cache = true - c.persist_cache = true - c.cache_path = 'tmp/billy_req_cache/' -end - -# RSpec.configure do |config| -# config.prepend_after(:example, type: :feature) do -# puts "Requests received via Puffing Billy Proxy:" - -# puts TablePrint::Printer.table_print(Billy.proxy.requests, [ -# :status, -# :handler, -# :method, -# { url: { width: 100 } }, -# :headers, -# :body -# ]) -# end -# end - -# RSpec.configure do |config| -# config.prepend_before(:suite) do -# if defined?(Billy) -# local_cache_path = Rails.root.join(Billy.config.cache_path) -# FileUtils.rm_rf(local_cache_path) if File.exist?(local_cache_path) -# end -# end -# end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index b6784ede..cdf08084 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -1,4 +1,4 @@ -# == Define helpers +require "capybara/cuprite" # Generates the arguments to register chrome as capybara driver # @@ -70,15 +70,19 @@ def chrome_driver_arguments(headless: false) Capybara::Selenium::Driver.new(app, **chrome_driver_arguments(headless: true)) end -require 'billy/capybara/rspec' -Capybara.javascript_driver = :headless_chrome - -# Register our custom driver name. otherwise 'screenshot_failed_tests' would fail -# see https://github.com/mattheworiordan/capybara-screenshot/issues/84#issuecomment-41219326 -Capybara::Screenshot.register_driver(Capybara.javascript_driver) do |driver, path| - driver.browser.save_screenshot(path) +Capybara.register_driver(:cuprite) do |app| + logger = StringIO.new + Capybara::Cuprite::Driver.new(app, window_size: [ 1024, 860 ], + js_errors: true, + logger: logger, + browser_options: { 'no-sandbox': nil }) end +# https://github.com/rubycdp/cuprite +Capybara.javascript_driver = :cuprite + + Capybara.default_driver = Capybara.javascript_driver +Capybara::Screenshot.autosave_on_failure = true # Start Puma silently Capybara.server = :puma, { Silent: true } diff --git a/spec/support/feature_helpers.rb b/spec/support/feature_helpers.rb index 15edabb7..8cad85a8 100644 --- a/spec/support/feature_helpers.rb +++ b/spec/support/feature_helpers.rb @@ -1,9 +1,12 @@ -module Features - module Helpers - def self.take_a_screenshot - filename = Rails.root.join("capybara-#{Time.zone.now.to_i}.png") - puts "\033[36mINFO: Saving screenshot at: #{filename}\033[0m\n\n" - page.save_screenshot(filename, full: true) - end - end +def take_a_screenshot + filename = Rails.root.join("tmp", "capybara", "screen-#{Time.zone.now.to_i}.png") + puts "\033[36mINFO: Saving screenshot at: #{filename}\033[0m\n\n" + browser = page.driver.browser + browser.screenshot(path: filename, full: true) +end + +def element_offset_height(selector) + page.driver.browser.evaluate <<~JS + document.querySelector('#{selector}').offsetHeight; + JS end diff --git a/spec/support/mouse_helpers.rb b/spec/support/mouse_helpers.rb index 40a81729..c137dd44 100644 --- a/spec/support/mouse_helpers.rb +++ b/spec/support/mouse_helpers.rb @@ -1,13 +1,24 @@ -# Selenium Webdriver -# https://rubydoc.info/github/jnicklas/capybara/Capybara/Selenium/Driver +# 0,0 is the left top of the page +def click_coord(_selector, x, y) + browser = page.driver.browser + browser.mouse.click(x: x, y: y) +end + +def click_center_of_screen + viewport = page.driver.browser.evaluate <<~JS + { + width: window.innerWidth, + height: window.innerHeight + } + JS + + center_x = viewport['width'] / 2 + center_y = viewport['height'] / 2 -# 0,0 is the middle of the element -def click_coord(selector, x, y) - element = find(selector) - page.driver.browser.action.move_to(element.native, x, y).click.perform + page.driver.click(center_x, center_y) end -def hover_coord(selector, x, y) - element = find(selector) - page.driver.browser.action.move_to(element.native, x, y).perform +def hover_coord(_selector, x, y) + browser = page.driver.browser + browser.mouse.move(x: x, y: y) end