browser_test_helper.rb 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766
  1. ENV['RAILS_ENV'] = 'test'
  2. # rubocop:disable Next, CyclomaticComplexity, PerceivedComplexity, HandleExceptions, ClassVars, NonLocalExitFromIterator
  3. require File.expand_path('../../config/environment', __FILE__)
  4. require 'selenium-webdriver'
  5. class TestCase < Test::Unit::TestCase
  6. @@debug = true
  7. def browser
  8. ENV['BROWSER'] || 'firefox'
  9. end
  10. def browser_support_cookies
  11. if browser =~ /(internet_explorer|ie)/i
  12. return false
  13. end
  14. true
  15. end
  16. def browser_url
  17. ENV['BROWSER_URL'] || 'http://localhost:3000'
  18. end
  19. def browser_instance
  20. if !@browsers
  21. @browsers = {}
  22. end
  23. if !ENV['REMOTE_URL'] || ENV['REMOTE_URL'].empty?
  24. local_browser = Selenium::WebDriver.for( browser.to_sym )
  25. browser_instance_preferences(local_browser)
  26. @browsers[local_browser.hash] = local_browser
  27. return local_browser
  28. end
  29. caps = Selenium::WebDriver::Remote::Capabilities.send( browser )
  30. if ENV['BROWSER_OS']
  31. caps.platform = ENV['BROWSER_OS']
  32. end
  33. if ENV['BROWSER_VERSION']
  34. caps.version = ENV['BROWSER_VERSION']
  35. end
  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[local_browser.hash] = local_browser
  43. local_browser
  44. end
  45. def browser_instance_close(local_browser)
  46. return if !@browsers[local_browser.hash]
  47. @browsers.delete( local_browser.hash )
  48. local_browser.quit
  49. end
  50. def browser_instance_preferences(local_browser)
  51. local_browser.manage.window.resize_to(1024, 800)
  52. if ENV['REMOTE_URL'] !~ /saucelabs|(grid|ci)\.(zammad\.org|znuny\.com)/i
  53. if @browsers.size < 1
  54. local_browser.manage.window.move_to(0, 0)
  55. else
  56. local_browser.manage.window.move_to(1024, 0)
  57. end
  58. end
  59. local_browser.manage.timeouts.implicit_wait = 3 # seconds
  60. end
  61. def teardown
  62. return if !@browsers
  63. @browsers.each { |hash, local_browser|
  64. screenshot( browser: local_browser, comment: 'teardown' )
  65. browser_instance_close(local_browser)
  66. }
  67. end
  68. def screenshot(params)
  69. instance = params[:browser] || @browser
  70. comment = params[:comment] || ''
  71. filename = "tmp/#{Time.zone.now.strftime('screenshot_%Y_%m_%d__%H_%M_%S')}_#{comment}_#{instance.hash}.png"
  72. log('screenshot', { filename: filename })
  73. instance.save_screenshot(filename)
  74. end
  75. =begin
  76. username = login(
  77. :browser => browser1,
  78. :username => 'someuser',
  79. :password => 'somepassword',
  80. :url => 'some url', # optional
  81. :remember_me => true, # optional
  82. )
  83. =end
  84. def login(params)
  85. log('login', params)
  86. instance = params[:browser] || @browser
  87. if params[:url]
  88. instance.get( params[:url] )
  89. end
  90. element = instance.find_elements( { css: '#login input[name="username"]' } )[0]
  91. if !element
  92. screenshot( browser: instance, comment: 'login_failed' )
  93. raise 'No login box found'
  94. end
  95. screenshot( browser: instance, comment: 'login' )
  96. element.clear
  97. element.send_keys( params[:username] )
  98. element = instance.find_elements( { css: '#login input[name="password"]' } )[0]
  99. element.clear
  100. element.send_keys( params[:password] )
  101. if params[:remember_me]
  102. instance.find_elements( { css: '#login [name="remember_me"]' } )[0].click
  103. end
  104. instance.find_elements( { css: '#login button' } )[0].click
  105. sleep 4
  106. login = instance.find_elements( { css: '.user-menu .user a' } )[0].attribute('title')
  107. if login != params[:username]
  108. screenshot( browser: instance, comment: 'login_failed' )
  109. raise 'login failed'
  110. end
  111. screenshot( browser: instance, comment: 'login_ok' )
  112. assert( true, 'login ok' )
  113. login
  114. end
  115. =begin
  116. logout(
  117. :browser => browser1
  118. )
  119. =end
  120. def logout(params = {})
  121. log('logout', params)
  122. instance = params[:browser] || @browser
  123. instance.find_elements( { css: 'a[href="#current_user"]' } )[0].click
  124. sleep 0.1
  125. instance.find_elements( { css: 'a[href="#logout"]' } )[0].click
  126. (1..6).each {|loop|
  127. sleep 1
  128. login = instance.find_elements( { css: '#login' } )[0]
  129. if login
  130. screenshot( browser: instance, comment: 'logout_ok' )
  131. assert( true, 'logout ok' )
  132. return
  133. end
  134. }
  135. screenshot( browser: instance, comment: 'logout_failed' )
  136. raise 'no login box found, seems logout was not successfully!'
  137. end
  138. =begin
  139. location(
  140. :browser => browser1,
  141. :url => 'http://someurl',
  142. )
  143. =end
  144. def location(params)
  145. log('location', params)
  146. instance = params[:browser] || @browser
  147. instance.get( params[:url] )
  148. screenshot( browser: instance, comment: 'location' )
  149. end
  150. =begin
  151. location_check(
  152. :browser => browser1,
  153. :url => 'http://someurl',
  154. )
  155. =end
  156. def location_check(params)
  157. log('location_check', params)
  158. instance = params[:browser] || @browser
  159. if instance.current_url !~ /#{Regexp.quote(params[:url])}/
  160. screenshot( browser: instance, comment: 'location_check_failed' )
  161. raise "url #{instance.current_url} is not matching #{params[:url]}"
  162. end
  163. assert( true, "url #{instance.current_url} is matching #{params[:url]}" )
  164. end
  165. =begin
  166. reload(
  167. :browser => browser1,
  168. )
  169. =end
  170. def reload(params = {})
  171. log('reload', params)
  172. instance = params[:browser] || @browser
  173. screenshot( browser: instance, comment: 'reload_before' )
  174. instance.navigate.refresh
  175. screenshot( browser: instance, comment: 'reload_after' )
  176. end
  177. =begin
  178. click(
  179. :browser => browser1,
  180. :css => '.some_class',
  181. :fast => false, # do not wait
  182. )
  183. click(
  184. :browser => browser1,
  185. :text => '.partial_link_text',
  186. :fast => false, # do not wait
  187. )
  188. =end
  189. def click(params)
  190. log('click', params)
  191. instance = params[:browser] || @browser
  192. if params[:css]
  193. instance.find_elements( { css: params[:css] } )[0].click
  194. else
  195. instance.find_elements( { partial_link_text: params[:text] } )[0].click
  196. end
  197. sleep 0.4 if !params[:fast]
  198. end
  199. =begin
  200. exists(
  201. :browser => browser1,
  202. :css => '.some_class',
  203. )
  204. =end
  205. def exists(params)
  206. log('exists', params)
  207. instance = params[:browser] || @browser
  208. if !instance.find_elements( { css: params[:css] } )[0]
  209. screenshot( browser: instance, comment: 'exists_failed' )
  210. raise "#{params[:css]} dosn't exist, but should"
  211. end
  212. true
  213. end
  214. =begin
  215. exists_not(
  216. :browser => browser1,
  217. :css => '.some_class',
  218. )
  219. =end
  220. def exists_not(params)
  221. log('exists_not', params)
  222. instance = params[:browser] || @browser
  223. if instance.find_elements( { css: params[:css] } )[0]
  224. screenshot( browser: instance, comment: 'exists_not_failed' )
  225. raise "#{params[:css]} exists but should not"
  226. end
  227. true
  228. end
  229. =begin
  230. set(
  231. :browser => browser1,
  232. :css => '.some_class',
  233. :value => true,
  234. :slow => false,
  235. :blur => true,
  236. :clear => true, # todo | default: true
  237. :contenteditable => true
  238. )
  239. =end
  240. def set(params)
  241. log('set', params)
  242. instance = params[:browser] || @browser
  243. element = instance.find_elements( { css: params[:css] } )[0]
  244. #element.click
  245. element.clear
  246. if !params[:slow]
  247. element.send_keys( params[:value] )
  248. else
  249. element.send_keys( '' )
  250. keys = params[:value].to_s.split('')
  251. keys.each {|key|
  252. instance.action.send_keys(key).perform
  253. }
  254. end
  255. if params[:blur]
  256. instance.execute_script( "$('#{params[:css]}').blur()" )
  257. end
  258. # it's not working stable via selenium, use js
  259. if params[:contenteditable]
  260. value = instance.find_elements( { css: params[:css] } )[0].text
  261. if value != params[:value]
  262. body_quoted = quote( params[:value] )
  263. instance.execute_script( "$('#{params[:css]}').focus().html('#{body_quoted}').trigger('focusout')" )
  264. end
  265. end
  266. sleep 0.5
  267. end
  268. =begin
  269. select(
  270. :browser => browser1,
  271. :css => '.some_class',
  272. :value => 'Some Value',
  273. )
  274. =end
  275. def select(params)
  276. log('select', params)
  277. instance = params[:browser] || @browser
  278. begin
  279. element = instance.find_elements( { css: params[:css] } )[0]
  280. dropdown = Selenium::WebDriver::Support::Select.new(element)
  281. dropdown.select_by(:text, params[:value])
  282. puts "select - #{params.inspect}"
  283. rescue
  284. # just try again
  285. element = instance.find_elements( { css: params[:css] } )[0]
  286. dropdown = Selenium::WebDriver::Support::Select.new(element)
  287. dropdown.select_by(:text, params[:value])
  288. puts "select2 - #{params.inspect}"
  289. end
  290. end
  291. =begin
  292. check(
  293. :browser => browser1,
  294. :css => '.some_class',
  295. )
  296. =end
  297. def check(params)
  298. log('check', params)
  299. instance = params[:browser] || @browser
  300. element = instance.find_elements( { css: params[:css] } )[0]
  301. checked = element.attribute('checked')
  302. element.click if !checked
  303. end
  304. =begin
  305. uncheck(
  306. :browser => browser1,
  307. :css => '.some_class',
  308. )
  309. =end
  310. def uncheck(params)
  311. log('uncheck', params)
  312. instance = params[:browser] || @browser
  313. element = instance.find_elements( { css: params[:css] } )[0]
  314. checked = element.attribute('checked')
  315. element.click if checked
  316. end
  317. =begin
  318. sendkey(
  319. :browser => browser1,
  320. :value => :enter,
  321. )
  322. =end
  323. def sendkey(params)
  324. log('sendkey', params)
  325. instance = params[:browser] || @browser
  326. if params[:value].class == Array
  327. params[:value].each {|key|
  328. instance.action.send_keys(key).perform
  329. }
  330. return
  331. end
  332. instance.action.send_keys(params[:value]).perform
  333. sleep 0.5
  334. end
  335. =begin
  336. match(
  337. :browser => browser1,
  338. :css => '#content .text-1',
  339. :value => 'some test for browser and some other for browser',
  340. :attribute => 'some_attribute', # match on attribute
  341. :should_not_match => true,
  342. :no_quote => false, # use regex
  343. )
  344. =end
  345. def match(params, fallback = false)
  346. log('match', params)
  347. instance = params[:browser] || @browser
  348. element = instance.find_elements( { css: params[:css] } )[0]
  349. if params[:css] =~ /select/
  350. dropdown = Selenium::WebDriver::Support::Select.new(element)
  351. success = false
  352. if dropdown.selected_options
  353. dropdown.selected_options.each {|option|
  354. if option.text == params[:value]
  355. success = true
  356. end
  357. }
  358. end
  359. if params[:should_not_match]
  360. if success
  361. raise "should not match '#{params[:value]}' in select list, but is matching"
  362. end
  363. return true
  364. else
  365. if !success
  366. raise "not matching '#{params[:value]}' in select list"
  367. end
  368. return true
  369. end
  370. end
  371. # match on attribute
  372. begin
  373. if params[:attribute]
  374. text = element.attribute( params[:attribute] )
  375. elsif params[:css] =~ /(input|textarea)/i
  376. text = element.attribute('value')
  377. else
  378. text = element.text
  379. end
  380. rescue => e
  381. # just try again
  382. if !fallback
  383. return match(params, true)
  384. else
  385. raise e.inspect
  386. end
  387. end
  388. # do cleanups (needed for richtext tests)
  389. if params[:cleanup]
  390. text.gsub!(/\s+$/m, '')
  391. params[:value].gsub!(/\s+$/m, '')
  392. end
  393. match = false
  394. if params[:no_quote]
  395. #puts "aaaa #{text}/#{params[:value]}"
  396. if text =~ /#{params[:value]}/i
  397. match = $1 || true
  398. end
  399. else
  400. if text =~ /#{Regexp.quote(params[:value])}/i
  401. match = true
  402. end
  403. end
  404. if match
  405. if params[:should_not_match]
  406. raise "matching '#{params[:value]}' in content '#{text}' but should not!"
  407. end
  408. else
  409. if !params[:should_not_match]
  410. raise "not matching '#{params[:value]}' in content '#{text}' but should!"
  411. end
  412. end
  413. sleep 0.8
  414. match
  415. end
  416. =begin
  417. match_not(
  418. :browser => browser1,
  419. :css => '#content .text-1',
  420. :value => 'some test for browser and some other for browser',
  421. :attribute => 'some_attribute', # match on attribute
  422. :should_not_match => true,
  423. :no_quote => false, # use regex
  424. )
  425. =end
  426. def match_not(params)
  427. log('match_not', params)
  428. params[:should_not_match] = true
  429. match(params)
  430. end
  431. =begin
  432. cookie(
  433. :browser => browser1,
  434. :name => '^_zammad.+?',
  435. :value => '.+?',
  436. :expires => nil,
  437. )
  438. cookie(
  439. :browser => browser1,
  440. :name => '^_zammad.+?',
  441. :should_not_exist => true,
  442. )
  443. =end
  444. def cookie(params)
  445. log('cookie', params)
  446. instance = params[:browser] || @browser
  447. if !browser_support_cookies
  448. assert( true, "'#{params[:value]}' ups browser is not supporting reading cookies, go ahead")
  449. return true
  450. end
  451. cookies = instance.manage.all_cookies
  452. cookies.each {|cookie|
  453. #puts "CCC #{cookie.inspect}"
  454. # :name=>"_zammad_session_c25832f4de2", :value=>"adc31cd21615cb0a7ab269184ec8b76f", :path=>"/", :domain=>"localhost", :expires=>nil, :secure=>false}
  455. if cookie[:name] =~ /#{params[:name]}/i
  456. if params.key?( :value ) && cookie[:value].to_s =~ /#{params[:value]}/i
  457. assert( true, "matching value '#{params[:value]}' in cookie '#{cookie}'" )
  458. else
  459. raise "not matching value '#{params[:value]}' in cookie '#{cookie}'"
  460. end
  461. if params.key?( :expires ) && cookie[:expires].to_s =~ /#{params[:expires]}/i
  462. assert( true, "matching expires '#{params[:expires].inspect}' in cookie '#{cookie}'" )
  463. else
  464. raise "not matching expires '#{params[:expires]}' in cookie '#{cookie}'"
  465. end
  466. if params[:should_not_exist]
  467. raise "cookie with name '#{params[:name]}' should not exist, but exists '#{cookies}'"
  468. end
  469. return
  470. end
  471. }
  472. if params[:should_not_exist]
  473. assert( true, "cookie with name '#{params[:name]}' is not existing" )
  474. return
  475. end
  476. raise "not matching name '#{params[:name]}' in cookie '#{cookies}'"
  477. end
  478. =begin
  479. verify_title(
  480. :browser => browser1,
  481. :value => 'some title',
  482. )
  483. =end
  484. def verify_title(params = {})
  485. log('verify_title', params)
  486. instance = params[:browser] || @browser
  487. title = instance.title
  488. if title =~ /#{params[:value]}/i
  489. assert( true, "matching '#{params[:value]}' in title '#{title}'" )
  490. else
  491. raise "not matching '#{params[:value]}' in title '#{title}'"
  492. end
  493. end
  494. =begin
  495. verify_task(
  496. :browser => browser1,
  497. :data => {
  498. :title => 'some title',
  499. :modified => true, # optional
  500. }
  501. )
  502. =end
  503. def verify_task(params = {}, fallback = false)
  504. log('verify_task', params)
  505. instance = params[:browser] || @browser
  506. data = params[:data]
  507. sleep 1
  508. begin
  509. # verify title
  510. if data[:title]
  511. title = instance.find_elements( { css: '.tasks .active' } )[0].text.strip
  512. if title =~ /#{data[:title]}/i
  513. assert( true, "matching '#{data[:title]}' in title '#{title}'" )
  514. else
  515. raise "not matching '#{data[:title]}' in title '#{title}'"
  516. end
  517. end
  518. puts "tv #{params.inspect}"
  519. # verify modified
  520. if data.key?(:modified)
  521. exists = instance.find_elements( { css: '.tasks .active .icon' } )[0]
  522. is_modified = instance.find_elements( { css: '.tasks .active .icon.modified' } )[0]
  523. puts "m #{data[:modified].inspect}"
  524. if exists
  525. puts ' ecists'
  526. end
  527. if is_modified
  528. puts ' is_modified'
  529. end
  530. if data[:modified] == true
  531. if is_modified
  532. assert( true, "task '#{data[:title]}' is modifed" )
  533. elsif !exists
  534. raise "task '#{data[:title]}' not exists, should not modified"
  535. else
  536. raise "task '#{data[:title]}' is not modifed"
  537. end
  538. else
  539. if !is_modified
  540. assert( true, "task '#{data[:title]}' is modifed" )
  541. elsif !exists
  542. raise "task '#{data[:title]}' not exists, should be not modified"
  543. else
  544. raise "task '#{data[:title]}' is modifed, but should not"
  545. end
  546. end
  547. end
  548. rescue => e
  549. # just try again
  550. if !fallback
  551. verify_task(params, true)
  552. else
  553. raise 'ERROR: ' + e.inspect
  554. end
  555. end
  556. true
  557. end
  558. =begin
  559. open_task(
  560. :browser => browser1,
  561. :data => {
  562. :title => 'some title',
  563. }
  564. )
  565. =end
  566. def open_task(params = {}, _fallback = false)
  567. log('open_task', params)
  568. instance = params[:browser] || @browser
  569. data = params[:data]
  570. element = instance.find_elements( { partial_link_text: data[:title] } )[0]
  571. if !element
  572. screenshot( browser: instance, comment: 'open_task_failed' )
  573. raise "no task with title '#{data[:title]}' found"
  574. end
  575. element.click
  576. true
  577. end
  578. =begin
  579. file_upload(
  580. :browser => browser1,
  581. :css => '#content .text-1',
  582. :value => 'some text',
  583. )
  584. =end
  585. def file_upload(params = {})
  586. log('file_upload', params)
  587. instance = params[:browser] || @browser
  588. filename = 'some-file.txt'
  589. file = File.join(Dir.pwd, filename)
  590. #file = 'some test lalal'
  591. instance.find_elements( { css: params[:css] } )[0].send_keys file
  592. #instance.find_elements( { :css => params[:css] } )[0]
  593. #element
  594. #@driver.find_element(id: 'file-submit').click
  595. end
  596. =begin
  597. watch_for(
  598. :browser => browser1,
  599. :css => '#content .text-1',
  600. :value => 'some text',
  601. :attribute => 'some_attribute' # optional
  602. :timeout => '16', # in sec, default 16
  603. )
  604. =end
  605. def watch_for(params = {})
  606. log('watch_for', params)
  607. instance = params[:browser] || @browser
  608. timeout = 16
  609. if params[:timeout]
  610. timeout = params[:timeout]
  611. end
  612. loops = (timeout).to_i * 2
  613. text = ''
  614. (1..loops).each { |loop|
  615. element = instance.find_elements( { css: params[:css] } )[0]
  616. if element #&& element.displayed?
  617. begin
  618. # match pn attribute
  619. if params[:attribute]
  620. text = element.attribute( params[:attribute] )
  621. elsif params[:css] =~ /(input|textarea)/i
  622. text = element.attribute('value')
  623. else
  624. text = element.text
  625. end
  626. if text =~ /#{params[:value]}/i
  627. assert( true, "'#{params[:value]}' found in '#{text}'" )
  628. sleep 0.5
  629. return true
  630. end
  631. rescue
  632. # try again
  633. end
  634. end
  635. sleep 0.5
  636. }
  637. screenshot( browser: instance, comment: 'watch_for_failed' )
  638. raise "'#{params[:value]}' found in '#{text}'"
  639. end
  640. =begin
  641. wait untill selector disabppears
  642. watch_for_disappear(
  643. :browser => browser1,
  644. :css => '#content .text-1',
  645. :timeout => '16', # in sec, default 16
  646. )
  647. wait untill text in selector disabppears
  648. watch_for_disappear(
  649. :browser => browser1,
  650. :css => '#content .text-1',
  651. :value => 'some value as regexp',
  652. :timeout => '16', # in sec, default 16
  653. )
  654. =end
  655. def watch_for_disappear(params = {})
  656. log('watch_for_disappear', params)
  657. instance = params[:browser] || @browser
  658. timeout = 16
  659. if params[:timeout]
  660. timeout = params[:timeout]
  661. end
  662. loops = (timeout).to_i
  663. text = ''
  664. (1..loops).each { |loop|
  665. element = instance.find_elements( { css: params[:css] } )[0]
  666. if !element #|| element.displayed?
  667. assert( true, 'not found' )
  668. sleep 1
  669. return true
  670. end
  671. if params[:value]
  672. begin
  673. text = instance.find_elements( { css: params[:css] } )[0].text
  674. if text !~ /#{params[:value]}/i
  675. assert( true, "not matching '#{params[:value]}' in text '#{text}'" )
  676. sleep 1
  677. return true
  678. end
  679. rescue
  680. # try again
  681. end
  682. end
  683. sleep 1
  684. }
  685. screenshot( browser: instance, comment: 'disappear_failed' )
  686. raise "#{params[:css]}) still exsists"
  687. end
  688. =begin
  689. tasks_close_all(
  690. :browser => browser1,
  691. :discard_changes => true,
  692. )
  693. =end
  694. def tasks_close_all(params = {})
  695. log('tasks_close_all', params)
  696. instance = params[:browser] || @browser
  697. (1..100).each do
  698. sleep 1
  699. begin
  700. if instance.find_elements( { css: '.navigation .tasks .task:first-child' } )[0]
  701. instance.mouse.move_to( instance.find_elements( { css: '.navigation .tasks .task:first-child' } )[0] )
  702. sleep 0.2
  703. click_element = instance.find_elements( { css: '.navigation .tasks .task:first-child .js-close' } )[0]
  704. if click_element
  705. sleep 0.1
  706. click_element.click
  707. # accept task close warning
  708. if params[:discard_changes]
  709. sleep 1
  710. instance.find_elements( { css: '.modal button.js-submit' } )[0].click
  711. end
  712. end
  713. else
  714. break
  715. end
  716. rescue
  717. # try again
  718. end
  719. end
  720. sleep 1
  721. assert( true, 'all tasks closed' )
  722. end
  723. =begin
  724. username = overview_create(
  725. :browser => browser1,
  726. :data => {
  727. :name => name,
  728. :link => name,
  729. :role => 'Agent',
  730. :prio => 1000,
  731. 'order::direction' => 'down',
  732. }
  733. )
  734. =end
  735. def overview_create(params)
  736. log('overview_create', params)
  737. instance = params[:browser] || @browser
  738. data = params[:data]
  739. instance.find_elements( { css: 'a[href="#manage"]' } )[0].click
  740. instance.find_elements( { css: 'a[href="#manage/overviews"]' } )[0].click
  741. sleep 0.2
  742. instance.find_elements( { css: '#content a[data-type="new"]' } )[0].click
  743. sleep 2
  744. if data[:name]
  745. element = instance.find_elements( { css: '.modal input[name=name]' } )[0]
  746. element.clear
  747. element.send_keys( data[:name] )
  748. end
  749. if data[:link]
  750. element = instance.find_elements( { css: '.modal input[name=link]' } )[0]
  751. element.clear
  752. element.send_keys( data[:link] )
  753. end
  754. if data[:role]
  755. element = instance.find_elements( { css: '.modal select[name="role_id"]' } )[0]
  756. dropdown = Selenium::WebDriver::Support::Select.new(element)
  757. dropdown.select_by( :text, data[:role])
  758. end
  759. if data[:prio]
  760. element = instance.find_elements( { css: '.modal input[name=prio]' } )[0]
  761. element.clear
  762. element.send_keys( data[:prio] )
  763. end
  764. if data['order::direction']
  765. element = instance.find_elements( { css: '.modal select[name="order::direction"]' } )[0]
  766. dropdown = Selenium::WebDriver::Support::Select.new(element)
  767. dropdown.select_by( :text, data['order::direction'])
  768. end
  769. instance.find_elements( { css: '.modal button.js-submit' } )[0].click
  770. (1..12).each {|loop|
  771. element = instance.find_elements( { css: 'body' } )[0]
  772. text = element.text
  773. if text =~ /#{Regexp.quote(data[:name])}/
  774. assert( true, 'overview created' )
  775. overview = {
  776. name: name,
  777. }
  778. return overview
  779. end
  780. sleep 1
  781. }
  782. screenshot( browser: instance, comment: 'overview_create_failed' )
  783. raise 'overview creation failed'
  784. end
  785. =begin
  786. ticket = ticket_create(
  787. :browser => browser1,
  788. :data => {
  789. :customer => 'nico',
  790. :group => 'Users',
  791. :title => 'overview #1',
  792. :body => 'overview #1',
  793. },
  794. :do_not_submit => true,
  795. )
  796. returns (in case of submitted)
  797. {
  798. :id => 123,
  799. :number => '100001',
  800. }
  801. =end
  802. def ticket_create(params)
  803. log('ticket_create', params)
  804. instance = params[:browser] || @browser
  805. data = params[:data]
  806. instance.find_elements( { css: 'a[href="#new"]' } )[0].click
  807. instance.find_elements( { css: 'a[href="#ticket/create"]' } )[0].click
  808. element = instance.find_elements( { css: '.active .newTicket' } )[0]
  809. if !element
  810. screenshot( browser: instance, comment: 'ticket_create_failed' )
  811. raise 'no ticket create screen found!'
  812. end
  813. sleep 1
  814. # check count of agents, should be only 1 / - selection on init screen
  815. count = instance.find_elements( { css: '.active .newTicket select[name="owner_id"] option' } ).count
  816. assert_equal( 1, count, 'check if owner selection is empty per default' )
  817. if data[:group]
  818. element = instance.find_elements( { css: '.active .newTicket select[name="group_id"]' } )[0]
  819. dropdown = Selenium::WebDriver::Support::Select.new(element)
  820. dropdown.select_by( :text, data[:group])
  821. sleep 0.2
  822. end
  823. if data[:title]
  824. element = instance.find_elements( { css: '.active .newTicket input[name="title"]' } )[0]
  825. element.clear
  826. element.send_keys( data[:title] )
  827. sleep 0.2
  828. end
  829. if data[:body]
  830. #instance.execute_script( '$(".active .newTicket div[data-name=body]").focus()' )
  831. sleep 0.5
  832. element = instance.find_elements( { css: '.active .newTicket div[data-name=body]' } )[0]
  833. element.clear
  834. element.send_keys( data[:body] )
  835. # it's not working stable via selenium, use js
  836. value = instance.find_elements( { css: '.content .newTicket div[data-name=body]' } )[0].text
  837. #puts "V #{value.inspect}"
  838. if value != data[:body]
  839. body_quoted = quote( data[:body] )
  840. instance.execute_script( "$('.content.active div[data-name=body]').html('#{body_quoted}').trigger('focusout')" )
  841. end
  842. end
  843. if data[:customer]
  844. element = instance.find_elements( { css: '.active .newTicket input[name="customer_id_completion"]' } )[0]
  845. element.click
  846. element.clear
  847. # workaround, sometimes focus is not triggered
  848. element.send_keys( data[:customer] )
  849. sleep 4
  850. # check if pulldown is open, it's not working stable via selenium
  851. res = instance.execute_script( "$('.active .newTicket .js-recipientDropdown').hasClass('open')" )
  852. #puts "res #{res.inspect}"
  853. if !res
  854. #puts "IS NOT OPEN!, open it"
  855. instance.execute_script( "$('.active .newTicket .js-recipientDropdown').addClass('open')" )
  856. end
  857. element.send_keys( :arrow_down )
  858. sleep 0.3
  859. instance.find_elements( { css: '.active .newTicket .recipientList-entry.js-user.is-active' } )[0].click
  860. sleep 0.3
  861. end
  862. if data[:attachment]
  863. file_upload(
  864. browser: instance,
  865. css: '#content .text-1',
  866. value: 'some text',
  867. )
  868. end
  869. if params[:do_not_submit]
  870. assert( true, 'ticket created without submit' )
  871. return
  872. end
  873. sleep 0.8
  874. #instance.execute_script( '$(".content.active .newTicket form").submit();' )
  875. instance.find_elements( { css: '.active .newTicket button.submit' } )[0].click
  876. sleep 1
  877. (1..10).each {|loop|
  878. if instance.current_url =~ /#{Regexp.quote('#ticket/zoom/')}/
  879. assert( true, 'ticket created' )
  880. sleep 2.5
  881. id = instance.current_url
  882. id.gsub!(//, )
  883. id.gsub!(%r{^.+?/(\d+)$}, '\\1')
  884. element = instance.find_elements( { css: '.active .page-header .ticket-number' } )[0]
  885. if element
  886. number = element.text
  887. ticket = {
  888. id: id,
  889. number: number,
  890. }
  891. sleep 3 # wait until notify is gone
  892. screenshot( browser: instance, comment: 'ticket_create_ok' )
  893. return ticket
  894. end
  895. end
  896. sleep 1
  897. }
  898. screenshot( browser: instance, comment: 'ticket_create_failed' )
  899. raise "ticket creation failed, can't get zoom url (current url is '#{ instance.current_url }')"
  900. end
  901. =begin
  902. ticket_update(
  903. :browser => browser1,
  904. :data => {
  905. :title => '',
  906. :customer => 'some_customer@example.com',
  907. :body => 'some body',
  908. :group => 'some group',
  909. :state => 'closed',
  910. },
  911. :do_not_submit => true,
  912. )
  913. =end
  914. def ticket_update(params)
  915. log('ticket_update', params)
  916. instance = params[:browser] || @browser
  917. data = params[:data]
  918. if data[:title]
  919. #element = instance.find_elements( { :css => '.content.active .page-header .ticket-title-update' } )[0]
  920. #element.clear
  921. #sleep 0.5
  922. #element = instance.find_elements( { :css => '.content.active .page-header .ticket-title-update' } )[0]
  923. #element.send_keys( data[:title] )
  924. #sleep 0.5
  925. #element.send_keys( :tab )
  926. instance.execute_script( '$(".content.active .page-header .ticket-title-update").focus()' )
  927. instance.execute_script( '$(".content.active .page-header .ticket-title-update").text("' + data[:title] + '")' )
  928. instance.execute_script( '$(".content.active .page-header .ticket-title-update").blur()' )
  929. instance.execute_script( '$(".content.active .page-header .ticket-title-update").trigger("blur")' )
  930. # {
  931. # :where => :instance2,
  932. # :execute => 'sendkey',
  933. # :css => '.content.active .page-header .ticket-title-update',
  934. # :value => 'TTT',
  935. # },
  936. # {
  937. # :where => :instance2,
  938. # :execute => 'sendkey',
  939. # :css => '.content.active .page-header .ticket-title-update',
  940. # :value => :tab,
  941. # },
  942. end
  943. if data[:customer]
  944. # select tab
  945. click( browser: instance, css: '.active .tabsSidebar-tab[data-tab="customer"]')
  946. click( browser: instance, css: '.active div[data-tab="customer"] .js-actions .select-arrow' )
  947. click( browser: instance, css: '.active div[data-tab="customer"] .js-actions a[data-type="customer-change"]' )
  948. watch_for(
  949. browser: instance,
  950. css: '.modal',
  951. value: 'change',
  952. )
  953. element = instance.find_elements( { css: '.modal input[name="customer_id_completion"]' } )[0]
  954. element.click
  955. element.clear
  956. # workaround, sometimes focus is not triggered
  957. element.send_keys( data[:customer] )
  958. sleep 4
  959. # check if pulldown is open, it's not working stable via selenium
  960. res = instance.execute_script( "$('.modal .user_autocompletion .js-recipientDropdown').hasClass('open')" )
  961. #puts "res #{res.inspect}"
  962. if !res
  963. #puts "IS NOT OPEN!, open it"
  964. instance.execute_script( "$('.modal .user_autocompletion .js-recipientDropdown').addClass('open')" )
  965. end
  966. element.send_keys( :arrow_down )
  967. sleep 0.3
  968. instance.find_elements( { css: '.modal .user_autocompletion .recipientList-entry.js-user.is-active' } )[0].click
  969. sleep 0.3
  970. click( browser: instance, css: '.modal .js-submit' )
  971. watch_for_disappear(
  972. browser: instance,
  973. css: '.modal',
  974. )
  975. watch_for(
  976. browser: instance,
  977. css: '.active .tabsSidebar',
  978. value: data[:customer],
  979. )
  980. # select tab
  981. click( browser: instance, css: '.active .tabsSidebar-tab[data-tab="ticket"]')
  982. end
  983. if data[:body]
  984. #instance.execute_script( '$(".content.active div[data-name=body]").focus()' )
  985. sleep 0.5
  986. element = instance.find_elements( { css: '.content.active div[data-name=body]' } )[0]
  987. element.clear
  988. element.send_keys( data[:body] )
  989. # it's not working stable via selenium, use js
  990. value = instance.find_elements( { css: '.content.active div[data-name=body]' } )[0].text
  991. puts "V #{value.inspect}"
  992. if value != data[:body]
  993. body_quoted = quote( data[:body] )
  994. instance.execute_script( "$('.content.active div[data-name=body]').html('#{body_quoted}').trigger('focusout')" )
  995. end
  996. end
  997. if data[:group]
  998. element = instance.find_elements( { css: '.active .sidebar select[name="group_id"]' } )[0]
  999. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1000. dropdown.select_by( :text, data[:group])
  1001. sleep 0.2
  1002. end
  1003. if data[:state]
  1004. element = instance.find_elements( { css: '.active .sidebar select[name="state_id"]' } )[0]
  1005. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1006. dropdown.select_by( :text, data[:state])
  1007. sleep 0.2
  1008. end
  1009. if data[:state] || data[:group] || data[:body]
  1010. found = nil
  1011. (1..5).each {|loop|
  1012. if !found
  1013. begin
  1014. text = instance.find_elements( { css: '.content.active .js-reset' } )[0].text
  1015. if text =~ /(Discard your unsaved changes.|Verwerfen der)/
  1016. found = true
  1017. end
  1018. rescue
  1019. # try again
  1020. end
  1021. sleep 1
  1022. end
  1023. }
  1024. if !found
  1025. screenshot( browser: instance, comment: 'ticket_update_discard_message_failed' )
  1026. raise 'no discard message found'
  1027. end
  1028. end
  1029. if params[:do_not_submit]
  1030. assert( true, 'ticket updated without submit' )
  1031. return true
  1032. end
  1033. instance.find_elements( { css: '.content.active button.js-submit' } )[0].click
  1034. (1..10).each {|loop|
  1035. begin
  1036. text = instance.find_elements( { css: '.content.active .js-reset' } )[0].text
  1037. if !text || text.empty?
  1038. screenshot( browser: instance, comment: 'ticket_update_ok' )
  1039. return true
  1040. end
  1041. rescue
  1042. # try again
  1043. end
  1044. sleep 1
  1045. }
  1046. screenshot( browser: instance, comment: 'ticket_update_failed' )
  1047. raise 'unable to update ticket'
  1048. end
  1049. =begin
  1050. ticket_verify(
  1051. :browser => browser1,
  1052. :data => {
  1053. :title => 'some title',
  1054. :body => 'some body',
  1055. ## :group => 'some group',
  1056. ## :state => 'closed',
  1057. },
  1058. )
  1059. =end
  1060. def ticket_verify(params)
  1061. log('ticket_verify', params)
  1062. instance = params[:browser] || @browser
  1063. data = params[:data]
  1064. if data[:title]
  1065. title = instance.find_elements( { css: '.content.active .page-header .ticket-title-update' } )[0].text.strip
  1066. if title =~ /#{data[:title]}/i
  1067. assert( true, "matching '#{data[:title]}' in title '#{title}'" )
  1068. else
  1069. raise "not matching '#{data[:title]}' in title '#{title}'"
  1070. end
  1071. end
  1072. if data[:body]
  1073. body = instance.find_elements( { css: '.content.active [data-name="body"]' } )[0].text.strip
  1074. if body =~ /#{data[:body]}/i
  1075. assert( true, "matching '#{data[:body]}' in body '#{body}'" )
  1076. else
  1077. raise "not matching '#{data[:body]}' in body '#{body}'"
  1078. end
  1079. end
  1080. true
  1081. end
  1082. =begin
  1083. ticket_open_by_overview(
  1084. :browser => browser2,
  1085. :number => ticket1[:number],
  1086. :link => '#ticket/view/' + name,
  1087. )
  1088. =end
  1089. def ticket_open_by_overview(params)
  1090. log('ticket_open_by_overview', params)
  1091. instance = params[:browser] || @browser
  1092. instance.find_elements( { css: '#navigation li.overviews a' } )[0].click
  1093. sleep 1
  1094. instance.find_elements( { css: ".content.active .sidebar a[href=\"#{params[:link]}\"]" } )[0].click
  1095. sleep 1
  1096. instance.find_elements( { partial_link_text: params[:number] } )[0].click
  1097. sleep 1
  1098. number = instance.find_elements( { css: '.active .page-header .ticket-number' } )[0].text
  1099. if number !~ /#{params[:number]}/
  1100. screenshot( browser: instance, comment: 'ticket_open_by_overview_failed' )
  1101. raise "unable to search/find ticket #{params[:number]}!"
  1102. end
  1103. sleep 1
  1104. assert( true, "ticket #{params[:number]} found" )
  1105. true
  1106. end
  1107. =begin
  1108. ticket_open_by_search(
  1109. :browser => browser2,
  1110. :number => ticket1[:number],
  1111. )
  1112. =end
  1113. def ticket_open_by_search(params)
  1114. log('ticket_open_by_search', params)
  1115. instance = params[:browser] || @browser
  1116. # search by number
  1117. element = instance.find_elements( { css: '#global-search' } )[0]
  1118. element.click
  1119. element.clear
  1120. element.send_keys( params[:number] )
  1121. sleep 3
  1122. # empty search box by x
  1123. instance.find_elements( { css: '.search .empty-search' } )[0].click
  1124. sleep 0.5
  1125. text = instance.find_elements( { css: '#global-search' } )[0].attribute('value')
  1126. if !text
  1127. raise '#global-search is not empty!'
  1128. end
  1129. # search by number again
  1130. element = instance.find_elements( { css: '#global-search' } )[0]
  1131. element.click
  1132. element.clear
  1133. element.send_keys( params[:number] )
  1134. sleep 1
  1135. # open ticket
  1136. instance.find_element( { partial_link_text: params[:number] } ).click
  1137. number = instance.find_elements( { css: '.active .page-header .ticket-number' } )[0].text
  1138. if number !~ /#{params[:number]}/
  1139. screenshot( browser: instance, comment: 'ticket_open_by_search_failed' )
  1140. raise "unable to search/find ticket #{params[:number]}!"
  1141. end
  1142. sleep 1
  1143. true
  1144. end
  1145. =begin
  1146. overview_count = overview_counter(
  1147. :browser => browser2,
  1148. )
  1149. returns
  1150. {
  1151. '#ticket/view/all_unassigned' => 42,
  1152. }
  1153. =end
  1154. def overview_counter(params = {})
  1155. log('overview_counter', params)
  1156. instance = params[:browser] || @browser
  1157. instance.find_elements( { css: '#navigation li.overviews a' } )[0].click
  1158. sleep 2
  1159. overviews = {}
  1160. instance.find_elements( { css: '.content.active .sidebar a[href]' } ).each {|element|
  1161. url = element.attribute('href')
  1162. url.gsub!(%r{(http|https)://.+?/(.+?)$}, '\\2')
  1163. overviews[url] = 0
  1164. #puts url.inspect
  1165. #puts element.inspect
  1166. }
  1167. overviews.each {|url, value|
  1168. count = instance.find_elements( { css: ".content.active .sidebar a[href=\"#{url}\"] .badge" } )[0].text
  1169. overviews[url] = count.to_i
  1170. }
  1171. overviews
  1172. end
  1173. =begin
  1174. organization_open_by_search(
  1175. :browser => browser2,
  1176. :value => 'some value',
  1177. )
  1178. =end
  1179. def organization_open_by_search(params = {})
  1180. log('organization_open_by_search', params)
  1181. instance = params[:browser] || @browser
  1182. element = instance.find_elements( { css: '#global-search' } )[0]
  1183. element.click
  1184. element.clear
  1185. element.send_keys( params[:value] )
  1186. sleep 3
  1187. instance.find_elements( { css: '.search .empty-search' } )[0].click
  1188. sleep 0.5
  1189. text = instance.find_elements( { css: '#global-search' } )[0].attribute('value')
  1190. if !text
  1191. raise '#global-search is not empty!'
  1192. end
  1193. element = instance.find_elements( { css: '#global-search' } )[0]
  1194. element.click
  1195. element.clear
  1196. element.send_keys( params[:value] )
  1197. sleep 2
  1198. instance.find_element( { partial_link_text: params[:value] } ).click
  1199. name = instance.find_elements( { css: '.active h1' } )[0].text
  1200. if name !~ /#{params[:value]}/
  1201. screenshot( browser: instance, comment: 'organization_open_by_search_failed' )
  1202. raise "unable to search/find org #{params[:value]}!"
  1203. end
  1204. assert( true, "org #{params[:value]} found" )
  1205. sleep 2
  1206. true
  1207. end
  1208. =begin
  1209. user_open_by_search(
  1210. :browser => browser2,
  1211. :value => 'some value',
  1212. )
  1213. =end
  1214. def user_open_by_search(params = {})
  1215. log('user_open_by_search', params)
  1216. instance = params[:browser] || @browser
  1217. element = instance.find_elements( { css: '#global-search' } )[0]
  1218. element.click
  1219. element.clear
  1220. element.send_keys( params[:value] )
  1221. sleep 3
  1222. instance.find_element( { partial_link_text: params[:value] } ).click
  1223. name = instance.find_elements( { css: '.active h1' } )[0].text
  1224. if name !~ /#{params[:value]}/
  1225. screenshot( browser: instance, comment: 'user_open_by_search_failed' )
  1226. raise "unable to search/find user #{params[:value]}!"
  1227. end
  1228. assert( true, "user #{params[:term]} found" )
  1229. sleep 2
  1230. true
  1231. end
  1232. =begin
  1233. user_create(
  1234. :browser => browser2,
  1235. :data => {
  1236. #:login => 'some login' + random,
  1237. :firstname => 'Manage Firstname' + random,
  1238. :lastname => 'Manage Lastname' + random,
  1239. :email => user_email,
  1240. :password => 'some-pass',
  1241. },
  1242. )
  1243. =end
  1244. def user_create(params = {})
  1245. log('user_create', params)
  1246. instance = params[:browser] || @browser
  1247. data = params[:data]
  1248. instance.find_elements( { css: 'a[href="#manage"]' } )[0].click
  1249. instance.find_elements( { css: 'a[href="#manage/users"]' } )[0].click
  1250. sleep 2
  1251. instance.find_elements( { css: 'a[data-type="new"]' } )[0].click
  1252. sleep 2
  1253. element = instance.find_elements( { css: '.modal input[name=firstname]' } )[0]
  1254. element.clear
  1255. element.send_keys( data[:firstname] )
  1256. element = instance.find_elements( { css: '.modal input[name=lastname]' } )[0]
  1257. element.clear
  1258. element.send_keys( data[:lastname] )
  1259. element = instance.find_elements( { css: '.modal input[name=email]' } )[0]
  1260. element.clear
  1261. element.send_keys( data[:email] )
  1262. element = instance.find_elements( { css: '.modal input[name=password]' } )[0]
  1263. element.clear
  1264. element.send_keys( data[:password] )
  1265. element = instance.find_elements( { css: '.modal input[name=password_confirm]' } )[0]
  1266. element.clear
  1267. element.send_keys( data[:password] )
  1268. instance.find_elements( { css: '.modal input[name="role_ids"][value="3"]' } )[0].click
  1269. instance.find_elements( { css: '.modal button.js-submit' } )[0].click
  1270. sleep 2
  1271. set(
  1272. browser: instance,
  1273. css: '.content .js-search',
  1274. value: data[:email],
  1275. )
  1276. watch_for(
  1277. browser: instance,
  1278. css: 'body',
  1279. value: data[:lastname],
  1280. )
  1281. assert( true, 'user created' )
  1282. end
  1283. =begin
  1284. sla_create(
  1285. :browser => browser2,
  1286. :data => {
  1287. :name => 'some sla' + random,
  1288. :first_response_time => 61
  1289. },
  1290. )
  1291. =end
  1292. def sla_create(params = {})
  1293. log('sla_create', params)
  1294. instance = params[:browser] || @browser
  1295. data = params[:data]
  1296. instance.find_elements( { css: 'a[href="#manage"]' } )[0].click
  1297. instance.find_elements( { css: 'a[href="#manage/slas"]' } )[0].click
  1298. sleep 2
  1299. instance.find_elements( { css: 'a[data-type="new"]' } )[0].click
  1300. sleep 2
  1301. element = instance.find_elements( { css: '.modal input[name=name]' } )[0]
  1302. element.clear
  1303. element.send_keys( data[:name] )
  1304. element = instance.find_elements( { css: '.modal input[name=first_response_time]' } )[0]
  1305. element.clear
  1306. element.send_keys( data[:first_response_time] )
  1307. instance.find_elements( { css: '.modal button.js-submit' } )[0].click
  1308. (1..8).each {|loop|
  1309. element = instance.find_elements( { css: 'body' } )[0]
  1310. text = element.text
  1311. if text =~ /#{Regexp.quote(data[:name])}/
  1312. assert( true, 'sla created' )
  1313. return true
  1314. end
  1315. sleep 1
  1316. }
  1317. screenshot( browser: instance, comment: 'sla_create_failed' )
  1318. raise 'sla creation failed'
  1319. end
  1320. =begin
  1321. text_module_create(
  1322. :browser => browser2,
  1323. :data => {
  1324. :name => 'some sla' + random,
  1325. :keywords => 'some keywords',
  1326. :content => 'some content',
  1327. },
  1328. )
  1329. =end
  1330. def text_module_create(params = {})
  1331. log('text_module_create', params)
  1332. instance = params[:browser] || @browser
  1333. data = params[:data]
  1334. instance.find_elements( { css: 'a[href="#manage"]' } )[0].click
  1335. instance.find_elements( { css: 'a[href="#manage/text_modules"]' } )[0].click
  1336. sleep 2
  1337. instance.find_elements( { css: 'a[data-type="new"]' } )[0].click
  1338. sleep 2
  1339. element = instance.find_elements( { css: '.modal input[name=name]' } )[0]
  1340. element.clear
  1341. element.send_keys( data[:name] )
  1342. element = instance.find_elements( { css: '.modal input[name=keywords]' } )[0]
  1343. element.clear
  1344. element.send_keys( data[:keywords] )
  1345. element = instance.find_elements( { css: '.modal textarea[name=content]' } )[0]
  1346. element.clear
  1347. element.send_keys( data[:content] )
  1348. instance.find_elements( { css: '.modal button.js-submit' } )[0].click
  1349. (1..8).each {|loop|
  1350. element = instance.find_elements( { css: 'body' } )[0]
  1351. text = element.text
  1352. if text =~ /#{Regexp.quote(data[:name])}/
  1353. assert( true, 'text module created' )
  1354. return true
  1355. end
  1356. sleep 1
  1357. }
  1358. screenshot( browser: instance, comment: 'text_module_create_failed' )
  1359. raise 'text module creation failed'
  1360. end
  1361. =begin
  1362. signature_create(
  1363. :browser => browser2,
  1364. :data => {
  1365. :name => 'some sla' + random,
  1366. :body => 'some body',
  1367. },
  1368. )
  1369. =end
  1370. def signature_create(params = {})
  1371. log('signature_create', params)
  1372. instance = params[:browser] || @browser
  1373. data = params[:data]
  1374. instance.find_elements( { css: 'a[href="#manage"]' } )[0].click
  1375. instance.find_elements( { css: 'a[href="#channels/email"]' } )[0].click
  1376. instance.find_elements( { css: 'a[href="#c-signature"]' } )[0].click
  1377. sleep 8
  1378. instance.find_elements( { css: '#content #c-signature a[data-type="new"]' } )[0].click
  1379. sleep 2
  1380. element = instance.find_elements( { css: '.modal input[name=name]' } )[0]
  1381. element.clear
  1382. element.send_keys( data[:name] )
  1383. element = instance.find_elements( { css: '.modal textarea[name=body]' } )[0]
  1384. element.clear
  1385. element.send_keys( data[:body] )
  1386. instance.find_elements( { css: '.modal button.js-submit' } )[0].click
  1387. (1..12).each {|loop|
  1388. element = instance.find_elements( { css: 'body' } )[0]
  1389. text = element.text
  1390. if text =~ /#{Regexp.quote(data[:name])}/
  1391. assert( true, 'signature created' )
  1392. return true
  1393. end
  1394. sleep 1
  1395. }
  1396. screenshot( browser: instance, comment: 'signature_create_failed' )
  1397. raise 'signature creation failed'
  1398. end
  1399. =begin
  1400. group_create(
  1401. :browser => browser2,
  1402. :data => {
  1403. :name => 'some sla' + random,
  1404. :signature => 'some signature bame',
  1405. :member => [
  1406. 'some_user_login',
  1407. ],
  1408. },
  1409. )
  1410. =end
  1411. def group_create(params = {})
  1412. log('group_create', params)
  1413. instance = params[:browser] || @browser
  1414. data = params[:data]
  1415. instance.find_elements( { css: 'a[href="#manage"]' } )[0].click
  1416. instance.find_elements( { css: 'a[href="#manage/groups"]' } )[0].click
  1417. sleep 2
  1418. instance.find_elements( { css: 'a[data-type="new"]' } )[0].click
  1419. sleep 2
  1420. element = instance.find_elements( { css: '.modal input[name=name]' } )[0]
  1421. element.clear
  1422. element.send_keys( data[:name] )
  1423. element = instance.find_elements( { css: '.modal select[name="email_address_id"]' } )[0]
  1424. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1425. dropdown.select_by( :index, 1 )
  1426. #dropdown.select_by( :text, action[:group])
  1427. if data[:signature]
  1428. element = instance.find_elements( { css: '.modal select[name="signature_id"]' } )[0]
  1429. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1430. dropdown.select_by( :text, data[:signature])
  1431. end
  1432. instance.find_elements( { css: '.modal button.js-submit' } )[0].click
  1433. (1..12).each {|loop|
  1434. element = instance.find_elements( { css: 'body' } )[0]
  1435. text = element.text
  1436. if text =~ /#{Regexp.quote(data[:name])}/
  1437. assert( true, 'group created' )
  1438. # add member
  1439. if data[:member]
  1440. data[:member].each {|login|
  1441. instance.find_elements( { css: 'a[href="#manage"]' } )[0].click
  1442. instance.find_elements( { css: 'a[href="#manage/users"]' } )[0].click
  1443. sleep 2
  1444. element = instance.find_elements( { css: '#content [name="search"]' } )[0]
  1445. element.clear
  1446. element.send_keys( login )
  1447. sleep 2
  1448. #instance.find_elements( { :css => '#content table [data-id]' } )[0].click
  1449. instance.execute_script( '$("#content table [data-id] td").first().click()' )
  1450. sleep 2
  1451. #instance.find_elements( { :css => 'label:contains(" ' + action[:name] + '")' } )[0].click
  1452. instance.execute_script( '$(\'label:contains(" ' + data[:name] + '")\').first().click()' )
  1453. instance.find_elements( { css: '.modal button.js-submit' } )[0].click
  1454. }
  1455. end
  1456. end
  1457. sleep 1
  1458. return true
  1459. }
  1460. screenshot( browser: instance, comment: 'group_create_failed' )
  1461. raise 'group creation failed'
  1462. end
  1463. def quote(string)
  1464. string_quoted = string
  1465. string_quoted.gsub!(/&/, '&amp;')
  1466. string_quoted.gsub!(/</, '&lt;')
  1467. string_quoted.gsub!(/>/, '&gt;')
  1468. string_quoted
  1469. end
  1470. def log(method, params)
  1471. return if !@@debug
  1472. puts "#{Time.zone.now}/#{method}: #{params.inspect}"
  1473. end
  1474. end