browser_test_helper.rb 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. ENV["RAILS_ENV"] = "test"
  2. require File.expand_path('../../config/environment', __FILE__)
  3. require 'rails/test_help'
  4. require 'selenium-webdriver'
  5. class TestCase < Test::Unit::TestCase
  6. def browser
  7. ENV['BROWSER'] || 'firefox'
  8. end
  9. def browser_support_cookies
  10. if browser =~ /(internet_explorer|ie)/i
  11. return false
  12. end
  13. return true
  14. end
  15. def browser_url
  16. ENV['BROWSER_URL'] || 'http://localhost:3000'
  17. end
  18. def browser_instance
  19. if !@browsers
  20. @browsers = []
  21. end
  22. if !ENV['REMOTE_URL']
  23. local_browser = Selenium::WebDriver.for( browser.to_sym )
  24. browser_instance_preferences(local_browser)
  25. @browsers.push local_browser
  26. return local_browser
  27. end
  28. caps = Selenium::WebDriver::Remote::Capabilities.send(
  29. browser,
  30. #:forceCreateProcess => true,
  31. #:ensureCleanSession => true,
  32. #:internetExplorerSwitches => 'InetCpl.cpl,ClearMyTracksByProcess 2',
  33. )
  34. caps.platform = ENV['BROWSER_OS'] || 'Windows 2008'
  35. caps.version = ENV['BROWSER_VERSION'] || '8'
  36. local_browser = Selenium::WebDriver.for(
  37. :remote,
  38. :url => ENV['REMOTE_URL'],
  39. :desired_capabilities => caps,
  40. )
  41. browser_instance_preferences(local_browser)
  42. @browsers.push local_browser
  43. return local_browser
  44. end
  45. def browser_instance_preferences(local_browser)
  46. local_browser.manage.window.resize_to(1024, 1024)
  47. if ENV['REMOTE_URL'] !~ /saucelabs/i
  48. if @browsers.size < 1
  49. local_browser.manage.window.move_to(0, 0)
  50. else
  51. local_browser.manage.window.move_to(1024, 0)
  52. end
  53. end
  54. local_browser.manage.timeouts.implicit_wait = 3 # seconds
  55. end
  56. def teardown
  57. return if !@browsers
  58. @browsers.each{ |local_browser|
  59. local_browser.quit
  60. }
  61. end
  62. # Add more helper methods to be used by all tests here...
  63. def browser_login(data)
  64. all_tests = [
  65. {
  66. :name => 'login',
  67. :instance => data[:instance] || browser_instance,
  68. :url => data[:url] || browser_url,
  69. :action => [
  70. {
  71. :execute => 'login',
  72. :username => data[:username] || 'nicole.braun@zammad.org',
  73. :password => data[:password] || 'test'
  74. },
  75. ],
  76. },
  77. ];
  78. return all_tests
  79. end
  80. def browser_signle_test_with_login(tests, login = {})
  81. all_tests = browser_login( login )
  82. all_tests = all_tests.concat( tests )
  83. browser_single_test(all_tests)
  84. end
  85. def browser_double_test(tests)
  86. instance1 = browser_single_test( browser_login({
  87. :instance => tests[0][:instance1],
  88. :username => tests[0][:instance1_username],
  89. :password => tests[0][:instance1_password],
  90. :url => tests[0][:url],
  91. }), true )
  92. instance2 = browser_single_test( browser_login({
  93. :instance => tests[0][:instance2],
  94. :username => tests[0][:instance2_username],
  95. :password => tests[0][:instance2_password],
  96. :url => tests[0][:url],
  97. }), true )
  98. tests.each { |test|
  99. if test[:action]
  100. test[:action].each { |action|
  101. if action[:execute] == 'wait'
  102. sleep action[:value]
  103. next
  104. end
  105. next if !action[:where]
  106. if action[:where] == :instance1
  107. instance = instance1
  108. else
  109. instance = instance2
  110. end
  111. browser_element_action(test, action, instance)
  112. }
  113. end
  114. }
  115. instance1.close
  116. instance2.close
  117. end
  118. def browser_single_test(tests, keep_connection = false)
  119. instance = nil
  120. @stack = nil
  121. tests.each { |test|
  122. if test[:instance]
  123. instance = test[:instance]
  124. end
  125. if test[:url]
  126. instance.get( test[:url] )
  127. end
  128. if test[:action]
  129. test[:action].each { |action|
  130. if action[:execute] == 'wait'
  131. sleep action[:value]
  132. next
  133. end
  134. browser_element_action(test, action, instance)
  135. }
  136. end
  137. }
  138. if keep_connection
  139. return instance
  140. end
  141. instance.close
  142. end
  143. def browser_element_action(test, action, instance)
  144. puts "NOTICE #{Time.now.to_s}: " + action.inspect
  145. sleep 0.1
  146. if action[:css]
  147. if action[:css].match '###stack###'
  148. action[:css].gsub! '###stack###', @stack
  149. end
  150. begin
  151. if action[:range] == 'all'
  152. element = instance.find_elements( { :css => action[:css] } )
  153. else
  154. element = instance.find_element( { :css => action[:css] } )
  155. end
  156. rescue
  157. element = nil
  158. end
  159. if action[:result] == false
  160. assert( !element, "(#{test[:name]}) Element with css '#{action[:css]}' exists" )
  161. else
  162. assert( element, "(#{test[:name]}) Element with css '#{action[:css]}' doesn't exist" )
  163. end
  164. elsif action[:element] == :url
  165. if instance.current_url =~ /#{Regexp.quote(action[:result])}/
  166. assert( true, "(#{test[:name]}) url #{instance.current_url} is matching #{action[:result]}" )
  167. else
  168. assert( false, "(#{test[:name]}) url #{instance.current_url} is not matching #{action[:result]}" )
  169. end
  170. elsif action[:element] == :title
  171. title = instance.title
  172. if title =~ /#{action[:value]}/i
  173. assert( true, "(#{test[:name]}) matching '#{action[:value]}' in title '#{title}'" )
  174. else
  175. assert( false, "(#{test[:name]}) not matching '#{action[:value]}' in title '#{title}'" )
  176. end
  177. return
  178. elsif action[:element] == :cookie
  179. if !browser_support_cookies
  180. assert( true, "(#{test[:name]}) '#{action[:value]}' ups browser is not supporting reading cookies")
  181. return
  182. end
  183. cookies = instance.manage.all_cookies
  184. cookies.each {|cookie|
  185. if cookie.to_s =~ /#{action[:value]}/i
  186. assert( true, "(#{test[:name]}) matching '#{action[:value]}' in cookie '#{cookie.to_s}'" )
  187. return
  188. end
  189. }
  190. assert( false, "(#{test[:name]}) not matching '#{action[:value]}' in cookie '#{cookies.to_s}'" )
  191. return
  192. elsif action[:element] == :alert
  193. element = instance.switch_to.alert
  194. elsif action[:execute] == 'login'
  195. sleep 1
  196. login = instance.find_element( { :css => '#login' } )
  197. if !login
  198. assert( false, "(#{test[:name]}) no login box found!" )
  199. return
  200. end
  201. element = instance.find_element( { :css => '#login input[name="username"]' } )
  202. element.clear
  203. element.send_keys( action[:username] )
  204. element = instance.find_element( { :css => '#login input[name="password"]' } )
  205. element.clear
  206. element.send_keys( action[:password] )
  207. instance.find_element( { :css => '#login button' } ).click
  208. sleep 4
  209. return
  210. elsif action[:execute] == 'logout'
  211. instance.find_element( { :css => 'a[href="#current_user"]' } ).click
  212. sleep 0.1
  213. instance.find_element( { :css => 'a[href="#logout"]' } ).click
  214. sleep 2
  215. login = instance.find_element( { :css => '#login' } )
  216. if !login
  217. assert( false, "(#{test[:name]}) no login box found!" )
  218. return
  219. end
  220. assert( true, "(#{test[:name]}) logout" )
  221. return
  222. elsif action[:execute] == 'create_ticket'
  223. instance.find_element( { :css => 'a[href="#new"]' } ).click
  224. instance.find_element( { :css => 'a[href="#ticket_create/call_inbound"]' } ).click
  225. sleep 4
  226. element = instance.find_element( { :css => '.active .ticket_create' } )
  227. if !element
  228. assert( false, "(#{test[:name]}) no ticket create screen found!" )
  229. return
  230. end
  231. sleep 5
  232. element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
  233. element.clear
  234. element.send_keys( 'ma' )
  235. sleep 4
  236. element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
  237. element.send_keys( :arrow_down )
  238. sleep 0.2
  239. element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
  240. element.send_keys( :tab )
  241. sleep 0.1
  242. element = instance.find_element( { :css => '.active .ticket_create select[name="group_id"]' } )
  243. dropdown = Selenium::WebDriver::Support::Select.new(element)
  244. dropdown.select_by( :text, action[:group])
  245. sleep 0.1
  246. element = instance.find_element( { :css => '.active .ticket_create input[name="subject"]' } )
  247. element.clear
  248. element.send_keys( action[:subject] )
  249. sleep 0.1
  250. element = instance.find_element( { :css => '.active .ticket_create textarea[name="body"]' } )
  251. element.clear
  252. element.send_keys( action[:body] )
  253. if action[:do_not_submit]
  254. assert( true, "(#{test[:name]}) ticket created without submit" )
  255. return
  256. end
  257. sleep 0.1
  258. instance.find_element( { :css => '.active .form-actions button[type="submit"]' } ).click
  259. sleep 6
  260. if instance.current_url !~ /#{Regexp.quote('#ticket/zoom/')}/
  261. assert( true, "(#{test[:name]}) ticket creation failed, can't get zoom url" )
  262. return
  263. end
  264. assert( true, "(#{test[:name]}) ticket created" )
  265. return
  266. elsif action[:execute] == 'close_all_tasks'
  267. for i in 1..100
  268. begin
  269. element = instance.find_element( { :css => '.taskbar [data-type="close"]' } )
  270. if element
  271. element.click
  272. sleep 0.8
  273. else
  274. break
  275. end
  276. rescue
  277. break
  278. end
  279. end
  280. assert( true, "(#{test[:name]}) all tasks closed" )
  281. return
  282. elsif action[:execute] == 'navigate'
  283. instance.navigate.to( action[:to] )
  284. return
  285. elsif action[:execute] == 'reload'
  286. instance.navigate.refresh
  287. return
  288. elsif action[:execute] == 'js'
  289. result = instance.execute_script( action[:value] )
  290. elsif action[:link]
  291. if action[:link].match '###stack###'
  292. action[:link].gsub! '###stack###', @stack
  293. end
  294. element = instance.find_element( { :partial_link_text => action[:link] } )
  295. else
  296. assert( false, "(#{test[:name]}) unknow selector for '#{action[:element]}'" )
  297. end
  298. if action[:execute] == 'setCheck'
  299. checked = element.attribute('checked')
  300. if !checked
  301. element.click
  302. end
  303. elsif action[:execute] == 'setUncheck'
  304. checked = element.attribute('checked')
  305. if checked
  306. element.click
  307. end
  308. elsif action[:execute] == 'set'
  309. element.clear
  310. if action[:value] == '###stack###'
  311. element.send_keys( @stack )
  312. else
  313. element.send_keys( action[:value] )
  314. end
  315. elsif action[:execute] == 'sendkey'
  316. element.send_keys( action[:value] )
  317. elsif action[:execute] == 'select'
  318. dropdown = Selenium::WebDriver::Support::Select.new(element)
  319. dropdown.select_by(:text, action[:value])
  320. elsif action[:execute] == 'click'
  321. if element.class == Array
  322. element.each {|item|
  323. item.click
  324. }
  325. else
  326. element.click
  327. end
  328. elsif action[:execute] == 'accept'
  329. element.accept
  330. elsif action[:execute] == 'dismiss'
  331. element.dismiss
  332. elsif action[:execute] == 'send_key'
  333. element.send_keys action[:value]
  334. elsif action[:execute] == 'match'
  335. if action[:css] =~ /select/
  336. dropdown = Selenium::WebDriver::Support::Select.new(element)
  337. success = false
  338. if dropdown.selected_options
  339. dropdown.selected_options.each {|option|
  340. if option.text == action[:value]
  341. success = true
  342. end
  343. }
  344. end
  345. if action[:match_result]
  346. if success
  347. assert( true, "(#{test[:name]}) matching '#{action[:value]}' in select list" )
  348. else
  349. assert( false, "(#{test[:name]}) not matching '#{action[:value]}' in select list" )
  350. end
  351. else
  352. if success
  353. assert( false, "(#{test[:name]}) not matching '#{action[:value]}' in select list" )
  354. else
  355. assert( true, "(#{test[:name]}) matching '#{action[:value]}' in select list" )
  356. end
  357. end
  358. else
  359. if action[:css] =~ /(input|textarea)/i
  360. text = element.attribute('value')
  361. else
  362. text = element.text
  363. end
  364. if action[:value] == '###stack###'
  365. action[:value] = @stack
  366. end
  367. match = false
  368. if action[:no_quote]
  369. if text =~ /#{action[:value]}/
  370. if $1
  371. @stack = $1
  372. end
  373. match = $1 || true
  374. end
  375. else
  376. if text =~ /#{Regexp.quote(action[:value])}/
  377. match = true
  378. end
  379. end
  380. if match
  381. if action[:match_result]
  382. assert( true, "(#{test[:name]}) matching '#{action[:value]}' in content '#{text}'" )
  383. else
  384. assert( false, "(#{test[:name]}) matching '#{action[:value]}' in content '#{text}' but should not!" )
  385. end
  386. else
  387. if !action[:match_result]
  388. assert( true, "(#{test[:name]}) not matching '#{action[:value]}' in content '#{text}'" )
  389. else
  390. assert( false, "(#{test[:name]}) not matching '#{action[:value]}' in content '#{text}' but should not!" )
  391. end
  392. end
  393. end
  394. elsif action[:execute] == 'check'
  395. elsif action[:execute] == 'js'
  396. else
  397. assert( false, "(#{test[:name]}) unknow action '#{action[:execute]}'" )
  398. end
  399. end
  400. end