What a system spec actually is

Free preview 3 min to read

A gap this app's request specs can't close

This app has dozens of request spec files under spec/requests/, with a few hundred examples between them. spec/requests/auth_spec.rb posts form params to auth_sign_up_path and checks expect(response).to redirect_to(new_auth_two_factor_setup_path). That proves the server accepted the signup and issued the right redirect. It proves nothing about what a person's browser did on the way there. Did the password checklist turn green as they typed? Did a dropdown open when they clicked it? A request spec never runs a line of JavaScript and never touches a DOM. A system spec is Rails' and Capybara's answer to that gap.

The syntax: type: :system

RSpec.describe "Sign up", type: :system do
  it "shows a live password strength checklist as the user types" do
    visit auth_sign_up_path
    fill_in "password", with: "weak"
    expect(page).to have_content("At least 8 characters")
  end
end

type: :system is the RSpec metadata tag, parallel to the type: :request this app's request specs already use. It pulls in a different toolkit: Capybara, driving a browser (or a fast in-process stand-in, lesson 3's subject) instead of a plain HTTP client.

Capybara's DSL, quoted from its README

Capybara's README, which ships inside the installed gem, documents the vocabulary a system spec is written in. Navigation is visit(path): "The visit method only takes a single parameter, the request method is always GET." Interaction is click_link, click_button and click_on, which "clicks on either links or buttons". Forms use fill_in(label, with: 'value'), select(option, from: 'select box'), check, uncheck, choose and attach_file. Assertions read against page, not response: have_content(text), have_css(selector), have_selector(selector) and have_current_path(path), plus their negatives (have_no_content, have_no_css and so on). All of them come from Capybara's documented API.

Up front: the gem is here, and nothing is built on it yet

grep -i capybara Gemfile                     # => gem "capybara"
grep -i selenium Gemfile Gemfile.lock        # => no matches
ls spec/system                               # => No such file or directory

All three were checked against this repo. capybara (3.40.0) is in this app's Gemfile, but nothing else a browser-driving spec needs is. There's no selenium-webdriver gem, which the default system-spec driver depends on, and there's no spec/system/ directory at all. A gem in the Gemfile and a spec that can drive a browser are separate steps, and only the first is done here. That's this course's starting point. The next lesson runs a spec against this app to show what the gap looks like today.

What this course covers

Seven lessons. This one covers what a system spec is and Capybara's DSL. Lesson 2 shows how much system-spec machinery this app's installed rspec-rails gem already ships, read from its source and checked with a throwaway spec run against this app. Lesson 3 covers rack_test, Capybara's fast default driver with no JavaScript. Lesson 4 covers the JavaScript-capable drivers, Selenium's variants, from Capybara's docs. Lesson 5 picks one interaction on this app's sign-up page that only a JS-capable system spec could verify. Lesson 6 takes stock of what this app's request specs already prove without a browser, and what they can't. Lesson 7 puts it together and points to the next course.

Lesson 1 of 7 · free

Keep going with lesson 2

rspec-rails already ships the plumbing, in this app's installed gem

Reads the system-spec support inside the installed rspec-rails gem and shows why a default system spec asks for selenium-webdriver.

A free account also gives you the quizzes, your progress and notes, and the discussion.

Type to start searching...