Slide 1

Slide 1 text

Embracing Capybara

Slide 2

Slide 2 text

Who Has Used Capybara?

Slide 3

Slide 3 text

Who Has Been Bitten By Capybara?

Slide 4

Slide 4 text

TimMoore tmoore

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

What’s a Capybara? World’s Largest Rodent! “Makes it easy to simulate how a user interacts with your application” http://git.io/capybara

Slide 10

Slide 10 text

Capybara Anatomy Browsing
 DSL Matchers/
 Selectors Browser Engines

Slide 11

Slide 11 text

visit '/sessions/new' within("#session") do fill_in 'Login',
 with: '[email protected]' fill_in 'Password',
 with: 'password' end click_link 'Sign in' expect(page).to have_content 'Success'

Slide 12

Slide 12 text

Understanding Capybara

Slide 13

Slide 13 text

Capybara is Patient visit '/sessions/new' within("#session") do
 fill_in 'Login',
 with: '[email protected]' fill_in 'Password',
 with: 'password'
 end click_link 'Sign in' expect(page).
 to have_content 'Success' Waits for page to load

Slide 14

Slide 14 text

Capybara is Patient visit '/sessions/new' within("#session") do
 fill_in 'Login',
 with: '[email protected]' fill_in 'Password',
 with: 'password'
 end click_link 'Sign in' Capybara.using_wait_time(60) do
 expect(page).
 to have_content 'Success'
 end Waits for page to load

Slide 15

Slide 15 text

Capybara is Patient visit '/sessions/new' within("#session") do
 fill_in 'Login',
 with: '[email protected]' fill_in 'Password',
 with: 'password'
 end click_link 'Sign in' expect(page).
 to have_content 'Success',
 wait: 60 Waits for page to load

Slide 16

Slide 16 text

Methods that Wait • find(selector), find_field, find_link, etc. • within(selector) (scoping) • has_selector?/has_no_selector? & assertions • form & link actions • click_link/button • fill_in • check/uncheck, select, choose, etc.

Slide 17

Slide 17 text

Methods that Don’t • visit(path) • current_path • all(selector) • first(selector) (counter-intuitively) • execute_script/evaluate_script • simple accessors: text, value, title, etc.

Slide 18

Slide 18 text

Don’t Do This click_link('Search') expect(all('.search-result').count).
 to eq 2 Returns 0 Does not wait

Slide 19

Slide 19 text

Good click_link('Search') expect(page).
 to have_css '.search-result',
 count: 2

Slide 20

Slide 20 text

Don’t Do This click_button('Save') expect(find('.dirty-warning').text).
 not_to contain('Unsaved changes') Does not wait

Slide 21

Slide 21 text

Good click_button('Save') expect(find('.dirty-warning')).
 to have_no_text('Unsaved changes')

Slide 22

Slide 22 text

Also Good click_button('Save') expect(find('.dirty-warning')).
 not_to have_text('Unsaved changes')

Slide 23

Slide 23 text

Training Capybara

Slide 24

Slide 24 text

Don’t Do This Scenario: Searching for cats Given I am on "/search" When I fill in "input.search_text" with "cats" And I press "Search" Then I should see "grumpy cat" within "div.search-results"

Slide 25

Slide 25 text

Don’t Do This Scenario: Searching for cats Given I am on "/search" When I fill in "input.search_text" with "cats" And I press "Search" Then I should see "grumpy cat" within "div.search-results" “A step description should never contain regexen, CSS or XPath selectors” “web_steps.rb is a terrible, terrible idea” - Boring scenarios - Brittle scenarios - Where is my workflow?

Slide 26

Slide 26 text

Better Scenario: Searching for cats Given I am on the search page When I fill in "Search" with "cats" And I press "Search" Then I should see "grumpy cat" within the search results

Slide 27

Slide 27 text

Best Scenario: Searching for cats When I search for "cats" Then I should see "grumpy cat" within the search results

Slide 28

Slide 28 text

Don’t Do This When /^I search for "([^"]*)"$/
 do |search_text| visit "/search" fill_in "input.search_text",
 with: search_text click_button "Search" end

Slide 29

Slide 29 text

Better When /^I search for "([^"]*)"$/
 do |search_text| search_page =
 my_app.search_page search_page.search_input.
 fill_in search_text search_page.search_button.click end

Slide 30

Slide 30 text

Better class MyAppTester def initialize @session = Capybara::Session.new(:selenium) end ! def search_page MyAppTester::SearchPage.new(@session) end end

Slide 31

Slide 31 text

Better class MyAppTester::SearchPage def initialize(session)
 session.visit "/search"
 @session = session
 end def search_input
 @session.find "input.search_text"
 end def search_button
 @session.find "button.search"
 end end

Slide 32

Slide 32 text

Better When /^I search for "([^"]*)"$/
 do |search_text| search_page =
 my_app.search_page search_page.search_input.
 fill_in search_text search_page.search_button.click end

Slide 33

Slide 33 text

Best When /^I search for "([^"]*)"$/
 do |search_text| my_app.search_for search_text end

Slide 34

Slide 34 text

Don’t Do This find(:css, "div.main div.sidebar div.search div.advanced div.actions button.submit").click Failure/Error: find(:css, "div.main div.sidebar div.search div.advanced div.actions button.submit").click Capybara::ElementNotFound: Unable to find css "div.main div.sidebar div.search div.advanced div.actions button.submit"

Slide 35

Slide 35 text

Disciplining Capybara

Slide 36

Slide 36 text

Setting Breakpoints When /^I debug$/ do debugger end

Slide 37

Slide 37 text

Taking Screenshots After do |scenario| filename =
 scenario.name.gsub(/\W/, '_') page.save_screenshot(
 "target/reports/#{filename}.png") end ! http://git.io/capybarascreenshot

Slide 38

Slide 38 text

Firefox •focusmanager.testmode = true • Update selenium-webdriver gem • Disable auto-update in CI • Beware platform differences • http://git.io/capybarafirebug

Slide 39

Slide 39 text

Getting Help • http://groups.google.com/group/ ruby-capybara • Freenode (IRC): #capybara • Stack Overflow

Slide 40

Slide 40 text

Summary • Understand Capybara synchronisation • Be explicit with Capybara • Use Page Objects for readable, flexible tests • Keep selectors simple • If you get bitten, seek help!

Slide 41

Slide 41 text

Fix Flaky Tests

Slide 42

Slide 42 text

Thanks! Any Questions?