diff --git a/README.md b/README.md index 2d4b24482..48a00826b 100644 --- a/README.md +++ b/README.md @@ -376,6 +376,7 @@ Note: If you have components from react-rails you want to use, then you will nee + [Node Dependencies and NPM](docs/additional_reading/node_dependencies_and_npm.md) + [Optional Configuration](docs/additional_reading/optional_configuration.md) + [React Router](docs/additional_reading/react_router.md) ++ [RSpec Configuration](docs/additional_reading/rspec_configuration.md) + [Server Rendering Tips](docs/additional_reading/server_rendering_tips.md) + [Tips](docs/additional_reading/tips.md) + [Turbolinks](docs/additional_reading/turbolinks.md) diff --git a/docs/additional_reading/rspec_configuration.md b/docs/additional_reading/rspec_configuration.md new file mode 100644 index 000000000..3f9edaeba --- /dev/null +++ b/docs/additional_reading/rspec_configuration.md @@ -0,0 +1,10 @@ +# RSpec Configuration +Because you will probably want to run RSpec tests that rely on compiled webpack assets (typically, your integration/feature specs where `js: true`), you will want to ensure you don't accidentally run tests on missing or stale webpack assets. If you did use stale Webpack assets, you will get invalid test results as your tests do not use the very latest JavaScript code. + +ReactOnRails provides a helper method called `configure_rspec_to_compile_assets`. Call this method from inside of the `RSpec.configure` block in your `spec/rails_helper.rb` file, passing the config as an argument. + +You can pass an RSpec metatag as an optional second parameter to this helper method if you want this helper to run on examples other than where `js: true` (default). The helper will compile webpack files only once per test run. + +If you do not want to be slowed down by re-compiling webpack assets from scratch every test run, you can call `npm run build:client` (and `npm run build:server` if doing server rendering) to have webpack recompile these files in the background, which will be much faster. The helper looks for these processes and will abort recompiling if it finds them to be running. + +If you want to use a testing framework other than RSpec, we suggest you implement similar logic. diff --git a/lib/react_on_rails.rb b/lib/react_on_rails.rb index 995deb0b6..0692ed994 100644 --- a/lib/react_on_rails.rb +++ b/lib/react_on_rails.rb @@ -4,3 +4,10 @@ require "react_on_rails/configuration" require "react_on_rails/server_rendering_pool" require "react_on_rails/engine" +require "react_on_rails/ensure_assets_compiled" + +module ReactOnRails + def self.configure_rspec_to_compile_assets(config, metatag = :js) + config.before(:example, metatag) { ReactOnRails::EnsureAssetsCompiled.check_built_assets } + end +end diff --git a/lib/react_on_rails/ensure_assets_compiled.rb b/lib/react_on_rails/ensure_assets_compiled.rb new file mode 100644 index 000000000..56d447c9e --- /dev/null +++ b/lib/react_on_rails/ensure_assets_compiled.rb @@ -0,0 +1,31 @@ +module ReactOnRails + module EnsureAssetsCompiled + def self.check_built_assets + return if @checks_complete + puts "Checking for existing webpack bundles before running tests." + build_assets_for_type("client") + build_assets_for_type("server") if ReactOnRails.configuration.server_bundle_js_file.present? + @checks_complete = true + end + + def self.build_assets_for_type(type) + unless running_webpack_watch?(type) + puts "Building Webpack #{type}-rendering assets..." + build_output = `cd client && npm run build:#{type}` + if build_output =~ /error/i + fail "Error in building assets!\n#{build_output}" + else + puts "Webpack #{type}-rendering assets built." + end + end + end + + def self.running_webpack_watch?(type) + running = `pgrep -fl '\\-w \\-\\-config webpack\\.#{type}\\.rails\\.build\\.config\\.js'` + if running.present? + puts "Webpack is running for #{type}-rendering assets, skipping rebuild => #{running.ai}" + return true + end + end + end +end diff --git a/spec/dummy/client/package.json b/spec/dummy/client/package.json index 22ab0365c..d14e72f52 100644 --- a/spec/dummy/client/package.json +++ b/spec/dummy/client/package.json @@ -48,7 +48,9 @@ "build:test": "webpack --config webpack.client.js && webpack --config webpack.server.js", "test": "npm run build:test && rspec", "build:dev:client": "webpack -w --config webpack.client.js", - "build:dev:server": "webpack -w --config webpack.server.js" + "build:dev:server": "webpack -w --config webpack.server.js", + "build:client": "webpack --config webpack.client.js", + "build:server": "webpack --config webpack.server.js" }, "author": "", "license": "ISC" diff --git a/spec/dummy/package.json b/spec/dummy/package.json index 81f8a44f1..1269d8ee6 100644 --- a/spec/dummy/package.json +++ b/spec/dummy/package.json @@ -11,7 +11,8 @@ "gulp": "cd ./client && npm run gulp", "test": "npm run build:test && npm run lint && rspec", "lint": "cd client && npm run lint", - "build:test": "cd client && npm run build:test" + "build:clent": "cd client && npm run build:client", + "build:server": "cd client && npm run build:server", }, "repository": { "type": "git", diff --git a/spec/dummy/spec/rails_helper.rb b/spec/dummy/spec/rails_helper.rb index e6f4645f9..5a00487e7 100644 --- a/spec/dummy/spec/rails_helper.rb +++ b/spec/dummy/spec/rails_helper.rb @@ -34,6 +34,9 @@ ActiveRecord::Migration.maintain_test_schema! RSpec.configure do |config| + # Ensure that if we are running js tests, we are using latest webpack assets + ReactOnRails.configure_rspec_to_compile_assets(config) + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures"