### Navigating

    visit articles_path

### Clicking links and buttons

    click_on 'Link Text'
    click_button
    click_link

### Interacting with forms

    attach_file 'Image', '/path/to/image.jpg'
    fill_in 'First Name', with: 'John'

    check 'A checkbox'
    uncheck 'A checkbox'

    choose 'A radio button'

    select 'Option', from: 'Select box'
    unselect

### Limiting

    within '.classname' do
      click '...'
    end

    within_fieldset :id do
      ...
    end

## Querying

### Predicates

    page.has_css?('.button')
    expect(page).to have_css('.button')
    page.should have_css('.button')

Positive | Negative
--- | ---
`has_content?` | `has_no_content?`
`has_css?` (selector) | `has_no_css?`
`has_xpath?` (path) | `has_no_xpath?`
`has_link?` (selector) | `has_no_link?`
`has_button?` (selector) | `has_no_button?`
`has_field?` (selector) | `has_no_field?`
`has_checked_field?` (selector) | `has_unchecked_field?`
`has_table?` (selector) | `has_no_table?`
`has_select?` (selector) | `has_no_select?`

In Rspec, these also map to matchers like `page.should have_content`.

### Selectors

    expect(page).to have_button('Save')

    expect(page).to have_button('#submit')

    expect(page).to have_button('//[@id="submit"]')

The `selector` arguments can be text, CSS selector, or XPath expression.

### RSpec assertions

    page.has_button?('Save')

    expect(page).to have_no_button('Save')

In RSpec, you can use `page.should` assertions.

### About negatives

    expect(page).to have_no_button('Save')   # OK

    expect(page).not_to have_button('Save')  # Bad

Use `should have_no_*` versions with RSpec matchers because `should_not have_*` doesn’t wait for a timeout from the driver.

## RSpec

### Matchers

    expect(page).to \

      have_selector '.blank-state'
      have_selector 'h1#hola', text: 'Welcome'
      have_button 'Save'
      have_checked_field '#field'
      have_unchecked_field
      have_css '.class'
      have_field '#field'
      have_table '#table'
      have_xpath '//div'

      have_link 'Logout', href: logout_path

      have_select 'Language',
        selected: 'German'
        options: ['Engish', 'German']
        with_options: ['Engish', 'German'] # partial match

      have_text 'Hello',
        type: :visible # or :all
        # alias: have_content

### Common options

All matchers have these options:

      text: 'welcome'
      text: /Hello/
      visible: true
      count: 4
      between: 2..5
      minimum: 2
      maximum: 5
      wait: 10

## Other features

### Finding

    find(selector)
    find_button(selector)
    find_by_id(id)
    find_field(selector)
    find_link(selector)
    locate

### Scoping

    within '#delivery' do
      fill_in 'Street', with: 'Hello'
    end

    within :xpath, '//article'
    within_fieldset
    within_table
    within_frame
    scope_to

    find('#x').fill_in('Street', with: 'Hello')
    # same as within

### Scripting

    execute_script('$("input").trigger("change")')
    evaluate_script('window.ga')

Executes JavaScript.

### Debugging

    save_and_open_page

Opens the webpage in your browser.

### Page

    page
      .all('h3')
      .body
      .html
      .source
      .current_host
      .current_path
      .current_url

### AJAX

    using_wait_time 10 do
      ...
    end

### Misc

    drag
    field_labeled

### Page object

    page.status_code == 200
    page.response_headers

See: http://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Session

### Poltergeist

    Capybara.register_driver :poltergeist do |app|
      Capybara::Poltergeist::Driver.new(app, :inspector => true)
    end
    Capybara.javascript_driver = :poltergeist

Use poltergeist to integrate PhantomJS.

### Blacklist

    config.before :each, :js do
      page.driver.browser.url_blacklist = [
        'fonts.googleapis.com',
        'use.typekit.net',
        'f.vimeocdn.com',
        'player.vimeo.com',
        'www.googletagmanager.com'
      ].flat_map { |domain| [ "http://#{domain}", "https://#{domain}" ] }
    end

### Debugging

Enable `inspector: true` and then:

    page.driver.debug

To pause execution for a while:

    page.driver.pause

## Selenium

### Accepting confirm() and alert()

    accept_alert { ... }
    dismiss_confirm { ... }
    accept_prompt(with: 'hi') { ... }

Alternatively:

    page.driver.browser.switch_to.alert.accept

### Updating session

    page.set_rack_session(foo: 'bar')

## See also

- http://rubydoc.info/github/jnicklas/capybara/Capybara/RSpecMatchers
- http://www.rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers

0 Comments for this cheatsheet. Write yours!