Skip to content

Configuration

Bryan edited this page Jan 30, 2026 · 10 revisions

SpecForge configuration lives in forge_helper.rb, created when you run spec_forge init. This file controls global settings, variables, callbacks, and framework integration.

Basic Configuration

# spec_forge/forge_helper.rb

SpecForge.configure do |config|
  # Base URL for all requests (required)
  config.base_url = "http://localhost:3000"

  # Global variables available to all blueprints
  config.global_variables = {
    api_version: "v1",
    admin_email: "admin@test.com"
  }
end

Configuration Options

Option Type Default Description
base_url String "http://localhost:3000" Base URL prepended to all request paths
global_variables Hash {} Variables available in all blueprints via {{ name }}
factories.auto_discover Boolean true Auto-load FactoryBot factories
factories.paths Array [] Additional factory file paths

Global Variables

Global variables are accessible in any blueprint using {{ variable_name }}:

SpecForge.configure do |config|
  config.global_variables = {
    api_version: "v1",
    default_timeout: 5000,
    admin_credentials: {
      email: "admin@test.com",
      password: "admin123"
    }
  }
end
# In any blueprint
- name: "Login as admin"
  request:
    url: "/api/{{ api_version }}/auth/login"
    http_verb: POST
    json:
      email: "{{ admin_credentials.email }}"
      password: "{{ admin_credentials.password }}"

Note: Local variables (defined with store:) can shadow global variables within a blueprint. See Context System for details.

Framework Integration

Rails Integration

# Load your Rails environment
require_relative "../config/environment"

RSpec Integration

SpecForge uses RSpec internally for expectations. You can load your existing RSpec configuration:

# Load your RSpec helpers, matchers, and configuration
require_relative "../spec/spec_helper"

If needed, you can access RSpec's configuration directly:

SpecForge.configure do |config|
  # Access RSpec config if you have specific requirements
  config.rspec.configure do |rspec_config|
    rspec_config.formatter = :documentation
  end
end

Note: For lifecycle hooks and callbacks, use SpecForge's native hooks (before_blueprint, after_step, etc.) instead of RSpec's callbacks. See Callbacks for details.

Custom Requires

# Load custom files (models, libraries, etc.)
Dir[File.join(__dir__, "..", "lib", "**", "*.rb")].sort.each { |f| require f }

Factory Configuration

SpecForge integrates with FactoryBot for test data generation:

SpecForge.configure do |config|
  # Disable auto-discovery if needed (default: true)
  config.factories.auto_discover = false

  # Add custom factory paths
  config.factories.paths += ["lib/factories", "spec/support/factories"]
end

Factories are then available in blueprints via the factories. expression:

- store:
    user: "{{ factories.user }}"

- name: "Use factory data"
  request:
    url: "/users/{{ user.id }}"

See Factory Support for more details.

Callback Registration

Register reusable callbacks for use in blueprints:

SpecForge.configure do |config|
  # Basic callback
  config.register_callback(:seed_database) do |context|
    User.create!(email: "test@test.com")
    Post.create!(title: "Test Post")
  end

  # Callback with arguments
  config.register_callback(:create_records) do |context, count:, type:|
    count.times { type.constantize.create! }
  end

  # Cleanup callback
  config.register_callback(:cleanup) do |context|
    DatabaseCleaner.clean
  end
end

The context parameter provides access to:

  • context.variables -- Current variable state
  • context.step -- Current step being executed (when applicable)

Use callbacks in blueprints with call: or hook::

# Direct invocation
- call: seed_database

# With arguments
- call:
    name: create_records
    arguments:
      count: 10
      type: "User"

# As lifecycle hook
- hook:
    before_blueprint: seed_database
    after_blueprint: cleanup

Aliases: define_callback and callback work the same as register_callback.

See Callbacks for more details.

Lifecycle Hooks

Register hooks that run at specific points in the test lifecycle:

SpecForge.configure do |config|
  # Register a callback first
  config.register_callback(:log_start) do |context|
    puts "Starting tests..."
  end

  # Attach it to a lifecycle event
  config.after(:forge, :log_start)
end

Available lifecycle events:

  • before_forge / after_forge -- Once per test run
  • before_blueprint / after_blueprint -- Per blueprint file
  • before_step / after_step -- Per step

You can also define inline hooks:

config.after(:step) do |context|
  next unless context.step.request?

  request = context.variables[:request]
  puts "→ #{request[:http_verb]} #{request[:url]}"
end

Debug Configuration

Configure what happens when a step has debug: true:

SpecForge.configure do |config|
  # Simple: drop into Pry
  config.on_debug { binding.pry }
end

The handler receives a context parameter if your block accepts one:

config.on_debug do |context|
  puts "Step: #{context.step.name}"
  puts "Variables: #{context.variables.inspect}"
  binding.pry
end

Environment-Based Configuration

Use environment variables for different environments:

SpecForge.configure do |config|
  config.base_url = ENV.fetch("API_BASE_URL", "http://localhost:3000")
  
  config.global_variables = {
    api_token: ENV["API_TOKEN"],
    environment: ENV.fetch("RAILS_ENV", "test")
  }
end

Run with different environments:

# Local development
spec_forge run

# Staging
API_BASE_URL=https://staging-api.example.com spec_forge run

# Production (docs only)
API_BASE_URL=https://api.example.com spec_forge docs

Complete Example

# spec_forge/forge_helper.rb
# frozen_string_literal: true

##########################################
# Framework Integration
##########################################

require_relative "../config/environment"
require_relative "../spec/spec_helper"

##########################################
# Configuration
##########################################

SpecForge.configure do |config|
  # Base URL
  config.base_url = ENV.fetch("API_BASE_URL", "http://localhost:3000")

  # Global variables
  config.global_variables = {
    api_version: "v1",
    admin_email: "admin@test.com"
  }

  # Factory configuration
  config.factories.paths += ["spec/support/factories"]

  # Debug handler
  config.on_debug do |context|
    binding.pry
  end

  # Callbacks
  config.register_callback(:seed_database) do |context|
    DatabaseCleaner.start
    load Rails.root.join("db/seeds/test.rb")
  end

  config.register_callback(:cleanup) do |context|
    DatabaseCleaner.clean
  end

  # RSpec configuration
  config.rspec.around do |example|
    DatabaseCleaner.cleaning { example.run }
  end
end

Related Documentation

Clone this wiki locally