Skip to content

henrahmagix/stimulus_tests

Repository files navigation

StimulusTests

Test your Stimulus controllers in Rails!

This gem provides a route in test environments by which you can render any HTML with an importmap entry point, and assert on it with the usual browser finders and actions.

This supports the latest minor versions from Rails 6.1 to 8.0. See Appraisals.

Installation

Add this line to your application's Gemfile:

gem "stimulus_tests", github: "henrahmagix/stimulus_tests", group: :test

And then execute:

$ bundle

Or install it yourself as:

$ bundle add stimulus_tests --github henrahmagix/stimulus_tests

I'm unsure how to gem install this from GitHub source. Unfortunately gem install instructions will be unavailable until I publish this on RubyGems.

Usage

See also Examples. All the code examples here reference the default Stimulus controller made by bin/rails stimulus:install named hello, which replaces the element's text with "Hello World!"

First, include the DSL and set an import in your test setup scope:

include StimulusTests::DSL

import "application"

Then call render_stimulus before your assertions. It can be called one of two ways:

# 1. With a HTML string.
render_stimulus '<p data-controller="hello">Initial text</p>'

# 2. With a block that gets evaluated in a View context where you can make use of tag helpers.
# The return value is used like the HTML string.
render_stimulus do
  content_tag :p, 'Initial text', data: { controller: "hello" }
end

Now you can assert on the browser page, like assert_text "Hello World!"


Under the hood, render_stimulus visits a route defined by this gem (see Configuration), where the controller action renders javascript_importmap_tags with the given import, and then the HTML. This is how we get a test browser to load a page with just the JavaScript we need without having to commit such a page to your app.

You can also call layout to configure the layout of the controller defined by this gem:

include StimulusTests::DSL

layout "application"

Most of the time you won't need both layout and import: if you have a layout with your entry point already, you can use that and you don't need to use import.

Defining an import entry point and not having a layout reduces the dependencies so you can more clearly unit-test your Stimulus controllers.

They can also be passed into render_stimulus to override the previous definitions:

render_stimulus(layout: "my_specific_layout", import: "controllers") do
  '<p data-controller="hello">Initial text</p>'
end

Note: if you specify both, and the layout already includes the importmap entry point, then it'll get added twice: this gem always renders the given import into the <head>.

Configuration

# config/environments/test.rb
Rails.application.configure do
  config.stimulus_tests.route_path = "/_stimulus_tests" # this is the default
end

Examples

Rails tests

# test/system/hello_stimulus_controller_test.rb
require "application_system_test_case"
require "stimulus_tests"

class HelloStimulusControllerTest < ApplicationSystemTestCase
  include StimulusTests::DSL

  layout "application"
  # or
  # import "application"

  test "runs my controllers" do
    render_stimulus <<~HTML
      <p data-controller="hello">Initial text</p>
    HTML

    assert_text "Hello World!"
  end
end

RSpec

Require this gem in your Rails helper:

# spec/rails_helper.rb
require "stimulus_tests"

Every example in spec/stimulus, spec/features/stimulus, and spec/system/stimulus automatically gets the DSL included.

# spec/stimulus/hello_controller_spec.rb
require "rails_helper"

RSpec.feature "Stimulus::HelloController" do
  layout "application"
  # or
  # import "application"

  it "runs my controllers" do
    render_stimulus <<~HTML
      <p data-controller="hello">Initial text</p>
    HTML

    assert_text "Hello World!"
  end
end

You can setup any other example individually by ensuring the following:

  • StimulusTests::DSL is included in the example group.
  • Examples are run with a JavaScript driver.

Contributing

Please do! Issues are 👆 up there, and feel free to submit pull-requests for your ideas.

I can't guarantee when I'll be able to read and respond, sorry.

Setup

bin/appraisal install

Dev

There's a custom bin/rails script that uses the Rails 8 appraisal and proxies to the test/dummy app.

bin/rails server # in the root folder

The test/dummy app is intentionally sparse: it's just meant to exemplify one simple Stimulus controller to System tests can assert on it.

Tests

We have both Minitest and RSpec tests because this gem works with both frameworks.

This gem's tests are written in Minitest in the test/ directory. The RSpec tests in spec/ are only to test the integration of this gem with RSpec.

bin/test has been edited to run all tests by default, unless given specific paths.

bin/appraisal bin/test
bin/appraisal bin/rspec

To run all the tests together:

bin/appraisal bin/test && bin/appraisal bin/rspec

License

The gem is available as open source under the terms of the MIT License.