browser_test_helper.rb 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361
  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. caps = Selenium::WebDriver::Remote::Capabilities.send(browser)
  46. if ENV['BROWSER_OS']
  47. caps.platform = ENV['BROWSER_OS']
  48. end
  49. if ENV['BROWSER_VERSION']
  50. caps.version = ENV['BROWSER_VERSION']
  51. end
  52. local_browser = Selenium::WebDriver.for(
  53. :remote,
  54. url: ENV['REMOTE_URL'],
  55. desired_capabilities: caps,
  56. )
  57. @browsers[local_browser.hash] = local_browser
  58. # avoid "Cannot read property 'get_Current' of undefined" issues
  59. begin
  60. browser_instance_preferences(local_browser)
  61. rescue
  62. # just try again
  63. sleep 10
  64. browser_instance_preferences(local_browser)
  65. end
  66. # upload files from remote dir
  67. local_browser.file_detector = lambda do |args|
  68. str = args.first.to_s
  69. str if File.file?(str)
  70. end
  71. local_browser
  72. end
  73. def browser_instance_close(local_browser)
  74. return if !@browsers[local_browser.hash]
  75. @browsers.delete(local_browser.hash)
  76. local_browser.quit
  77. end
  78. def browser_instance_preferences(local_browser)
  79. local_browser.manage.window.resize_to(1024, 800)
  80. if ENV['REMOTE_URL'] !~ /saucelabs|(grid|ci)\.(zammad\.org|znuny\.com)/i
  81. if @browsers.count == 1
  82. local_browser.manage.window.move_to(0, 0)
  83. else
  84. local_browser.manage.window.move_to(1024, 0)
  85. end
  86. end
  87. local_browser.manage.timeouts.implicit_wait = 3 # seconds
  88. end
  89. def teardown
  90. return if !@browsers
  91. @browsers.each { |_hash, local_browser|
  92. screenshot(browser: local_browser, comment: 'teardown')
  93. browser_instance_close(local_browser)
  94. }
  95. end
  96. def screenshot(params)
  97. instance = params[:browser] || @browser
  98. comment = params[:comment] || ''
  99. filename = "tmp/#{Time.zone.now.strftime('screenshot_%Y_%m_%d__%H_%M_%S')}_#{comment}_#{instance.hash}.png"
  100. log('screenshot', { filename: filename })
  101. instance.save_screenshot(filename)
  102. end
  103. =begin
  104. username = login(
  105. browser: browser1,
  106. username: 'someuser',
  107. password: 'somepassword',
  108. url: 'some url', # optional
  109. remember_me: true, # optional
  110. auto_wizard: false, # optional, in case of auto wizard, skip login
  111. )
  112. =end
  113. def login(params)
  114. switch_window_focus(params)
  115. log('login', params)
  116. instance = params[:browser] || @browser
  117. if params[:url]
  118. instance.get(params[:url])
  119. end
  120. element = instance.find_elements(css: '#login input[name="username"]')[0]
  121. if !element
  122. if params[:auto_wizard]
  123. watch_for(
  124. browser: instance,
  125. css: 'body',
  126. value: 'auto wizard is enabled',
  127. timeout: 10,
  128. )
  129. location( url: "#{browser_url}/#getting_started/auto_wizard" )
  130. sleep 10
  131. login = instance.find_elements(css: '.user-menu .user a')[0].attribute('title')
  132. if login != params[:username]
  133. screenshot(browser: instance, comment: 'auto wizard login failed')
  134. raise 'auto wizard login failed'
  135. end
  136. assert(true, 'auto wizard login ok')
  137. clues_close(
  138. browser: instance,
  139. optional: true,
  140. )
  141. return
  142. end
  143. screenshot(browser: instance, comment: 'login_failed')
  144. raise 'No login box found'
  145. end
  146. screenshot(browser: instance, comment: 'login')
  147. element.clear
  148. element.send_keys(params[:username])
  149. element = instance.find_elements(css: '#login input[name="password"]')[0]
  150. element.clear
  151. element.send_keys(params[:password])
  152. if params[:remember_me]
  153. instance.find_elements(css: '#login .checkbox-replacement')[0].click
  154. end
  155. instance.find_elements(css: '#login button')[0].click
  156. sleep 5
  157. login = instance.find_elements(css: '.user-menu .user a')[0].attribute('title')
  158. if login != params[:username]
  159. screenshot(browser: instance, comment: 'login_failed')
  160. raise 'login failed'
  161. end
  162. clues_close(
  163. browser: instance,
  164. optional: true,
  165. )
  166. screenshot(browser: instance, comment: 'login_ok')
  167. assert(true, 'login ok')
  168. login
  169. end
  170. =begin
  171. logout(
  172. browser: browser1
  173. )
  174. =end
  175. def logout(params = {})
  176. switch_window_focus(params)
  177. log('logout', params)
  178. instance = params[:browser] || @browser
  179. instance.find_elements(css: 'a[href="#current_user"]')[0].click
  180. sleep 0.1
  181. instance.find_elements(css: 'a[href="#logout"]')[0].click
  182. (1..6).each {
  183. sleep 1
  184. login = instance.find_elements(css: '#login')[0]
  185. next if !login
  186. screenshot(browser: instance, comment: 'logout_ok')
  187. assert(true, 'logout ok')
  188. return
  189. }
  190. screenshot(browser: instance, comment: 'logout_failed')
  191. raise 'no login box found, seems logout was not successfully!'
  192. end
  193. =begin
  194. clues_close(
  195. browser: browser1,
  196. optional: false,
  197. )
  198. =end
  199. def clues_close(params = {})
  200. switch_window_focus(params)
  201. log('clues_close', params)
  202. instance = params[:browser] || @browser
  203. clues = instance.find_elements(css: '.js-modal--clue .js-close')[0]
  204. if !params[:optional] && !clues
  205. screenshot(browser: instance, comment: 'no_clues')
  206. raise 'Unable to closes clues, no clues found!'
  207. end
  208. return if !clues
  209. instance.execute_script("$('.js-modal--clue .js-close').click()")
  210. assert(true, 'clues closed')
  211. sleep 4
  212. end
  213. =begin
  214. location(
  215. browser: browser1,
  216. url: 'http://someurl',
  217. )
  218. =end
  219. def location(params)
  220. switch_window_focus(params)
  221. log('location', params)
  222. instance = params[:browser] || @browser
  223. instance.get(params[:url])
  224. # check if reload was successfull
  225. if !instance.find_elements(css: 'body')[0] || instance.find_elements(css: 'body')[0].text =~ /unavailable or too busy/i
  226. instance.navigate.refresh
  227. end
  228. screenshot(browser: instance, comment: 'location')
  229. end
  230. =begin
  231. location_check(
  232. browser: browser1,
  233. url: 'http://someurl',
  234. )
  235. =end
  236. def location_check(params)
  237. switch_window_focus(params)
  238. log('location_check', params)
  239. instance = params[:browser] || @browser
  240. sleep 0.7
  241. current_url = instance.current_url
  242. if current_url !~ /#{Regexp.quote(params[:url])}/
  243. screenshot(browser: instance, comment: 'location_check_failed')
  244. raise "url #{current_url} is not matching #{params[:url]}"
  245. end
  246. assert(true, "url #{current_url} is matching #{params[:url]}")
  247. end
  248. =begin
  249. reload(
  250. browser: browser1,
  251. )
  252. =end
  253. def reload(params = {})
  254. switch_window_focus(params)
  255. log('reload', params)
  256. instance = params[:browser] || @browser
  257. screenshot(browser: instance, comment: 'reload_before')
  258. instance.navigate.refresh
  259. # check if reload was successfull
  260. if !instance.find_elements(css: 'body')[0] || instance.find_elements(css: 'body')[0].text =~ /unavailable or too busy/i
  261. instance.navigate.refresh
  262. end
  263. screenshot(browser: instance, comment: 'reload_after')
  264. end
  265. =begin
  266. click(
  267. browser: browser1,
  268. css: '.some_class',
  269. fast: false, # do not wait
  270. wait: 1, # wait 1 sec.
  271. )
  272. click(
  273. browser: browser1,
  274. text: '.partial_link_text',
  275. fast: false, # do not wait
  276. wait: 1, # wait 1 sec.
  277. )
  278. =end
  279. def click(params)
  280. switch_window_focus(params)
  281. log('click', params)
  282. instance = params[:browser] || @browser
  283. if params[:css]
  284. element = instance.find_elements(css: params[:css])[0]
  285. #instance.mouse.move_to(element)
  286. #sleep 0.2
  287. element.click
  288. # trigger also focus on input/select and textarea fields
  289. #if params[:css] =~ /(input|select|textarea)/
  290. # instance.execute_script("$('#{params[:css]}').trigger('focus')")
  291. # sleep 0.2
  292. #end
  293. else
  294. sleep 1
  295. instance.find_elements(partial_link_text: params[:text])[0].click
  296. end
  297. sleep 0.4 if !params[:fast]
  298. sleep params[:wait] if params[:wait]
  299. end
  300. =begin
  301. scroll_to(
  302. browser: browser1,
  303. position: 'top', # botton
  304. css: '.some_class',
  305. )
  306. =end
  307. def scroll_to(params)
  308. switch_window_focus(params)
  309. log('scroll_to', params)
  310. instance = params[:browser] || @browser
  311. position = 'true'
  312. if params[:position] == 'botton'
  313. position = 'false'
  314. end
  315. execute(
  316. browser: instance,
  317. js: "\$('#{params[:css]}').get(0).scrollIntoView(#{position})",
  318. mute_log: params[:mute_log]
  319. )
  320. sleep 0.2
  321. end
  322. =begin
  323. execute(
  324. browser: browser1,
  325. js: '.some_class',
  326. )
  327. =end
  328. def execute(params)
  329. switch_window_focus(params)
  330. log('js', params)
  331. instance = params[:browser] || @browser
  332. if params[:js]
  333. return instance.execute_script(params[:js])
  334. end
  335. raise "Invalid execute params #{params.inspect}"
  336. end
  337. =begin
  338. exists(
  339. browser: browser1,
  340. css: '.some_class',
  341. )
  342. =end
  343. def exists(params)
  344. switch_window_focus(params)
  345. log('exists', params)
  346. instance = params[:browser] || @browser
  347. if !instance.find_elements(css: params[:css])[0]
  348. screenshot(browser: instance, comment: 'exists_failed')
  349. raise "#{params[:css]} dosn't exist, but should"
  350. end
  351. true
  352. end
  353. =begin
  354. exists_not(
  355. browser: browser1,
  356. css: '.some_class',
  357. )
  358. =end
  359. def exists_not(params)
  360. switch_window_focus(params)
  361. log('exists_not', params)
  362. instance = params[:browser] || @browser
  363. if instance.find_elements(css: params[:css])[0]
  364. screenshot(browser: instance, comment: 'exists_not_failed')
  365. raise "#{params[:css]} exists but should not"
  366. end
  367. true
  368. end
  369. =begin
  370. set(
  371. browser: browser1,
  372. css: '.some_class',
  373. value: true,
  374. slow: false,
  375. blur: true,
  376. clear: true, # todo | default: true
  377. no_click: true,
  378. )
  379. =end
  380. def set(params)
  381. switch_window_focus(params)
  382. log('set', params)
  383. instance = params[:browser] || @browser
  384. element = instance.find_elements(css: params[:css])[0]
  385. if !params[:no_click]
  386. element.click
  387. end
  388. element.clear
  389. if !params[:slow]
  390. element.send_keys(params[:value])
  391. else
  392. element.send_keys('')
  393. keys = params[:value].to_s.split('')
  394. keys.each {|key|
  395. instance.action.send_keys(key).perform
  396. }
  397. end
  398. if params[:blur]
  399. instance.execute_script("$('#{params[:css]}').blur()")
  400. end
  401. sleep 0.5
  402. end
  403. =begin
  404. select(
  405. browser: browser1,
  406. css: '.some_class',
  407. value: 'Some Value',
  408. )
  409. =end
  410. def select(params)
  411. switch_window_focus(params)
  412. log('select', params)
  413. instance = params[:browser] || @browser
  414. # searchable select
  415. element = instance.find_elements(css: "#{params[:css]}.js-shadow")[0]
  416. if element
  417. element = instance.find_elements(css: "#{params[:css]}.js-shadow + .js-input")[0]
  418. element.click
  419. element.clear
  420. sleep 1
  421. element.send_keys(params[:value])
  422. sleep 0.5
  423. element.send_keys(:enter)
  424. sleep 0.5
  425. return
  426. end
  427. # native select
  428. begin
  429. element = instance.find_elements(css: params[:css])[0]
  430. dropdown = Selenium::WebDriver::Support::Select.new(element)
  431. dropdown.select_by(:text, params[:value])
  432. puts "select - #{params.inspect}"
  433. rescue
  434. # just try again
  435. element = instance.find_elements(css: params[:css])[0]
  436. dropdown = Selenium::WebDriver::Support::Select.new(element)
  437. dropdown.select_by(:text, params[:value])
  438. puts "select2 - #{params.inspect}"
  439. end
  440. end
  441. =begin
  442. switch(
  443. browser: browser1,
  444. css: '.some_class',
  445. type: 'on', # 'off'
  446. )
  447. =end
  448. def switch(params)
  449. switch_window_focus(params)
  450. log('switch', params)
  451. instance = params[:browser] || @browser
  452. element = instance.find_elements(css: "#{params[:css]} input[type=checkbox]")[0]
  453. checked = element.attribute('checked')
  454. if !checked
  455. if params[:type] == 'on'
  456. instance.find_elements(css: "#{params[:css]} label")[0].click
  457. end
  458. elsif params[:type] == 'off'
  459. instance.find_elements(css: "#{params[:css]} label")[0].click
  460. end
  461. end
  462. =begin
  463. check(
  464. browser: browser1,
  465. css: '.some_class',
  466. )
  467. =end
  468. def check(params)
  469. switch_window_focus(params)
  470. log('check', params)
  471. instance = params[:browser] || @browser
  472. instance.execute_script("if (!$('#{params[:css]}').prop('checked')) { $('#{params[:css]}').click() }")
  473. #element = instance.find_elements(css: params[:css])[0]
  474. #checked = element.attribute('checked')
  475. #element.click if !checked
  476. end
  477. =begin
  478. uncheck(
  479. browser: browser1,
  480. css: '.some_class',
  481. )
  482. =end
  483. def uncheck(params)
  484. switch_window_focus(params)
  485. log('uncheck', params)
  486. instance = params[:browser] || @browser
  487. instance.execute_script("if ($('#{params[:css]}').prop('checked')) { $('#{params[:css]}').click() }")
  488. #element = instance.find_elements(css: params[:css])[0]
  489. #checked = element.attribute('checked')
  490. #element.click if checked
  491. end
  492. =begin
  493. sendkey(
  494. browser: browser1,
  495. value: :enter,
  496. slow: false,
  497. )
  498. =end
  499. def sendkey(params)
  500. switch_window_focus(params)
  501. log('sendkey', params)
  502. instance = params[:browser] || @browser
  503. if params[:value].class == Array
  504. params[:value].each {|key|
  505. instance.action.send_keys(key).perform
  506. }
  507. return
  508. end
  509. instance.action.send_keys(params[:value]).perform
  510. if params[:slow]
  511. sleep 2
  512. else
  513. sleep 0.3
  514. end
  515. end
  516. =begin
  517. match(
  518. browser: browser1,
  519. css: '#content .text-1',
  520. value: 'some test for browser and some other for browser',
  521. attribute: 'some_attribute', # match on attribute
  522. should_not_match: true,
  523. no_quote: false, # use regex
  524. )
  525. =end
  526. def match(params, fallback = false)
  527. switch_window_focus(params)
  528. log('match', params)
  529. instance = params[:browser] || @browser
  530. element = instance.find_elements(css: params[:css])[0]
  531. if params[:css] =~ /select/
  532. dropdown = Selenium::WebDriver::Support::Select.new(element)
  533. success = false
  534. if dropdown.selected_options
  535. dropdown.selected_options.each {|option|
  536. if option.text == params[:value]
  537. success = true
  538. end
  539. }
  540. end
  541. if params[:should_not_match]
  542. if success
  543. raise "should not match '#{params[:value]}' in select list, but is matching"
  544. end
  545. elsif !success
  546. raise "not matching '#{params[:value]}' in select list"
  547. end
  548. return true
  549. end
  550. # match on attribute
  551. begin
  552. text = if params[:attribute]
  553. element.attribute(params[:attribute])
  554. elsif params[:css] =~ /(input|textarea)/i
  555. element.attribute('value')
  556. else
  557. element.text
  558. end
  559. rescue => e
  560. # just try again
  561. if !fallback
  562. return match(params, true)
  563. end
  564. raise e.inspect
  565. end
  566. # do cleanups (needed for richtext tests)
  567. if params[:cleanup]
  568. text.gsub!(/\s+$/m, '')
  569. params[:value].gsub!(/\s+$/m, '')
  570. end
  571. match = false
  572. if params[:no_quote]
  573. #puts "aaaa #{text}/#{params[:value]}"
  574. if text =~ /#{params[:value]}/i
  575. match = $1 || true
  576. end
  577. elsif text =~ /#{Regexp.quote(params[:value])}/i
  578. match = true
  579. end
  580. if match
  581. if params[:should_not_match]
  582. raise "matching '#{params[:value]}' in content '#{text}' but should not!"
  583. end
  584. elsif !params[:should_not_match]
  585. raise "not matching '#{params[:value]}' in content '#{text}' but should!"
  586. end
  587. sleep 0.8
  588. match
  589. end
  590. =begin
  591. match_not(
  592. browser: browser1,
  593. css: '#content .text-1',
  594. value: 'some test for browser and some other for browser',
  595. attribute: 'some_attribute', # match on attribute
  596. should_not_match: true,
  597. no_quote: false, # use regex
  598. )
  599. =end
  600. def match_not(params)
  601. switch_window_focus(params)
  602. log('match_not', params)
  603. params[:should_not_match] = true
  604. match(params)
  605. end
  606. =begin
  607. task_type(
  608. browser: browser1,
  609. type: 'stayOnTab',
  610. )
  611. =end
  612. def task_type(params)
  613. switch_window_focus(params)
  614. log('task_type', params)
  615. instance = params[:browser] || @browser
  616. if params[:type]
  617. instance.find_elements(css: '.content.active .js-secondaryActionButtonLabel')[0].click
  618. instance.find_elements(css: ".content.active .js-secondaryActionLabel[data-type=#{params[:type]}]")[0].click
  619. return
  620. end
  621. raise "Unknown params for task_type: #{params.inspect}"
  622. end
  623. =begin
  624. cookie(
  625. browser: browser1,
  626. name: '^_zammad.+?',
  627. value: '.+?',
  628. expires: nil,
  629. )
  630. cookie(
  631. browser: browser1,
  632. name: '^_zammad.+?',
  633. should_not_exist: true,
  634. )
  635. =end
  636. def cookie(params)
  637. switch_window_focus(params)
  638. log('cookie', params)
  639. instance = params[:browser] || @browser
  640. if !browser_support_cookies
  641. assert(true, "'#{params[:value]}' ups browser is not supporting reading cookies, go ahead")
  642. return true
  643. end
  644. cookies = instance.manage.all_cookies
  645. cookies.each {|cookie|
  646. #puts "CCC #{cookie.inspect}"
  647. # :name=>"_zammad_session_c25832f4de2", :value=>"adc31cd21615cb0a7ab269184ec8b76f", :path=>"/", :domain=>"localhost", :expires=>nil, :secure=>false}
  648. next if cookie[:name] !~ /#{params[:name]}/i
  649. if params.key?(:value) && cookie[:value].to_s =~ /#{params[:value]}/i
  650. assert(true, "matching value '#{params[:value]}' in cookie '#{cookie}'")
  651. else
  652. raise "not matching value '#{params[:value]}' in cookie '#{cookie}'"
  653. end
  654. if params.key?(:expires) && cookie[:expires].to_s =~ /#{params[:expires]}/i
  655. assert(true, "matching expires '#{params[:expires].inspect}' in cookie '#{cookie}'")
  656. else
  657. raise "not matching expires '#{params[:expires]}' in cookie '#{cookie}'"
  658. end
  659. return if !params[:should_not_exist]
  660. raise "cookie with name '#{params[:name]}' should not exist, but exists '#{cookies}'"
  661. }
  662. if params[:should_not_exist]
  663. assert(true, "cookie with name '#{params[:name]}' is not existing")
  664. return
  665. end
  666. raise "not matching name '#{params[:name]}' in cookie '#{cookies}'"
  667. end
  668. =begin
  669. verify_title(
  670. browser: browser1,
  671. value: 'some title',
  672. )
  673. =end
  674. def verify_title(params = {})
  675. switch_window_focus(params)
  676. log('verify_title', params)
  677. instance = params[:browser] || @browser
  678. title = instance.title
  679. if title =~ /#{params[:value]}/i
  680. assert(true, "matching '#{params[:value]}' in title '#{title}'")
  681. else
  682. raise "not matching '#{params[:value]}' in title '#{title}'"
  683. end
  684. end
  685. =begin
  686. verify_task(
  687. browser: browser1,
  688. data: {
  689. title: 'some title',
  690. modified: true, # optional
  691. }
  692. )
  693. =end
  694. def verify_task(params = {}, fallback = false)
  695. switch_window_focus(params)
  696. log('verify_task', params)
  697. instance = params[:browser] || @browser
  698. data = params[:data]
  699. sleep 1
  700. begin
  701. # verify title
  702. if data[:title]
  703. title = instance.find_elements(css: '.tasks .is-active')[0].text.strip
  704. if title =~ /#{data[:title]}/i
  705. assert(true, "matching '#{data[:title]}' in title '#{title}'")
  706. else
  707. raise "not matching '#{data[:title]}' in title '#{title}'"
  708. end
  709. end
  710. puts "tv #{params.inspect}"
  711. # verify modified
  712. if data.key?(:modified)
  713. exists = instance.find_elements(css: '.tasks .is-active')[0]
  714. is_modified = instance.find_elements(css: '.tasks .is-modified')[0]
  715. puts "m #{data[:modified].inspect}"
  716. if exists
  717. puts ' exists'
  718. end
  719. if is_modified
  720. puts ' is_modified'
  721. end
  722. if data[:modified] == true
  723. if is_modified
  724. assert(true, "task '#{data[:title]}' is modifed")
  725. elsif !exists
  726. raise "task '#{data[:title]}' not exists, should not modified"
  727. else
  728. raise "task '#{data[:title]}' is not modifed"
  729. end
  730. elsif !is_modified
  731. assert(true, "task '#{data[:title]}' is modifed")
  732. elsif !exists
  733. raise "task '#{data[:title]}' not exists, should be not modified"
  734. else
  735. raise "task '#{data[:title]}' is modifed, but should not"
  736. end
  737. end
  738. rescue => e
  739. # just try again
  740. if !fallback
  741. verify_task(params, true)
  742. end
  743. raise 'ERROR: ' + e.inspect
  744. end
  745. true
  746. end
  747. =begin
  748. open_task(
  749. browser: browser1,
  750. data: {
  751. title: 'some title',
  752. }
  753. )
  754. =end
  755. def open_task(params = {})
  756. switch_window_focus(params)
  757. log('open_task', params)
  758. instance = params[:browser] || @browser
  759. data = params[:data]
  760. element = instance.find_elements(partial_link_text: data[:title])[0]
  761. if !element
  762. screenshot(browser: instance, comment: 'open_task_failed')
  763. raise "no task with title '#{data[:title]}' found"
  764. end
  765. element.click
  766. true
  767. end
  768. =begin
  769. close_task(
  770. browser: browser1,
  771. data: {
  772. title: 'some title',
  773. },
  774. discard_changes: true,
  775. )
  776. =end
  777. def close_task(params = {})
  778. switch_window_focus(params)
  779. log('close_task', params)
  780. instance = params[:browser] || @browser
  781. data = params[:data]
  782. element = instance.find_elements(partial_link_text: data[:title])[0]
  783. if !element
  784. screenshot(browser: instance, comment: 'close_task_failed')
  785. raise "no task with title '#{data[:title]}' found"
  786. end
  787. instance.mouse.move_to(element)
  788. sleep 0.1
  789. instance.execute_script("$('.navigation .tasks .task:contains(\"#{data[:title]}\") .js-close').click()")
  790. # accept task close warning
  791. if params[:discard_changes]
  792. sleep 1
  793. instance.find_elements(css: '.modal button.js-submit')[0].click
  794. end
  795. true
  796. end
  797. =begin
  798. file_upload(
  799. browser: browser1,
  800. css: '.active .attachmentPlaceholder-inputHolder input'
  801. files: ['path/in/home/some_file.ext'], # 'test/fixtures/test1.pdf'
  802. )
  803. =end
  804. def file_upload(params = {})
  805. switch_window_focus(params)
  806. log('file_upload', params)
  807. instance = params[:browser] || @browser
  808. params[:files].each {|file|
  809. instance.find_elements(css: params[:css])[0].send_keys "#{Rails.root}/#{file}"
  810. }
  811. sleep 2 * params[:files].count
  812. end
  813. =begin
  814. watch_for(
  815. browser: browser1,
  816. css: '#content .text-1',
  817. value: 'some text',
  818. attribute: 'some_attribute' # optional
  819. timeout: 16, # in sec, default 16
  820. )
  821. =end
  822. def watch_for(params = {})
  823. switch_window_focus(params)
  824. log('watch_for', params)
  825. instance = params[:browser] || @browser
  826. timeout = 16
  827. if params[:timeout]
  828. timeout = params[:timeout]
  829. end
  830. loops = timeout.to_i * 2
  831. text = ''
  832. (1..loops).each {
  833. element = instance.find_elements(css: params[:css])[0]
  834. if element #&& element.displayed?
  835. begin
  836. # match pn attribute
  837. text = if params[:attribute]
  838. element.attribute(params[:attribute])
  839. elsif params[:css] =~ /(input|textarea)/i
  840. element.attribute('value')
  841. else
  842. element.text
  843. end
  844. if text =~ /#{params[:value]}/i
  845. assert(true, "'#{params[:value]}' found in '#{text}'")
  846. sleep 0.5
  847. return true
  848. end
  849. rescue
  850. # try again
  851. end
  852. end
  853. sleep 0.5
  854. }
  855. screenshot(browser: instance, comment: 'watch_for_failed')
  856. raise "'#{params[:value]}' found in '#{text}'"
  857. end
  858. =begin
  859. wait untill selector disabppears
  860. watch_for_disappear(
  861. browser: browser1,
  862. css: '#content .text-1',
  863. timeout: 16, # in sec, default 16
  864. )
  865. wait untill text in selector disabppears
  866. watch_for_disappear(
  867. browser: browser1,
  868. css: '#content .text-1',
  869. value: 'some value as regexp',
  870. timeout: 16, # in sec, default 16
  871. )
  872. =end
  873. def watch_for_disappear(params = {})
  874. switch_window_focus(params)
  875. log('watch_for_disappear', params)
  876. instance = params[:browser] || @browser
  877. timeout = 16
  878. if params[:timeout]
  879. timeout = params[:timeout]
  880. end
  881. loops = timeout.to_i
  882. text = ''
  883. (1..loops).each {
  884. element = instance.find_elements(css: params[:css])[0]
  885. if !element #|| element.displayed?
  886. assert(true, 'not found')
  887. sleep 1
  888. return true
  889. end
  890. if params[:value]
  891. begin
  892. text = instance.find_elements(css: params[:css])[0].text
  893. if text !~ /#{params[:value]}/i
  894. assert(true, "not matching '#{params[:value]}' in text '#{text}'")
  895. sleep 1
  896. return true
  897. end
  898. rescue
  899. # try again
  900. end
  901. end
  902. sleep 1
  903. }
  904. screenshot(browser: instance, comment: 'disappear_failed')
  905. raise "#{params[:css]}) still exsists"
  906. end
  907. =begin
  908. shortcut(
  909. browser: browser1,
  910. key: 'x',
  911. )
  912. =end
  913. def shortcut(params = {})
  914. switch_window_focus(params)
  915. log('shortcut', params)
  916. instance = params[:browser] || @browser
  917. instance.action.key_down(:control)
  918. .key_down(:alt)
  919. .send_keys(params[:key])
  920. .key_up(:alt)
  921. .key_up(:control)
  922. .perform
  923. end
  924. =begin
  925. window_keys(
  926. browser: browser1,
  927. value: 'x',
  928. )
  929. =end
  930. def window_keys(params = {})
  931. switch_window_focus(params)
  932. log('window_keys', params)
  933. instance = params[:browser] || @browser
  934. instance.action.send_keys(params[:value]).perform
  935. end
  936. =begin
  937. tasks_close_all(
  938. browser: browser1,
  939. )
  940. =end
  941. def tasks_close_all(params = {})
  942. switch_window_focus(params)
  943. log('tasks_close_all', params)
  944. instance = params[:browser] || @browser
  945. (1..100).each do
  946. sleep 0.2
  947. begin
  948. if instance.find_elements(css: '.navigation .tasks .task:first-child')[0]
  949. instance.mouse.move_to(instance.find_elements(css: '.navigation .tasks .task:first-child')[0])
  950. sleep 0.1
  951. click_element = instance.find_elements(css: '.navigation .tasks .task:first-child .js-close')[0]
  952. if click_element
  953. click_element.click
  954. # accept task close warning
  955. if instance.find_elements(css: '.modal button.js-submit')[0]
  956. sleep 0.5
  957. instance.find_elements(css: '.modal button.js-submit')[0].click
  958. end
  959. end
  960. else
  961. break
  962. end
  963. rescue
  964. # try again
  965. end
  966. end
  967. assert(true, 'all tasks closed')
  968. end
  969. =begin
  970. empty_search(
  971. browser: browser1,
  972. )
  973. =end
  974. def empty_search(params = {})
  975. switch_window_focus(params)
  976. log('empty_search', params)
  977. instance = params[:browser] || @browser
  978. # empty search box by x
  979. begin
  980. instance.find_elements(css: '.search .empty-search')[0].click
  981. rescue
  982. # in issues with ff & selenium, sometimes exeption appears
  983. # "Element is not currently visible and so may not be interacted with"
  984. log('empty_search via js')
  985. instance.execute_script('$(".search .empty-search").click()')
  986. end
  987. sleep 0.5
  988. text = instance.find_elements(css: '#global-search')[0].attribute('value')
  989. if !text
  990. raise '#global-search is not empty!'
  991. end
  992. true
  993. end
  994. =begin
  995. ticket_customer_select(
  996. browser: browser1,
  997. css: '#content .text-1',
  998. customer: '',
  999. )
  1000. =end
  1001. def ticket_customer_select(params = {})
  1002. switch_window_focus(params)
  1003. log('ticket_customer_select', params)
  1004. instance = params[:browser] || @browser
  1005. element = instance.find_elements(css: params[:css] + ' input[name="customer_id_completion"]')[0]
  1006. element.click
  1007. element.clear
  1008. # workaround, sometimes focus is not triggered
  1009. element.send_keys(params[:customer])
  1010. sleep 3.5
  1011. # check if pulldown is open, it's not working stable via selenium
  1012. #instance.execute_script("$('#{params[:css]} .js-recipientDropdown').addClass('open')")
  1013. #sleep 0.5
  1014. element.send_keys(:arrow_down)
  1015. sleep 0.3
  1016. element.send_keys(:enter)
  1017. #instance.find_elements(css: params[:css] + ' .recipientList-entry.js-user.is-active')[0].click
  1018. sleep 0.6
  1019. assert(true, 'ticket_customer_select')
  1020. end
  1021. =begin
  1022. overview_create(
  1023. browser: browser1,
  1024. data: {
  1025. name: name,
  1026. role: 'Agent',
  1027. selector: {
  1028. 'Priority': '1 low',
  1029. },
  1030. 'order::direction' => 'down',
  1031. }
  1032. )
  1033. =end
  1034. def overview_create(params)
  1035. switch_window_focus(params)
  1036. log('overview_create', params)
  1037. instance = params[:browser] || @browser
  1038. data = params[:data]
  1039. instance.find_elements(css: 'a[href="#manage"]')[0].click
  1040. sleep 0.2
  1041. instance.find_elements(css: 'a[href="#manage/overviews"]')[0].click
  1042. sleep 0.2
  1043. instance.find_elements(css: '#content a[data-type="new"]')[0].click
  1044. sleep 2
  1045. if data[:name]
  1046. element = instance.find_elements(css: '.modal input[name=name]')[0]
  1047. element.clear
  1048. element.send_keys(data[:name])
  1049. end
  1050. if data[:role]
  1051. element = instance.find_elements(css: '.modal select[name="role_id"]')[0]
  1052. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1053. dropdown.select_by(:text, data[:role])
  1054. end
  1055. if data[:selector]
  1056. data[:selector].each {|key, value|
  1057. element = instance.find_elements(css: '.modal .ticket_selector .js-attributeSelector select')[0]
  1058. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1059. dropdown.select_by(:text, key)
  1060. sleep 0.5
  1061. element = instance.find_elements(css: '.modal .ticket_selector .js-value select')[0]
  1062. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1063. dropdown.deselect_all
  1064. dropdown.select_by(:text, value)
  1065. }
  1066. end
  1067. if data['order::direction']
  1068. element = instance.find_elements(css: '.modal select[name="order::direction"]')[0]
  1069. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1070. dropdown.select_by(:text, data['order::direction'])
  1071. end
  1072. instance.find_elements(css: '.modal button.js-submit')[0].click
  1073. (1..12).each {
  1074. element = instance.find_elements(css: 'body')[0]
  1075. text = element.text
  1076. if text =~ /#{Regexp.quote(data[:name])}/
  1077. assert(true, 'overview created')
  1078. overview = {
  1079. name: name,
  1080. }
  1081. sleep 1
  1082. return overview
  1083. end
  1084. sleep 1
  1085. }
  1086. screenshot(browser: instance, comment: 'overview_create_failed')
  1087. raise 'overview creation failed'
  1088. end
  1089. =begin
  1090. overview_update(
  1091. browser: browser1,
  1092. data: {
  1093. name: name,
  1094. role: 'Agent',
  1095. selector: {
  1096. 'Priority': '1 low',
  1097. },
  1098. 'order::direction' => 'down',
  1099. }
  1100. )
  1101. =end
  1102. def overview_update(params)
  1103. switch_window_focus(params)
  1104. log('overview_create', params)
  1105. instance = params[:browser] || @browser
  1106. data = params[:data]
  1107. instance.find_elements(css: 'a[href="#manage"]')[0].click
  1108. sleep 0.2
  1109. instance.find_elements(css: 'a[href="#manage/overviews"]')[0].click
  1110. sleep 1
  1111. #instance.find_elements(css: '#content a[data-type="new"]')[0].click
  1112. #sleep 2
  1113. instance.execute_script("$(\"#content td:contains('#{data[:name]}')\").first().click()")
  1114. sleep 2
  1115. if data[:name]
  1116. element = instance.find_elements(css: '.modal input[name=name]')[0]
  1117. element.clear
  1118. element.send_keys(data[:name])
  1119. end
  1120. if data[:role]
  1121. element = instance.find_elements(css: '.modal select[name="role_id"]')[0]
  1122. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1123. dropdown.select_by(:text, data[:role])
  1124. end
  1125. if data[:selector]
  1126. data[:selector].each {|key, value|
  1127. element = instance.find_elements(css: '.modal .ticket_selector .js-attributeSelector select')[0]
  1128. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1129. dropdown.select_by(:text, key)
  1130. instance.execute_script("$('#content .modal .ticket_selector .js-attributeSelector select').first().trigger('change')")
  1131. element = instance.find_elements(css: '.modal .ticket_selector .js-value select')[0]
  1132. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1133. dropdown.deselect_all
  1134. dropdown.select_by(:text, value)
  1135. }
  1136. end
  1137. if data['order::direction']
  1138. element = instance.find_elements(css: '.modal select[name="order::direction"]')[0]
  1139. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1140. dropdown.select_by(:text, data['order::direction'])
  1141. end
  1142. instance.find_elements(css: '.modal button.js-submit')[0].click
  1143. (1..12).each {
  1144. element = instance.find_elements(css: 'body')[0]
  1145. text = element.text
  1146. if text =~ /#{Regexp.quote(data[:name])}/
  1147. assert(true, 'overview updated')
  1148. overview = {
  1149. name: name,
  1150. }
  1151. sleep 1
  1152. return overview
  1153. end
  1154. sleep 1
  1155. }
  1156. screenshot(browser: instance, comment: 'overview_update_failed')
  1157. raise 'overview update failed'
  1158. end
  1159. =begin
  1160. ticket = ticket_create(
  1161. browser: browser1,
  1162. data: {
  1163. customer: 'nico',
  1164. group: 'Users', # optional / '-NONE-' # if group selection should not be shown
  1165. priority: '2 normal',
  1166. title: 'overview #1',
  1167. body: 'overview #1',
  1168. },
  1169. do_not_submit: true,
  1170. )
  1171. returns (in case of submitted)
  1172. {
  1173. id: 123,
  1174. number: '100001',
  1175. title: 'overview #1',
  1176. }
  1177. =end
  1178. def ticket_create(params)
  1179. switch_window_focus(params)
  1180. log('ticket_create', params)
  1181. instance = params[:browser] || @browser
  1182. data = params[:data]
  1183. instance.find_elements(css: 'a[href="#new"]')[0].click
  1184. instance.find_elements(css: 'a[href="#ticket/create"]')[0].click
  1185. element = instance.find_elements(css: '.active .newTicket')[0]
  1186. if !element
  1187. screenshot(browser: instance, comment: 'ticket_create_failed')
  1188. raise 'no ticket create screen found!'
  1189. end
  1190. sleep 1
  1191. if data[:group]
  1192. if data[:group] == '-NONE-'
  1193. # check if owner selection exists
  1194. count = instance.find_elements(css: '.active .newTicket select[name="group_id"] option').count
  1195. assert_equal(0, count, 'owner selection should not be showm')
  1196. # check count of agents, should be only 3 / - selection + master + agent on init screen
  1197. count = instance.find_elements(css: '.active .newTicket select[name="owner_id"] option').count
  1198. assert_equal(3, count, 'check if owner selection is - selection + master + agent per default')
  1199. else
  1200. # check count of agents, should be only 1 / - selection on init screen
  1201. count = instance.find_elements(css: '.active .newTicket select[name="owner_id"] option').count
  1202. assert_equal(1, count, 'check if owner selection is empty per default')
  1203. element = instance.find_elements(css: '.active .newTicket select[name="group_id"]')[0]
  1204. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1205. dropdown.select_by(:text, data[:group])
  1206. sleep 0.2
  1207. end
  1208. end
  1209. if data[:priority]
  1210. element = instance.find_elements(css: '.active .newTicket select[name="priority_id"]')[0]
  1211. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1212. dropdown.select_by(:text, data[:priority])
  1213. sleep 0.2
  1214. end
  1215. if data[:title]
  1216. element = instance.find_elements(css: '.active .newTicket input[name="title"]')[0]
  1217. element.clear
  1218. element.send_keys(data[:title])
  1219. sleep 0.2
  1220. end
  1221. if data[:body]
  1222. #instance.execute_script('$(".active .newTicket div[data-name=body]").focus()')
  1223. sleep 0.5
  1224. element = instance.find_elements(css: '.active .newTicket div[data-name=body]')[0]
  1225. element.clear
  1226. element.send_keys(data[:body])
  1227. # it's not working stable via selenium, use js
  1228. value = instance.find_elements(css: '.content .newTicket div[data-name=body]')[0].text
  1229. #puts "V #{value.inspect}"
  1230. if value != data[:body]
  1231. body_quoted = quote(data[:body])
  1232. instance.execute_script("$('.content.active div[data-name=body]').html('#{body_quoted}').trigger('focusout')")
  1233. end
  1234. end
  1235. if data[:customer]
  1236. element = instance.find_elements(css: '.active .newTicket input[name="customer_id_completion"]')[0]
  1237. element.click
  1238. element.clear
  1239. # workaround, sometimes focus is not triggered
  1240. element.send_keys(data[:customer])
  1241. sleep 3.5
  1242. # check if pulldown is open, it's not working stable via selenium
  1243. #instance.execute_script("$('.active .newTicket .js-recipientDropdown').addClass('open')")
  1244. #sleep 0.5
  1245. element.send_keys(:arrow_down)
  1246. sleep 0.3
  1247. element.send_keys(:enter)
  1248. #instance.find_elements(css: '.active .newTicket .recipientList-entry.js-user.is-active')[0].click
  1249. sleep 0.6
  1250. end
  1251. if data[:attachment]
  1252. file_upload(
  1253. browser: instance,
  1254. css: '#content .text-1',
  1255. value: 'some text',
  1256. )
  1257. end
  1258. if params[:do_not_submit]
  1259. assert(true, 'ticket created without submit')
  1260. return
  1261. end
  1262. sleep 0.8
  1263. #instance.execute_script('$(".content.active .newTicket form").submit();')
  1264. instance.find_elements(css: '.active .newTicket button.js-submit')[0].click
  1265. sleep 1
  1266. (1..10).each {
  1267. if instance.current_url =~ /#{Regexp.quote('#ticket/zoom/')}/
  1268. assert(true, 'ticket created')
  1269. sleep 2.5
  1270. id = instance.current_url
  1271. id.gsub!(//,)
  1272. id.gsub!(%r{^.+?/(\d+)$}, '\\1')
  1273. element = instance.find_elements(css: '.active .ticketZoom-header .ticket-number')[0]
  1274. if element
  1275. number = element.text
  1276. ticket = {
  1277. id: id,
  1278. number: number,
  1279. title: data[:title],
  1280. }
  1281. sleep 3 # wait until notify is gone
  1282. screenshot(browser: instance, comment: 'ticket_create_ok')
  1283. return ticket
  1284. end
  1285. end
  1286. sleep 1
  1287. }
  1288. screenshot(browser: instance, comment: 'ticket_create_failed')
  1289. raise "ticket creation failed, can't get zoom url (current url is '#{instance.current_url}')"
  1290. end
  1291. =begin
  1292. ticket_update(
  1293. browser: browser1,
  1294. data: {
  1295. title: '',
  1296. customer: 'some_customer@example.com',
  1297. body: 'some body',
  1298. group: 'some group', # optional
  1299. priority: '1 low',
  1300. state: 'closed',
  1301. },
  1302. do_not_submit: true,
  1303. )
  1304. =end
  1305. def ticket_update(params)
  1306. switch_window_focus(params)
  1307. log('ticket_update', params)
  1308. instance = params[:browser] || @browser
  1309. data = params[:data]
  1310. if data[:title]
  1311. #element = instance.find_elements(:css => '.content.active .ticketZoom-header .ticket-title-update')[0]
  1312. #element.clear
  1313. #sleep 0.5
  1314. #element = instance.find_elements(:css => '.content.active .ticketZoom-header .ticket-title-update')[0]
  1315. #element.send_keys(data[:title])
  1316. #sleep 0.5
  1317. #element.send_keys(:tab)
  1318. instance.execute_script('$(".content.active .ticketZoom-header .ticket-title-update").focus()')
  1319. instance.execute_script('$(".content.active .ticketZoom-header .ticket-title-update").text("' + data[:title] + '")')
  1320. instance.execute_script('$(".content.active .ticketZoom-header .ticket-title-update").blur()')
  1321. instance.execute_script('$(".content.active .ticketZoom-header .ticket-title-update").trigger("blur")')
  1322. # {
  1323. # :where => :instance2,
  1324. # :execute => 'sendkey',
  1325. # :css => '.content.active .ticketZoom-header .ticket-title-update',
  1326. # :value => 'TTT',
  1327. # },
  1328. # {
  1329. # :where => :instance2,
  1330. # :execute => 'sendkey',
  1331. # :css => '.content.active .ticketZoom-header .ticket-title-update',
  1332. # :value => :tab,
  1333. # },
  1334. end
  1335. if data[:customer]
  1336. # select tab
  1337. click(browser: instance, css: '.active .tabsSidebar-tab[data-tab="customer"]')
  1338. click(browser: instance, css: '.active div[data-tab="customer"] .js-actions .icon-arrow-down')
  1339. click(browser: instance, css: '.active div[data-tab="customer"] .js-actions [data-type="customer-change"]')
  1340. watch_for(
  1341. browser: instance,
  1342. css: '.modal',
  1343. value: 'change',
  1344. )
  1345. element = instance.find_elements(css: '.modal input[name="customer_id_completion"]')[0]
  1346. element.click
  1347. element.clear
  1348. # workaround, sometimes focus is not triggered
  1349. element.send_keys(data[:customer])
  1350. sleep 3.5
  1351. # check if pulldown is open, it's not working stable via selenium
  1352. #instance.execute_script("$('.modal .user_autocompletion .js-recipientDropdown').addClass('open')")
  1353. #sleep 0.5
  1354. element.send_keys(:arrow_down)
  1355. sleep 0.6
  1356. element.send_keys(:enter)
  1357. #instance.find_elements(css: '.modal .user_autocompletion .recipientList-entry.js-user.is-active')[0].click
  1358. sleep 0.3
  1359. click(browser: instance, css: '.modal .js-submit')
  1360. watch_for_disappear(
  1361. browser: instance,
  1362. css: '.modal',
  1363. )
  1364. watch_for(
  1365. browser: instance,
  1366. css: '.active .tabsSidebar',
  1367. value: data[:customer],
  1368. )
  1369. # select tab
  1370. click(browser: instance, css: '.active .tabsSidebar-tab[data-tab="ticket"]')
  1371. end
  1372. if data[:body]
  1373. #instance.execute_script('$(".content.active div[data-name=body]").focus()')
  1374. sleep 0.5
  1375. element = instance.find_elements(css: '.content.active div[data-name=body]')[0]
  1376. element.clear
  1377. element.send_keys(data[:body])
  1378. # it's not working stable via selenium, use js
  1379. value = instance.find_elements(css: '.content.active div[data-name=body]')[0].text
  1380. if value != data[:body]
  1381. body_quoted = quote(data[:body])
  1382. instance.execute_script("$('.content.active div[data-name=body]').html('#{body_quoted}').trigger('focusout')")
  1383. end
  1384. end
  1385. if data[:group]
  1386. if data[:group] == '-NONE-'
  1387. # check if owner selection exists
  1388. count = instance.find_elements(css: '.active .sidebar select[name="group_id"] option').count
  1389. assert_equal(0, count, 'owner selection should not be showm')
  1390. # check count of agents, should be only 3 / - selection + master + agent on init screen
  1391. count = instance.find_elements(css: '.active .sidebar select[name="owner_id"] option').count
  1392. assert_equal(3, count, 'check if owner selection is - selection + master + agent per default')
  1393. else
  1394. element = instance.find_elements(css: '.active .sidebar select[name="group_id"]')[0]
  1395. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1396. dropdown.select_by(:text, data[:group])
  1397. sleep 0.2
  1398. end
  1399. end
  1400. if data[:priority]
  1401. element = instance.find_elements(css: '.active .sidebar select[name="priority_id"]')[0]
  1402. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1403. dropdown.select_by(:text, data[:priority])
  1404. sleep 0.2
  1405. end
  1406. if data[:state]
  1407. element = instance.find_elements(css: '.active .sidebar select[name="state_id"]')[0]
  1408. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1409. dropdown.select_by(:text, data[:state])
  1410. sleep 0.2
  1411. end
  1412. if data[:state] || data[:group] || data[:body]
  1413. found = nil
  1414. (1..10).each {
  1415. break if found
  1416. begin
  1417. text = instance.find_elements(css: '.content.active .js-reset')[0].text
  1418. if text =~ /(Discard your unsaved changes.|Verwerfen der)/
  1419. found = true
  1420. end
  1421. rescue
  1422. # try again
  1423. end
  1424. sleep 1
  1425. }
  1426. if !found
  1427. screenshot(browser: instance, comment: 'ticket_update_discard_message_failed')
  1428. raise 'no discard message found'
  1429. end
  1430. end
  1431. task_type(
  1432. browser: instance,
  1433. type: 'stayOnTab',
  1434. )
  1435. if params[:do_not_submit]
  1436. assert(true, 'ticket updated without submit')
  1437. return true
  1438. end
  1439. instance.find_elements(css: '.content.active .js-submit')[0].click
  1440. (1..10).each {
  1441. begin
  1442. text = instance.find_elements(css: '.content.active .js-reset')[0].text
  1443. if !text || text.empty?
  1444. screenshot(browser: instance, comment: 'ticket_update_ok')
  1445. sleep 1
  1446. return true
  1447. end
  1448. rescue
  1449. # try again
  1450. end
  1451. sleep 1
  1452. }
  1453. screenshot(browser: instance, comment: 'ticket_update_failed')
  1454. raise 'unable to update ticket'
  1455. end
  1456. =begin
  1457. ticket_verify(
  1458. browser: browser1,
  1459. data: {
  1460. title: 'some title',
  1461. body: 'some body',
  1462. ## group: 'some group',
  1463. ## state: 'closed',
  1464. },
  1465. )
  1466. =end
  1467. def ticket_verify(params)
  1468. switch_window_focus(params)
  1469. log('ticket_verify', params)
  1470. instance = params[:browser] || @browser
  1471. data = params[:data]
  1472. if data[:title]
  1473. title = instance.find_elements(css: '.content.active .ticketZoom-header .ticket-title-update')[0].text.strip
  1474. if title =~ /#{data[:title]}/i
  1475. assert(true, "matching '#{data[:title]}' in title '#{title}'")
  1476. else
  1477. raise "not matching '#{data[:title]}' in title '#{title}'"
  1478. end
  1479. end
  1480. if data[:body]
  1481. body = instance.find_elements(css: '.content.active [data-name="body"]')[0].text.strip
  1482. if body =~ /#{data[:body]}/i
  1483. assert(true, "matching '#{data[:body]}' in body '#{body}'")
  1484. else
  1485. raise "not matching '#{data[:body]}' in body '#{body}'"
  1486. end
  1487. end
  1488. true
  1489. end
  1490. =begin
  1491. ticket_open_by_overview(
  1492. browser: browser2,
  1493. number: ticket1[:number],
  1494. link: "#ticket/view/#{name}",
  1495. )
  1496. =end
  1497. def ticket_open_by_overview(params)
  1498. switch_window_focus(params)
  1499. log('ticket_open_by_overview', params)
  1500. instance = params[:browser] || @browser
  1501. instance.find_elements(css: '.js-overviewsMenuItem')[0].click
  1502. sleep 1
  1503. execute(
  1504. browser: instance,
  1505. js: '$(".content.active .sidebar").css("display", "block")',
  1506. )
  1507. instance.find_elements(css: ".content.active .sidebar a[href=\"#{params[:link]}\"]")[0].click
  1508. sleep 1
  1509. execute(
  1510. browser: instance,
  1511. js: '$(".content.active .sidebar").css("display", "none")',
  1512. )
  1513. instance.find_elements(partial_link_text: params[:number])[0].click
  1514. sleep 1
  1515. number = instance.find_elements(css: '.active .ticketZoom-header .ticket-number')[0].text
  1516. if number !~ /#{params[:number]}/
  1517. screenshot(browser: instance, comment: 'ticket_open_by_overview_failed')
  1518. raise "unable to search/find ticket #{params[:number]}!"
  1519. end
  1520. sleep 1
  1521. assert(true, "ticket #{params[:number]} found")
  1522. true
  1523. end
  1524. =begin
  1525. ticket_open_by_search(
  1526. browser: browser2,
  1527. number: ticket1[:number],
  1528. )
  1529. =end
  1530. def ticket_open_by_search(params)
  1531. switch_window_focus(params)
  1532. log('ticket_open_by_search', params)
  1533. instance = params[:browser] || @browser
  1534. # search by number
  1535. element = instance.find_elements(css: '#global-search')[0]
  1536. element.click
  1537. element.clear
  1538. element.send_keys(params[:number])
  1539. sleep 3
  1540. empty_search(browser: instance)
  1541. # search by number again
  1542. element = instance.find_elements(css: '#global-search')[0]
  1543. element.click
  1544. element.clear
  1545. element.send_keys(params[:number])
  1546. sleep 1
  1547. # open ticket
  1548. #instance.find_element(partial_link_text: params[:number] } ).click
  1549. instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
  1550. number = instance.find_elements(css: '.active .ticketZoom-header .ticket-number')[0].text
  1551. if number !~ /#{params[:number]}/
  1552. screenshot(browser: instance, comment: 'ticket_open_by_search_failed')
  1553. raise "unable to search/find ticket #{params[:number]}!"
  1554. end
  1555. sleep 1
  1556. true
  1557. end
  1558. =begin
  1559. ticket_open_by_title(
  1560. browser: browser2,
  1561. title: ticket1[:title],
  1562. )
  1563. =end
  1564. def ticket_open_by_title(params)
  1565. switch_window_focus(params)
  1566. log('ticket_open_by_title', params)
  1567. instance = params[:browser] || @browser
  1568. # search by number
  1569. element = instance.find_elements(css: '#global-search')[0]
  1570. element.click
  1571. element.clear
  1572. element.send_keys(params[:title])
  1573. sleep 3
  1574. # open ticket
  1575. #instance.find_element(partial_link_text: params[:title] } ).click
  1576. instance.execute_script("$(\"#global-search-result a:contains('#{params[:title]}') .nav-tab-icon\").click()")
  1577. title = instance.find_elements(css: '.active .ticketZoom-header .ticket-title-update')[0].text
  1578. if title !~ /#{params[:title]}/
  1579. screenshot(browser: instance, comment: 'ticket_open_by_title_failed')
  1580. raise "unable to search/find ticket #{params[:title]}!"
  1581. end
  1582. sleep 1
  1583. true
  1584. end
  1585. =begin
  1586. overview_count = overview_counter(
  1587. browser: browser2,
  1588. )
  1589. returns
  1590. {
  1591. '#ticket/view/all_unassigned' => 42,
  1592. }
  1593. =end
  1594. def overview_counter(params = {})
  1595. switch_window_focus(params)
  1596. log('overview_counter', params)
  1597. instance = params[:browser] || @browser
  1598. instance.find_elements(css: '.js-overviewsMenuItem')[0].click
  1599. sleep 2
  1600. execute(
  1601. browser: instance,
  1602. js: '$(".content.active .sidebar").css("display", "block")',
  1603. )
  1604. #execute(
  1605. # browser: instance,
  1606. # js: '$(".content.active .overview-header").css("display", "none")',
  1607. #)
  1608. overviews = {}
  1609. instance.find_elements(css: '.content.active .sidebar a[href]').each {|element|
  1610. url = element.attribute('href')
  1611. url.gsub!(%r{(http|https)://.+?/(.+?)$}, '\\2')
  1612. overviews[url] = 0
  1613. #puts url.inspect
  1614. #puts element.inspect
  1615. }
  1616. overviews.each {|url, _value|
  1617. count = instance.find_elements(css: ".content.active .sidebar a[href=\"#{url}\"] .badge")[0].text
  1618. overviews[url] = count.to_i
  1619. }
  1620. log('overview_counter', overviews)
  1621. overviews
  1622. end
  1623. =begin
  1624. organization_open_by_search(
  1625. browser: browser2,
  1626. value: 'some value',
  1627. )
  1628. =end
  1629. def organization_open_by_search(params = {})
  1630. switch_window_focus(params)
  1631. log('organization_open_by_search', params)
  1632. instance = params[:browser] || @browser
  1633. element = instance.find_elements(css: '#global-search')[0]
  1634. element.click
  1635. element.clear
  1636. element.send_keys(params[:value])
  1637. sleep 3
  1638. empty_search(browser: instance)
  1639. element = instance.find_elements(css: '#global-search')[0]
  1640. element.click
  1641. element.clear
  1642. element.send_keys(params[:value])
  1643. sleep 2
  1644. #instance.find_element(partial_link_text: params[:value] } ).click
  1645. instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
  1646. name = instance.find_elements(css: '.active h1')[0].text
  1647. if name !~ /#{params[:value]}/
  1648. screenshot(browser: instance, comment: 'organization_open_by_search_failed')
  1649. raise "unable to search/find org #{params[:value]}!"
  1650. end
  1651. assert(true, "org #{params[:value]} found")
  1652. sleep 2
  1653. true
  1654. end
  1655. =begin
  1656. user_open_by_search(
  1657. browser: browser2,
  1658. value: 'some value',
  1659. )
  1660. =end
  1661. def user_open_by_search(params = {})
  1662. switch_window_focus(params)
  1663. log('user_open_by_search', params)
  1664. instance = params[:browser] || @browser
  1665. element = instance.find_elements(css: '#global-search')[0]
  1666. element.click
  1667. element.clear
  1668. element.send_keys(params[:value])
  1669. sleep 3
  1670. #instance.find_element(partial_link_text: params[:value]).click
  1671. instance.execute_script("$(\"#global-search-result a:contains('#{params[:value]}') .nav-tab-icon\").click()")
  1672. name = instance.find_elements(css: '.active h1')[0].text
  1673. if name !~ /#{params[:value]}/
  1674. screenshot(browser: instance, comment: 'user_open_by_search_failed')
  1675. raise "unable to search/find user #{params[:value]}!"
  1676. end
  1677. assert(true, "user #{params[:term]} found")
  1678. sleep 2
  1679. true
  1680. end
  1681. =begin
  1682. user_create(
  1683. browser: browser2,
  1684. data: {
  1685. #login: 'some login' + random,
  1686. firstname: 'Manage Firstname' + random,
  1687. lastname: 'Manage Lastname' + random,
  1688. email: user_email,
  1689. password: 'some-pass',
  1690. },
  1691. )
  1692. =end
  1693. def user_create(params = {})
  1694. switch_window_focus(params)
  1695. log('user_create', params)
  1696. instance = params[:browser] || @browser
  1697. data = params[:data]
  1698. instance.find_elements(css: 'a[href="#manage"]')[0].click
  1699. sleep 1
  1700. instance.find_elements(css: 'a[href="#manage/users"]')[0].click
  1701. sleep 2
  1702. instance.find_elements(css: 'a[data-type="new"]')[0].click
  1703. sleep 2
  1704. element = instance.find_elements(css: '.modal input[name=firstname]')[0]
  1705. element.clear
  1706. element.send_keys(data[:firstname])
  1707. element = instance.find_elements(css: '.modal input[name=lastname]')[0]
  1708. element.clear
  1709. element.send_keys(data[:lastname])
  1710. element = instance.find_elements(css: '.modal input[name=email]')[0]
  1711. element.clear
  1712. element.send_keys(data[:email])
  1713. element = instance.find_elements(css: '.modal input[name=password]')[0]
  1714. element.clear
  1715. element.send_keys(data[:password])
  1716. element = instance.find_elements(css: '.modal input[name=password_confirm]')[0]
  1717. element.clear
  1718. element.send_keys(data[:password])
  1719. check(
  1720. browser: instance,
  1721. css: '.modal input[name=role_ids][value=3]',
  1722. )
  1723. instance.find_elements(css: '.modal button.js-submit')[0].click
  1724. sleep 3.5
  1725. set(
  1726. browser: instance,
  1727. css: '.content .js-search',
  1728. value: data[:email],
  1729. )
  1730. watch_for(
  1731. browser: instance,
  1732. css: 'body',
  1733. value: data[:lastname],
  1734. )
  1735. assert(true, 'user created')
  1736. end
  1737. =begin
  1738. sla_create(
  1739. browser: browser2,
  1740. data: {
  1741. name: 'some sla' + random,
  1742. first_response_time_in_text: 61
  1743. },
  1744. )
  1745. =end
  1746. def sla_create(params = {})
  1747. switch_window_focus(params)
  1748. log('sla_create', params)
  1749. instance = params[:browser] || @browser
  1750. data = params[:data]
  1751. instance.find_elements(css: 'a[href="#manage"]')[0].click
  1752. sleep 1
  1753. instance.find_elements(css: 'a[href="#manage/slas"]')[0].click
  1754. sleep 2
  1755. instance.find_elements(css: 'a.js-new')[0].click
  1756. sleep 2
  1757. element = instance.find_elements(css: '.modal input[name=name]')[0]
  1758. element.clear
  1759. element.send_keys(data[:name])
  1760. element = instance.find_elements(css: '.modal input[name=first_response_time_in_text]')[0]
  1761. element.clear
  1762. element.send_keys(data[:first_response_time_in_text])
  1763. instance.find_elements(css: '.modal button.js-submit')[0].click
  1764. (1..8).each {
  1765. element = instance.find_elements(css: 'body')[0]
  1766. text = element.text
  1767. if text =~ /#{Regexp.quote(data[:name])}/
  1768. assert(true, 'sla created')
  1769. sleep 1
  1770. return true
  1771. end
  1772. sleep 1
  1773. }
  1774. screenshot(browser: instance, comment: 'sla_create_failed')
  1775. raise 'sla creation failed'
  1776. end
  1777. =begin
  1778. text_module_create(
  1779. browser: browser2,
  1780. data: {
  1781. name: 'some sla' + random,
  1782. keywords: 'some keywords',
  1783. content: 'some content',
  1784. },
  1785. )
  1786. =end
  1787. def text_module_create(params = {})
  1788. switch_window_focus(params)
  1789. log('text_module_create', params)
  1790. instance = params[:browser] || @browser
  1791. data = params[:data]
  1792. instance.find_elements(css: 'a[href="#manage"]')[0].click
  1793. sleep 1
  1794. instance.find_elements(css: 'a[href="#manage/text_modules"]')[0].click
  1795. sleep 2
  1796. instance.find_elements(css: 'a[data-type="new"]')[0].click
  1797. sleep 2
  1798. element = instance.find_elements(css: '.modal input[name=name]')[0]
  1799. element.clear
  1800. element.send_keys(data[:name])
  1801. element = instance.find_elements(css: '.modal input[name=keywords]')[0]
  1802. element.clear
  1803. element.send_keys(data[:keywords])
  1804. element = instance.find_elements(css: '.modal [data-name=content]')[0]
  1805. element.clear
  1806. element.send_keys(data[:content])
  1807. instance.find_elements(css: '.modal button.js-submit')[0].click
  1808. (1..8).each {
  1809. element = instance.find_elements(css: 'body')[0]
  1810. text = element.text
  1811. if text =~ /#{Regexp.quote(data[:name])}/
  1812. assert(true, 'text module created')
  1813. sleep 1
  1814. return true
  1815. end
  1816. sleep 1
  1817. }
  1818. screenshot(browser: instance, comment: 'text_module_create_failed')
  1819. raise 'text module creation failed'
  1820. end
  1821. =begin
  1822. signature_create(
  1823. browser: browser2,
  1824. data: {
  1825. name: 'some sla' + random,
  1826. body: 'some body',
  1827. },
  1828. )
  1829. =end
  1830. def signature_create(params = {})
  1831. switch_window_focus(params)
  1832. log('signature_create', params)
  1833. instance = params[:browser] || @browser
  1834. data = params[:data]
  1835. instance.find_elements(css: 'a[href="#manage"]')[0].click
  1836. sleep 1
  1837. instance.find_elements(css: 'a[href="#channels/email"]')[0].click
  1838. sleep 1
  1839. instance.find_elements(css: 'a[href="#c-signature"]')[0].click
  1840. sleep 8
  1841. instance.find_elements(css: '#content #c-signature a[data-type="new"]')[0].click
  1842. sleep 2
  1843. element = instance.find_elements(css: '.modal input[name=name]')[0]
  1844. element.clear
  1845. element.send_keys(data[:name])
  1846. element = instance.find_elements(css: '.modal [data-name=body]')[0]
  1847. element.clear
  1848. element.send_keys(data[:body])
  1849. instance.find_elements(css: '.modal button.js-submit')[0].click
  1850. (1..12).each {
  1851. element = instance.find_elements(css: 'body')[0]
  1852. text = element.text
  1853. if text =~ /#{Regexp.quote(data[:name])}/
  1854. assert(true, 'signature created')
  1855. sleep 1
  1856. return true
  1857. end
  1858. sleep 1
  1859. }
  1860. screenshot(browser: instance, comment: 'signature_create_failed')
  1861. raise 'signature creation failed'
  1862. end
  1863. =begin
  1864. group_create(
  1865. browser: browser2,
  1866. data: {
  1867. name: 'some sla' + random,
  1868. signature: 'some signature bame',
  1869. member: [
  1870. 'some_user_login',
  1871. ],
  1872. },
  1873. )
  1874. =end
  1875. def group_create(params = {})
  1876. switch_window_focus(params)
  1877. log('group_create', params)
  1878. instance = params[:browser] || @browser
  1879. data = params[:data]
  1880. instance.find_elements(css: 'a[href="#manage"]')[0].click
  1881. sleep 0.5
  1882. instance.find_elements(css: 'a[href="#manage/groups"]')[0].click
  1883. sleep 2
  1884. instance.find_elements(css: 'a[data-type="new"]')[0].click
  1885. sleep 2
  1886. element = instance.find_elements(css: '.modal input[name=name]')[0]
  1887. element.clear
  1888. element.send_keys(data[:name])
  1889. element = instance.find_elements(css: '.modal select[name="email_address_id"]')[0]
  1890. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1891. dropdown.select_by(:index, 1)
  1892. #dropdown.select_by(:text, action[:group])
  1893. if data[:signature]
  1894. element = instance.find_elements(css: '.modal select[name="signature_id"]')[0]
  1895. dropdown = Selenium::WebDriver::Support::Select.new(element)
  1896. dropdown.select_by(:text, data[:signature])
  1897. end
  1898. instance.find_elements(css: '.modal button.js-submit')[0].click
  1899. (1..12).each {
  1900. element = instance.find_elements(css: 'body')[0]
  1901. text = element.text
  1902. if text =~ /#{Regexp.quote(data[:name])}/
  1903. assert(true, 'group created')
  1904. # add member
  1905. if data[:member]
  1906. data[:member].each {|login|
  1907. instance.find_elements(css: 'a[href="#manage"]')[0].click
  1908. sleep 0.5
  1909. instance.find_elements(css: 'a[href="#manage/users"]')[0].click
  1910. sleep 3
  1911. element = instance.find_elements(css: '#content [name="search"]')[0]
  1912. element.clear
  1913. element.send_keys(login)
  1914. sleep 3
  1915. #instance.find_elements(:css => '#content table [data-id]')[0].click
  1916. instance.execute_script('$("#content table [data-id] td").first().click()')
  1917. sleep 3
  1918. #instance.find_elements(:css => 'label:contains(" ' + action[:name] + '")')[0].click
  1919. instance.execute_script('$(\'label:contains(" ' + data[:name] + '")\').first().click()')
  1920. instance.find_elements(css: '.modal button.js-submit')[0].click
  1921. sleep 3
  1922. }
  1923. end
  1924. end
  1925. sleep 1
  1926. return true
  1927. }
  1928. screenshot(browser: instance, comment: 'group_create_failed')
  1929. raise 'group creation failed'
  1930. end
  1931. def quote(string)
  1932. string_quoted = string
  1933. string_quoted.gsub!(/&/, '&amp;')
  1934. string_quoted.gsub!(/</, '&lt;')
  1935. string_quoted.gsub!(/>/, '&gt;')
  1936. string_quoted
  1937. end
  1938. def switch_window_focus(params)
  1939. instance = params[:browser] || @browser
  1940. if instance != @last_used_browser
  1941. log('switch browser window focus', {})
  1942. instance.switch_to.window(instance.window_handles.first)
  1943. end
  1944. @last_used_browser = instance
  1945. end
  1946. def log(method, params = {})
  1947. return if !@@debug
  1948. return if params[:mute_log]
  1949. puts "#{Time.zone.now}/#{method}: #{params.inspect}"
  1950. end
  1951. end