Created
March 9, 2019 11:26
-
-
Save peterkappus/33f8d0e93677b4761ca4488ebc47f6e8 to your computer and use it in GitHub Desktop.
Some basic BDD step definitions in Capybara (Ruby)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#This file contains some useful steps for interacting with specific page elements, moving forwards and backwards in time, etc. They're pretty low-level so you might use them to get started but eventually you'll want to write your own application-specific steps. | |
#things to do before each scenario | |
Before do |scenario| | |
end | |
#and after.... | |
After do |scenario| | |
end | |
#travel back to the correct time after runniung a @time_travel tagged step | |
After('@time_travel') do | |
travel_back | |
end | |
#time-travel to the given date | |
Given(/^the current date is (.+)$/) do |time_string| | |
travel_to(Time.parse(time_string)) | |
end | |
#see some text within a css selector | |
Then(/^I should see "([^"]*)" within "([^"]*)" (\d+) time(?:s)?$/) do |text, selector, count| #debug | |
all(selector,text: /\A#{text}\z/).count.to_i.should equal? count.to_i | |
end | |
Then(/^I should see "([^"]*)" before "([^"]*)"$/) do |first_thing, second_thing| | |
#make sure we see the first thing before the second thing... | |
body.index(first_thing).should be < body.index(second_thing) | |
end | |
#fill in a field | |
When(/^I fill in "([^"]*)" with "([^"]*)"$/) do |field_name, content| | |
fill_in field_name, :with=>content | |
end | |
#file attach | |
When(/^I attach "([^"]*)" to the field called "([^"]*)"$/) do |file_path, field_name| | |
attach_file(field_name,"#{ENV['RAILS_ROOT']}/#{file_path}") | |
end | |
#NOTE: this is custom to work with bootstrap-select-rails select boxes | |
#This only works because the drop-down in question is the first one. | |
#hence we can click "Please select" to open the dropdown. | |
#TODO: make this work for multiple dropdowns | |
When(/^I select "([^"]*)" from the first dropdown$/) do |option_text| | |
click_on "Please select" | |
find(:css,"div.dropdown-menu span",:text=>option_text).click | |
end | |
def get_all_link_text | |
linktxt = "" | |
page.all("a").each {|node| linktxt += node.text } | |
return linktxt | |
end | |
def find_first_link(text) | |
all('a',:text=>text,visible:true).to_a.first | |
end | |
def find_first_link_in(selector,text) | |
return all(selector,text:text).to_a.first | |
end | |
def click_random_link_in(selector,text) | |
all(selector,:text=>text).to_a.shuffle.first | |
end | |
#NOTE: this is only taking the last link right now... | |
#need a smart way to specify that it should randomise or select one in particular | |
def handle_modal_window | |
#if we have a modal window, randomly select a subject from within | |
if(all(".modal-cover .modal").count > 0) | |
node = page.all(".modal-cover .modal li a", :visible=>true).to_a.last | |
#node = all(".modal-cover .modal a",:text=>/Select/i).to_a.last | |
Kernel.puts "Select last link from modal window: #{node.text}" | |
node.click | |
end | |
end | |
def check_node_for_link(link) | |
puts "Link: #{link.text} href: #{link[:href]}" | |
link[:href].should(be_true) | |
end | |
#STEPS DOWN HERE.... | |
#give us a step definition for "debug" | |
Then(/(?:I )?debug/) do | |
debug | |
end | |
#throw a 'debug' command in your step defs to open an PRY session and poke around interactively | |
def debug | |
binding.pry #unless ENV['DEBUG'].to_s.empty? | |
end | |
#use a non-capturing group on the 's' so we can say "1 second" or "2 seconds" | |
Then(/^I wait (\d+) second(?:s)?/) do |seconds| | |
sleep seconds.to_i # express the regexp above with the code you wish you had | |
end | |
Then(/^I do a screen shot/) do | |
screenshot_and_save_page | |
end | |
#click on button or link | |
When(/^I click (?:on )?"([^"]+?)"$/) do |text| | |
click_on text | |
end | |
#click on button or link | |
When(/^I click (?:on )?the label called "([^"]+?)"$/) do |text| | |
first("label",text: text).click | |
end | |
#click a checkbox | |
When(/^I tick the box "([^"]+?)"$/) do |box_id| | |
check box_id | |
end | |
When(/^I choose the radio button "([^"]+?)"$/) do |button_id| | |
choose button_id | |
end | |
#click on button or link within a selector | |
When(/^I click on link "([^"]+?)" number (\d+) within "([^"]+?)"$/) do |text, number, css_selector| | |
links = all(css_selector,:text=>text).to_a | |
int = 1; | |
# puts "number argument: #{ number }" | |
# puts "int variable: #{ int }" | |
#Check to see if there are any links | |
if links.any? | |
links.each do |node| | |
if int == number.to_i | |
# puts "They are equal: #{ int } - #{ number }" | |
node.click | |
break | |
else | |
# puts "They are not equal: #{ int } - #{ number }" | |
int = int.next | |
end | |
if int > links.length | |
raise ArgumentError, "The selected index is not present in this list" | |
end | |
end | |
else | |
raise ArgumentError, "No elements in this list" | |
end | |
end | |
#click on button or link within a selector | |
When(/^I click (?:on )?"([^"]*?)" within "([^"]+?)"$/) do |text, selector| | |
#find(css_selector).click_on(link_to_click) | |
#within(:css, css_selector) | |
#find_first_link_in(css_selector, link_to_click).click | |
#def find_first(text,selector) | |
#node = first(selector) | |
node = all("#{selector} a",text:text).first #unless node.present? | |
node = all("#{selector} input",text:text).first unless node.present? | |
node = all(selector,text:text).first unless node.present? | |
node.click | |
end | |
#click on nth button or link within a selector | |
When(/^I click on first "([^"]+?)"(?: link,) within "([^"]+?)"$/) do |link_to_click, css_selector| | |
#find_first_link_in(css_selector, link_to_click).trigger('click') | |
find_first_link_in(css_selector, text:link_to_click).click | |
end | |
#click on text within a selector | |
When(/^I click on text "([^"]+?)" within "([^"]+?)"$/) do |text_to_click, css_selector| | |
find(css_selector, ":text => 'text_to_click'").trigger('click') | |
end | |
When(/^I click on (?:the )?"([^"]*)" button$/) do |button_text| | |
#click the first one... | |
first(:button,button_text,{visible:true}).click | |
end | |
Then(/^I click on random "(.*?)" link$/) do |selector| | |
all(selector).to_a.reject{|node| node.text.empty?}.shuffle.first.click | |
end | |
Given(/^I (?:visit|am on) the (?:homepage|home page)$/) do | |
visit "/" | |
end | |
When(/^I visit "([^"]*)"$/) do |path| | |
visit path | |
end | |
#Blank to provide headers to the tests | |
Then(/^: (.*?)$/) do | no_need_to_process | | |
end | |
Then(/^I should see "([^"]+?)"$/) do |text_to_see| | |
page.should have_content(text_to_see) | |
end | |
Then(/^I should see content within "([^"]+?)"$/) do | selector | | |
page.should have_css(selector) | |
node = all(selector).to_a.first | |
node.text.should_not == "" | |
end | |
Then(/^I should see (\d+) "([^"]+?)" elements, within "([^"]+?)"$/) do |number_of_elements, css_element, css_container| | |
all(css_container + " " + css_element, "").to_a.size.should == number_of_elements.to_i | |
end | |
Then(/^I should see more than (\d+) "([^"]+?)" elements, within "([^"]+?)"$/) do |number_of_elements, css_element, css_container| | |
all(css_container + " " + css_element, "").to_a.size.should > number_of_elements.to_i | |
end | |
Then(/^I should see (\d+) or more "([^"]+?)" elements, within "([^"]+?)"$/) do |number_of_elements, css_element, css_container| | |
all(css_container + " " + css_element, "").to_a.size.should >= number_of_elements.to_i | |
end | |
Then(/^I should see the selector "(.+?)"$/) do |css_selector| | |
page.should have_css(css_selector) | |
end | |
Then(/^I should see the css selector "(.+?)" for "([^"]+?)"$/) do |css_selector, dummy_text| | |
page.should have_css(css_selector) | |
end | |
Then(/^I should see "([^"]+?)" within "([^"]+?)"$/) do |text_to_see, css_selector| | |
page.should have_selector(css_selector, :text=>text_to_see) | |
end | |
Then(/^I should see "([^"]+?)" within "([^"]+?)" tag$/) do |text_to_see, html_tag| | |
pending # express the regexp above with the code you wish you had | |
end | |
Then(/^I should see "([^"]+?)" within "([^"]+?)" only "([^"]+?)" time/) do |text_to_see, css_selector, number_of_times| | |
page.all(css_selector, :text=>text_to_see).to_a.size.should equal(number_of_times.to_i) | |
end | |
Then(/^I should NOT see "([^"]+?)" within "(.+?)"$/) do |text_to_see, css_selector| | |
should_not have_selector(css_selector,:text=>text_to_see) | |
end | |
#generic NOT see with no selector context...maybe not very useful | |
Then(/^I should NOT see "([^"]+?)"$/) do |text| | |
should_not have_content(text) | |
end | |
Then(/^I should see in order "([^"]+?)" within "([^"]+?)"$/) do |text_to_see, css_selector| | |
found_text = page.all(css_selector + " a").to_a.map{|node| node.text}.join(',') | |
found_text.should match(text_to_see) | |
end | |
Then(/^I should see results in "([^"]+?)", displayed in alphabetical order$/) do |css_selector| | |
if all(css_selector).to_a.size <= 0 | |
raise ArgumentError, "No elements in this list", caller | |
end | |
previous = "" | |
all(css_selector).to_a.each do |node| | |
puts node.text.downcase | |
if(previous != "") | |
then | |
diff = node.text.downcase <=> previous.text.downcase | |
diff == 1 | |
end | |
previous = node | |
end | |
end | |
#throw a 'debug' command in your step defs to open an PRY session and poke around interactively | |
def debug | |
binding.pry #unless ENV['DEBUG'].to_s.empty? | |
end | |
Then(/^I should see a date in the correct format within "([^"]+?)"$/) do |css_selector| | |
#find all matches for css, look at the text of each found node, and test against our date format regex | |
all(css_selector).each {|node| node.text.should match(/^\d{1,2} January|February|March|April|May|June|July|August|September|October|November|December \d{4}$/) } | |
end | |
Then(/^I should see "(.*?)" on the right hand side$/) do |text_to_see| | |
page.should have_selector(".righthand-nav", :text=>text_to_see) | |
end | |
Given(/^the current timeout is (\d+) seconds$/) do |number_of_seconds| | |
Capybara.default_wait_time = number_of_seconds.to_i | |
end | |
When(/^I hover mouse over "([^"]+?)"$/) do | css_selector| | |
find(css_selector).hover | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment