gherkin_system
Compile Gherkin features into Rails system tests.
Gherkin describes behavior. Rails owns execution. Each scenario becomes a Minitest method on your ApplicationSystemTestCase, so Capybara, fixtures, routes, and screenshots stay the ones you already use. cucumber-rails is a separate runner. This gem is not.
Installation
gem "gherkin_system"bundle install
bin/rails g gherkin:install
bin/rails g gherkin:feature checkout
bin/rails g gherkin:steps checkoutinstall creates test/system/gherkin_test.rb, features/, and test/support/gherkin/. feature and steps add a .feature file and a steps module; wire the module into the loader with require_relative and config.include_steps.
Agent skill
For agents writing Gherkin scenarios in a Rails app, install the skill with npx skills:
npx skills add dpaluy/gherkin_systemUse -g for a global install, -a to target specific agents, and -y to skip prompts. The skill source is skills/gherkin-system.
Configuration
Configure in the loader created by the install generator:
# test/system/gherkin_test.rb
require "application_system_test_case"
require "gherkin_system/rails"
GherkinSystem.configure do |config|
config.features = Rails.root.join("features/**/*.feature")
config.include_steps AuthenticationSteps
config.strict = true
end
GherkinSystem.load!(base: ApplicationSystemTestCase)Generated tests subclass the class you pass. The gem does not install its own system-test superclass.
| Option | ENV variable | Default |
|---|---|---|
features |
features/**/*.feature |
|
tags |
GHERKIN_TAGS |
unset → every scenario is compiled |
strict |
true. A broken scenario fails itself. The rest still run |
|
base_test_class |
required by load! when base: is omitted |
|
test_file |
test/system/gherkin_test.rb |
config.tags / GHERKIN_TAGS is a Cucumber tag expression. Only matching scenarios are compiled into Minitest methods:
GHERKIN_TAGS="@critical and not @slow" bin/rails test:systemSame filter via the CLI: bin/rails gherkin --tags "@critical and not @slow" (sets GHERKIN_TAGS for that run). Leave it unset to compile every scenario. If the env var stays set, later bin/rails test:system runs keep the filter.
Steps
module AuthenticationSteps
extend GherkinSystem::Steps
Given("I am signed in") do
sign_in users(:customer)
end
When("I purchase the {string} plan") do |plan|
visit plans_path
click_on plan
end
Then(/^I have (\d+) products$/) do |count|
assert_equal count.to_i, Product.count
end
ParameterType(
name: "user",
regexp: /alice|bob/,
type: User,
transformer: ->(name) { users(name.to_sym) }
)
endGiven, When, Then, And, and But share one registry. Blocks run with instance_exec on the system test, so instance variables set in one step are visible in the next.
Wait for navigation
After a step triggers navigation, assert visible page content or use a Capybara waiting assertion. Do not compare current_path directly. A direct comparison does not wait for navigation.
When("I open an order") do
click_on "Order details"
assert_current_path(/\/orders\/\d+/, url: true)
end
When("I stay on the orders page") do
click_on "Refresh orders"
assert_selector "h1", text: "Orders"
refute_current_path(/\/orders\/\d+\/details/)
endFor a negative URL check, first assert content that only the destination page shows. This prevents a check from passing before the browser navigates.
Hooks
module CheckoutHooks
extend GherkinSystem::Hooks
Before do
end
Before("@admin") do
end
After do |scenario|
end
Around("@external") do |scenario|
scenario.run
end
endRails setup runs first. Gherkin hooks and steps run inside the test method. Rails teardown and failure screenshots run after.
Commands
bin/rails gherkin
bin/rails gherkin features
bin/rails gherkin features/checkout.feature
bin/rails gherkin features/checkout.feature:42
bin/rails gherkin --tags "@critical and not @slow"
bin/rails gherkin:check
bin/rails gherkin:listA directory path selects every feature under that directory. A path or line filter that matches nothing raises instead of running an empty suite.
gherkin:check parses features and resolves steps. It does not start a browser. bin/rails test:system and bin/rails test:all run the generated tests as normal Minitest tests.
Tag filters use Cucumber tag expressions.
Error handling
begin
GherkinSystem.load!(base: ApplicationSystemTestCase)
rescue GherkinSystem::ConfigurationError => e
warn e.message
rescue GherkinSystem::CompilationError => e
warn e.message
end| Class | When |
|---|---|
ConfigurationError |
Missing base class or test file |
CompilationError |
Invalid Gherkin, tag expression, or hook |
UndefinedStep |
No definition matches the step |
AmbiguousStep |
More than one definition matches |
DuplicateStep |
The same pattern is registered twice |
StepFailure |
A step raised (Minitest::Assertion). cause is the original exception. Message includes feature, step, line, and bin/rails gherkin … rerun |
Undefined and ambiguous steps raise in before_setup, before the driver starts. The message names the feature, scenario, step, feature line, and a suggested definition.
Development
bin/setup
bundle exec rake
bundle exec rake test
bundle exec rubocopContributing
Issues and pull requests: github.com/dpaluy/gherkin_system.
License
MIT. See LICENSE.txt.
Supported by Majestic Labs.