From e65457f36b60b5e8670b865094886b156703d688 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Tue, 27 Feb 2018 14:38:25 +0100 Subject: [PATCH] Switch browser-based tests to headless chrome --- .circleci/config.yml | 2 +- CHANGELOG.md | 4 ++ Gemfile.lock | 14 +++--- .../renderer_with_two_packs_test.rb | 8 +-- test/test_helper.rb | 50 ++++++++++++++++++- webpacker-react.gemspec | 2 +- 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b2cf4fc..4a0557f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ jobs: build: working_directory: ~/webpacker-react docker: - - image: circleci/ruby:2.4.3-node + - image: circleci/ruby:2.4.3-node-browsers environment: RAILS_ENV: test steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 37d8618..5b34ba2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Updated - Instructions for setting up `webpacker-react` with a modern Webpacker version +### Changed +- Tests now uses headless chrome instead of Poltergeist +- Babel is configured with `babel-preset-env` + ### Removed - Support for `react-hot-loader`. Please look at the README for instructions on how to use `react-hot-loader` 4 with your app, it is much simpler and better! diff --git a/Gemfile.lock b/Gemfile.lock index dd34f35..4e2d0ad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,10 +56,12 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (>= 2.0, < 4.0) - cliver (0.3.2) + childprocess (0.8.0) + ffi (~> 1.0, >= 1.0.11) concurrent-ruby (1.0.5) crass (1.0.3) erubi (1.7.0) + ffi (1.9.23) globalid (0.4.1) activesupport (>= 4.2.0) i18n (0.9.5) @@ -80,10 +82,6 @@ GEM parallel (1.12.1) parser (2.5.0.2) ast (~> 2.4.0) - poltergeist (1.17.0) - capybara (~> 2.1) - cliver (~> 0.3.1) - websocket-driver (>= 0.2.0) powerpack (0.1.1) public_suffix (3.0.2) rack (2.0.4) @@ -122,6 +120,10 @@ GEM ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-progressbar (1.9.0) + rubyzip (1.2.1) + selenium-webdriver (3.9.0) + childprocess (~> 0.5) + rubyzip (~> 1.2) sprockets (3.7.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -151,10 +153,10 @@ DEPENDENCIES bundler (~> 1.13) capybara minitest (~> 5.0) - poltergeist rails (~> 5.1.1) rake (~> 10.0) rubocop (>= 0.47) + selenium-webdriver webpacker (~> 2.0.0) webpacker-react! diff --git a/test/integration/renderer_with_two_packs_test.rb b/test/integration/renderer_with_two_packs_test.rb index 4c90052..e9b2f9f 100644 --- a/test/integration/renderer_with_two_packs_test.rb +++ b/test/integration/renderer_with_two_packs_test.rb @@ -5,12 +5,8 @@ class RendererWithTwoPacksTest < ActionDispatch::IntegrationTest test "component mounts" do require_js - begin - visit "/two_packs/view_all" - rescue Capybara::Poltergeist::JavascriptError => error - assert error.message =~ /Following components are already registered: HelloReact/ - end - + visit "/two_packs/view_all" + assert_js_error /Following components are already registered: HelloReact/ assert page.has_content? "Hello, I am a component rendered from a view!" assert page.has_content? "Component A" assert page.has_content? "Component B" diff --git a/test/test_helper.rb b/test/test_helper.rb index 720f5e6..aadef7b 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -5,17 +5,63 @@ require "minitest/autorun" require "capybara/rails" +require "selenium/webdriver" + +Capybara.register_driver :headless_chrome do |app| + capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( + chromeOptions: { args: %w(headless disable-gpu) } + ) + + Capybara::Selenium::Driver.new app, + browser: :chrome, + desired_capabilities: capabilities +end + +Capybara.javascript_driver = :headless_chrome + class ActionDispatch::IntegrationTest + class DriverJSError < StandardError; end include Capybara::DSL - require "capybara/poltergeist" - Capybara.javascript_driver = :poltergeist + def setup + @ignored_js_errors = [] + end def teardown + if Capybara.current_driver == :headless_chrome + errors = current_js_errors.select do |message| + # If the message matches any ones ignored, skip it + puts "===" + puts @ignored_js_errors.inspect + puts message + !@ignored_js_errors.any? { |e| !(message =~ e) } + end + + assert errors.empty?, "Got JS errors: \n#{errors.join("\n\n")}" + end + Capybara.current_driver = nil end def require_js Capybara.current_driver = Capybara.javascript_driver end + + def current_js_errors + page.driver.browser.manage.logs.get(:browser) + .select { |e| e.level == "SEVERE" && message.present? } + .map(&:message) + .to_a + end + + def assert_js_error(error_match) + error = current_js_errors.find { |e| e. =~ error_match } + + if error + @ignored_js_errors << error + else + puts error.to_s + assert false, "Expected a JS error matching: #{error_match.to_s}" + end + end end diff --git a/webpacker-react.gemspec b/webpacker-react.gemspec index 722d4a4..b0b97c1 100644 --- a/webpacker-react.gemspec +++ b/webpacker-react.gemspec @@ -28,5 +28,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "minitest", "~> 5.0" spec.add_development_dependency "capybara" - spec.add_development_dependency "poltergeist" + spec.add_development_dependency "selenium-webdriver" end