Applitools Eyes Capybara SDK

Gem Version

The Applitools Eyes Capybara SDK seamlessly integrates visual testing into your Capybara test automation. Add AI-powered visual validations to your existing Capybara tests with minimal code changes.

Table of Contents

  1. Overview
  2. Installation
  3. Quick Start
  4. Key Components
  5. Advanced Usage
  6. Common Patterns
  7. Best Practices
  8. Common Pitfalls
  9. FAQ

Overview

The Applitools Eyes Capybara SDK bridges Capybara's browser automation with Applitools' visual AI technology. This integration enables you to perform visual validations within your Capybara tests, whether you're using RSpec, Cucumber, or any other Ruby testing framework.

Key Features

  • Seamless Integration: Works with your existing Capybara setup
  • Framework Agnostic: Compatible with RSpec, Cucumber, Minitest, and more
  • Multiple Driver Support: Works with Selenium-based Capybara drivers
  • Visual Grid Support: Test across multiple browsers and viewports in parallel
  • Flexible API: Use the same familiar Applitools API with Capybara conveniences

The SDK leverages the underlying Eyes Selenium SDK while providing a tailored interface specifically designed for Capybara's driver architecture and testing patterns.

Installation

Add the gem to your Gemfile:

gem 'eyes_capybara'

Or install it directly:

gem install eyes_capybara

Quick Start

Here's a simple example to get started with Eyes Capybara SDK in an RSpec test:

require 'eyes_capybara'
require 'capybara/rspec'

describe 'My First Visual Test' do
  let(:eyes) { Applitools::Selenium::Eyes.new }

  before do
    # Set your API key
    eyes.api_key = ENV['APPLITOOLS_API_KEY']

    # Configure Capybara
    Applitools.register_capybara_driver browser: :chrome

    # Visit the page to test
    visit 'https://example.com'
  end

  it 'should look correct' do
    # Start the test
    eyes.open(
      app_name: 'My App',
      test_name: 'My First Test',
      viewport_size: { width: 1200, height: 800 }
    )

    # Perform a visual validation
    eyes.check('Homepage', Applitools::Selenium::Target.window.fully)

    # End the test
    eyes.close
  end

  after do
    # Clean up
    eyes.abort_if_not_closed
  end
end

Key Components

Driver Integration

The Eyes Capybara SDK modifies Capybara's driver architecture to enable visual testing:

  1. Custom Capybara Driver: The Applitools::Selenium::Capybara::Driver class extends Capybara's Selenium driver to integrate with Applitools Eyes.

  2. Driver Registration: The SDK provides a convenient registration method through the register_capybara_driver function, which sets up the custom driver.

  3. Session Extensions: The SDK extends Capybara's Session class to provide additional methods for Eyes integration.

Core Functionality

The SDK offers these primary capabilities:

  1. Seamless Initialization: Register a custom Capybara driver that works with Applitools Eyes.

  2. Browser Management: Switch between the Eyes-wrapped browser and the native browser as needed.

  3. Visual Validation: Capture and validate screenshots of the application under test.

  4. Cross-Browser Testing: Test your application across multiple browsers and configurations with Visual Grid integration.

Advanced Usage

Customizing the Capybara Driver

You can customize the Capybara driver with various options:

Applitools.register_capybara_driver(
  browser: :chrome,
  options: {
    args: ['--headless', '--disable-gpu', '--window-size=1200,800']
  }
)

Working with Remote Browsers

For remote WebDriver connections:

Applitools.register_capybara_driver(
  browser: :remote,
  url: 'http://selenium-hub:4444/wd/hub',
  capabilities: Selenium::WebDriver::Remote::Capabilities.chrome
)

Switching Between Eyes and Native Browser

Sometimes you may need to perform operations with the native browser:

# Use Eyes-enabled browser for visual testing
eyes.open(app_name: 'My App', test_name: 'My Test')
eyes.check('Homepage', Applitools::Selenium::Target.window)

# Switch to native browser for other operations
page.use_native_browser
page.find('.some-element').click

# Switch back to Eyes browser
driver_for_eyes(eyes)
eyes.check('After Click', Applitools::Selenium::Target.window)

Common Patterns

Integration with RSpec

# spec_helper.rb
require 'eyes_capybara'
require 'capybara/rspec'

Applitools.register_capybara_driver browser: :chrome

RSpec.configure do |config|
  config.before(:each) do |example|
    @eyes = Applitools::Selenium::Eyes.new
    @eyes.api_key = ENV['APPLITOOLS_API_KEY']
  end

  config.after(:each) do |example|
    @eyes.abort_if_not_closed
  end
end

# In your spec file
describe 'Visual Tests' do
  it 'validates the homepage' do
    visit '/'

    @eyes.open(
      app_name: 'My App',
      test_name: 'Homepage Test',
      viewport_size: { width: 1200, height: 800 }
    )

    @eyes.check('Homepage', Applitools::Selenium::Target.window.fully)
    @eyes.close
  end
end

Integration with Cucumber

# env.rb
require 'eyes_capybara'
require 'capybara/cucumber'

Applitools.register_capybara_driver browser: :chrome

Before do |scenario|
  @eyes = Applitools::Selenium::Eyes.new
  @eyes.api_key = ENV['APPLITOOLS_API_KEY']
end

After do |scenario|
  @eyes.abort_if_not_closed
end

# In your step definitions
Given('I am on the homepage') do
  visit '/'
end

When('I start visual testing') do
  @eyes.open(
    app_name: 'My App',
    test_name: @scenario_name, 
    viewport_size: { width: 1200, height: 800 }
  )
