### 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 # => '
Hello world
' page.find(:css, 'div').text # => 'Hello world' page.find(:xpath, './/div').text # => 'Hello world' ``` ```ruby page.html # => '
Hello world
' 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