jam-cloud/web/spec/support/utilities.rb

588 lines
18 KiB
Ruby
Raw Normal View History

include ApplicationHelper
# add a hover_intent method to element, so that you can do find(selector).hover_intent
module Capybara
module Node
class Element
2014-04-11 14:45:54 +00:00
def attempt_hover
begin
hover
rescue => e
end
end
def hover_intent
hover
2014-04-11 14:45:54 +00:00
sleep 0.3
attempt_hover
sleep 0.3
attempt_hover
end
end
end
end
2013-12-21 15:12:25 +00:00
# holds a single test's session name's, mapped to pooled session names
$capybara_session_mapper = {}
# called in before (or after) test, to make sure each test run has it's own map of session names
def reset_session_mapper
$capybara_session_mapper.clear
Capybara.session_name = :default
2013-01-31 05:43:26 +00:00
end
2013-12-21 15:12:25 +00:00
# manages the mapped session name
def mapped_session_name(session_name)
return :default if session_name == :default # special treatment for the built-in session
$capybara_session_mapper[session_name] ||= 'session_' + $capybara_session_mapper.length.to_s
2013-12-21 15:12:25 +00:00
end
# in place of ever using Capybara.session_name directly,
# this utility is used to handle the mapping of session names in a way across all tests runs
def in_client(name)
session_name = name.class == JamRuby::User ? name.id : name
2013-12-21 15:12:25 +00:00
Capybara.session_name = mapped_session_name(session_name)
yield
end
2013-12-21 15:12:25 +00:00
def cookie_jar
Capybara.current_session.driver.browser.current_session.instance_variable_get(:@rack_mock_session).cookie_jar
end
2014-01-07 22:32:16 +00:00
#see also ruby/spec/support/utilities.rb
JAMKAZAM_TESTING_BUCKET = 'jamkazam-testing' #at least, this is the name given in jam-ruby
def wipe_s3_test_bucket
2014-01-07 22:32:16 +00:00
s3 = AWS::S3.new(:access_key_id => Rails.application.config.aws_access_key_id,
:secret_access_key => Rails.application.config.aws_secret_access_key)
test_bucket = s3.buckets[JAMKAZAM_TESTING_BUCKET]
if test_bucket.name == JAMKAZAM_TESTING_BUCKET
test_bucket.objects.each do |obj|
obj.delete
end
end
end
2013-12-21 15:12:25 +00:00
def sign_in(user)
visit signin_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
2013-01-29 02:24:25 +00:00
click_button "SIGN IN"
# Sign in when not using Capybara as well.
2013-01-31 05:43:26 +00:00
cookie_jar[:remember_token] = user.remember_token
end
def set_cookie(k, v)
case Capybara.current_session.driver
when Capybara::Poltergeist::Driver
page.driver.set_cookie(k,v)
when Capybara::RackTest::Driver
headers = {}
Rack::Utils.set_cookie_header!(headers,k,v)
cookie_string = headers['Set-Cookie']
Capybara.current_session.driver.browser.set_cookie(cookie_string)
when Capybara::Selenium::Driver
page.driver.browser.manage.add_cookie(:name=>k, :value=>v)
else
raise "no cookie-setter implemented for driver #{Capybara.current_session.driver.class.name}"
end
end
2014-04-09 17:25:52 +00:00
def sign_in_poltergeist(user, options = {})
validate = options[:validate]
validate = true if validate.nil?
visit signin_path
fill_in "Email Address:", with: user.email
fill_in "Password:", with: user.password
click_button "SIGN IN"
wait_until_curtain_gone
2014-04-09 17:25:52 +00:00
# presence of this means websocket gateway is not working
page.should have_no_selector('.no-websocket-connection') if validate
end
2013-10-21 22:13:53 +00:00
# skip the typical login form, which redirects to /client (sloooow). Just sets the cookie, and puts you where you want to be
def fast_signin(user, url)
page.driver.set_cookie(:remember_token, user.remember_token)
visit url
end
#skip the 'hunt' for Sign Out, and redirect after. Just empty cookie, and go to '/'
def fast_signout
page.driver.set_cookie(:remember_token, '')
visit '/'
end
def sign_out()
if Capybara.javascript_driver == :poltergeist
page.driver.remove_cookie(:remember_token)
else
page.driver.browser.manage.remove_cookie :name => :remember_token
end
end
def sign_out_poltergeist(options = {})
open_user_dropdown
click_link 'Sign Out'
2014-03-25 15:29:08 +00:00
should_be_at_root if options[:validate]
end
def open_user_dropdown
find('.userinfo').hover()
end
2014-03-25 15:29:08 +00:00
def should_be_at_root
find('h1', text: 'Play music together over the Internet as if in the same room')
end
2013-10-21 22:13:53 +00:00
def leave_music_session_sleep_delay
# add a buffer to ensure WSG has enough time to expire
sleep_dur = (Rails.application.config.websocket_gateway_connect_time_stale_browser +
Rails.application.config.websocket_gateway_connect_time_expire_browser) * 1.4
sleep sleep_dur
end
2013-10-21 22:13:53 +00:00
def wait_for_ajax(wait=Capybara.default_wait_time)
wait = wait * 10 #(because we sleep .1)
counter = 0
while page.execute_script("$.active").to_i > 0
counter += 1
sleep(0.1)
raise "AJAX request took longer than #{wait} seconds." if counter >= wait
end
end
# waits until the user object has been requested, which comes after the 'curtain' is lifted
# and after a call to /api/user/:id for the current user is called initially
def wait_until_user(wait=Capybara.default_wait_time)
wait = wait * 10 #(because we sleep .1)
counter = 0
# while page.execute_script("$('.curtain').is(:visible)") == "true"
# counter += 1
# sleep(0.1)
# raise "Waiting for user to populate took longer than #{wait} seconds." if counter >= wait
# end
2013-10-21 22:13:53 +00:00
end
def wait_until_curtain_gone
page.should have_no_selector('.curtain')
end
def wait_to_see_my_track
within('div.session-mytracks') {first('div.session-track.track')}
end
2014-05-07 03:35:00 +00:00
def repeat_for(duration=Capybara.default_wait_time)
finish_time = Time.now + duration.seconds
loop do
yield
sleep 1 # by default this will execute the block every 1 second
break if (Time.now > finish_time)
end
end
def determine_test_name(metadata, test_name_buffer = '')
description = metadata[:description_args]
if description.kind_of?(Array)
description = description[0]
end
if metadata.has_key? :example_group
return determine_test_name(metadata[:example_group], "#{description} #{test_name_buffer}")
else
return "#{description} #{test_name_buffer}"
end
end
def get_description
description = example.metadata[:description_args]
if description.kind_of?(Array)
description = description[0]
end
return description
end
# will select the value from a easydropdown'ed select element
def jk_select(text, select)
# the approach here is to find the hidden select element, and work way back up to the elements that need to be interacted with
find(select, :visible => false).find(:xpath, 'ancestor::div[contains(@class, "dropdown easydropdown")]').trigger(:click)
find(select, :visible => false).find(:xpath, 'ancestor::div[contains(@class, "dropdown-wrapper") and contains(@class, "easydropdown-wrapper") and contains(@class, "open")]').find('li', text: text).trigger(:click)
# works, but is 'cheating' because of visible = false
#select(genre, :from => 'genres', :visible => false)
end
# takes, or creates, a unique session description which is returned for subsequent calls to join_session to use
# in finding this session)
def create_session(options={})
creator = options[:creator] || FactoryGirl.create(:user)
2014-06-09 22:13:54 +00:00
unique_session_name = options[:name] || "create_join_session #{SecureRandom.urlsafe_base64}"
unique_session_desc = options[:description] || "create_join_session #{SecureRandom.urlsafe_base64}"
genre = options[:genre] || 'Rock'
musician_access = options[:musician_access].nil? ? true : options[:musician_access]
2014-06-09 22:13:54 +00:00
approval_required = options[:approval_required].nil? ? true : options[:approval_required]
fan_access = options[:fan_access].nil? ? true : options[:fan_access]
2014-06-09 22:13:54 +00:00
fan_chat = options[:fan_chat].nil? ? true : options[:fan_chat]
# create session in one client
in_client(creator) do
page.driver.resize(1500, 800) # makes sure all the elements are visible
emulate_client
sign_in_poltergeist creator
wait_until_curtain_gone
visit "/client#/createSession"
2014-06-09 22:13:54 +00:00
expect(page).to have_selector('h1', text: 'create session')
within('#create-session-form') do
2014-06-09 22:13:54 +00:00
# step 1
find('li[create-type="immediately"] ins').trigger(:click)
find('.btn-next').trigger(:click)
# step 2
jk_select(genre, '#create-session-form select[name="genres"]')
2014-06-09 22:13:54 +00:00
fill_in('session-name', :with => unique_session_name)
fill_in('session-description', :with => unique_session_desc)
find('.btn-next').trigger(:click)
# step 3
find('.btn-next').trigger(:click)
# step 4
musician_access_value = "Musicians may join by approval"
if !musician_access && !approval_required
musician_access_value = "Only RSVP musicians may join"
elsif musician_access && approval_required
musician_access_value = "Musicians may join at will"
end
jk_select(musician_access_value, '#session-musician-access')
fan_access_value = "Fans may listen, chat with each other"
if !fan_access && !fan_chat
fan_access_value = 'Fans may not listen to session'
elsif fan_access && fan_chat
fan_access_value = 'Fans may listen, chat with the band'
end
jk_select(fan_access_value, '#session-fans-access')
find('#divSessionPolicy ins').trigger(:click)
find('.btn-next').trigger(:click)
2014-06-09 22:13:54 +00:00
# step 5
find('.btn-next').trigger(:click)
end
# verify that the in-session page is showing
expect(page).to have_selector('h2', text: 'my tracks')
find('#session-screen .session-mytracks .session-track')
end
return creator, unique_session_desc, genre
end
2014-06-20 16:52:36 +00:00
def schedule_session(options = {})
creator = options[:creator] || FactoryGirl.create(:user)
unique_session_name = options[:name] || "schedule_session #{SecureRandom.urlsafe_base64}"
unique_session_desc = options[:description] || "schedule_session #{SecureRandom.urlsafe_base64}"
genre = options[:genre] || 'Rock'
musician_access = options[:musician_access].nil? ? true : options[:musician_access]
approval_required = options[:approval_required].nil? ? true : options[:approval_required]
fan_access = options[:fan_access].nil? ? true : options[:fan_access]
fan_chat = options[:fan_chat].nil? ? true : options[:fan_chat]
musician_access_value = 'Musicians may join by approval'
fan_permission_value = 'Fans may listen, chat with each other'
if musician_access && !approval_required
musician_access_value = 'Musicians may join at will'
elsif !musician_access && !approval_required
musician_access_value = 'Only RSVP musicians may join'
end
if fan_access && fan_chat
fan_permission_value = 'Fans may listen, chat with the band'
elsif !fan_access && !fan_chat
fan_permission_value = 'Fans may not listen to session'
end
# schedule a session in one client
in_client(creator) do
page.driver.resize(1500, 800) # makes sure all the elements are visible
emulate_client
sign_in_poltergeist creator
wait_until_curtain_gone
visit "/client#/createSession"
expect(page).to have_selector('h1', text: 'create session')
find('li[create-type="schedule-future"] ins').trigger(:click)
find('.btn-next').trigger(:click)
jk_select(genre, '#create-session-form select[name="genres"]')
fill_in('session-name', :with => unique_session_name)
fill_in('session-description', :with => unique_session_desc)
find('.btn-next').trigger(:click)
find('.btn-next').trigger(:click)
find('div#divSessionPolicy ins').trigger(:click)
jk_select(musician_access_value, '#session-musician-access')
jk_select(fan_permission_value, '#session-fans-access')
find('.btn-next').trigger(:click)
find('.btn-next', text: 'PUBLISH SESSION').trigger(:click)
2014-06-24 04:03:04 +00:00
find('h2', text: 'create session')
2014-06-26 02:50:20 +00:00
2014-06-24 04:03:04 +00:00
sleep 1 # to get rid of this, we need to verify that the URL is /client#/home.. otherwise intermittent fails
2014-06-20 16:52:36 +00:00
end
end
# this code assumes that there are no music sessions in the database. it should fail on the
# find('.join-link') call if > 1 session exists because capybara will complain of multiple matches
def join_session(joiner, options)
description = options[:description]
in_client(joiner) do
page.driver.resize(1500, 800) # makes sure all the elements are visible
emulate_client
sign_in_poltergeist joiner
wait_until_curtain_gone
visit "/client#/findSession"
# verify the session description is seen by second client
expect(page).to have_text(description)
find('.join-link').trigger(:click)
find('#btn-accept-terms').trigger(:click)
expect(page).to have_selector('h2', text: 'my tracks')
find('#session-screen .session-mytracks .session-track')
end
end
def emulate_client
page.driver.headers = { 'User-Agent' => ' JamKazam ' }
end
def create_join_session(creator, joiners=[], options={})
options[:creator] = creator
creator, unique_session_desc = create_session(options)
# find session in second client
joiners.each do |joiner|
join_session(joiner, description: unique_session_desc)
end
return creator, unique_session_desc
end
def formal_leave_by user
in_client(user) do
find('#session-leave').trigger(:click)
2014-02-25 03:25:34 +00:00
#find('#btn-accept-leave-session').trigger(:click)
expect(page).to have_selector('h2', text: 'feed')
end
end
def start_recording_with(creator, joiners=[], genre=nil)
create_join_session(creator, joiners, {genre: genre})
in_client(creator) do
find('#recording-start-stop').trigger(:click)
find('#recording-status').should have_content 'Stop Recording'
end
joiners.each do |joiner|
in_client(joiner) do
find('#notification').should have_content 'started a recording'
find('#recording-status').should have_content 'Stop Recording'
end
end
end
def stop_recording
find('#recording-start-stop').trigger(:click)
end
def assert_recording_finished
find('#recording-status').should have_content 'Make a Recording'
should have_selector('h1', text: 'recording finished')
end
def check_recording_finished_for(users=[])
users.each do |user|
in_client(user) do
assert_recording_finished
end
end
end
def claim_recording(name, description)
find('#recording-finished-dialog h1')
fill_in "claim-recording-name", with: name
fill_in "claim-recording-description", with: description
find('#keep-session-recording').trigger(:click)
2014-04-29 07:33:37 +00:00
page.should have_no_selector('h1', text: 'recording finished')
end
def set_session_as_private()
find('#session-settings-button').trigger(:click)
within('#session-settings-dialog') do
jk_select("Private", '#session-settings-dialog #session-settings-musician-access')
#select('Private', :from => 'session-settings-musician-access')
find('#session-settings-dialog-submit').trigger(:click)
end
# verify it's dismissed
page.should have_no_selector('h1', text: 'update session settings')
end
def set_session_as_public()
find('#session-settings-button').trigger(:click)
within('#session-settings-dialog') do
jk_select("Public", '#session-settings-dialog #session-settings-musician-access')
# select('Public', :from => 'session-settings-musician-access')
find('#session-settings-dialog-submit').trigger(:click)
end
# verify it's dismissed
page.should have_no_selector('h1', text: 'update session settings')
end
def get_options(selector)
find(selector, :visible => false).all('option', :visible => false).collect(&:text).uniq
end
def selected_genres(selector='#session-settings-genre')
page.evaluate_script("JK.GenreSelectorHelper.getSelectedGenres('#{selector}')")
end
def random_genre
['African',
'Ambient',
'Asian',
'Blues',
'Classical',
'Country',
'Electronic',
'Folk',
'Hip Hop',
'Jazz',
'Latin',
'Metal',
'Pop',
'R&B',
'Reggae',
'Religious',
'Rock',
'Ska',
'Other'].sample
end
def change_session_genre #randomly just change it
here = 'select.genre-list'
#wait_for_ajax
find('#session-settings-button').trigger(:click)
2014-04-16 03:09:16 +00:00
find('#session-settings-dialog') # ensure the dialog is visible
within('#session-settings-dialog') do
wait_for_ajax
@new_genre = get_options(here).-(["Select Genre"]).-(selected_genres).sample.to_s
jk_select(@new_genre, '#session-settings-dialog select[name="genres"]')
wait_for_ajax
find('#session-settings-dialog-submit').trigger(:click)
end
return @new_genre
end
def get_session_genre
here = 'select.genre-list'
find('#session-settings-button').trigger(:click)
wait_for_ajax
@current_genres = selected_genres
find('#session-settings-dialog-submit').trigger(:click)
return @current_genres.join(" ")
end
def find_session_contains?(text)
visit "/client#/findSession"
wait_for_ajax
within('#find-session-form') do
expect(page).to have_text(text)
end
end
def assert_all_tracks_seen(users=[])
users.each do |user|
in_client(user) do
users.reject {|u| u==user}.each do |other|
find('div.track-label', text: other.name)
#puts user.name + " is able to see " + other.name + "\'s track"
end
end
end
end
def view_profile_of user
id = user.kind_of?(JamRuby::User) ? user.id : user
2014-04-16 03:09:16 +00:00
# assume some user signed in already
visit "/client#/profile/#{id}"
wait_until_curtain_gone
end
2014-04-16 03:09:16 +00:00
def view_band_profile_of band
id = band.kind_of?(JamRuby::Band) ? band.id :
band.kind_of?(JamRuby::BandMusician) ? band.bands.first.id : band
visit "/client#/bandProfile/#{id}"
wait_until_curtain_gone
end
2014-05-07 03:35:00 +00:00
def sidebar_search_for string, category
visit "/client#/home"
find('#search-input')
fill_in "search", with: string
sleep 1
page.execute_script("JK.Sidebar.searchForInput()")
wait_for_ajax
jk_select(category, "search_text_type")
wait_for_ajax
end
def show_user_menu
page.execute_script("$('ul.shortcuts').show()")
#page.execute_script("JK.UserDropdown.menuHoverIn()")
end
# wait for the easydropdown version of the specified select element to become visible
def wait_for_easydropdown(select)
find(select, :visible => false).find(:xpath, 'ancestor::div[contains(@class, "dropdown easydropdown")]')
end
# defaults to enter key (13)
2014-04-09 17:25:52 +00:00
def send_key(selector, keycode = 13)
keypress_script = "var e = $.Event('keyup', { keyCode: #{keycode} }); jQuery('#{selector}').trigger(e);"
page.driver.execute_script(keypress_script)
end
def special_characters
["?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}"]
end
def garbage length
output = ''
length.times { output << special_characters.sample }
output.slice(0, length)
2014-05-19 21:57:08 +00:00
end
2014-06-27 19:17:56 +00:00
def nav_profile_history(user)
visit Nav.profile(user)
find('#profile-history-link').trigger(:click)
end