<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://mdominiak.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mdominiak.com/" rel="alternate" type="text/html" /><updated>2021-08-18T09:55:34+00:00</updated><id>https://mdominiak.com/feed.xml</id><title type="html">Mateusz Dominiak</title><subtitle>Crafting awesome web applications in Ruby on Rails and blogging about interesting engineering challenges.</subtitle><entry><title type="html">Hotwire Chat: Turbo and Stimulus demo</title><link href="https://mdominiak.com/2021/01/25/hotwire-chat.html" rel="alternate" type="text/html" title="Hotwire Chat: Turbo and Stimulus demo" /><published>2021-01-25T00:00:00+00:00</published><updated>2021-01-25T00:00:00+00:00</updated><id>https://mdominiak.com/2021/01/25/hotwire-chat</id><content type="html" xml:base="https://mdominiak.com/2021/01/25/hotwire-chat.html">&lt;p&gt;&lt;a href=&quot;https://github.com/mdominiak/hotwire-chat&quot;&gt;Hotwire Chat&lt;/a&gt; is a simple chat web app built in Ruby on Rails and &lt;a href=&quot;https://hotwire.dev&quot;&gt;Hotwire&lt;/a&gt; demonstrating Turbo Drive/Frames/Streams, Stimulus, caching, and testing. See &lt;a href=&quot;https://github.com/mdominiak/hotwire-chat/blob/master/README.md&quot;&gt;readme&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;Source code: &lt;a href=&quot;https://github.com/mdominiak/hotwire-chat&quot;&gt;https://github.com/mdominiak/hotwire-chat&lt;/a&gt;
&lt;br /&gt;
Live to play with at: &lt;a href=&quot;https://hotwired-chat.herokuapp.com&quot;&gt;https://hotwired-chat.herokuapp.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/mdominiak/hotwire-chat&quot;&gt;&lt;img src=&quot;/assets/hotwire-chat.gif&quot; alt=&quot;Hotwire Chat&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content><author><name></name></author><summary type="html">Hotwire Chat is a simple chat web app built in Ruby on Rails and Hotwire demonstrating Turbo Drive/Frames/Streams, Stimulus, caching, and testing. See readme for more details.</summary></entry><entry><title type="html">Rails system tests with RSpec</title><link href="https://mdominiak.com/2017/12/28/rspec-system-specs.html" rel="alternate" type="text/html" title="Rails system tests with RSpec" /><published>2017-12-28T00:00:00+00:00</published><updated>2017-12-28T00:00:00+00:00</updated><id>https://mdominiak.com/2017/12/28/rspec-system-specs</id><content type="html" xml:base="https://mdominiak.com/2017/12/28/rspec-system-specs.html">&lt;p&gt;Prior to RSpec 3.7 &lt;a href=&quot;https://relishapp.com/rspec/rspec-rails/v/3-7/docs/feature-specs/feature-spec&quot;&gt;feature specs&lt;/a&gt; were the way to go for full-stack testing of application interactions involving javascript in a real/headless browser environment. Recently released &lt;a href=&quot;http://rspec.info/blog/2017/10/rspec-3-7-has-been-released/&quot;&gt;RSpec 3.7&lt;/a&gt; added support for &lt;a href=&quot;https://relishapp.com/rspec/rspec-rails/v/3-7/docs/system-specs/system-spec&quot;&gt;system specs&lt;/a&gt; based on Rails &lt;a href=&quot;http://guides.rubyonrails.org/v5.1/testing.html#system-testing&quot;&gt;system tests&lt;/a&gt;. &lt;a href=&quot;http://api.rubyonrails.org/v5.1/classes/ActionDispatch/SystemTestCase.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionDispatch::SystemTestCase&lt;/code&gt;&lt;/a&gt; was introduced in &lt;a href=&quot;http://weblog.rubyonrails.org/2017/4/27/Rails-5-1-final/&quot;&gt;Rails 5.1&lt;/a&gt; and provides preconfigured &lt;a href=&quot;https://github.com/teamcapybara/capybara&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Capybara&lt;/code&gt;&lt;/a&gt; wrapper for real browser testing. Having preconfigured Capybara with commonly used features baked right in the framework means much less manual configuration hassle which often was tricky to set up properly. The advantages of using &lt;a href=&quot;https://relishapp.com/rspec/rspec-rails/v/3-7/docs/system-specs/system-spec&quot;&gt;system specs&lt;/a&gt; over &lt;a href=&quot;https://relishapp.com/rspec/rspec-rails/v/3-7/docs/feature-specs/feature-spec&quot;&gt;feature specs&lt;/a&gt; are the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Database changes are automatically rolled back after a test and there is no need to manually configure and use &lt;a href=&quot;https://github.com/DatabaseCleaner/database_cleaner&quot;&gt;database_cleaner&lt;/a&gt; strategies.&lt;/li&gt;
  &lt;li&gt;More convenient way to switch a browser driver for each spec individually with &lt;a href=&quot;http://api.rubyonrails.org/v5.1/classes/ActionDispatch/SystemTestCase.html#method-c-driven_by&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;driven_by&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Automatic browser screenshots on failure displayed right in the terminal. Again, that’s preconfigured, no need to add supporting gem like &lt;a href=&quot;https://github.com/mattheworiordan/capybara-screenshot&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;capybara-screenshot&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Given the above, it’s also worth emphasizing that the RSpec team now recommends system specs over feature specs for Rails 5.1 and above.&lt;/p&gt;

