browser_test_helper.rb 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085
  1. ENV['RAILS_ENV'] = 'test'
  2. # rubocop:disable 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 profile
  11. browser_profile = nil
  12. if browser == 'firefox'
  13. browser_profile = Selenium::WebDriver::Firefox::Profile.new
  14. browser_profile['intl.locale.matchOS'] = false
  15. browser_profile['intl.accept_languages'] = 'en-US'
  16. browser_profile['general.useragent.locale'] = 'en-US'
  17. elsif browser == 'chrome'
  18. # profile are only working on remote selenium
  19. if ENV['REMOTE_URL']
  20. browser_profile = Selenium::WebDriver::Chrome::Profile.new
  21. browser_profile['intl.accept_languages'] = 'en'
  22. end
  23. end
  24. browser_profile
  25. end
  26. def browser_support_cookies
  27. if browser =~ /(internet_explorer|ie)/i
  28. return false
  29. end
  30. true
  31. end
  32. def browser_url
  33. ENV['BROWSER_URL'] || 'http://localhost:3000'
  34. end
  35. def browser_instance
  36. if !@browsers
  37. @browsers = {}
  38. end
  39. if !ENV['REMOTE_URL'] || ENV['REMOTE_URL'].empty?
  40. local_browser = Selenium::WebDriver.for(browser.to_sym, profile: profile)
  41. @browsers[local_browser.hash] = local_browser
  42. browser_instance_preferences(local_browser)
  43. return local_browser
  44. end
  45. # avoid "Cannot read property 'get_Current' of undefined" issues
  46. (1..5).each {|count|
  47. begin
  48. local_browser = browser_instance_remote
  49. break
  50. rescue
  51. wait_until_ready = rand(9) + 5
  52. sleep wait_until_ready
  53. log('browser_instance', { rescure: true, count: count, sleep: wait_until_ready })
  54. end
  55. }
  56. local_browser
  57. end
  58. def browser_instance_remote
  59. caps = Selenium::WebDriver::Remote::Capabilities.send(browser)
  60. if ENV['BROWSER_OS']
  61. caps.platform = ENV['BROWSER_OS']
  62. end
  63. if ENV['BROWSER_VERSION']
  64. caps.version = ENV['BROWSER_VERSION']
  65. end
  66. local_browser = Selenium::WebDriver.for(
  67. :remote,
  68. url: ENV['REMOTE_URL'],
  69. desired_capabilities: caps,
  70. )
  71. @browsers[local_browser.hash] = local_browser
  72. browser_instance_preferences(local_browser)
  73. # upload files from remote dir
  74. local_browser.file_detector = lambda do |args|
  75. str = args.first.to_s
  76. str if File.file?(str)
  77. end
  78. local_browser
  79. end
  80. def browser_instance_close(local_browser)
  81. return if !@browsers[local_browser.hash]
  82. @browsers.delete(local_browser.hash)
  83. local_browser.quit
  84. end
  85. def browser_instance_preferences(local_browser)
  86. local_browser.manage.window.resize_to(1024, 800)
  87. if ENV['REMOTE_URL'] !~ /saucelabs|(grid|ci)\.(zammad\.org|znuny\.com)/i
  88. if @browsers.count == 1
  89. local_browser.manage.window.move_to(0, 0)
  90. else
  91. local_browser.manage.window.move_to(1024, 0)
  92. end
  93. end
  94. local_browser.manage.timeouts.implicit_wait = 3 # seconds
  95. end
  96. def teardown
  97. return if !@browsers
  98. @browsers.each { |_hash, local_browser|
  99. screenshot(browser: local_browser, comment: 'teardown')
  100. browser_instance_close(local_browser)
  101. }
  102. end
  103. def screenshot(params)
  104. instance = params[:browser] || @browser
  105. comment = params[:comment] || ''
  106. filename = "tmp/#{Time.zone.now.strftime('screenshot_%Y_%m_%d__%H_%M_%S')}_#{comment}_#{instance.hash}.png"
  107. log('screenshot', { filename: filename })
  108. instance.save_screenshot(filename)
  109. end
  110. =begin
  111. username = login(
  112. browser: browser1,
  113. username: 'someuser',
  114. password: 'somepassword',
  115. url: 'some url', # optional
  116. remember_me: true, # optional
  117. auto_wizard: false, # optional, in case of auto wizard, skip login
  118. success: false, #optional
  119. )
  120. =end
  121. def login(params)
  122. switch_window_focus(params)
  123. log('login', params)
  124. instance = params[:browser] || @browser
  125. if params[:url]
  126. instance.get(params[:url])
  127. end
  128. # submit logs anyway
  129. instance.execute_script('App.Track.force()')
  130. element = instance.find_elements(css: '#login input[name="username"]')[0]
  131. if !element
  132. if params[:auto_wizard]
  133. watch_for(
  134. browser: instance,
  135. css: 'body',
  136. value: 'auto wizard is enabled',
  137. timeout: 10,
  138. )
  139. location(url: "#{browser_url}/#getting_started/auto_wizard")
  140. sleep 10
  141. login = instance.find_elements(css: '.user-menu .user a')[0].attribute('title')
  142. if login != params[:username]
  143. screenshot(browser: instance, comment: 'auto wizard login failed')
  144. raise 'auto wizard login failed'
  145. end
  146. assert(true, 'auto wizard login ok')
  147. clues_close(
  148. browser: instance,
  149. optional: true,
  150. )
  151. return
  152. end
  153. screenshot(browser: instance, comment: 'login_failed')
  154. raise 'No login box found'
  155. end
  156. screenshot(browser: instance, comment: 'login')
  157. element.clear
  158. element.send_keys(params[:username])
  159. element = instance.find_elements(css: '#login input[name="password"]')[0]
  160. element.clear
  161. element.send_keys(params[:password])
  162. if params[:remember_me]
  163. instance.find_elements(css: '#login .checkbox-replacement')[0].click
  164. end
  165. instance.find_elements(css: '#login button')[0].click
  166. sleep 4
  167. login_failed = false
  168. if !instance.find_elements(css: '.user-menu .user a')[0]
  169. login_failed = true
  170. else
  171. login = instance.find_elements(css: '.user-menu .user a')[0].attribute('title')
  172. if login != params[:username]
  173. login_failed = true
  174. end
  175. end
  176. if login_failed
  177. if params[:success] == false
  178. assert(true, 'login not successfull, like wanted')
  179. return true
  180. end
  181. screenshot(browser: instance, comment: 'login_failed')
  182. raise 'login failed'
  183. end
  184. if params[:success] == false
  185. raise 'login successfull but should not'
  186. end
  187. clues_close(
  188. browser: instance,
  189. optional: true,
  190. )
  191. screenshot(browser: instance, comment: 'login_ok')
  192. assert(true, 'login ok')
  193. login
  194. end
  195. =begin
  196. logout(
  197. browser: browser1
  198. )
  199. =end
  200. def logout(params = {})
  201. switch_window_focus(params)
  202. log('logout', params)
  203. instance = params[:browser] || @browser
  204. click(
  205. browser: instance,
  206. css: 'a[href="#current_user"]',
  207. mute_log: true,
  208. )
  209. click(
  210. browser: instance,
  211. css: 'a[href="#logout"]',
  212. mute_log: true,
  213. )
  214. (1..6).each {
  215. sleep 1
  216. login = instance.find_elements(css: '#login')[0]
  217. next if !login
  218. screenshot(browser: instance, comment: 'logout_ok')
  219. assert(true, 'logout ok')
  220. return
  221. }
  222. screenshot(browser: instance, comment: 'logout_failed')
  223. raise 'no login box found, seems logout was not successfully!'
  224. end
  225. =begin
  226. clues_close(
  227. browser: browser1,
  228. optional: false,
  229. )
  230. =end
  231. def clues_close(params = {})
  232. switch_window_focus(params)
  233. log('clues_close', params)
  234. instance = params[:browser] || @browser
  235. clues = instance.find_elements(css: '.js-modal--clue .js-close')[0]
  236. if !params[:optional] && !clues
  237. screenshot(browser: instance, comment: 'no_clues')
  238. raise 'Unable to closes clues, no clues found!'
  239. end
  240. return if !clues
  241. instance.execute_script("$('.js-modal--clue .js-close').click()")
  242. assert(true, 'clues closed')
  243. sleep 1
  244. end
  245. =begin
  246. location(
  247. browser: browser1,
  248. url: 'http://someurl',
  249. )
  250. =end
  251. def location(params)
  252. switch_window_focus(params)
  253. log('location', params)
  254. instance = params[:browser] || @browser
  255. instance.get(params[:url])
  256. # check if reload was successfull
  257. if !instance.find_elements(css: 'body')[0] || instance.find_elements(css: 'body')[0].text =~ /unavailable or too busy/i
  258. instance.navigate.refresh
  259. end
  260. screenshot(browser: instance, comment: 'location')
  261. end
  262. =begin
  263. location_check(
  264. browser: browser1,
  265. url: 'http://someurl',
  266. )
  267. =end
  268. def location_check(params)
  269. switch_window_focus(params)
  270. log('location_check', params)
  271. instance = params[:browser] || @browser
  272. sleep 0.7
  273. current_url = instance.current_url
  274. if current_url !~ /#{Regexp.quote(params[:url])}/
  275. screenshot(browser: instance, comment: 'location_check_failed')
  276. raise "url #{current_url} is not matching #{params[:url]}"
  277. end
  278. assert(true, "url #{current_url} is matching #{params[:url]}")
  279. end
  280. =begin
  281. reload(
  282. browser: browser1,
  283. )
  284. =end
  285. def reload(params = {})
  286. switch_window_focus(params)
  287. log('reload', params)
  288. instance = params[:browser] || @browser
  289. screenshot(browser: instance, comment: 'reload_before')
  290. instance.navigate.refresh
  291. # check if reload was successfull
  292. if !instance.find_elements(css: 'body')[0] || instance.find_elements(css: 'body')[0].text =~ /unavailable or too busy/i
  293. instance.navigate.refresh
  294. end
  295. screenshot(browser: instance, comment: 'reload_after')
  296. end
  297. =begin
  298. click(
  299. browser: browser1,
  300. css: '.some_class',
  301. fast: false, # do not wait
  302. wait: 1, # wait 1 sec.
  303. )
  304. click(
  305. browser: browser1,
  306. text: '.partial_link_text',
  307. fast: false, # do not wait
  308. wait: 1, # wait 1 sec.
  309. )
  310. =end
  311. def click(params)
  312. switch_window_focus(params)
  313. log('click', params)
  314. instance = params[:browser] || @browser
  315. if params[:css]
  316. begin
  317. element = instance.find_elements(css: params[:css])[0]
  318. #if element
  319. # instance.mouse.move_to(element)
  320. #end
  321. element.click
  322. rescue => e
  323. sleep 0.5
  324. # just try again
  325. log('click', { rescure: true })
  326. element = instance.find_elements(css: params[:css])[0]
  327. #if element
  328. # instance.mouse.move_to(element)
  329. #end
  330. element.click
  331. end
  332. else
  333. sleep 0.5
  334. begin
  335. instance.find_elements(partial_link_text: params[:text])[0].click
  336. rescue => e
  337. sleep 0.5
  338. # just try again
  339. log('click', { rescure: true })
  340. instance.find_elements(partial_link_text: params[:text])[0].click
  341. end
  342. end
  343. sleep 0.2 if !params[:fast]
  344. sleep params[:wait] if params[:wait]
  345. end
  346. =begin
  347. scroll_to(
  348. browser: browser1,
  349. position: 'top', # botton
  350. css: '.some_class',
  351. )
  352. =end
  353. def scroll_to(params)
  354. switch_window_focus(params)
  355. log('scroll_to', params)
  356. instance = params[:browser] || @browser
  357. position = 'true'
  358. if params[:position] == 'botton'
  359. position = 'false'
  360. end
  361. execute(
  362. browser: instance,
  363. js: "\$('#{params[:css]}').get(0).scrollIntoView(#{position})",
  364. mute_log: params[:mute_log]
  365. )
  366. sleep 0.3
  367. end
  368. =begin
  369. modal_ready(
  370. browser: browser1,
  371. )
  372. =end
  373. def modal_ready(params = {})
  374. switch_window_focus(params)
  375. log('modal_ready', params)
  376. instance = params[:browser] || @browser
  377. sleep 2
  378. end
  379. =begin
  380. execute(
  381. browser: browser1,
  382. js: '.some_class',
  383. )
  384. =end
  385. def execute(params)
  386. switch_window_focus(params)
  387. log('js', params)
  388. instance = params[:browser] || @browser
  389. if params[:js]
  390. return instance.execute_script(params[:js])
  391. end
  392. raise "Invalid execute params #{params.inspect}"
  393. end
  394. =begin
  395. exists(
  396. browser: browser1,
  397. css: '.some_class',
  398. )
  399. =end
  400. def exists(params)
  401. switch_window_focus(params)
  402. log('exists', params)
  403. instance = params[:browser] || @browser
  404. if !instance.find_elements(css: params[:css])[0]
  405. screenshot(browser: instance, comment: 'exists_failed')
  406. raise "#{params[:css]} dosn't exist, but should"
  407. end
  408. true
  409. end
  410. =begin
  411. exists_not(
  412. browser: browser1,
  413. css: '.some_class',
  414. )
  415. =end
  416. def exists_not(params)
  417. switch_window_focus(params)
  418. log('exists_not', params)
  419. instance = params[:browser] || @browser
  420. if instance.find_elements(css: params[:css])[0]
  421. screenshot(browser: instance, comment: 'exists_not_failed')
  422. raise "#{params[:css]} exists but should not"
  423. end
  424. true
  425. end
  426. =begin
  427. set(
  428. browser: browser1,
  429. css: '.some_class',
  430. value: true,
  431. slow: false,
  432. blur: true,
  433. clear: true, # todo | default: true
  434. no_click: true,
  435. )
  436. =end
  437. def set(params)
  438. switch_window_focus(params)
  439. log('set', params)
  440. instance = params[:browser] || @browser
  441. element = instance.find_elements(css: params[:css])[0]
  442. if !params[:no_click]
  443. element.click
  444. end
  445. element.clear
  446. if !params[:slow]
  447. element.send_keys(params[:value])
  448. else
  449. element.send_keys('')
  450. keys = params[:value].to_s.split('')
  451. keys.each {|key|
  452. instance.action.send_keys(key).perform
  453. }
  454. end
  455. if params[:blur]
  456. instance.execute_script("$('#{params[:css]}').blur()")
  457. end
  458. sleep 0.2
  459. end
  460. =begin
  461. select(
  462. browser: browser1,
  463. css: '.some_class',
  464. value: 'Some Value',
  465. deselect_all: false, # default false
  466. )
  467. =end
  468. def select(params)
  469. switch_window_focus(params)
  470. log('select', params)
  471. instance = params[:browser] || @browser
  472. # searchable select
  473. element = instance.find_elements(css: "#{params[:css]}.js-shadow")[0]
  474. if element
  475. element = instance.find_elements(css: "#{params[:css]}.js-shadow + .js-input")[0]
  476. element.click
  477. element.clear
  478. sleep 0.4
  479. element.send_keys(params[:value])
  480. sleep 0.2
  481. element.send_keys(:enter)
  482. sleep 0.2
  483. return
  484. end
  485. # native select
  486. begin
  487. element = instance.find_elements(css: params[:css])[0]
  488. dropdown = Selenium::WebDriver::Support::Select.new(element)
  489. if params[:deselect_all]
  490. dropdown.deselect_all
  491. end
  492. dropdown.select_by(:text, params[:value])
  493. #puts "select - #{params.inspect}"
  494. rescue
  495. sleep 0.4
  496. # just try again
  497. log('select', { rescure: true })
  498. element = instance.find_elements(css: params[:css])[0]
  499. dropdown = Selenium::WebDriver::Support::Select.new(element)
  500. if params[:deselect_all]
  501. dropdown.deselect_all
  502. end
  503. dropdown.select_by(:text, params[:value])
  504. #puts "select2 - #{params.inspect}"
  505. end
  506. sleep 0.4
  507. end
  508. =begin
  509. switch(
  510. browser: browser1,
  511. css: '.some_class',
  512. type: 'on', # 'off'
  513. )
  514. =end
  515. def switch(params)
  516. switch_window_focus(params)
  517. log('switch', params)
  518. instance = params[:browser] || @browser
  519. element = instance.find_elements(css: "#{params[:css]} input[type=checkbox]")[0]
  520. checked = element.attribute('checked')
  521. if !checked
  522. if params[:type] == 'on'
  523. instance.find_elements(css: "#{params[:css]} label")[0].click
  524. end
  525. elsif params[:type] == 'off'
  526. instance.find_elements(css: "#{params[:css]} label")[0].click
  527. end
  528. end
  529. =begin
  530. check(
  531. browser: browser1,
  532. css: '.some_class',
  533. )
  534. =end
  535. def check(params)
  536. switch_window_focus(params)
  537. log('check', params)
  538. instance = params[:browser] || @browser
  539. instance.execute_script("if (!$('#{params[:css]}').prop('checked')) { $('#{params[:css]}').click() }")
  540. #element = instance.find_elements(css: params[:css])[0]
  541. #checked = element.attribute('checked')
  542. #element.click if !checked
  543. end
  544. =begin
  545. uncheck(
  546. browser: browser1,
  547. css: '.some_class',
  548. )
  549. =end
  550. def uncheck(params)
  551. switch_window_focus(params)
  552. log('uncheck', params)
  553. instance = params[:browser] || @browser
  554. instance.execute_script("if ($('#{params[:css]}').prop('checked')) { $('#{params[:css]}').click() }")
  555. #element = instance.find_elements(css: params[:css])[0]
  556. #checked = element.attribute('checked')
  557. #element.click if checked
  558. end
  559. =begin
  560. sendkey(
  561. browser: browser1,
  562. value: :enter,
  563. slow: false,
  564. )
  565. =end
  566. def sendkey(params)
  567. switch_window_focus(params)
  568. log('sendkey', params)
  569. instance = params[:browser] || @browser
  570. if params[:value].class == Array
  571. params[:value].each {|key|
  572. instance.action.send_keys(key).perform
  573. }
  574. return
  575. end
  576. instance.action.send_keys(params[:value]).perform
  577. if params[:slow]
  578. sleep 1.5
  579. else
  580. sleep 0.2
  581. end
  582. end
  583. =begin
  584. match(
  585. browser: browser1,
  586. css: '#content .text-1',
  587. value: 'some test for browser and some other for browser',
  588. attribute: 'some_attribute', # match on attribute
  589. should_not_match: true,
  590. no_quote: false, # use regex
  591. )
  592. =end
  593. def match(params, fallback = false)
  594. switch_window_focus(params)
  595. log('match', params)
  596. instance = params[:browser] || @browser
  597. element = instance.find_elements(css: params[:css])[0]
  598. if params[:css] =~ /select/
  599. dropdown = Selenium::WebDriver::Support::Select.new(element)
  600. success = false
  601. if dropdown.selected_options
  602. dropdown.selected_options.each {|option|
  603. if option.text == params[:value]
  604. success = true
  605. end
  606. }
  607. end
  608. if params[:should_not_match]
  609. if success
  610. raise "should not match '#{params[:value]}' in select list, but is matching"
  611. end
  612. elsif !success
  613. raise "not matching '#{params[:value]}' in select list"
  614. end
  615. return true
  616. end
  617. # match on attribute
  618. begin
  619. text = if params[:attribute]
  620. element.attribute(params[:attribute])
  621. elsif params[:css] =~ /(input|textarea)/i
  622. element.attribute('value')
  623. else
  624. element.text
  625. end
  626. rescue => e
  627. # just try again
  628. if !fallback
  629. return match(params, true)
  630. end
  631. raise e.inspect
  632. end
  633. # do cleanups (needed for richtext tests)
  634. if params[:cleanup]
  635. text.gsub!(/\s+$/m, '')
  636. params[:value].gsub!(/\s+$/m, '')
  637. end
  638. match = false
  639. if params[:no_quote]
  640. #puts "aaaa #{text}/#{params[:value]}"
  641. if text =~ /#{params[:value]}/i
  642. match = $1 || true
  643. end
  644. elsif text =~ /#{Regexp.quote(params[:value])}/i
  645. match = true
  646. end
  647. if match
  648. if params[:should_not_match]
  649. raise "matching '#{params[:value]}' in content '#{text}' but should not!"
  650. end
  651. elsif !params[:should_not_match]
  652. raise "not matching '#{params[:value]}' in content '#{text}' but should!"
  653. end
  654. sleep 0.2
  655. match
  656. end
  657. =begin
  658. match_not(
  659. browser: browser1,
  660. css: '#content .text-1',
  661. value: 'some test for browser and some other for browser',
  662. attribute: 'some_attribute', # match on attribute
  663. should_not_match: true,
  664. no_quote: false, # use regex
  665. )
  666. =end
  667. def match_not(params)
  668. switch_window_focus(params)
  669. log('match_not', params)
  670. params[:should_not_match] = true
  671. match(params)
  672. end
  673. =begin
  674. task_type(
  675. browser: browser1,
  676. type: 'stayOnTab',
  677. )
  678. =end
  679. def task_type(params)
  680. switch_window_focus(params)
  681. log('task_type', params)
  682. instance = params[:browser] || @browser
  683. if params[:type]
  684. instance.find_elements(css: '.content.active .js-secondaryActionButtonLabel')[0].click
  685. instance.find_elements(css: ".content.active .js-secondaryActionLabel[data-type=#{params[:type]}]")[0].click
  686. return
  687. end
  688. raise "Unknown params for task_type: #{params.inspect}"
  689. end
  690. =begin
  691. cookie(
  692. browser: browser1,
  693. name: '^_zammad.+?',
  694. value: '.+?',
  695. expires: nil,
  696. )
  697. cookie(
  698. browser: browser1,
  699. name: '^_zammad.+?',
  700. should_not_exist: true,
  701. )
  702. =end
  703. def cookie(params)
  704. switch_window_focus(params)
  705. log('cookie', params)
  706. instance = params[:browser] || @browser
  707. if !browser_support_cookies
  708. assert(true, "'#{params[:value]}' ups browser is not supporting reading cookies, go ahead")
  709. return true
  710. end
  711. cookies = instance.manage.all_cookies
  712. cookies.each {|cookie|
  713. #puts "CCC #{cookie.inspect}"
  714. # :name=>"_zammad_session_c25832f4de2", :value=>"adc31cd21615cb0a7ab269184ec8b76f", :path=>"/", :domain=>"localhost", :expires=>nil, :secure=>false}
  715. next if cookie[:name] !~ /#{params[:name]}/i
  716. if params.key?(:value) && cookie[:value].to_s =~ /#{params[:value]}/i
  717. assert(true, "matching value '#{params[:value]}' in cookie '#{cookie}'")
  718. else
  719. raise "not matching value '#{params[:value]}' in cookie '#{cookie}'"
  720. end
  721. if params.key?(:expires) && cookie[:expires].to_s =~ /#{params[:expires]}/i
  722. assert(true, "matching expires '#{params[:expires].inspect}' in cookie '#{cookie}'")
  723. else
  724. raise "not matching expires '#{params[:expires]}' in cookie '#{cookie}'"
  725. end
  726. return if !params[:should_not_exist]
  727. raise "cookie with name '#{params[:name]}' should not exist, but exists '#{cookies}'"
  728. }
  729. if params[:should_not_exist]
  730. assert(true, "cookie with name '#{params[:name]}' is not existing")
  731. return
  732. end
  733. raise "not matching name '#{params[:name]}' in cookie '#{cookies}'"
  734. end
  735. =begin
  736. verify_title(
  737. browser: browser1,
  738. value: 'some title',
  739. )
  740. =end
  741. def verify_title(params = {})
  742. switch_window_focus(params)
  743. log('verify_title', params)
  744. instance = params[:browser] || @browser
  745. title = instance.title
  746. if title =~ /#{params[:value]}/i
  747. assert(true, "matching '#{params[:value]}' in title '#{title}'")
  748. else
  749. raise "not matching '#{params[:value]}' in title '#{title}'"
  750. end
  751. end
  752. =begin
  753. verify_task(
  754. browser: browser1,
  755. data: {
  756. title: 'some title',
  757. modified: true, # optional
  758. }
  759. )
  760. =end
  761. def verify_task(params = {}, fallback = false)
  762. switch_window_focus(params)
  763. log('verify_task', params)
  764. instance = params[:browser] || @browser
  765. data = params[:data]
  766. sleep 1
  767. begin
  768. # verify title
  769. if data[:title]
  770. title = instance.find_elements(css: '.tasks .is-active')[0].text.strip
  771. if title =~ /#{data[:title]}/i
  772. assert(true, "matching '#{data[:title]}' in title '#{title}'")
  773. else
  774. raise "not matching '#{data[:title]}' in title '#{title}'"
  775. end
  776. end
  777. puts "tv #{params.inspect}"
  778. # verify modified
  779. if data.key?(:modified)
  780. exists = instance.find_elements(css: '.tasks .is-active')[0]
  781. is_modified = instance.find_elements(css: '.tasks .is-modified')[0]
  782. puts "m #{data[:modified].inspect}"
  783. if exists
  784. puts ' exists'
  785. end
  786. if is_modified
  787. puts ' is_modified'
  788. end
  789. if data[:modified] == true
  790. if is_modified
  791. assert(true, "task '#{data[:title]}' is modifed")
  792. elsif !exists
  793. raise "task '#{data[:title]}' not exists, should not modified"
  794. else
  795. raise "task '#{data[:title]}' is not modifed"
  796. end
  797. elsif !is_modified
  798. assert(true, "task '#{data[:title]}' is modifed")
  799. elsif !exists
  800. raise "task '#{data[:title]}' not exists, should be not modified"
  801. else
  802. raise "task '#{data[:title]}' is modifed, but should not"
  803. end
  804. end
  805. rescue => e
  806. # just try again
  807. if !fallback
  808. verify_task(params, true)
  809. end
  810. raise 'ERROR: ' + e.inspect
  811. end
  812. true
  813. end
  814. =begin
  815. open_task(
  816. browser: browser1,
  817. data: {
  818. title: 'some title',
  819. }
  820. )
  821. =end
  822. def open_task(params = {})
  823. switch_window_focus(params)
  824. log('open_task', params)
  825. instance = params[:browser] || @browser
  826. data = params[:data]
  827. element = instance.find_elements(partial_link_text: data[:title])[0]
  828. if !element
  829. screenshot(browser: instance, comment: 'open_task_failed')
  830. raise "no task with title '#{data[:title]}' found"
  831. end
  832. element.click
  833. true
  834. end
  835. =begin
  836. close_task(
  837. browser: browser1,
  838. data: {
  839. title: 'some title',
  840. },
  841. discard_changes: true,
  842. )
  843. =end
  844. def close_task(params = {})
  845. switch_window_focus(params)
  846. log('close_task', params)
  847. instance = params[:browser] || @browser
  848. data = params[:data]
  849. element = instance.find_elements(partial_link_text: data[:title])[0]
  850. if !element
  851. screenshot(browser: instance, comment: 'close_task_failed')
  852. raise "no task with title '#{data[:title]}' found"
  853. end
  854. instance.mouse.move_to(element)
  855. sleep 0.1
  856. instance.execute_script("$('.navigation .tasks .task:contains(\"#{data[:title]}\") .js-close').click()")
  857. # accept task close warning
  858. if params[:discard_changes]
  859. modal_ready()
  860. instance.find_elements(css: '.modal button.js-submit')[0].click
  861. end
  862. true
  863. end
  864. =begin
  865. file_upload(
  866. browser: browser1,
  867. css: '.active .attachmentPlaceholder-inputHolder input'
  868. files: ['path/in/home/some_file.ext'], # 'test/fixtures/test1.pdf'
  869. )
  870. =end
  871. def file_upload(params = {})
  872. switch_window_focus(params)
  873. log('file_upload', params)
  874. instance = params[:browser] || @browser
  875. params[:files].each {|file|
  876. instance.find_elements(css: params[:css])[0].send_keys "#{Rails.root}/#{file}"
  877. }
  878. sleep 2 * params[:files].count
  879. end
  880. =begin
  881. watch_for(
  882. browser: browser1,
  883. css: '#content .text-1',
  884. value: 'some text',
  885. attribute: 'some_attribute' # optional
  886. timeout: 16, # in sec, default 16
  887. )
  888. =end
  889. def watch_for(params = {})
  890. switch_window_focus(params)
  891. log('watch_for', params)
  892. instance = params[:browser] || @browser
  893. timeout = 16
  894. if params[:timeout]
  895. timeout = params[:timeout]
  896. end
  897. loops = timeout.to_i * 2
  898. text = ''
  899. (1..loops).each {
  900. element = instance.find_elements(css: params[:css])[0]
  901. if element #&& element.displayed?
  902. begin
  903. # match pn attribute
  904. text = if params[:attribute]
  905. element.attribute(params[:attribute])
  906. elsif params[:css] =~ /(input|textarea)/i
  907. element.attribute('value')
  908. else
  909. element.text
  910. end
  911. if text =~ /#{params[:value]}/i
  912. assert(true, "'#{params[:value]}' found in '#{text}'")
  913. sleep 0.5
  914. return true
  915. end
  916. rescue
  917. # try again
  918. end
  919. end
  920. sleep 0.5
  921. }
  922. screenshot(browser: instance, comment: 'watch_for_failed')
  923. raise "'#{params[:value]}' found in '#{text}'"
  924. end
  925. =begin
  926. wait untill selector disabppears
  927. watch_for_disappear(
  928. browser: browser1,
  929. css: '#content .text-1',
  930. timeout: 16, # in sec, default 16
  931. )
  932. wait untill text in selector disabppears
  933. watch_for_disappear(
  934. browser: browser1,
  935. css: '#content .text-1',
  936. value: 'some value as regexp',
  937. timeout: 16, # in sec, default 16
  938. )
  939. =end
  940. def watch_for_disappear(params = {})
  941. switch_window_focus(params)
  942. log('watch_for_disappear', params)
  943. instance = params[:browser] || @browser
  944. timeout = 16
  945. if params[:timeout]
  946. timeout = params[:timeout]
  947. end
  948. loops = timeout.to_i
  949. text = ''
  950. (1..loops).each {
  951. element = instance.find_elements(css: params[:css])[0]
  952. if !element #|| element.displayed?
  953. assert(true, 'not found')
  954. sleep 1
  955. return true
  956. end
  957. if params[:value]
  958. begin
  959. text = instance.find_elements(css: params[:css])[0].text
  960. if text !~ /#{params[:value]}/i
  961. assert(true, "not matching '#{params[:value]}' in text '#{text}'")
  962. sleep 1
  963. return true
  964. end
  965. rescue
  966. # try again
  967. end
  968. end
  969. sleep 1
  970. }
  971. screenshot(browser: instance, comment: 'disappear_failed')
  972. raise "#{params[:css]}) still exsists"
  973. end
  974. =begin
  975. shortcut(
  976. browser: browser1,
  977. key: 'x',
  978. )
  979. =end
  980. def shortcut(params = {})
  981. switch_window_focus(params)
  982. log('shortcut', params)
  983. instance = params[:browser] || @browser
  984. instance.action.key_down(:control)
  985. .key_down(:alt)
  986. .send_keys(params[:key])
  987. .key_up(:alt)
  988. .key_up(:control)
  989. .perform
  990. end
  991. =begin
  992. window_keys(
  993. browser: browser1,
  994. value: 'x',
  995. )
  996. =end
  997. def window_keys(params = {})
  998. switch_window_focus(params)
  999. log('window_keys', params)
  1000. instance = params[:browser] || @browser
  1001. instance.action.send_keys(params[:value]).perform
  1002. end
  1003. =begin
  1004. tasks_close_all(
  1005. browser: browser1,
  1006. )
  1007. =end
  1008. def tasks_close_all(params = {})
  1009. switch_window_focus(params)
  1010. log('tasks_close_all', params)
  1011. instance = params[:browser] || @browser
  1012. (1..100).each do
  1013. #sleep 0.5
  1014. begin
  1015. if instance.find_elements(css: '.navigation .tasks .task:first-child')[0]
  1016. instance.mouse.move_to(instance.find_elements(css: '.navigation .tasks .task:first-child')[0])
  1017. sleep 0.1
  1018. click_element = instance.find_elements(css: '.navigation .tasks .task:first-child .js-close')[0]
  1019. if click_element
  1020. click_element.click
  1021. # accept task close warning
  1022. if instance.find_elements(css: '.modal button.js-submit')[0]
  1023. sleep 0.4
  1024. instance.find_elements(css: '.modal button.js-submit')[0].click
  1025. end
  1026. end
  1027. else
  1028. break
  1029. end
  1030. rescue
  1031. # try again
  1032. end
  1033. end
  1034. assert(true, 'all tasks closed')
  1035. end
  1036. =begin
  1037. close_online_notitifcation(
  1038. browser: browser1,
  1039. data: {
  1040. #title: 'some title',
  1041. position: 3,
  1042. },
  1043. )
  1044. =end
  1045. def close_online_notitifcation(params = {})
  1046. switch_window_focus(params)
  1047. log('close_online_notitifcation', params)
  1048. instance = params[:browser] || @browser
  1049. data = params[:data]
  1050. if data[:title]
  1051. element = instance.find_elements(partial_link_text: data[:title])[0]
  1052. if !element
  1053. screenshot(browser: instance, comment: 'close_online_notitifcation')
  1054. raise "no online notification with title '#{data[:title]}' found"
  1055. end
  1056. instance.mouse.move_to(element)
  1057. sleep 0.1
  1058. instance.execute_script("$('.js-notificationsContainer .js-items .js-item .activity-text:contains(\"#{data[:title]}\") .js-remove').first().click()")
  1059. else
  1060. css = ".js-notificationsContainer .js-items .js-item:nth-child(#{data[:position]})"
  1061. element = instance.find_elements(css: css)[0]
  1062. if !element
  1063. screenshot(browser: instance, comment: 'close_online_notitifcation')
  1064. raise "no online notification with postion '#{css}' found"
  1065. end
  1066. instance.mouse.move_to(element)
  1067. sleep 0.1
  1068. instance.find_elements(css: "#{css} .js-remove")[0].click
  1069. end
  1070. true
  1071. end
  1072. =begin
  1073. online_notitifcation_close_all(
  1074. browser: browser1,
  1075. )
  1076. =end
  1077. def online_notitifcation_close_all(params = {})
  1078. switch_window_focus(params)
  1079. log('online_notitifcation_close_all', params)
  1080. instance = params[:browser] || @browser
  1081. (1..100).each do
  1082. sleep 0.5
  1083. begin
  1084. if instance.find_elements(css: '.js-notificationsContainer .js-item:first-child')[0]
  1085. instance.mouse.move_to(instance.find_elements(css: '.js-notificationsContainer .js-item:first-child')[0])
  1086. sleep 0.1
  1087. click_element = instance.find_elements(css: '.js-notificationsContainer .js-item:first-child .js-remove')[0]
  1088. if click_element
  1089. click_element.click
  1090. end
  1091. else
  1092. break
  1093. end
  1094. rescue
  1095. # try again
  1096. end
  1097. end
  1098. assert(true, 'all online notification closed')
  1099. end
  1100. =begin
  1101. empty_search(
  1102. browser: browser1,
  1103. )
  1104. =end
  1105. def empty_search(params = {})
  1106. switch_window_focus(params)
  1107. log('empty_search', params)
  1108. instance = params[:browser] || @browser
  1109. # empty search box by x
  1110. begin
  1111. instance.find_elements(css: '.search .empty-search')[0].click
  1112. rescue
  1113. # in issues with ff & selenium, sometimes exeption appears
  1114. # "Element is not currently visible and so may not be interacted with"
  1115. log('empty_search via js')
  1116. instance.execute_script('$(".search .empty-search").click()')
  1117. end
  1118. sleep 0.5
  1119. text = instance.find_elements(css: '#global-search')[0].attribute('value')
  1120. if !text
  1121. raise '#global-search is not empty!'
  1122. end
  1123. true
  1124. end
  1125. =begin
  1126. ticket_customer_select(
  1127. browser: browser1,
  1128. css: '#content .text-1',
  1129. customer: '',
  1130. )
  1131. =end
  1132. def ticket_customer_select(params = {})
  1133. switch_window_focus(params)
  1134. log('ticket_customer_select', params)
  1135. instance = params[:browser] || @browser
  1136. element = instance.find_elements(css: params[:css] + ' input[name="customer_id_completion"]')[0]
  1137. element.click
  1138. element.clear
  1139. # workaround, sometimes focus is not triggered
  1140. element.send_keys(params[:customer])
  1141. sleep 2.5
  1142. element.send_keys(:enter)
  1143. #instance.find_elements(css: params[:css] + ' .recipientList-entry.js-user.is-active')[0].click
  1144. sleep 0.4
  1145. assert(true, 'ticket_customer_select')
  1146. end
  1147. =begin
  1148. overview_create(
  1149. browser: browser1,
  1150. data: {
  1151. name: name,
  1152. role: 'Agent',
  1153. selector: {
  1154. 'Priority': '1 low',
  1155. },
  1156. 'order::direction' => 'down',
  1157. }
  1158. )
  1159. =end
  1160. def overview_create(params)
  1161. switch_window_focus(params)
  1162. log('overview_create', params)
  1163. instance = params[:browser] || @browser
  1164. data = params[:data]
  1165. click(
  1166. browser: instance,
  1167. css: 'a[href="#manage"]',
  1168. mute_log: true,
  1169. )
  1170. click(
  1171. browser: instance,
  1172. css: 'a[href="#manage/overviews"]',
  1173. mute_log: true,
  1174. )
  1175. click(
  1176. browser: instance,
  1177. css: '#content a[data-type="new"]',
  1178. mute_log: true,
  1179. )
  1180. sleep 2
  1181. if data[:name]
  1182. set(
  1183. browser: instance,
  1184. css: '.modal input[name=name]',
  1185. value: data[:name],
  1186. mute_log: true,
  1187. )
  1188. end
  1189. if data[:role]
  1190. select(
  1191. browser: instance,
  1192. css: '.modal select[name="role_id"]',
  1193. value: data[:role],
  1194. mute_log: true,
  1195. )
  1196. end
  1197. if data[:selector]
  1198. data[:selector].each {|key, value|
  1199. select(
  1200. browser: instance,
  1201. css: '.modal .ticket_selector .js-attributeSelector select',
  1202. value: key,
  1203. mute_log: true,
  1204. )
  1205. sleep 0.5
  1206. select(
  1207. browser: instance,
  1208. css: '.modal .ticket_selector .js-value select',
  1209. value: value,
  1210. deselect_all: true,
  1211. mute_log: true,
  1212. )
  1213. }
  1214. end
  1215. if data['order::direction']
  1216. select(
  1217. browser: instance,
  1218. css: '.modal select[name="order::direction"]',
  1219. value: data['order::direction'],
  1220. mute_log: true,
  1221. )
  1222. end
  1223. instance.find_elements(css: '.modal button.js-submit')[0].click
  1224. (1..12).each {
  1225. element = instance.find_elements(css: 'body')[0]
  1226. text = element.text
  1227. if text =~ /#{Regexp.quote(data[:name])}/
  1228. assert(true, 'overview created')
  1229. overview = {
  1230. name: name,
  1231. }
  1232. sleep 1
  1233. return overview
  1234. end
  1235. sleep 1
  1236. }
  1237. screenshot(browser: instance, comment: 'overview_create_failed')
  1238. raise 'overview creation failed'
  1239. end
  1240. =begin
  1241. overview_update(
  1242. browser: browser1,
  1243. data: {
  1244. name: name,
  1245. role: 'Agent',
  1246. selector: {
  1247. 'Priority': '1 low',
  1248. },
  1249. 'order::direction' => 'down',
  1250. }
  1251. )
  1252. =end
  1253. def overview_update(params)
  1254. switch_window_focus(params)
  1255. log('overview_create', params)
  1256. instance = params[:browser] || @browser
  1257. data = params[:data]
  1258. click(
  1259. browser: instance,
  1260. css: 'a[href="#manage"]',
  1261. mute_log: true,
  1262. )
  1263. click(
  1264. browser: instance,
  1265. css: 'a[href="#manage/overviews"]',
  1266. mute_log: true,
  1267. )
  1268. instance.execute_script("$(\"#content td:contains('#{data[:name]}')\").first().click()")
  1269. sleep 2
  1270. if data[:name]
  1271. set(
  1272. browser: instance,
  1273. css: '.modal input[name=name]',
  1274. value: data[:name],
  1275. mute_log: true,
  1276. )
  1277. end
  1278. if data[:role]
  1279. select(
  1280. browser: instance,
  1281. css: '.modal select[name="role_id"]',
  1282. value: data[:role],
  1283. mute_log: true,
  1284. )
  1285. end
  1286. if data[:selector]
  1287. data[:selector].each {|key, value|
  1288. select(
  1289. browser: instance,
  1290. css: '.modal .ticket_selector .js-attributeSelector select',
  1291. value: key,
  1292. mute_log: true,
  1293. )
  1294. sleep 0.5
  1295. select(
  1296. browser: instance,
  1297. css: '.modal .ticket_selector .js-value select',
  1298. value: value,
  1299. deselect_all: true,
  1300. mute_log: true,
  1301. )
  1302. }
  1303. end
  1304. if data['order::direction']
  1305. select(
  1306. browser: instance,
  1307. css: '.modal select[name="order::direction"]',
  1308. value: data['order::direction'],
  1309. mute_log: true,
  1310. )
  1311. end
  1312. instance.find_elements(css: '.modal button.js-submit')[0].click
  1313. (1..12).each {
  1314. element = instance.find_elements(css: 'body')[0]
  1315. text = element.text
  1316. if text =~ /#{Regexp.quote(data[:name])}/
  1317. assert(true, 'overview updated')
  1318. overview = {
  1319. name: name,
  1320. }
  1321. sleep 1
  1322. return overview
  1323. end
  1324. sleep 1
  1325. }
  1326. screenshot(browser: instance, comment: 'overview_update_failed')
  1327. raise 'overview update failed'
  1328. end
  1329. =begin
  1330. ticket = ticket_create(
  1331. browser: browser1,
  1332. data: {
  1333. customer: 'nico',
  1334. group: 'Users', # optional / '-NONE-' # if group selection should not be shown
  1335. priority: '2 normal',
  1336. state: 'open',
  1337. title: 'overview #1',
  1338. body: 'overview #1',
  1339. },
  1340. do_not_submit: true,
  1341. )
  1342. returns (in case of submitted)
  1343. {
  1344. id: 123,
  1345. number: '100001',
  1346. title: 'overview #1',
  1347. }
  1348. ticket = ticket_create(
  1349. browser: browser1,
  1350. data: {
  1351. customer: 'nico',
  1352. group: 'Users', # optional / '-NONE-' # if group selection should not be shown
  1353. priority: '2 normal',
  1354. state: 'open',
  1355. title: 'overview #1',
  1356. body: 'overview #1',
  1357. },
  1358. custom_data_select: {
  1359. key1: 'some value',
  1360. },
  1361. custom_data_input: {
  1362. key1: 'some value',
  1363. },
  1364. disable_group_check: true,
  1365. )
  1366. =end
  1367. def ticket_create(params)
  1368. switch_window_focus(params)
  1369. log('ticket_create', params)
  1370. instance = params[:browser] || @browser
  1371. data = params[:data]
  1372. click(
  1373. browser: instance,
  1374. css: 'a[href="#new"]',
  1375. mute_log: true,
  1376. )
  1377. click(
  1378. browser: instance,
  1379. css: 'a[href="#ticket/create"]',
  1380. mute_log: true,
  1381. )
  1382. found = false
  1383. (1..8).each {
  1384. element = instance.find_elements(css: '.active .newTicket')[0]
  1385. if element
  1386. found = true
  1387. break
  1388. end
  1389. sleep 1
  1390. }
  1391. if !found
  1392. screenshot(browser: instance, comment: 'ticket_create_failed')
  1393. raise 'no ticket create screen found!'
  1394. end
  1395. if data[:group]
  1396. if data[:group] == '-NONE-'
  1397. # check if owner selection exists
  1398. count = instance.find_elements(css: '.active .newTicket select[name="group_id"] option').count
  1399. assert_equal(0, count, 'owner selection should not be showm')
  1400. # check count of agents, should be only 3 / - selection + master + agent on init screen
  1401. count = instance.find_elements(css: '.active .newTicket select[name="owner_id"] option').count
  1402. assert_equal(3, count, 'check if owner selection is - selection + master + agent per default')
  1403. else
  1404. # check count of agents, should be only 1 / - selection on init screen
  1405. if !params[:disable_group_check]
  1406. count = instance.find_elements(css: '.active .newTicket select[name="owner_id"] option').count
  1407. assert_equal(1, count, 'check if owner selection is empty per default')
  1408. end
  1409. select(
  1410. browser: instance,
  1411. css: '.active .newTicket select[name="group_id"]',
  1412. value: data[:group],
  1413. mute_log: true,
  1414. )
  1415. sleep 0.2
  1416. end
  1417. end
  1418. if data[:priority]
  1419. select(
  1420. browser: instance,
  1421. css: '.active .newTicket select[name="priority_id"]',
  1422. value: data[:priority],
  1423. mute_log: true,
  1424. )
  1425. end
  1426. if data[:state]
  1427. select(
  1428. browser: instance,
  1429. css: '.active .newTicket select[name="state_id"]',
  1430. value: data[:state],
  1431. mute_log: true,
  1432. )
  1433. end
  1434. if data[:title]
  1435. set(
  1436. browser: instance,
  1437. css: '.active .newTicket input[name="title"]',
  1438. value: data[:title],
  1439. clear: true,
  1440. mute_log: true,
  1441. )
  1442. end
  1443. if data[:body]
  1444. set(
  1445. browser: instance,
  1446. css: '.active .newTicket div[data-name=body]',
  1447. value: data[:body],
  1448. clear: true,
  1449. mute_log: true,
  1450. )
  1451. # it's not working stable via selenium, use js
  1452. value = instance.find_elements(css: '.content .newTicket div[data-name=body]')[0].text
  1453. #puts "V #{value.inspect}"
  1454. if value != data[:body]
  1455. body_quoted = quote(data[:body])
  1456. instance.execute_script("$('.content.active div[data-name=body]').html('#{body_quoted}').trigger('focusout')")
  1457. end
  1458. end
  1459. if data[:customer]
  1460. element = instance.find_elements(css: '.active .newTicket input[name="customer_id_completion"]')[0]
  1461. element.click
  1462. element.clear
  1463. # workaround, sometimes focus is not triggered
  1464. element.send_keys(data[:customer])
  1465. sleep 2.5
  1466. element.send_keys(:enter)
  1467. #instance.find_elements(css: '.active .newTicket .recipientList-entry.js-user.is-active')[0].click
  1468. sleep 0.4
  1469. end
  1470. if params[:custom_data_select]
  1471. params[:custom_data_select].each {|local_key, local_value|
  1472. select(
  1473. browser: instance,
  1474. css: ".active .newTicket select[name=\"#{local_key}\"]",
  1475. value: local_value,
  1476. )
  1477. }
  1478. end
  1479. if params[:custom_data_input]
  1480. params[:custom_data_input].each {|local_key, local_value|
  1481. set(
  1482. browser: instance,
  1483. css: ".active .newTicket input[name=\"#{local_key}\"]",
  1484. value: local_value,
  1485. clear: true,
  1486. )
  1487. }
  1488. end
  1489. if data[:attachment]
  1490. file_upload(
  1491. browser: instance,
  1492. css: '#content .text-1',
  1493. value: 'some text',
  1494. )
  1495. end
  1496. if params[:do_not_submit]
  1497. assert(true, 'ticket created without submit')
  1498. return
  1499. end
  1500. sleep 0.5
  1501. #instance.execute_script('$(".content.active .newTicket form").submit();')
  1502. click(
  1503. browser: instance,
  1504. css: '.active .newTicket button.js-submit',
  1505. mute_log: true,
  1506. )
  1507. sleep 1
  1508. (1..10).each {
  1509. if instance.current_url =~ /#{Regexp.quote('#ticket/zoom/')}/
  1510. assert(true, 'ticket created')
  1511. sleep 2.5
  1512. id = instance.current_url
  1513. id.gsub!(//,)
  1514. id.gsub!(%r{^.+?/(\d+)$}, '\\1')
  1515. element = instance.find_elements(css: '.active .ticketZoom-header .ticket-number')[0]
  1516. if element
  1517. number = element.text
  1518. ticket = {
  1519. id: id,
  1520. number: number,
  1521. title: data[:title],
  1522. }
  1523. sleep 3 # wait until notify is gone
  1524. screenshot(browser: instance, comment: 'ticket_create_ok')
  1525. return ticket
  1526. end
  1527. end
  1528. sleep 1
  1529. }
  1530. screenshot(browser: instance, comment: 'ticket_create_failed')
  1531. raise "ticket creation failed, can't get zoom url (current url is '#{instance.current_url}')"
  1532. end
  1533. =begin
  1534. ticket_update(
  1535. browser: browser1,
  1536. data: {
  1537. title: '',
  1538. customer: 'some_customer@example.com',
  1539. body: 'some body',
  1540. group: 'some group', # optional
  1541. priority: '1 low',
  1542. state: 'closed',
  1543. },
  1544. do_not_submit: true,
  1545. )
  1546. ticket_update(
  1547. browser: browser1,
  1548. data: {
  1549. title: '',
  1550. customer: 'some_customer@example.com',
  1551. body: 'some body',
  1552. group: 'some group', # optional
  1553. priority: '1 low',
  1554. state: 'closed',
  1555. },
  1556. custom_data_select: {
  1557. key1: 'some value',
  1558. },
  1559. custom_data_input: {
  1560. key1: 'some value',
  1561. },
  1562. do_not_submit: true,
  1563. )
  1564. =end
  1565. def ticket_update(params)
  1566. switch_window_focus(params)
  1567. log('ticket_update', params)
  1568. instance = params[:browser] || @browser
  1569. data = params[:data]
  1570. if data[:title]
  1571. #element = instance.find_elements(:css => '.content.active .ticketZoom-header .js-objectTitle')[0]
  1572. #element.clear
  1573. #sleep 0.5
  1574. #element = instance.find_elements(:css => '.content.active .ticketZoom-header .js-objectTitle')[0]
  1575. #element.send_keys(data[:title])
  1576. #sleep 0.5
  1577. #element.send_keys(:tab)
  1578. instance.execute_script('$(".content.active .ticketZoom-header .js-objectTitle").focus()')
  1579. instance.execute_script('$(".content.active .ticketZoom-header .js-objectTitle").text("' + data[:title] + '")')
  1580. instance.execute_script('$(".content.active .ticketZoom-header .js-objectTitle").blur()')
  1581. instance.execute_script('$(".content.active .ticketZoom-header .js-objectTitle").trigger("blur")')
  1582. # {
  1583. # :where => :instance2,
  1584. # :execute => 'sendkey',
  1585. # :css => '.content.active .ticketZoom-header .js-objectTitle',
  1586. # :value => 'TTT',
  1587. # },
  1588. # {
  1589. # :where => :instance2,
  1590. # :execute => 'sendkey',
  1591. # :css => '.content.active .ticketZoom-header .js-objectTitle',
  1592. # :value => :tab,
  1593. # },
  1594. end
  1595. if data[:customer]
  1596. # select tab
  1597. click(browser: instance, css: '.active .tabsSidebar-tab[data-tab="customer"]')
  1598. click(browser: instance, css: '.active div[data-tab="customer"] .js-actions .icon-arrow-down')
  1599. click(browser: instance, css: '.active div[data-tab="customer"] .js-actions [data-type="customer-change"]')
  1600. watch_for(
  1601. browser: instance,
  1602. css: '.modal',
  1603. value: 'change',
  1604. )
  1605. element = instance.find_elements(css: '.modal input[name="customer_id_completion"]')[0]
  1606. element.click
  1607. element.clear
  1608. # workaround, sometimes focus is not triggered
  1609. element.send_keys(data[:customer])
  1610. sleep 2.5
  1611. element.send_keys(:enter)
  1612. #instance.find_elements(css: '.modal .user_autocompletion .recipientList-entry.js-user.is-active')[0].click
  1613. sleep 0.2
  1614. click(browser: instance, css: '.modal .js-submit')
  1615. watch_for_disappear(
  1616. browser: instance,
  1617. css: '.modal',
  1618. )
  1619. watch_for(
  1620. browser: instance,
  1621. css: '.active .tabsSidebar',
  1622. value: data[:customer],
  1623. )
  1624. # select tab
  1625. click(browser: instance, css: '.active .tabsSidebar-tab[data-tab="ticket"]')
  1626. end
  1627. if data[:body]
  1628. set(
  1629. browser: instance,
  1630. css: '.content.active div[data-name=body]',
  1631. value: data[:body],
  1632. no_click: true,
  1633. mute_log: true,
  1634. )
  1635. # it's not working stable via selenium, use js
  1636. value = instance.find_elements(css: '.content.active div[data-name=body]')[0].text
  1637. if value != data[:body]
  1638. body_quoted = quote(data[:body])
  1639. instance.execute_script("$('.content.active div[data-name=body]').html('#{body_quoted}').trigger('focusout')")
  1640. end
  1641. end
  1642. if data[:group]
  1643. if data[:group] == '-NONE-'
  1644. # check if owner selection exists
  1645. count = instance.find_elements(css: '.active .sidebar select[name="group_id"] option').count
  1646. assert_equal(0, count, 'owner selection should not be showm')
  1647. # check count of agents, should be only 3 / - selection + master + agent on init screen
  1648. count = instance.find_elements(css: '.active .sidebar select[name="owner_id"] option').count
  1649. assert_equal(3, count, 'check if owner selection is - selection + master + agent per default')
  1650. else
  1651. select(
  1652. browser: instance,
  1653. css: '.active .sidebar select[name="group_id"]',
  1654. value: data[:group],
  1655. mute_log: true,
  1656. )
  1657. sleep 0.2
  1658. end
  1659. end
  1660. if data[:priority]
  1661. select(
  1662. browser: instance,
  1663. css: '.active .sidebar select[name="priority_id"]',
  1664. value: data[:priority],
  1665. mute_log: true,
  1666. )
  1667. end
  1668. if data[:state]
  1669. select(
  1670. browser: instance,
  1671. css: '.active .sidebar select[name="state_id"]',
  1672. value: data[:state],
  1673. mute_log: true,
  1674. )
  1675. end
  1676. if params[:custom_data_select]
  1677. params[:custom_data_select].each {|local_key, local_value|
  1678. select(
  1679. browser: instance,
  1680. css: ".active .sidebar select[name=\"#{local_key}\"]",
  1681. value: local_value,
  1682. )
  1683. }
  1684. end
  1685. if params[:custom_data_input]
  1686. params[:custom_data_input].each {|local_key, local_value|
  1687. set(
  1688. browser: instance,
  1689. css: ".active .sidebar input[name=\"#{local_key}\"]",
  1690. value: local_value,
  1691. clear: true,
  1692. )
  1693. }
  1694. end
  1695. if data[:state] || data[:group] || data[:body] || !params[:custom_data_select].empty? || !params[:custom_data_input].empty?
  1696. found = nil
  1697. (1..10).each {
  1698. break if found
  1699. begin
  1700. text = instance.find_elements(css: '.content.active .js-reset')[0].text
  1701. if text =~ /(Discard your unsaved changes.|Verwerfen der)/
  1702. found = true
  1703. end
  1704. rescue
  1705. # try again
  1706. end
  1707. sleep 1
  1708. }
  1709. if !found
  1710. screenshot(browser: instance, comment: 'ticket_update_discard_message_failed')
  1711. raise 'no discard message found'
  1712. end
  1713. end
  1714. task_type(
  1715. browser: instance,
  1716. type: 'stayOnTab',
  1717. )
  1718. if params[:do_not_submit]
  1719. assert(true, 'ticket updated without submit')
  1720. return true
  1721. end
  1722. instance.find_elements(css: '.content.active .js-submit')[0].click
  1723. (1..10).each {
  1724. begin
  1725. text = instance.find_elements(css: '.content.active .js-reset')[0].text
  1726. if !text || text.empty?
  1727. screenshot(browser: instance, comment: 'ticket_update_ok')
  1728. sleep 1
  1729. return true
  1730. end
  1731. rescue
  1732. # try again
  1733. end
  1734. sleep 1
  1735. }
  1736. screenshot(browser: instance, comment: 'ticket_update_failed')
  1737. raise 'unable to update ticket'
  1738. end
  1739. =begin
  1740. ticket_verify(
  1741. browser: browser1,
  1742. data: {
  1743. title: 'some title',
  1744. body: 'some body',
  1745. ## group: 'some group',
  1746. ## state: 'closed',
  1747. custom_data_select: {
  1748. key1: 'some value',
  1749. },
  1750. custom_data_input: {
  1751. key1: 'some value',
  1752. },
  1753. },
  1754. )
  1755. =end
  1756. def ticket_verify(params)
  1757. switch_window_focus(params)
  1758. log('ticket_verify', params)
  1759. instance = params[:browser] || @browser
  1760. data = params[:data]
  1761. if data[:title]
  1762. title = instance.find_elements(css: '.content.active .ticketZoom-header .js-objectTitle').first.text.strip
  1763. if title =~ /#{data[:title]}/i
  1764. assert(true, "matching '#{data[:title]}' in title '#{title}'")
  1765. else
  1766. raise "not matching '#{data[:title]}' in title '#{title}'"
  1767. end
  1768. end
  1769. if data[:body]
  1770. body = instance.find_elements(css: '.content.active [data-name="body"]').first.text.strip
  1771. if body =~ /#{data[:body]}/i
  1772. assert(true, "matching '#{data[:body]}' in body '#{body}'")
  1773. else
  1774. raise "not matching '#{data[:body]}' in body '#{body}'"
  1775. end
  1776. end
  1777. if params[:custom_data_select]
  1778. params[:custom_data_select].each {|local_key, local_value|
  1779. element = instance.find_elements(css: ".active .sidebar select[name=\"#{local_key}\"] option[selected]").first
  1780. value = element.text.strip
  1781. if value =~ /#{local_value}/i
  1782. assert(true, "matching '#{value}' in #{local_key} '#{local_value}'")
  1783. else
  1784. raise "not matching '#{value}' in #{local_key} '#{local_value}'"
  1785. end
  1786. }
  1787. end
  1788. if params[:custom_data_input]
  1789. params[:custom_data_input].each {|local_key, local_value|
  1790. element = instance.find_elements(css: ".active .sidebar input[name=\"#{local_key}\"]").first
  1791. value = element.text.strip
  1792. if value =~ /#{local_value}/i
  1793. assert(true, "matching '#{value}' in #{local_key} '#{local_value}'")
  1794. else
  1795. raise "not matching '#{value}' in #{local_key} '#{local_value}'"
  1796. end
  1797. }
  1798. end
  1799. true
  1800. end
  1801. =begin
  1802. ticket_open_by_overview(
  1803. browser: browser2,
  1804. number: ticket1[:number],
  1805. link: "#ticket/view/#{name}",
  1806. )
  1807. =end
  1808. def ticket_open_by_overview(params)
  1809. switch_window_focus(params)
  1810. log('ticket_open_by_overview', params)
  1811. instance = params[:browser] || @browser
  1812. instance.find_elements(css: '.js-overviewsMenuItem')[0].click
  1813. sleep 1
  1814. execute(
  1815. browser: instance,
  1816. js: '$(".content.active .sidebar").css("display", "block")',
  1817. )
  1818. instance.find_elements(css: ".content.active .sidebar a[href=\"#{params[:link]}\"]")[0].click
  1819. sleep 1
  1820. execute(
  1821. browser: instance,
  1822. js: '$(".content.active .sidebar").css("display", "none")',
  1823. )
  1824. instance.find_elements(partial_link_text: params[:number])[0].click
  1825. sleep 1
  1826. number = instance.find_elements(css: '.active .ticketZoom-header .ticket-number')[0].text
  1827. if number !~ /#{params[:number]}/
  1828. screenshot(browser: instance, comment: 'ticket_open_by_overview_failed')
  1829. raise "unable to search/find ticket #{params[:number]}!"
  1830. end
  1831. sleep 1
  1832. assert(true, "ticket #{params[:number]} found")
  1833. true
  1834. end
  1835. =begin
  1836. ticket_open_by_search(
  1837. browser: browser2,
  1838. number: ticket1[:number],
  1839. )
  1840. =end
  1841. def ticket_open_by_search(params)
  1842. switch_window_focus(params)
  1843. log('ticket_open_by_search', params)
  1844. instance = params[:browser] || @browser
  1845. # search by number
  1846. element = instance.find_elements(css: '#global-search')[0]
  1847. element.click
  1848. element.clear
  1849. element.send_keys(params[:number])
  1850. sleep 3
  1851. empty_search(browser: instance)
  1852. # search by number again
  1853. element = instance.find_elements(css: '#global-search')[0]
  1854. element.click
  1855. element.clear
  1856. element.send_keys(params[:number])
  1857. sleep 1
  1858. # open ticket
  1859. #instance.find_element(partial_link_text: params[:number] } ).click
  1860. instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
  1861. sleep 1
  1862. number = instance.find_elements(css: '.active .ticketZoom-header .ticket-number')[0].text
  1863. if number !~ /#{params[:number]}/
  1864. screenshot(browser: instance, comment: 'ticket_open_by_search_failed')
  1865. raise "unable to search/find ticket #{params[:number]}!"
  1866. end
  1867. sleep 1
  1868. true
  1869. end
  1870. =begin
  1871. ticket_open_by_title(
  1872. browser: browser2,
  1873. title: ticket1[:title],
  1874. )
  1875. =end
  1876. def ticket_open_by_title(params)
  1877. switch_window_focus(params)
  1878. log('ticket_open_by_title', params)
  1879. instance = params[:browser] || @browser
  1880. # search by number
  1881. element = instance.find_elements(css: '#global-search')[0]
  1882. element.click
  1883. element.clear
  1884. element.send_keys(params[:title])
  1885. sleep 3
  1886. # open ticket
  1887. #instance.find_element(partial_link_text: params[:title] } ).click
  1888. instance.execute_script("$(\"#global-search-result a:contains('#{params[:title]}') .nav-tab-icon\").click()")
  1889. sleep 1
  1890. title = instance.find_elements(css: '.active .ticketZoom-header .js-objectTitle')[0].text
  1891. if title !~ /#{params[:title]}/
  1892. screenshot(browser: instance, comment: 'ticket_open_by_title_failed')
  1893. raise "unable to search/find ticket #{params[:title]}!"
  1894. end
  1895. sleep 1
  1896. true
  1897. end
  1898. =begin
  1899. overview_count = overview_counter(
  1900. browser: browser2,
  1901. )
  1902. returns
  1903. {
  1904. '#ticket/view/all_unassigned' => 42,
  1905. }
  1906. =end
  1907. def overview_counter(params = {})
  1908. switch_window_focus(params)
  1909. log('overview_counter', params)
  1910. instance = params[:browser] || @browser
  1911. instance.find_elements(css: '.js-overviewsMenuItem')[0].click
  1912. sleep 2
  1913. execute(
  1914. browser: instance,
  1915. js: '$(".content.active .sidebar").css("display", "block")',
  1916. )
  1917. #execute(
  1918. # browser: instance,
  1919. # js: '$(".content.active .overview-header").css("display", "none")',
  1920. #)
  1921. overviews = {}
  1922. instance.find_elements(css: '.content.active .sidebar a[href]').each {|element|
  1923. url = element.attribute('href')
  1924. url.gsub!(%r{(http|https)://.+?/(.+?)$}, '\\2')
  1925. overviews[url] = 0
  1926. #puts url.inspect
  1927. #puts element.inspect
  1928. }
  1929. overviews.each {|url, _value|
  1930. count = instance.find_elements(css: ".content.active .sidebar a[href=\"#{url}\"] .badge")[0].text
  1931. overviews[url] = count.to_i
  1932. }
  1933. log('overview_counter', overviews)
  1934. overviews
  1935. end
  1936. =begin
  1937. organization_open_by_search(
  1938. browser: browser2,
  1939. value: 'some value',
  1940. )
  1941. =end
  1942. def organization_open_by_search(params = {})
  1943. switch_window_focus(params)
  1944. log('organization_open_by_search', params)
  1945. instance = params[:browser] || @browser
  1946. element = instance.find_elements(css: '#global-search')[0]
  1947. element.click
  1948. element.clear
  1949. element.send_keys(params[:value])
  1950. sleep 3
  1951. empty_search(browser: instance)
  1952. element = instance.find_elements(css: '#global-search')[0]
  1953. element.click
  1954. element.clear
  1955. element.send_keys(params[:value])
  1956. sleep 2
  1957. #instance.find_element(partial_link_text: params[:value] } ).click
  1958. instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
  1959. sleep 1
  1960. name = instance.find_elements(css: '.active h1')[0].text
  1961. if name !~ /#{params[:value]}/
  1962. screenshot(browser: instance, comment: 'organization_open_by_search_failed')
  1963. raise "unable to search/find org #{params[:value]}!"
  1964. end
  1965. assert(true, "org #{params[:value]} found")
  1966. sleep 2
  1967. true
  1968. end
  1969. =begin
  1970. user_open_by_search(
  1971. browser: browser2,
  1972. value: 'some value',
  1973. )
  1974. =end
  1975. def user_open_by_search(params = {})
  1976. switch_window_focus(params)
  1977. log('user_open_by_search', params)
  1978. instance = params[:browser] || @browser
  1979. element = instance.find_elements(css: '#global-search')[0]
  1980. element.click
  1981. element.clear
  1982. element.send_keys(params[:value])
  1983. sleep 3
  1984. #instance.find_element(partial_link_text: params[:value]).click
  1985. instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
  1986. sleep 1
  1987. name = instance.find_elements(css: '.active h1')[0].text
  1988. if name !~ /#{params[:value]}/
  1989. screenshot(browser: instance, comment: 'user_open_by_search_failed')
  1990. raise "unable to search/find user #{params[:value]}!"
  1991. end
  1992. assert(true, "user #{params[:term]} found")
  1993. sleep 2
  1994. true
  1995. end
  1996. =begin
  1997. user_create(
  1998. browser: browser2,
  1999. data: {
  2000. #login: 'some login' + random,
  2001. firstname: 'Manage Firstname' + random,
  2002. lastname: 'Manage Lastname' + random,
  2003. email: user_email,
  2004. password: 'some-pass',
  2005. },
  2006. )
  2007. =end
  2008. def user_create(params = {})
  2009. switch_window_focus(params)
  2010. log('user_create', params)
  2011. instance = params[:browser] || @browser
  2012. data = params[:data]
  2013. click(
  2014. browser: instance,
  2015. css: 'a[href="#manage"]',
  2016. mute_log: true,
  2017. )
  2018. click(
  2019. browser: instance,
  2020. css: 'a[href="#manage/users"]',
  2021. mute_log: true,
  2022. )
  2023. click(
  2024. browser: instance,
  2025. css: 'a[data-type="new"]',
  2026. mute_log: true,
  2027. )
  2028. sleep 2
  2029. element = instance.find_elements(css: '.modal input[name=firstname]')[0]
  2030. element.clear
  2031. element.send_keys(data[:firstname])
  2032. element = instance.find_elements(css: '.modal input[name=lastname]')[0]
  2033. element.clear
  2034. element.send_keys(data[:lastname])
  2035. element = instance.find_elements(css: '.modal input[name=email]')[0]
  2036. element.clear
  2037. element.send_keys(data[:email])
  2038. element = instance.find_elements(css: '.modal input[name=password]')[0]
  2039. element.clear
  2040. element.send_keys(data[:password])
  2041. element = instance.find_elements(css: '.modal input[name=password_confirm]')[0]
  2042. element.clear
  2043. element.send_keys(data[:password])
  2044. check(
  2045. browser: instance,
  2046. css: '.modal input[name=role_ids][value=3]',
  2047. )
  2048. instance.find_elements(css: '.modal button.js-submit')[0].click
  2049. sleep 3.5
  2050. set(
  2051. browser: instance,
  2052. css: '.content .js-search',
  2053. value: data[:email],
  2054. )
  2055. watch_for(
  2056. browser: instance,
  2057. css: 'body',
  2058. value: data[:lastname],
  2059. )
  2060. assert(true, 'user created')
  2061. end
  2062. =begin
  2063. sla_create(
  2064. browser: browser2,
  2065. data: {
  2066. name: 'some sla' + random,
  2067. first_response_time_in_text: 61
  2068. },
  2069. )
  2070. =end
  2071. def sla_create(params = {})
  2072. switch_window_focus(params)
  2073. log('sla_create', params)
  2074. instance = params[:browser] || @browser
  2075. data = params[:data]
  2076. click(
  2077. browser: instance,
  2078. css: 'a[href="#manage"]',
  2079. mute_log: true,
  2080. )
  2081. click(
  2082. browser: instance,
  2083. css: 'a[href="#manage/slas"]',
  2084. mute_log: true,
  2085. )
  2086. click(
  2087. browser: instance,
  2088. css: 'a.js-new',
  2089. mute_log: true,
  2090. )
  2091. sleep 2
  2092. element = instance.find_elements(css: '.modal input[name=name]')[0]
  2093. element.clear
  2094. element.send_keys(data[:name])
  2095. element = instance.find_elements(css: '.modal input[name=first_response_time_in_text]')[0]
  2096. element.clear
  2097. element.send_keys(data[:first_response_time_in_text])
  2098. instance.find_elements(css: '.modal button.js-submit')[0].click
  2099. (1..8).each {
  2100. element = instance.find_elements(css: 'body')[0]
  2101. text = element.text
  2102. if text =~ /#{Regexp.quote(data[:name])}/
  2103. assert(true, 'sla created')
  2104. sleep 1
  2105. return true
  2106. end
  2107. sleep 1
  2108. }
  2109. screenshot(browser: instance, comment: 'sla_create_failed')
  2110. raise 'sla creation failed'
  2111. end
  2112. =begin
  2113. text_module_create(
  2114. browser: browser2,
  2115. data: {
  2116. name: 'some sla' + random,
  2117. keywords: 'some keywords',
  2118. content: 'some content',
  2119. },
  2120. )
  2121. =end
  2122. def text_module_create(params = {})
  2123. switch_window_focus(params)
  2124. log('text_module_create', params)
  2125. instance = params[:browser] || @browser
  2126. data = params[:data]
  2127. click(
  2128. browser: instance,
  2129. css: 'a[href="#manage"]',
  2130. mute_log: true,
  2131. )
  2132. click(
  2133. browser: instance,
  2134. css: 'a[href="#manage/text_modules"]',
  2135. mute_log: true,
  2136. )
  2137. click(
  2138. browser: instance,
  2139. css: 'a[data-type="new"]',
  2140. mute_log: true,
  2141. )
  2142. sleep 2
  2143. element = instance.find_elements(css: '.modal input[name=name]')[0]
  2144. element.clear
  2145. element.send_keys(data[:name])
  2146. element = instance.find_elements(css: '.modal input[name=keywords]')[0]
  2147. element.clear
  2148. element.send_keys(data[:keywords])
  2149. element = instance.find_elements(css: '.modal [data-name=content]')[0]
  2150. element.clear
  2151. element.send_keys(data[:content])
  2152. instance.find_elements(css: '.modal button.js-submit')[0].click
  2153. (1..8).each {
  2154. element = instance.find_elements(css: 'body')[0]
  2155. text = element.text
  2156. if text =~ /#{Regexp.quote(data[:name])}/
  2157. assert(true, 'text module created')
  2158. sleep 1
  2159. return true
  2160. end
  2161. sleep 1
  2162. }
  2163. screenshot(browser: instance, comment: 'text_module_create_failed')
  2164. raise 'text module creation failed'
  2165. end
  2166. =begin
  2167. signature_create(
  2168. browser: browser2,
  2169. data: {
  2170. name: 'some sla' + random,
  2171. body: 'some body',
  2172. },
  2173. )
  2174. =end
  2175. def signature_create(params = {})
  2176. switch_window_focus(params)
  2177. log('signature_create', params)
  2178. instance = params[:browser] || @browser
  2179. data = params[:data]
  2180. click(
  2181. browser: instance,
  2182. css: 'a[href="#manage"]',
  2183. mute_log: true,
  2184. )
  2185. click(
  2186. browser: instance,
  2187. css: 'a[href="#channels/email"]',
  2188. mute_log: true,
  2189. )
  2190. click(
  2191. browser: instance,
  2192. css: 'a[href="#c-signature"]',
  2193. mute_log: true,
  2194. )
  2195. sleep 4
  2196. click(
  2197. browser: instance,
  2198. css: '#content #c-signature a[data-type="new"]',
  2199. mute_log: true,
  2200. )
  2201. sleep 2
  2202. element = instance.find_elements(css: '.modal input[name=name]')[0]
  2203. element.clear
  2204. element.send_keys(data[:name])
  2205. element = instance.find_elements(css: '.modal [data-name=body]')[0]
  2206. element.clear
  2207. element.send_keys(data[:body])
  2208. instance.find_elements(css: '.modal button.js-submit')[0].click
  2209. (1..12).each {
  2210. element = instance.find_elements(css: 'body')[0]
  2211. text = element.text
  2212. if text =~ /#{Regexp.quote(data[:name])}/
  2213. assert(true, 'signature created')
  2214. sleep 1
  2215. return true
  2216. end
  2217. sleep 1
  2218. }
  2219. screenshot(browser: instance, comment: 'signature_create_failed')
  2220. raise 'signature creation failed'
  2221. end
  2222. =begin
  2223. group_create(
  2224. browser: browser2,
  2225. data: {
  2226. name: 'some sla' + random,
  2227. signature: 'some signature bame',
  2228. member: [
  2229. 'some_user_login',
  2230. ],
  2231. },
  2232. )
  2233. =end
  2234. def group_create(params = {})
  2235. switch_window_focus(params)
  2236. log('group_create', params)
  2237. instance = params[:browser] || @browser
  2238. data = params[:data]
  2239. click(
  2240. browser: instance,
  2241. css: 'a[href="#manage"]',
  2242. mute_log: true,
  2243. )
  2244. click(
  2245. browser: instance,
  2246. css: 'a[href="#manage/groups"]',
  2247. mute_log: true,
  2248. )
  2249. click(
  2250. browser: instance,
  2251. css: 'a[data-type="new"]',
  2252. mute_log: true,
  2253. )
  2254. sleep 2
  2255. element = instance.find_elements(css: '.modal input[name=name]')[0]
  2256. element.clear
  2257. element.send_keys(data[:name])
  2258. element = instance.find_elements(css: '.modal select[name="email_address_id"]')[0]
  2259. dropdown = Selenium::WebDriver::Support::Select.new(element)
  2260. dropdown.select_by(:index, 1)
  2261. #dropdown.select_by(:text, action[:group])
  2262. if data[:signature]
  2263. element = instance.find_elements(css: '.modal select[name="signature_id"]')[0]
  2264. dropdown = Selenium::WebDriver::Support::Select.new(element)
  2265. dropdown.select_by(:text, data[:signature])
  2266. end
  2267. instance.find_elements(css: '.modal button.js-submit')[0].click
  2268. (1..12).each {
  2269. element = instance.find_elements(css: 'body')[0]
  2270. text = element.text
  2271. if text =~ /#{Regexp.quote(data[:name])}/
  2272. assert(true, 'group created')
  2273. modal_ready # wait until modal has gone
  2274. # add member
  2275. if data[:member]
  2276. data[:member].each {|login|
  2277. instance.find_elements(css: 'a[href="#manage"]')[0].click
  2278. sleep 0.5
  2279. instance.find_elements(css: 'a[href="#manage/users"]')[0].click
  2280. sleep 3
  2281. element = instance.find_elements(css: '#content [name="search"]')[0]
  2282. element.clear
  2283. element.send_keys(login)
  2284. sleep 3
  2285. #instance.find_elements(:css => '#content table [data-id]')[0].click
  2286. instance.execute_script('$("#content table [data-id] td").first().click()')
  2287. sleep 3
  2288. #instance.find_elements(:css => 'label:contains(" ' + action[:name] + '")')[0].click
  2289. instance.execute_script('$(\'label:contains(" ' + data[:name] + '")\').first().click()')
  2290. instance.find_elements(css: '.modal button.js-submit')[0].click
  2291. sleep 3
  2292. }
  2293. end
  2294. end
  2295. sleep 1
  2296. return true
  2297. }
  2298. screenshot(browser: instance, comment: 'group_create_failed')
  2299. raise 'group creation failed'
  2300. end
  2301. =begin
  2302. object_manager_attribute_create(
  2303. browser: browser2,
  2304. data: {
  2305. name: 'field_name' + random,
  2306. display: 'Display Name of Field',
  2307. data_type: 'Select',
  2308. data_option: {
  2309. options: {
  2310. 'aa' => 'AA',
  2311. 'bb' => 'BB',
  2312. },
  2313. default: 'abc',
  2314. },
  2315. },
  2316. error: 'already exists'
  2317. )
  2318. object_manager_attribute_create(
  2319. browser: browser2,
  2320. data: {
  2321. name: 'field_name' + random,
  2322. display: 'Display Name of Field',
  2323. data_type: 'Text',
  2324. data_option: {
  2325. default: 'abc',
  2326. },
  2327. },
  2328. error: 'already exists'
  2329. )
  2330. object_manager_attribute_create(
  2331. browser: browser2,
  2332. data: {
  2333. name: 'field_name' + random,
  2334. display: 'Display Name of Field',
  2335. data_type: 'Integer',
  2336. data_option: {
  2337. default: '15',
  2338. min: 1,
  2339. max: 999999,
  2340. },
  2341. },
  2342. error: 'already exists'
  2343. )
  2344. object_manager_attribute_create(
  2345. browser: browser2,
  2346. data: {
  2347. name: 'field_name' + random,
  2348. display: 'Display Name of Field',
  2349. data_type: 'Datetime',
  2350. data_option: {
  2351. future: true,
  2352. past: true,
  2353. diff: 24,
  2354. },
  2355. },
  2356. error: 'already exists'
  2357. )
  2358. object_manager_attribute_create(
  2359. browser: browser2,
  2360. data: {
  2361. name: 'field_name' + random,
  2362. display: 'Display Name of Field',
  2363. data_type: 'Date',
  2364. data_option: {
  2365. future: true,
  2366. past: true,
  2367. diff: 24,
  2368. },
  2369. },
  2370. error: 'already exists'
  2371. )
  2372. object_manager_attribute_create(
  2373. browser: browser2,
  2374. data: {
  2375. name: 'field_name' + random,
  2376. display: 'Display Name of Field',
  2377. data_type: 'Boolean',
  2378. data_option: {
  2379. options: {
  2380. true: 'YES',
  2381. false: 'NO',
  2382. }
  2383. default: undefined,
  2384. },
  2385. },
  2386. error: 'already exists'
  2387. )
  2388. =end
  2389. def object_manager_attribute_create(params = {})
  2390. switch_window_focus(params)
  2391. log('object_manager_attribute_create', params)
  2392. instance = params[:browser] || @browser
  2393. data = params[:data]
  2394. click(
  2395. browser: instance,
  2396. css: 'a[href="#manage"]',
  2397. mute_log: true,
  2398. )
  2399. click(
  2400. browser: instance,
  2401. css: 'a[href="#system/object_manager"]',
  2402. mute_log: true,
  2403. )
  2404. sleep 4
  2405. click(
  2406. browser: instance,
  2407. css: '#content .js-new',
  2408. mute_log: true,
  2409. )
  2410. modal_ready
  2411. element = instance.find_elements(css: '.modal input[name=name]')[0]
  2412. element.clear
  2413. element.send_keys(data[:name])
  2414. element = instance.find_elements(css: '.modal input[name=display]')[0]
  2415. element.clear
  2416. element.send_keys(data[:display])
  2417. select(
  2418. browser: instance,
  2419. css: '.modal select[name="data_type"]',
  2420. value: data[:data_type],
  2421. mute_log: true,
  2422. )
  2423. if data[:data_option]
  2424. if data[:data_option][:options]
  2425. if data[:data_type] == 'Boolean'
  2426. element = instance.find_elements(css: '.modal .js-valueTrue').first
  2427. element.clear
  2428. element.send_keys(data[:data_option][:options][:true])
  2429. element = instance.find_elements(css: '.modal .js-valueFalse').first
  2430. element.clear
  2431. element.send_keys(data[:data_option][:options][:false])
  2432. else
  2433. data[:data_option][:options].each {|key, value|
  2434. element = instance.find_elements(css: '.modal .js-Table .js-key').last
  2435. element.clear
  2436. element.send_keys(key)
  2437. element = instance.find_elements(css: '.modal .js-Table .js-value').last
  2438. element.clear
  2439. element.send_keys(value)
  2440. element = instance.find_elements(css: '.modal .js-Table .js-add')[0]
  2441. element.click
  2442. }
  2443. end
  2444. end
  2445. [:default, :min, :max, :diff].each {|key|
  2446. next if !data[:data_option].key?(key)
  2447. element = instance.find_elements(css: ".modal [name=\"data_option::#{key}\"]").first
  2448. element.clear
  2449. element.send_keys(data[:data_option][key])
  2450. }
  2451. [:future, :past].each {|key|
  2452. next if !data[:data_option].key?(key)
  2453. select(
  2454. browser: instance,
  2455. css: ".modal select[name=\"data_option::#{key}\"]",
  2456. value: data[:data_option][key],
  2457. mute_log: true,
  2458. )
  2459. }
  2460. end
  2461. instance.find_elements(css: '.modal button.js-submit')[0].click
  2462. if params[:error]
  2463. sleep 4
  2464. watch_for(
  2465. css: '.modal',
  2466. value: params[:error],
  2467. )
  2468. click(
  2469. browser: instance,
  2470. css: '.modal .js-close',
  2471. mute_log: true,
  2472. )
  2473. return
  2474. end
  2475. (1..12).each {
  2476. element = instance.find_elements(css: 'body')[0]
  2477. text = element.text
  2478. if text =~ /#{Regexp.quote(data[:name])}/
  2479. assert(true, 'object manager attribute created')
  2480. sleep 1
  2481. return true
  2482. end
  2483. sleep 1
  2484. }
  2485. screenshot(browser: instance, comment: 'object_manager_attribute_create_failed')
  2486. raise 'object manager attribute creation failed'
  2487. end
  2488. =begin
  2489. object_manager_attribute_delete(
  2490. browser: browser2,
  2491. data: {
  2492. name: 'field_name' + random,
  2493. },
  2494. )
  2495. =end
  2496. def object_manager_attribute_delete(params = {})
  2497. switch_window_focus(params)
  2498. log('object_manager_attribute_delete', params)
  2499. instance = params[:browser] || @browser
  2500. data = params[:data]
  2501. click(
  2502. browser: instance,
  2503. css: 'a[href="#manage"]',
  2504. mute_log: true,
  2505. )
  2506. click(
  2507. browser: instance,
  2508. css: 'a[href="#system/object_manager"]',
  2509. mute_log: true,
  2510. )
  2511. sleep 4
  2512. instance = params[:browser] || @browser
  2513. data = params[:data]
  2514. r = instance.execute_script("$(\"#content td:contains('#{data[:name]}')\").first().closest('tr').find('.js-delete').click()")
  2515. p "rrr #{r.inspect}"
  2516. end
  2517. =begin
  2518. object_manager_attribute_discard_changes(
  2519. browser: browser2,
  2520. )
  2521. =end
  2522. def object_manager_attribute_discard_changes(params = {})
  2523. switch_window_focus(params)
  2524. log('object_manager_attribute_discard_changes', params)
  2525. instance = params[:browser] || @browser
  2526. click(
  2527. browser: instance,
  2528. css: 'a[href="#manage"]',
  2529. mute_log: true,
  2530. )
  2531. click(
  2532. browser: instance,
  2533. css: 'a[href="#system/object_manager"]',
  2534. mute_log: true,
  2535. )
  2536. sleep 4
  2537. element = instance.find_elements(css: '#content .js-discard').first
  2538. element.click
  2539. watch_for_disappear(
  2540. browser: instance,
  2541. css: '#content .js-discard',
  2542. )
  2543. end
  2544. =begin
  2545. tags_verify(
  2546. browser: browser2,
  2547. tags: {
  2548. 'tag 1' => true,
  2549. 'tag 2' => true,
  2550. 'tag 3' => false,
  2551. },
  2552. )
  2553. =end
  2554. def tags_verify(params = {})
  2555. switch_window_focus(params)
  2556. log('tags_verify', params)
  2557. instance = params[:browser] || @browser
  2558. tags = instance.find_elements({ css: '.content.active .js-tag' })
  2559. assert(tags)
  2560. assert(tags[0])
  2561. tags_found = {}
  2562. params[:tags].each {|key, _value|
  2563. tags_found[key] = false
  2564. }
  2565. tags.each {|element|
  2566. text = element.text
  2567. if tags_found.key?(text)
  2568. tags_found[text] = true
  2569. else
  2570. assert(false, "tag exists but is not in check to verify '#{text}'")
  2571. end
  2572. }
  2573. params[:tags].each {|key, value|
  2574. assert_equal(value, tags_found[key], "tag '#{key}'")
  2575. }
  2576. end
  2577. def quote(string)
  2578. string_quoted = string
  2579. string_quoted.gsub!(/&/, '&amp;')
  2580. string_quoted.gsub!(/</, '&lt;')
  2581. string_quoted.gsub!(/>/, '&gt;')
  2582. string_quoted
  2583. end
  2584. def switch_window_focus(params)
  2585. instance = params[:browser] || @browser
  2586. if instance != @last_used_browser
  2587. log('switch browser window focus', {})
  2588. instance.switch_to.window(instance.window_handles.first)
  2589. end
  2590. @last_used_browser = instance
  2591. end
  2592. def log(method, params = {})
  2593. return if !@@debug
  2594. return if params[:mute_log]
  2595. puts "#{Time.zone.now}/#{method}: #{params.inspect}"
  2596. end
  2597. end