high abstraction dsl for tests (from end user perspective) [kameleon - mean chameleon, from polish]
Kameleon is a high abstraction dsl for better writing acceptance and integration tests using Capybara.
And “better” means: more easily to mimic how user interact with browser.
for 1.x capybara please use kameleon in version below 1.0
gem 'kameleon', '< 1.0'
for 2.x capybara please use kameleon in version higher or equeal 1.0
gem 'kameleon', '>= 1.0.0'
Kameleon requires:
Optionally is nice to use:
Gemfile
gem 'kameleon', '>= 0.2.0'
Before you start using Kameleon ensure that capybara is properly loaded (in your test helper file)
require 'kameleon/ext/rspec/all'
or just components you want; kemeleon/ext/rspec/all
by default loads:
require 'kameleon/ext/rspec/dsl'
require 'kameleon/ext/rspec/garbage_collector'
require 'kameleon/ext/rspec/headless'
checkout this slides from wrocloverb 2012
kameleon
click "Products"
within('table.index') do
see :ordered => [ "apache baseball cap",
"zomg shirt" ]
end
click "admin_products_listing_name_title"
within('table.index') do
see :ordered => [ "zomg shirt",
"apache baseball cap"]
end
vs capybara
click_link "Products"
within('table.index tr:nth-child(2)') { page.should have_content("apache baseball cap") }
within('table.index tr:nth-child(3)') { page.should have_content("zomg shirt") }
click_link "admin_products_listing_name_title"
within('table.index tr:nth-child(2)') { page.should have_content("zomg shirt") }
within('table.index tr:nth-child(3)') { page.should have_content("apache baseball cap") }
taken from: https://github.com/spree/spree/blob/master/core/spec/requests/admin/products/products_spec.rb#L22
kameleon
click "Products",
"admin_new_product"
fill_in "Baseball Cap" => "product_name",
"B100" => "product_sku",
"100" => "product_price",
"2012/01/24" => "product_available_on",
:select => { "Size" => "Prototype" },
:check => "Large"
click "Create"
see "successfully created!"
vs capybara
click_link "Products"
click_link "admin_new_product"
fill_in "product_name", :with => "Baseball Cap"
fill_in "product_sku", :with => "B100"
fill_in "product_price", :with => "100"
fill_in "product_available_on", :with => "2012/01/24"
select "Size", :from => "Prototype"
check "Large"
click_button "Create"
page.should have_content("successfully created!")
taken from: https://github.com/spree/spree/blob/master/core/spec/requests/admin/products/products_spec.rb#L77
kameleon
within(:row => 2).click "Edit"
fill_in 99 => "adjustment_amount",
"rebate 99" => "adjustment_label"
click "Continue"
see "successfully updated!",
"rebate 99",
"$99.00"
vs capybara
within(:css, 'table.index tr:nth-child(2)') { click_link "Edit" }
fill_in "adjustment_amount", :with => "99"
fill_in "adjustment_label", :with => "rebate 99"
click_button "Continue"
page.should have_content("successfully updated!")
page.should have_content("rebate 99")
page.should have_content("$99.00")
taken from: https://github.com/spree/spree/blob/master/core/spec/requests/admin/orders/adjustments_spec.rb#L48
kameleon
click "Orders"
within('table#listing_orders', :row => 1).click_link "R100"
click "Payments"
within('#payment_status').see "Payment: balance due"
within(:cell => [2, 2]).see "$39.98"
within(:cell => [2, 3]).see "Credit Card"
within(:cell => [2, 4]).see "pending"
vs capybara
visit spree.admin_path
click_link "Orders"
within('table#listing_orders tbody tr:nth-child(1)') { click_link "R100" }
click_link "Payments"
within('#payment_status') { page.should have_content("Payment: balance due") }
find('table.index tbody tr:nth-child(2) td:nth-child(2)').text.should == "$39.98"
find('table.index tbody tr:nth-child(2) td:nth-child(3)').text.should == "Credit Card"
find('table.index tbody tr:nth-child(2) td:nth-child(4)').text.should == "pending"
kameleon
click "Void"
within('#payment_status').see "Payment: balance due"
see "Payment Updated"
within(:cell => [2,2]).see "$39.98"
within(:cell => [2,3]).see "Credit Card"
within(:cell => [2,4]).see "void"
vs capybara
click_button "Void"
within('#payment_status') { page.should have_content("Payment: balance due") }
page.should have_content("Payment Updated")
find('table.index tbody tr:nth-child(2) td:nth-child(2)').text.should == "$39.98"
find('table.index tbody tr:nth-child(2) td:nth-child(3)').text.should == "Credit Card"
find('table.index tbody tr:nth-child(2) td:nth-child(4)').text.should == "void"
kameleon
click "New Payment"
see "New Payment"
click "Continue",
"Capture"
within('#payment_status').see "Payment: paid"
see :element => '#new_payment_section'
click "Shipments",
"New Shipment"
within('table.index', :row => 2).check "#inventory_unit"
click "Create"
see "successfully created!"
vs capybara
click_on "New Payment"
page.should have_content("New Payment")
click_button "Continue"
click_button "Capture"
within('#payment_status') { page.should have_content("Payment: paid") }
page.should_not have_css('#new_payment_section')
click_link "Shipments"
click_on "New Shipment"
within('table.index tbody tr:nth-child(2)') { check "#inventory_unit" }
click_button "Create"
page.should have_content("successfully created!")
taken from: https://github.com/spree/spree/blob/master/core/spec/requests/admin/orders/payments_spec.rb#L32
page.should have_css("li.banner_message", :count => 10)
. Of course, after you’ve submitted feature request to the owner of the original repository 😉Kameleon::Session.defined_areas.merge!({ :menu => [:xpath, "//nav/ul"],
:main => '.main_body',
:right_column => '.col_aside',
:ordered_list => '.ordered_list',
:favourites => '.favourites_list',
:gallery_tiny => '.gallery_tiny',
:gallery_list => '.gallery_list',
:content => '.col_content',
:col_aside => '.col_aside' })
within
can also work with Capybara::Node::Element objects. It is usefull when you want to fetch the node by your ownnode = page.all('div.item')[2]
within(node).see('Something cool!')