&lt;h1 id=&quot;setting-up-rspec-system-specs-with-headless-chrome&quot;&gt;Setting up RSpec system specs with headless Chrome&lt;/h1&gt;

&lt;p&gt;Let’s start by creating a new rails project. We’re going to exclude the default Rails Minitest integration with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--skip-test&lt;/code&gt; as we’re going to use RSpec.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;rails &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;
Rails 5.2.0.beta2
rails new rspec-system-specs &lt;span class=&quot;nt&quot;&gt;--skip-test&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--skip-active-storage&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Except for adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rspec-rails&lt;/code&gt; to &lt;a href=&quot;https://github.com/mdominiak/rspec-system-specs/blob/master/Gemfile&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Gemfile&lt;/code&gt;&lt;/a&gt;, the most challenging part of the setup may be to figure out which gems are required for headless Chrome browser testing. Here is list the of required gems:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:development&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:test&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Adds support for Capybara system testing and selenium driver&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'capybara'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'~&amp;gt; 2.16.1'&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'selenium-webdriver'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'~&amp;gt; 3.8.0'&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Easy installation and use of chromedriver to run system tests with Chrome&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'chromedriver-helper'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'~&amp;gt; 1.1.0'&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rspec-rails'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'~&amp;gt; 3.7.2'&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Make sure that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chromedriver&lt;/code&gt; is installed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;chromedriver
chromedriver &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;
ChromeDriver 2.34.522932 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;4140ab217e1ca1bec0c4b4d1b148f3361eb3a03e&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Generate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec/test_helper.rb&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec/rails_helper.rb&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;rails g rspec:install&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;writing-system-spec&quot;&gt;Writing system spec&lt;/h1&gt;

&lt;p&gt;Given we have a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;home#index&lt;/code&gt; action, configured as root in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;routes.rb&lt;/code&gt;, that renders &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/views/home/index.html.erb&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-erb&quot; data-lang=&quot;erb&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Hello World&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;we can implement the first system spec &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec/system/home_spec.rb&lt;/code&gt; as follows:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rails_helper'&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Homepage'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;driven_by&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:selenium_chrome_headless&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'shows greeting'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root_url&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_content&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Hello World'&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We’re setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:selenium_chrome_headless&lt;/code&gt; driver as we want to use headless Chrome. Other registered drivers provided by Capybara are: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:rack_test&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:selenium&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:selenium_chrome&lt;/code&gt;. See the &lt;a href=&quot;http://api.rubyonrails.org/v5.1/classes/ActionDispatch/SystemTestCase.html#method-c-driven_by&quot;&gt;driven_by&lt;/a&gt; documentation for more advanced configuration options, e.g. browser resolution.&lt;/p&gt;

