browser_test_helper.rb 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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_url
  7. ENV['BROWSER_URL'] || 'http://localhost:3000'
  8. end
  9. def browser_instance
  10. if !@browsers
  11. @browsers = []
  12. end
  13. if !ENV['REMOTE_URL']
  14. if !ENV['BROWSER']
  15. ENV['BROWSER'] = 'firefox'
  16. end
  17. browser = Selenium::WebDriver.for( ENV['BROWSER'].to_sym )
  18. @browsers.push browser
  19. return browser
  20. end
  21. caps = Selenium::WebDriver::Remote::Capabilities.send( ENV['BROWSER'] )
  22. caps.platform = ENV['BROWSER_OS'] || 'Windows 2008'
  23. caps.version = ENV['BROWSER_VERSION'] || '8'
  24. browser = Selenium::WebDriver.for(
  25. :remote,
  26. :url => ENV['REMOTE_URL'],
  27. :desired_capabilities => caps,
  28. )
  29. @browsers.push browser
  30. return browser
  31. end
  32. def teardown
  33. return if !@browsers
  34. # only shut down browser type once
  35. # otherwise this error will happen "Errno::ECONNREFUSED: Connection refused - connect(2)"
  36. shutdown = {}
  37. @browsers.each{ |browser|
  38. next if shutdown[ browser.browser ]
  39. shutdown[ browser.browser ] = true
  40. browser.quit
  41. }
  42. end
  43. # Add more helper methods to be used by all tests here...
  44. def browser_login(data)
  45. all_tests = [
  46. {
  47. :name => 'login',
  48. :instance => data[:instance] || browser_instance,
  49. :url => data[:url] || browser_url,
  50. :action => [
  51. {
  52. :execute => 'wait',
  53. :value => 2,
  54. },
  55. {
  56. :execute => 'check',
  57. :css => '#login',
  58. :result => true,
  59. },
  60. {
  61. :execute => 'set',
  62. :css => 'input[name="username"]',
  63. :value => data[:username] || 'nicole.braun@zammad.org',
  64. },
  65. {
  66. :execute => 'set',
  67. :css => 'input[name="password"]',
  68. :value => data[:password] || 'test'
  69. },
  70. {
  71. :execute => 'click',
  72. :css => '#login button',
  73. },
  74. {
  75. :execute => 'wait',
  76. :value => 2,
  77. },
  78. {
  79. :execute => 'check',
  80. :css => '#login',
  81. :result => false,
  82. },
  83. ],
  84. },
  85. ];
  86. return all_tests
  87. end
  88. def browser_signle_test_with_login(tests, login = {})
  89. all_tests = browser_login( login )
  90. all_tests = all_tests.concat( tests )
  91. browser_single_test(all_tests)
  92. end
  93. def browser_double_test(tests)
  94. instance1 = browser_single_test( browser_login({
  95. :instance => tests[0][:instance1],
  96. :username => tests[0][:instance1_username],
  97. :password => tests[0][:instance1_password],
  98. :url => tests[0][:url],
  99. }), true )
  100. instance2 = browser_single_test( browser_login({
  101. :instance => tests[0][:instance2],
  102. :username => tests[0][:instance2_username],
  103. :password => tests[0][:instance2_password],
  104. :url => tests[0][:url],
  105. }), true )
  106. tests.each { |test|
  107. if test[:action]
  108. test[:action].each { |action|
  109. if action[:execute] == 'wait'
  110. sleep action[:value]
  111. next
  112. end
  113. next if !action[:where]
  114. if action[:where] == :instance1
  115. instance = instance1
  116. else
  117. instance = instance2
  118. end
  119. browser_element_action(test, action, instance)
  120. }
  121. end
  122. }
  123. instance1.close
  124. instance2.close
  125. end
  126. def browser_single_test(tests, keep_connection = false)
  127. instance = nil
  128. @stack = nil
  129. tests.each { |test|
  130. if test[:instance]
  131. instance = test[:instance]
  132. end
  133. if test[:url]
  134. instance.get( test[:url] )
  135. end
  136. if test[:action]
  137. test[:action].each { |action|
  138. if action[:execute] == 'wait'
  139. sleep action[:value]
  140. next
  141. end
  142. browser_element_action(test, action, instance)
  143. }
  144. end
  145. }
  146. if keep_connection
  147. return instance
  148. end
  149. instance.close
  150. end
  151. def browser_element_action(test, action, instance)
  152. #puts "NOTICE: " + action.inspect
  153. if action[:css]
  154. begin
  155. if action[:range] == 'all'
  156. element = instance.find_elements( { :css => action[:css] } )
  157. else
  158. element = instance.find_element( { :css => action[:css] } )
  159. end
  160. rescue
  161. element = nil
  162. end
  163. if action[:result] == false
  164. assert( !element, "(#{test[:name]}) Element with css '#{action[:css]}' exists" )
  165. else
  166. assert( element, "(#{test[:name]}) Element with css '#{action[:css]}' doesn't exist" )
  167. end
  168. elsif action[:element] == :url
  169. if instance.current_url =~ /#{Regexp.quote(action[:result])}/
  170. assert( true, "(#{test[:name]}) url #{instance.current_url} is matching #{action[:result]}" )
  171. else
  172. assert( false, "(#{test[:name]}) url #{instance.current_url} is not matching #{action[:result]}" )
  173. end
  174. elsif action[:element] == :alert
  175. element = instance.switch_to.alert
  176. elsif action[:execute] == 'close_all_tasks'
  177. while true
  178. begin
  179. element = instance.find_element( { :css => '.taskbar [data-type="close"]' } )
  180. if element
  181. element.click
  182. sleep 0.8
  183. else
  184. break
  185. end
  186. rescue
  187. break
  188. end
  189. end
  190. elsif action[:execute] == 'navigate'
  191. instance.navigate.to( action[:to] )
  192. else
  193. assert( false, "(#{test[:name]}) unknow selector for '#{action[:element]}'" )
  194. end
  195. if action[:execute] == 'set'
  196. element.clear
  197. if action[:value] == '###stack###'
  198. element.send_keys( @stack )
  199. else
  200. element.send_keys( action[:value] )
  201. end
  202. elsif action[:execute] == 'sendkey'
  203. element.send_keys( action[:value] )
  204. elsif action[:execute] == 'select'
  205. dropdown = Selenium::WebDriver::Support::Select.new(element)
  206. dropdown.select_by(:text, action[:value])
  207. elsif action[:execute] == 'click'
  208. if element.class == Array
  209. element.each {|item|
  210. item.click
  211. }
  212. else
  213. element.click
  214. end
  215. elsif action[:execute] == 'accept'
  216. element.accept
  217. elsif action[:execute] == 'dismiss'
  218. element.dismiss
  219. elsif action[:execute] == 'send_key'
  220. element.send_keys action[:value]
  221. elsif action[:execute] == 'match'
  222. if action[:css] =~ /select/
  223. dropdown = Selenium::WebDriver::Support::Select.new(element)
  224. success = false
  225. if dropdown.selected_options
  226. dropdown.selected_options.each {|option|
  227. if option.text == action[:value]
  228. success = true
  229. end
  230. }
  231. end
  232. if action[:match_result]
  233. if success
  234. assert( true, "(#{test[:name]}) matching '#{action[:value]}' in select list" )
  235. else
  236. assert( false, "(#{test[:name]}) not matching '#{action[:value]}' in select list" )
  237. end
  238. else
  239. if success
  240. assert( false, "(#{test[:name]}) not matching '#{action[:value]}' in select list" )
  241. else
  242. assert( true, "(#{test[:name]}) matching '#{action[:value]}' in select list" )
  243. end
  244. end
  245. else
  246. if action[:css] =~ /(input|textarea)/i
  247. text = element.attribute('value')
  248. else
  249. text = element.text
  250. end
  251. if action[:value] == '###stack###'
  252. action[:value] = @stack
  253. end
  254. match = false
  255. if action[:no_quote]
  256. if text =~ /#{action[:value]}/
  257. if $1
  258. @stack = $1
  259. end
  260. match = $1 || true
  261. end
  262. else
  263. if text =~ /#{Regexp.quote(action[:value])}/
  264. match = true
  265. end
  266. end
  267. if match
  268. if action[:match_result]
  269. assert( true, "(#{test[:name]}) matching '#{action[:value]}' in content '#{text}'" )
  270. else
  271. assert( false, "(#{test[:name]}) matching '#{action[:value]}' in content '#{text}' but should not!" )
  272. end
  273. else
  274. if !action[:match_result]
  275. assert( true, "(#{test[:name]}) not matching '#{action[:value]}' in content '#{text}'" )
  276. else
  277. assert( false, "(#{test[:name]}) not matching '#{action[:value]}' in content '#{text}' but should not!" )
  278. end
  279. end
  280. end
  281. elsif action[:execute] == 'check'
  282. elsif action[:execute] == 'close_all_tasks'
  283. elsif action[:execute] == 'navigate'
  284. else
  285. assert( false, "(#{test[:name]}) unknow action '#{action[:execute]}'" )
  286. end
  287. end
  288. end