Web UI testing in Scala
Radim.pavlicek@gmail.com
@radimpavlicek
Why should I care?
●
●
●
●
●

regression errors
cross web browser (Firefox/IE/Chrome)
cross OS (Mac/Linux/Windows)
cross versions (browsers)
use cases documentation
Selenium
● open-source
● Domain Specific Language support in
ScalaTest 2.0
What’s needed?
● continuous integration (Jenkins)
● server with browser installation
● test-cases from domain users
Recorder
Recorder cont.
+ quickly record
+ no knowledge required
- fragile test cases
- spaghetti test-case
Example
Scenario
Continuous integration
Jenkins

Java application
JSF

Scala code
Selenium
Invoked on Jenkins?
● @Midnight
● Maven
clean integration-test -P ui-test
Maven settings.xml
<profile>
<id>ui-test</id>
<properties>
<onlineUsers.login>rpavlicek</onlineUsers.login>
<onlineUsers.password>*******</onlineUsers.password>
<onlineUsers.url>localhost</onlineUsers.url>
<onlineUsers.port>9090</onlineUsers.port>
</properties>
</profile>
Scala part
Input parameters
object Settings {
val url = System.getProperty ("onlineUsers.url" )
val login = System.getProperty ("onlineUsers.login" )
val password = System.getProperty ("onlineUsers.password" )
val port = {
val tmp = System.getProperty ("onlineUsers.port" )
if (null == tmp)
new Integer(9090)
else new Integer(tmp)
}
}
WebDriver
object WebDriverAccess {
val defaultDriver : WebDriver = {
print("Creating WebDriver... " )
try {
new FirefoxDriver()
} finally { println( "Done.") }
}
}
WebDriver cont.
trait WebDriverAccess {
implicit val driver = WebDriverAccess.defaultDriver
}

implicit = if a parameter value is not supplied
then the compiler will search for an "implicit"
value defined within scope
Page objects pattern
●
●
●
●

model UI as services
not exposing internals
model just what is tested
public service methods return PageObjects
Wait
protected def waitUntil(f: => Boolean): Unit = {
new WebDriverWait(driver, 25, 50) until
(new ExpectedCondition[Boolean] {
def apply(input: WebDriver) = f
})
}
WebDriverWait(WebDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds, long
sleepTimeOut)
waitUntil {

!driver.findElements(By.id(“ mainForm:isLoggedIn ”)).isEmpty }
PageObject implementation
abstract class Page[T <: Page[T]]( expectedId: String, val driver:
WebDriver) {
self: T =>
waitUntil {

!driver.findElements(By.id(expectedId)).isEmpty }

private val tmpId: By = By.id(expectedId)
try { driver.findElement(tmpId)
} catch {
case nsee: NoSuchElementException =>
Assert.fail( "ID not found:" +expectedId)
}
}
PageObject cont.
class HomePage( driver: WebDriver) extends Page[HomePage]( "mainForm:
isLoggedIn" , driver) {
def goToUserManagementPage () =
click(id("mainForm:mainNavPTS:0:usersPTText" ))
.expecting[UserManagementPage]

def goToReportPage () =
click(id("mainForm:mainNavPTS:0:reportsPTText" ))
.expecting[ReportPage]
}
Use case
class UserManagementWebTest extends WebDriverAccess {
var homePage: HomePage = _
@Test
def shouldLandOnUserManagement {
val loginPage: LoginPage = LoginPage.open(
server = Settings.url, port = Settings.
port)
homePage = loginPage.login()
val mngPage: UserManagementPage = homePage.goToUserManagementPage()
assertThat(mngPage.text, containsString( "Create new User" ))
}
That’s it!

Q&A

Web ui testing