&lt;p&gt;Let’s see if it works:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rspec
Puma starting &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;single mode...
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Version 3.11.0 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;ruby 2.5.0-p0&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;, codename: Love Song
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Min threads: 0, max threads: 4
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Environment: &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; Listening on tcp://127.0.0.1:50713
Use Ctrl-C to stop
&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;

Finished &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;1.41 seconds &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;files took 2.04 seconds to load&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
1 example, 0 failures&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Obviously we don’t want to set the driver in each spec. We can configure a global default in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec_helper.rb&lt;/code&gt;. For example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;RSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;type: :system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;driven_by&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:selenium_chrome_headless&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and override the default driver in individual spec files when needed.&lt;/p&gt;

&lt;h1 id=&quot;browser-screenshots-on-failure&quot;&gt;Browser screenshots on failure&lt;/h1&gt;

&lt;p&gt;It’s worth mentioning that in case of spec failure, system spec automatically takes the browser screenshot and displays it right in the terminal output which is a very handy feature.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://mdominiak.com/assets/rspec-system-specs/rspec-sys-spec-failure.png&quot; alt=&quot;spec failure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s the feature baked in Rails system tests. There is no need to configure it manually as it was in case of feature specs, for example with supporting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;capybara-screenshot&lt;/code&gt; gem.&lt;/p&gt;

&lt;h1 id=&quot;javascript-testing&quot;&gt;Javascript testing&lt;/h1&gt;

&lt;p&gt;So far we’ve only tested server-side rendered content. Let’s add some client-side javascript to prove that indeed system spec is using javascript capable browser (headless Chrome in our case):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-coffeescript&quot; data-lang=&quot;coffeescript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'#title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Hello Universe'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After modifying the spec assertion to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expect(page).to have_content 'Hello Universe'&lt;/code&gt;, we still get the passing spec testing client-side javascript changes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rspec
Finished &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;1.99 seconds &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;files took 2.44 seconds to load&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
1 example, 0 failures&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h1 id=&quot;automatic-database-rollback&quot;&gt;Automatic database rollback&lt;/h1&gt;

&lt;p&gt;As mentioned before, database changes in system specs are automatically rolled back. Let’s see if it’s the case by adding some database output in our page under test:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-erb&quot; data-lang=&quot;erb&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;h1&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Hello World&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  Planet count: &lt;span class=&quot;cp&quot;&gt;&amp;lt;%=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Planet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Modify the spec to seed a record and add new spec example asserting rendered record count:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Homepage'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;driven_by&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:selenium_chrome_headless&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'creating a planet'&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Planet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;name: &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Mars'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'shows greeting'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root_url&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_content&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Hello Universe'&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'shows planet count'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;visit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root_url&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_content&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Planet count: 1'&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rspec&lt;/code&gt; result is:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rspec &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; d
creating a planet
  shows greeting
&lt;span class=&quot;c&quot;&gt;# automatic database rollback after spec example&lt;/span&gt;
creating a planet
  shows planet count

Finished &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;1.52 seconds &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;files took 1.03 seconds to load&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
2 examples, 0 failures&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That’s great! We no longer need to configure &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;database_cleaner&lt;/code&gt; to clean database state after spec example run as it was previously required in case of feature specs.&lt;/p&gt;

&lt;p&gt;The source code of the demonstrated example can be found on &lt;a href=&quot;https://github.com/mdominiak/rspec-system-specs&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</content><author><name></name></author><summary type="html">Prior to RSpec 3.7 feature specs were the way to go for full-stack testing of application interactions involving javascript in a real/headless browser environment. Recently released RSpec 3.7 added support for system specs based on Rails system tests. ActionDispatch::SystemTestCase was introduced in Rails 5.1 and provides preconfigured Capybara wrapper for real browser testing. Having preconfigured Capybara with commonly used features baked right in the framework means much less manual configuration hassle which often was tricky to set up properly. The advantages of using system specs over feature specs are the following:</summary></entry></feed>