Craig Atkinson | Principal Consultant | Object Partners
go "http://www.google.com"
$("input", name: "q").value("geb")
$("button", name: "btnG").click()
waitFor { $("#search").displayed }
$("h3.r").first().click()
waitFor { title == "Geb - Very Groovy Browser Automation" }
$("#by-id")
$(".by-class")
$("div", name: "by-attribute")
$("div", text: "By text")
to GoogleHomePage
searchBox = "Geb"
searchButton.click()
searchResultsLinks.first().click()
assert at(GebHomePage)
class GoogleHomePage extends geb.Page {
static url = "http://www.google.com"
static content = {
searchBox { $("input", name: "q") }
searchButton { $("button", name: "btnG") }
searchResultsLinks(wait: true) { $("h3.r") }
}
}
class IdeaCreatePage extends geb.Page {
static content = {
titleField { $("#title") }
descriptionField { $("#description") }
createButton { $("#create") }
}
}
class IdeaCreatePage extends geb.Page {
static at = { $("div#create-idea").displayed }
}
class IdeaCreatePage extends geb.Page {
static url = "idea/create"
}
IdeaCreatePage ideaCreatePage = to(IdeaCreatePage)
static content = {
createButton(to: IdeaShowPage) { $("input#create") }
}
void clickCreateButton() {
createButton.click()
assert browser.page.class == IdeaShowPage
}
static content = {
createButton(to: [IdeaShowPage, IdeaErrorPage]) { $("input#create") }
}
Standard: Geb delegates method calls to current page object
to HomePage
loginButton.click()
username = "user1"
password = "password1"
submitButton.click()
// What page is the test on now?
// What fields are on the current page?
Test uses reference to current page object
HomePage homePage = to HomePage
LoginPage loginPage = homePage.clickLoginButton()
DashboardPage dashboardPage = loginPage.login("user1", "password1")
HomePage homePage = to HomePage
DashboardPage dashboardPage = homePage
.clickLoginButton()
.login("user1", "password1")
class HomePage extends geb.Page {
static content = {
loginButton(to: LoginPage) { $("#loginButton") }
}
LoginPage clickLoginButton() {
loginButton.click()
return browser.page
}
}
class LoginPage extends geb.Page {
static content = {
usernameField { $("#username") }
passwordField { $("#password") }
submitButton(to: DashboardPage) { $("#submit") }
}
DashboardPage login(String username, String password) {
usernameField.value(username)
passwordField.value(password)
submitButton.click()
return browser.page
}
}
class DependentPage extends geb.Page {
static content = {
firstNameField { $("#firstName") }
lastNameField { $("#lastName") }
birthdayDayField { $("#birthdayDay") }
birthdayMonthField { $("#birthdayMonth") }
birthdayYearField { $("#birthdayYear") }
}
void addSpouse(String firstName, String lastName, LocalDate birthday) {
firstNameField.value(firstName)
lastNameField.value(lastName)
birthdayDayField.value(birthday.dayOfMonth.toString())
birthdayMonthField.value(birthday.monthOfYear.toString())
birthdayYearField.value(birthday.year.toString())
}
}
waitFor {
$("div.alert").displayed
}
waitFor {
$("div.message").text() == "Update successful"
}
Sliders, date pickers, etc.
static content = {
ratingSliderHandle { $(".ui-slider-handle") }
}
void moveRatingSlider(Integer rating) {
// Slider is 400 pixels wide and starts at 1,
// so each notch above 1 is 100 pixels apart
Integer numPixelsX = (rating - 1) * 100
interact {
clickAndHold(ratingSliderHandle)
moveByOffset(numPixelsX, 0)
release()
}
}
$("#myInputField") << "value"
$(".ui-slider-handle") << Keys.ARROW_RIGHT
static content = {
hiddenLink { $("#hiddenLink") }
}
void clickHiddenLink() {
hiddenLink.jquery.show()
hiddenLink.click()
}
def seleniumVersion = "2.46.0"
test "org.seleniumhq.selenium:selenium-support:${seleniumVersion}"
test "org.seleniumhq.selenium:selenium-chrome-driver:${seleniumVersion}"
test "org.seleniumhq.selenium:selenium-firefox-driver:${seleniumVersion}"
test "org.seleniumhq.selenium:selenium-ie-driver:${seleniumVersion}"
environments {
chrome {
String version = "2.14"
String zipFileName
String execFileName
if (Platform.current.is(Platform.MAC)) {
zipFileName = "chromedriver_mac32.zip"
execFileName = "chromedriver"
} else if (Platform.current.is(Platform.LINUX)) {
zipFileName = "chromedriver_linux32.zip"
execFileName = "chromedriver"
} else if (Platform.current.is(Platform.WINDOWS)) {
zipFileName = "chromedriver_win32.zip"
execFileName = "chromedriver.exe"
}
String url = "http://chromedriver.storage.googleapis.com/${version}/${zipFileName}"
File localExecutable = downloadDriver(url, execFileName, 'zip')
System.setProperty('webdriver.chrome.driver', localExecutable.absolutePath)
driver = { new ChromeDriver() }
}
}
grails -Dgeb.env=chrome test-app functional:
Idea createIdea(String title, String description) {
RemoteControl remote = new RemoteControl()
remote {
Idea idea = new Idea(
title: title,
description: description
)
idea.save()
}
}
List ideas = (1..5).collect { i ->
ideaRemoteControl.createIdea("Title ${i}", "Description ${i}")
}
Idea findByTitle(String title) {
RemoteControl remote = new RemoteControl()
remote {
Idea.findByTitle(title)
}
}
PatentService sends ideas to patent office
class PatentService {
def sendToPatentOffice(Idea idea) {
// Send the idea to the real patent office
}
}
class PatentServiceMock extends PatentService {
List ideasSentToPatentOffice = []
@Override
def sendToPatentOffice(Idea idea) {
ideasSentToPatentOffice << idea
}
}
beans = {
if (Environment.current == Environment.TEST) {
// Override the PatentService with our mock version when running tests
patentService(PatentServiceMock)
}
}
def 'should submit idea to patent office'() {
given:
IdeaRemoteControl ideaRemoteControl = new IdeaRemoteControl()
IdeaCreatePage ideaCreatePage = to(IdeaCreatePage)
String ideaTitle = "Patentable Idea"
String ideaDescription = "This idea is going to change the world"
when:
IdeaShowPage ideaShowPage = ideaCreatePage.createIdea(ideaTitle, ideaDescription)
ideaShowPage = ideaShowPage.submitIdeaToPatentOffice()
then:
Idea newIdea = ideaRemoteControl.findByTitle(ideaTitle)
List ideasSubmittedToPatentOffice = ideaRemoteControl
.findIdeasSubmittedToPatentOffice()
assert ideasSubmittedToPatentOffice*.id.contains(newIdea.id)
}
class IdeaRemoteControl {
RemoteControl remote = new RemoteControl()
List findIdeasSubmittedToPatentOffice() {
remote {
return ctx.patentService.ideasSentToPatentOffice
}
}
}