end

Then('the page should look correct') do
  @eyes.check('Homepage', Applitools::Selenium::Target.window.fully)
  @eyes.close
end

Best Practices

  1. API Key Management: Always use environment variables for your API key.

    eyes.api_key = ENV['APPLITOOLS_API_KEY']
    
  2. Clean Up Resources: Always use abort_if_not_closed in your teardown phase.

    after do
     eyes.abort_if_not_closed
    end
    
  3. Descriptive Test Names: Use meaningful app and test names for better organization in the Applitools dashboard.

    eyes.open(
     app_name: 'E-commerce Website',
     test_name: 'Product Page - Desktop Chrome'
    )
    
  4. Batch Tests: Group related tests in a batch.

    batch = Applitools::BatchInfo.new('Login Flow Tests')
    eyes.batch = batch
    
  5. Viewport Size: Set a consistent viewport size for reliable testing.

    eyes.open(
     # other parameters...
     viewport_size: { width: 1200, height: 800 }
    )
    
  6. Error Handling: Implement proper error handling to ensure tests fail gracefully.

    begin
     eyes.check('Page', Applitools::Selenium::Target.window)
     results = eyes.close
     expect(results.passed?).to be true
    rescue => e
     puts "Eyes error: #{e.message}"
     raise e
    ensure
     eyes.abort_if_not_closed
    end
    

Common Pitfalls

  1. Driver Mismatches: Ensure you're using the right driver for your testing needs.

    # Correct way to register driver with specific options
    Applitools.register_capybara_driver browser: :chrome, options: { args: ['--headless'] }
    
  2. Session Confusion: Be careful when switching between Eyes and native browsers.

    # Incorrect - may cause issues if not properly tracked
    page.use_native_browser
    # ... code ...
    # Forgot to switch back to Eyes browser before checking
    

# Correct page.use_native_browser # ... code ... page.driver_for_eyes(eyes)


3. **Missing Screenshots**: Ensure the page is fully loaded before visual checks.
   ```ruby
   # Add explicit waits when needed
   expect(page).to have_selector('.loading-indicator', visible: false)
   eyes.check('After Loading', Applitools::Selenium::Target.window)
  1. Overlooking Browser Options: Don't forget to configure browser options appropriately.

    Applitools.register_capybara_driver(
     browser: :chrome,
     options: {
       args: ['--disable-gpu', '--no-sandbox', '--disable-dev-shm-usage']
     }
    )
    
  2. Ignoring Cleanup: Failing to properly clean up resources.

    # Always include in ensure block
    ensure
     eyes.abort_if_not_closed
    

FAQ

How does Eyes Capybara differ from Eyes Selenium?

Eyes Capybara builds on top of Eyes Selenium, providing specific integration with Capybara's driver architecture. If you're using Capybara for your tests, Eyes Capybara provides a more seamless integration with better support for Capybara-specific patterns and conveniences.

Can I use Eyes Capybara with any Capybara driver?

Eyes Capybara is designed to work with Selenium-based Capybara drivers. It requires a JavaScript-capable driver and will not work with drivers like :rack_test or headless drivers like :poltergeist that don't use Selenium WebDriver.

How do I handle dynamic content?

You can use various strategies:

# Ignore specific regions by selector (recommended)
eyes.check(
  'Dynamic Content',
  Applitools::Selenium::Target.window.ignore(:css, '.timestamp-area')
)

# Alternatively, using WebDriver element
eyes.check(
  'Dynamic Content',
  Applitools::Selenium::Target.window.ignore(
    page.find('.timestamp-area')
  )
)

# Use a more flexible match level
eyes.match_level = Applitools::MatchLevel::LAYOUT

Can I use Eyes Capybara with headless browsers?

Yes, configure your driver with headless options:

Applitools.register_capybara_driver(
  browser: :chrome,
  options: { args: ['--headless'] }
)

How do I debug failed visual tests?

  1. Check the Applitools dashboard for visual differences
  2. Use eyes.save_debug_screenshots = true to save diagnostic screenshots
  3. Enable verbose logging with: ruby Applitools::EyesLogger.log_handler = Logger.new(STDOUT) Applitools::EyesLogger.log_handler.level = Logger::DEBUG

How do I test responsive designs?

Use viewport configuration and multiple tests:

['small', 'medium', 'large'].each do |size|
  viewport = case size
             when 'small' then { width: 375, height: 667 }
             when 'medium' then { width: 768, height: 1024 }
             when 'large' then { width: 1440, height: 900 }
             end

  eyes.open(
    app_name: 'Responsive Website',
    test_name: "Homepage - #{size}",
    viewport_size: viewport
  )

  eyes.check("Homepage - #{size}", Applitools::Selenium::Target.window.fully)
  eyes.close
end

How can I capture a specific region instead of the entire window?

Use the Target API to specify regions by selector (recommended):

# Capture a specific region by CSS selector
eyes.check('Hero Section', Applitools::Selenium::Target.region(:css, '.hero-section'))

# Or by ID
eyes.check('Menu', Applitools::Selenium::Target.region(:id, 'main-navigation'))

# Alternatively, using WebDriver element
element = page.find('.hero-section')
eyes.check('Hero Section', Applitools::Selenium::Target.region(element))

License

This SDK is distributed under the Applitools SDK License Agreement. See the LICENSE file for more details.

Important: This SDK may be used solely for your personal, non-commercial purposes. For commercial use, please contact your Applitools representative or visit applitools.com to obtain a commercial license.