### Install Capybara Gem
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Add this line to your Gemfile to install Capybara. Run `bundle install` afterwards.
```ruby
gem 'capybara'
```
--------------------------------
### Install Dependencies and Run Tests
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Install project dependencies using Bundler and run the test suite. Use `spec_chrome` for Chrome tests, which requires `chromedriver`.
```bash
bundle install
```
```bash
bundle exec rake # run the test suite with Firefox - requires `geckodriver` to be installed
```
```bash
bundle exec rake spec_chrome # run the test suite with Chrome - require `chromedriver` to be installed
```
--------------------------------
### Selector Name Argument Examples
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Demonstrates how the name argument in selectors can be explicit or inferred by helper methods.
```ruby
page.html # => 'Home'
page.find(:link) == page.find_link
page.html # => ''
page.find(:field) == page.find_field
```
--------------------------------
### Selector Locator Argument Examples
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Shows how to use CSS and XPath locators to find elements. The default selector can be configured.
```ruby
page.html # => '
'
Capybara.default_selector = :css
page.find('div').text # => 'Hello world'
Capybara.default_selector = :xpath
page.find('.//div').text # => 'Hello world'
```
--------------------------------
### Navigating with visit
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
The `visit` method navigates the browser to a specified URL. The request method is always GET.
```APIDOC
## visit
### Description
Navigates the browser to a specified URL.
### Method
GET
### Endpoint
[URL]
### Parameters
#### Path Parameters
- **url** (string) - Required - The URL to navigate to.
### Request Example
```ruby
visit('/projects')
visit(post_comments_path(post))
```
```
--------------------------------
### Selector Filter Argument Examples
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Demonstrates using filter arguments like 'href', 'text', and 'id' to refine element selection.
```ruby
page.html # => 'Home'
# find by the [href] attribute
page.find_link(href: '/') == page.find_link(text: 'Home') # => true
page.html # => '
Content
'
# find by the [id] attribute
page.find(id: 'element') == page.find(text: 'Content') # => true
# find by the [data-attribute] attribute
page.find(:element, 'data-attribute': /value/) == page.find(text: 'Content') # => true
page.html # => ''
```
--------------------------------
### Configure RackTest Driver Headers
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Register a custom RackTest driver with specific headers. This example sets the 'HTTP_USER_AGENT' header.
```ruby
Capybara.register_driver :rack_test do |app|
Capybara::RackTest::Driver.new(app, headers: { 'HTTP_USER_AGENT' => 'Capybara' })
end
```
--------------------------------
### Manually Create and Use a Capybara Session
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Instantiate a `Capybara::Session` manually for full control. Requires Capybara and a Rack app. This example demonstrates filling form fields and clicking a button.
```ruby
require 'capybara'
session = Capybara::Session.new(:webkit, my_rack_app)
session.within("form#session") do
session.fill_in 'Email', with: 'user@example.com'
session.fill_in 'Password', with: 'password'
end
session.click_button 'Sign in'
```
--------------------------------
### Configure Capybara Session Options
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
In threadsafe mode, options can be set per session. This example shows how to configure `automatic_label_click` and `default_max_wait_time` for a specific session.
```ruby
my_session = Capybara::Session.new(:driver, some_app) do |config|
config.automatic_label_click = true # only set for my_session
end
my_session.config.default_max_wait_time = 10 # only set for my_session
Capybara.default_max_wait_time = 2 # will not change the default_max_wait in my_session
```
--------------------------------
### Basic Asynchronous Operation (Likely to Fail)
Source: https://github.com/teamcapybara/capybara/wiki/Asynchronous-Javascript-drivers
This example demonstrates a common pitfall where assertions are made before the server has finished processing the request, often leading to test failures.
```ruby
visit "/posts/new"
fill_in :title, :with => "Hello"
click_button "Create Post"
Post.last.title.should == "Hello"
```
--------------------------------
### Retrieve Page HTML
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Get the current state of the DOM as a string. Primarily for debugging, avoid testing against this directly.
```ruby
print page.html
```
--------------------------------
### Navigate to a URL with Capybara
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Use the `visit` method to navigate to a specific path or URL. The request method is always GET.
```ruby
visit('/projects')
visit(post_comments_path(post))
```
--------------------------------
### Minitest::Spec Assertion Example
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
An example of using Capybara's `must_have_content` assertion within Minitest::Spec. Ensure `capybara/minitest/spec` is required.
```ruby
page.must_have_content('Important!')
```
--------------------------------
### Find Multiple Elements with `all` and `first`
Source: https://context7.com/teamcapybara/capybara/llms.txt
Use `all` to get a collection of matching elements, optionally with count constraints. `first` returns the first match or nil if none found (with `minimum: 0`). Waits for count constraints if specified.
```ruby
# All matching links
links = all('a')
links.each { |a| puts a[:href] }
# With count constraints (raises if not satisfied after waiting)
rows = all('tr', minimum: 3)
cells = all('td.price', count: 5)
items = all('li', between: 2..8)
# Filter by text / visibility
labels = all('label', text: /required/i, visible: true)
# XPath
all(:xpath, './/input[@type="checkbox"]').each(&:check)
# First match (returns nil if minimum: 0 and nothing found)
first_error = first('.error-msg', minimum: 0)
puts first_error&.text
# Custom filter block
all(:field, 'Qty') { |el| el.value.to_i > 0 }
```
--------------------------------
### Set Default Capybara Driver
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Configure Capybara to use a specific driver by default. This example sets the default driver to `:selenium`.
```ruby
Capybara.default_driver = :selenium # :selenium_chrome and :selenium_chrome_headless are also registered
```
--------------------------------
### Registering Custom Capybara Drivers
Source: https://context7.com/teamcapybara/capybara/llms.txt
Register custom driver configurations with `Capybara.register_driver` for specialized browser setups, such as mobile emulation or custom profiles.
```ruby
# Custom Selenium Chrome driver with options
Capybara.register_driver :chrome_mobile do |app|
options = Selenium::WebDriver::Chrome::Options.new
options.add_emulation(device_name: 'iPhone X')
options.add_argument('--headless')
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
# Selenium with custom profile
Capybara.register_driver :firefox_custom do |app|
profile = Selenium::WebDriver::Firefox::Profile.new
profile['browser.download.folderList'] = 2
profile['browser.download.dir'] = '/tmp/downloads'
options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
Capybara::Selenium::Driver.new(app, browser: :firefox, options: options)
end
# Use in specs
Capybara.current_driver = :chrome_mobile
visit '/mobile-landing'
expect(page).to have_css('.mobile-nav')
# Temporarily switch driver
Capybara.using_driver(:chrome_mobile) do
visit '/checkout'
end
```
--------------------------------
### Temporarily Switch Capybara Driver
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Switch the Capybara driver temporarily within test setup and teardown blocks. Remember to switch back to the default driver afterwards.
```ruby
Capybara.current_driver = :selenium # temporarily select different driver
# tests here
Capybara.use_default_driver # switch back to default driver
```
--------------------------------
### Working with Browser Windows
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Use `window_opened_by` to capture a new window opened by an action and `within_window` to scope interactions to that specific window.
```ruby
facebook_window = window_opened_by do
click_button 'Like'
end
within_window facebook_window do
find('#login_email').set('a@example.com')
find('#login_password').set('qwerty')
click_button 'Submit'
end
```
--------------------------------
### Navigation - visit, refresh, go_back, go_forward
Source: https://context7.com/teamcapybara/capybara/llms.txt
Navigate the browser to a URL. `visit` accepts both relative paths and absolute URLs; relative paths are resolved against `app_host` or the running server.
```APIDOC
## Navigation - `visit`, `refresh`, `go_back`, `go_forward`
### Description
Navigate the browser to a URL. `visit` accepts both relative paths and absolute URLs; relative paths are resolved against `app_host` or the running server.
### Code Example
```ruby
# With Capybara::DSL included (RSpec feature spec, Cucumber step, etc.)
visit '/products'
visit 'http://external-site.com/page'
puts current_url # => "http://127.0.0.1:4567/products"
puts current_path # => "/products"
puts current_host # => "http://127.0.0.1:4567"
puts html # => current DOM as string
puts status_code # => 200 (rack_test only)
puts response_headers['Content-Type'] # rack_test only
refresh # reload current page
go_back # browser back
go_forward # browser forward
```
```
--------------------------------
### Save and Open Current Page
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Use this to take a snapshot of the current page for debugging purposes.
```ruby
save_and_open_page
```
--------------------------------
### Configuration - Capybara.configure
Source: https://context7.com/teamcapybara/capybara/llms.txt
Global configuration block for setting driver selection, wait times, selector strategy, server settings, and more. Options can also be set on a per-session basis when `threadsafe` mode is enabled.
```APIDOC
## Configuration - `Capybara.configure`
### Description
Global configuration block that sets driver selection, wait times, selector strategy, server settings, and more. All options are also settable on a per-session basis when `threadsafe` mode is enabled.
### Code Example
```ruby
require 'capybara/rspec'
Capybara.configure do |config|
config.default_driver = :rack_test # fastest, no JS
config.javascript_driver = :selenium_chrome_headless
config.default_max_wait_time = 5 # seconds to retry async queries
config.default_selector = :css # :css (default) or :xpath
config.match = :smart # :one, :first, :smart, :prefer_exact
config.exact = false # allow partial text matches
config.exact_text = false
config.ignore_hidden_elements = true # visible elements only by default
config.automatic_label_click = false # auto-click labels for checkboxes
config.enable_aria_label = false # use aria-label as locator fallback
config.enable_aria_role = false
config.save_path = 'tmp/capybara' # for save_page / save_screenshot
config.asset_host = 'http://localhost:3000'
config.app_host = nil
config.server = :puma # or :webrick, or custom proc
config.server = :puma, { Silent: true }
config.raise_server_errors = true
config.threadsafe = false # must be set before any session is created
config.test_id = 'data-testid' # custom attribute checked alongside id
config.default_normalize_ws = false
config.w3c_click_offset = false
config.predicates_wait = true
config.disable_animation = false
end
```
```
--------------------------------
### Revert to WEBRick Server
Source: https://github.com/teamcapybara/capybara/blob/master/UPGRADING.md
If your project does not use Puma, you can revert to the previous default WEBRick server by specifying it.
```ruby
Capybara.server = :webrick
```
--------------------------------
### Visit a Specific URL Directly
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Visit any URL directly, useful when working with drivers that support remote connections.
```ruby
visit('http://www.google.com')
```
--------------------------------
### Set Capybara Driver in Rails Test
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Temporarily set the Capybara driver for a specific test class in Rails. This example sets the driver to the JavaScript-capable Selenium driver.
```ruby
class BlogTest < ActionDispatch::IntegrationTest
setup do
Capybara.current_driver = Capybara.javascript_driver # :selenium by default
end
test 'shows blog posts' do
# ... this test is run with Selenium ...
end
end
```
--------------------------------
### Capybara Configuration
Source: https://context7.com/teamcapybara/capybara/llms.txt
Configure global settings for Capybara, including drivers, wait times, and selector strategies. Ensure `threadsafe` is set before creating any sessions.
```ruby
require 'capybara/rspec'
Capybara.configure do |config|
config.default_driver = :rack_test # fastest, no JS
config.javascript_driver = :selenium_chrome_headless
config.default_max_wait_time = 5 # seconds to retry async queries
config.default_selector = :css # :css (default) or :xpath
config.match = :smart # :one, :first, :smart, :prefer_exact
config.exact = false # allow partial text matches
config.exact_text = false
config.ignore_hidden_elements = true # visible elements only by default
config.automatic_label_click = false # auto-click labels for checkboxes
config.enable_aria_label = false # use aria-label as locator fallback
config.enable_aria_role = false
config.save_path = 'tmp/capybara' # for save_page / save_screenshot
config.asset_host = 'http://localhost:3000'
config.app_host = nil
config.server = :puma # or :webrick, or custom proc
config.server = :puma, { Silent: true }
config.raise_server_errors = true
config.threadsafe = false # must be set before any session is created
config.test_id = 'data-testid' # custom attribute checked alongside id
config.default_normalize_ws = false
config.w3c_click_offset = false
config.predicates_wait = true
config.disable_animation = false
end
```
--------------------------------
### Perform Drag-and-Drop Operations
Source: https://context7.com/teamcapybara/capybara/llms.txt
Simulate dragging an element to a target element or dropping files onto a drop zone. Options like delay, HTML5 mode, and modifier keys are available.
```ruby
source = find('#item-1')
target = find('#trash-bin')
source.drag_to(target)
```
```ruby
source.drag_to(target, delay: 0.1, html5: true, drop_modifiers: :shift)
```
```ruby
dropzone = find('#dropzone')
dropzone.drop('/path/to/upload.csv')
```
```ruby
dropzone.drop({ 'text/plain' => 'pasted text content' })
```
--------------------------------
### Restricting Scope within Elements
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Use `find` to get a specific element and then chain Capybara DSL methods to interact with elements only within that found element's scope.
```ruby
find('#navigation').click_link('Home')
expect(find('#navigation')).to have_button('Sign out')
```
--------------------------------
### Access Shadow DOM Elements
Source: https://context7.com/teamcapybara/capybara/llms.txt
Interact with elements inside a web component's shadow root. Find the host element, get its shadow root, and then query elements within it.
```ruby
host = find('my-custom-element')
shadow = host.shadow_root
within shadow do
fill_in 'Internal Input', with: 'hello'
click_button 'Submit'
end
```
```ruby
shadow.find('button.close').click
expect(shadow).to have_css('.result', text: 'Done')
```
--------------------------------
### Handle Browser Alerts
Source: https://context7.com/teamcapybara/capybara/llms.txt
Accept a browser alert dialog. The action that triggers the alert must be wrapped in a block. The alert's message is returned.
```ruby
message = accept_alert do
click_button 'Show Alert'
end
puts message # => "Are you sure?"
```
```ruby
accept_alert 'Warning: data will be lost' do
click_link 'Delete Account'
end
```
--------------------------------
### Define Custom Capybara Selectors
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Add custom selectors using `Capybara.add_selector`. The block must return an XPath or CSS expression. Examples show attribute, row number, and flash type selectors.
```ruby
Capybara.add_selector(:my_attribute) do
xpath { |id| XPath.descendant[XPath.attr(:my_attribute) == id.to_s] }
end
Capybara.add_selector(:row) do
xpath { |num| ".//tbody/tr[#{num}]" }
end
Capybara.add_selector(:flash_type) do
css { |type| "#flash.#{type}" }
end
```
--------------------------------
### Execute JavaScript with Arguments
Source: https://context7.com/teamcapybara/capybara/llms.txt
Evaluate a JavaScript expression within the page context, passing arguments. The first argument is the script, followed by any arguments to be passed to the script.
```ruby
result = evaluate_script(<<~JS, 3, find('#counter'))
(function(n, el) {
return parseInt(el.textContent, 10) + n;
})(arguments[0], arguments[1])
JS
```
--------------------------------
### Manage Multiple Browser Windows
Source: https://context7.com/teamcapybara/capybara/llms.txt
Open new windows/tabs, switch between them, and wait for them to open or close. This functionality is Selenium-specific.
```ruby
new_win = open_new_window
within_window new_win do
visit '/help'
expect(page).to have_text 'Help Center'
end
```
```ruby
popup = window_opened_by do
click_link 'Open in new window'
end
within_window popup do
expect(page).to have_current_path '/preview'
popup.close
end
```
```ruby
switch_to_window { title == 'Payment Gateway' }
```
```ruby
windows.each do |win|
within_window(win) { puts current_url }
end
```
```ruby
popup = window_opened_by { click_button 'Popup' }
within_window popup do
click_button 'Close'
end
expect(popup).to become_closed(wait: 2)
```
--------------------------------
### Selector Locator with Different Argument Types
Source: https://github.com/teamcapybara/capybara/blob/master/README.md
Illustrates finding elements using various locator argument types like String, Array, and Hash.
```ruby
page.html # => '
# '
# find by the element's [id] attribute
page.find(:id, 'greeting') == page.find_by_id('greeting') # => true
# find by the element's [id] attribute
page.find(:field, 'greeting') == page.find_field('greeting') # => true
# find by the element's [name] attribute
page.find(:field, 'content') == page.find_field('content') # => true
# find by the