/* Ċ Ġ* ĠCopyright ĠÂ© Ġ 2 0 2 0 ĠAlex ander ĠG ir ke Ġ( alex gir ke @ post eo . de ) Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġde . al x gr k . spring _ selenium _ pool Ċ Ċ import Ġcom . github . docker java . api . model . Bind Ċ import Ġcom . github . docker java . api . model . Volume Ċ import Ġcom . google . common . annotations . Visible ForTesting Ċ import Ġorg . openqa . selenium . Capabilities Ċ import Ġorg . openqa . selenium . chrome . Chrome Options Ċ import Ġorg . openqa . selenium . remote . Remote WebDriver Ċ import Ġorg . rn orth . duct tape . timeout s . Timeout s Ċ import Ġorg . rn orth . duct tape . un reli ables . Un reli ables Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġorg . test containers . containers . Browser WebDriver Container Ċ import Ġjava . io . File Ċ import Ġjava . nio . file . Paths Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ Ċ /** Ċ Ġ* ĠThis Ġclass Ġserver Ġas Ġa Ġwrapper Ġaround ĠTest container 's Ġclass . ĠBy Ġthis : Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġ- Ġthe Ġworkaround Ġfor Ġhttps :// github . com / test containers / test containers - java / issues / 3 1 8 Ġis Ġincluded Ċ Ġ* ĠĠĠĠ Ġ- Ġit Ġis Ġpossible Ġto Ġcontrol Ġthe Ġ[ Remote WebDriver ]' s Ġcreation , Ġwhich Ġis Ġnecessary Ġto Ġrestart ĠChrome Ġwith Ġdifferent Ġprofiles Ċ Ġ*/ Ċ internal Ġclass ĠProfile Sensitive Sel enium Container ( ĊĠĠĠ Ġinternal Ġval Ġid : ĠContainer Id Ġ= ĠContainer Id . random (), ĊĠĠĠ Ġinternal Ġval Ġin Use : ĠAtomic Boolean Ġ= ĠAtomic Boolean ( false ) Ċ ) Ġ: ĠBrowser WebDriver Container < Profile Sensitive Sel enium Container >() Ġ{ ĊĊĠĠĠ Ġinternal Ġvar Ġprofile : ĠChrome Profile ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġprivate Ġvar Ġdriver By Profile : ĠRemote WebDriver ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcapabilities : ĠChrome Options ? Ġ= Ġnull ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( profiles Directory Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbind Ġprofiles Ġdirectory Ġto Ġdocker Ġcontainer ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprofiles Bind Ġ= ĠBind ( profiles Directory !!. absolute Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠVolume ( DOCKER _ PRO FILES _ DIR )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbind s . plus Assign ( profiles Bind ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġmethod Ġreturns Ġa Ġ[ Remote WebDriver ]. ĊĠĠĠĠ Ġ* ĠDep ending Ġon Ġthe Ġvalue Ġof Ġ[ chrome Profile ], Ġthis Ġmight Ġbe Ġeither ĊĠĠĠĠ Ġ* Ġthe Ġoriginal Ġ[ get WebDriver ]' s Ġresult Ġor Ġa Ġnew Ġ[ Remote WebDriver ] ĊĠĠĠĠ Ġ* Ġstarted Ġwith Ġthe Ġspecified Ġprofile . ĊĠĠĠĠ Ġ* ĠNote , Ġthat Ġif Ġonce Ġretrieved Ġa Ġ[ Remote WebDriver ] Ġwith Ġa Ġspecial Ġprofile , ĊĠĠĠĠ Ġ* Ġsubsequent Ġcalls Ġwith Ġan Ġempty Ġstring Ġas Ġan Ġargument Ġwill ĊĠĠĠĠ Ġ* Ġreturn Ġthe Ġalready Ġused Ġ[ Remote WebDriver ]. ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġchrome Profile Ġthe Ġprofile Ġto Ġstart Ġthe Ġ[ Remote WebDriver ] Ġwith ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( typ ically , Ġa Ġsocial Ġmedia Ġplatform Ġusername ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġfun Ġget WebDriver ( chrome Profile : ĠChrome Profile ): ĠRemote WebDriver Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( capabilities Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" You Ġneed Ġto Ġdefine ĠChrome Options Ġvia Ġwith Capabilities Ġfirst ." ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġearly Ġexit Ġif Ġthere Ġis Ġno Ġspecial Ġprofile Ġrequested ĊĠĠĠĠĠĠĠ Ġif Ġ( chrome Profile Ġ== ĠChrome Profile . EMPTY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( web Driver Ġ!= Ġnull Ġ&& Ġ! web Driver !!. stopped ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġweb Driver !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( driver By Profile Ġ!= Ġnull Ġ&& Ġ! driver By Profile !!. stopped ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdriver By Profile !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠRuntimeException (" No ĠRemote WebDriver Ġavailable ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġquit Ġthe Ġoriginal Ġweb Ġdriver ĊĠĠĠĠĠĠĠ Ġquit ( web Driver ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġonly Ġrecreate Ġdriver By Profile Ġif Ġanother Ġprofile Ġis Ġrequested ĊĠĠĠĠĠĠĠ Ġif Ġ( chrome Profile Ġ!= Ġthis . profile ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġprofile Directory OrNull Ġ= Ġprofile Directories . get OrDefault ( chrome Profile , Ġnull ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( profiles Directory Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( profile Directory OrNull Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( profiles Directory , Ġchrome Profile . id ). apply Ġ{ Ġmkdir () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprofile Directory OrNull Ġ= ĠPaths . get ( DOCKER _ PRO FILES _ DIR ). resolve ( chrome Profile . id ). to File () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprofile Directories Ġ+= Ġ( chrome Profile Ġto Ġprofile Directory OrNull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcapabilities !!. add Arguments ("-- user - data - dir =${ profile Directory OrNull !!. absolute Path }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . profile Ġ= Ġchrome Profile ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOGGER . warn (" No Ġdirectory Ġfor Ġsaving ĠChrome Ġprofiles Ġto Ġwas Ġspecified , Ġso Ġusing Ġdefault Ġprofile .") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġrecreate Driver () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( driver By Profile Ġ!= Ġnull Ġ&& Ġ! driver By Profile !!. stopped ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" If Ġthe Ġprofile Ġalready Ġmatches , Ġthe Ġdriver Ġshould Ġexist ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdriver By Profile !! ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget WebDriver (): ĠRemote WebDriver ? Ġ= Ġsuper . get WebDriver () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . stopped ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull Ġ// Ġthe ĠRemote WebDriver Ġhas Ġalready Ġstopped , Ġso Ġdon 't Ġuse Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġwith Capabilities ( capabilities : ĠCap abilities ): ĠProfile Sensitive Sel enium Container Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( capabilities Ġis ĠChrome Options ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" You Ġneed Ġto Ġsupply ĠChrome Options Ġhere ." ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthis . capabilities Ġ= Ġcapabilities ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . with Capabilities ( capabilities ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġquit ( driver By Profile ) ĊĠĠĠĠĠĠĠ Ġsuper . stop () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Visible ForTesting ĊĠĠĠ Ġinternal Ġfun Ġrecreate Driver (): ĠRemote WebDriver Ġ{ ĊĠĠĠĠĠĠĠ Ġquit ( driver By Profile ) ĊĠĠĠĠĠĠĠ Ġthis . driver By Profile Ġ= Ġcreate () ĊĠĠĠĠĠĠĠ Ġreturn Ġthis . driver By Profile !! ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate (): ĠRemote WebDriver Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUn reli ables . retry Until Success ( 1 0 , ĠTimeUnit . SECONDS , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTimeout s . get WithTimeout ( 5 , ĠTimeUnit . SECONDS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRemote WebDriver ( selenium Address , Ġcapabilities ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĊĠĠĠ Ġprivate Ġfun Ġquit ( web Driver : ĠRemote WebDriver ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( web Driver Ġ!= Ġnull Ġ&& Ġ! web Driver . stopped ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġweb Driver . quit () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOGGER . debug (" Failed Ġto Ġquit Ġthe Ġdriver ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠRemote WebDriver . stopped () Ġ= ĠsessionId Ġ== Ġnull ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOGGER Ġ= ĠLoggerFactory . getLogger ( Profile Sensitive Sel enium Container :: class . java ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠDO CKER _ PRO FILES _ DIR Ġ= Ġ"/ home / sel user / profiles " ĊĊĠĠĠĠĠĠĠ Ġ// Ġthis Ġvalue Ġis Ġset Ġin ĠSelen ium Pool Ġ( inject ed Ġby ĠSpring ) ĊĠĠĠĠĠĠĠ Ġinternal Ġvar Ġprofiles Directory : ĠFile ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġ@ get : Synchron ized ĊĠĠĠĠĠĠĠ Ġprivate Ġvar Ġprofile Directories : ĠMap < Chrome Profile , ĠFile > Ġ= Ġupdate Profiles Map () ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġupdate Profiles Map (): ĠMap < Chrome Profile , ĠFile > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( profiles Directory ?. list Files Ġ{ Ġfile Ġ-> Ġfile . isDirectory Ġ} Ġ?: Ġempty Array < File >()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. groupBy Ġ{ Ġfile Ġ-> ĠChrome Profile ( file . name ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Values Ġ{ Ġentry Ġ-> Ġentry . value . first () Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠA Ġholder Ġfor Ġthe Ġprofile Ġthat Ġshould Ġbe Ġused Ġwith ĠChrome . Ċ Ġ*/ Ċ data Ġclass ĠChrome Profile ( val Ġid : ĠString ) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠEMPTY Ġ= ĠChrome Profile ("") ĊĠĠĠ Ġ} Ċ }