Geb's page objects don't prevent one from making higher-level methods to
abstract the WebDriver API, so I don't think it's a matter of something
that Geb is doing. I haven't tried using an inner trait for that, so
I'm not sure about the trade-offs. I guess it would give one some
static type safety, but a false sense of safety, because it would seem
to apply to the whole test class, but I wouldn't expect it to work
unless the test were on the right page at the time.
For comparison, I use a page property with a closure, which I expect
will be dynamically available where it is relevant in the test:
import grails.util.Holders as CH
class CasLoginPage extends Page {
static at = {title =="University of Hawaii Web Login Service" }
def login = { testuser ->
$("input",name:"username").value( testuser )
$("input",name:"password").value(casTestPassword())
$("input",value:"Login").click()
}
private static casTestPassword() {
def pw
=System.getProperty('casTestPassword',CH.config?.cas?.test?.password ?:null)
if (!pw) {
def configMethods = [
'* define cas.test.password="xxx" in
$HOME/grails-conf/taps-secret-config.groovy, or',
'* for running in IDE without Grails, use JVM option
-DcasTestPassword=xxx' ]
throw new IllegalStateException('configure password xxx for Load
Testing CAS like so:\n' + configMethods.join('\n'))
}
pw
}
}
My tests can use it like this:
def "main menu requires CAS login"() {
when:
via MainMenuPage then:
at CasLoginPage }
def "can login as an hourly employee"() {
given:
assert at(CasLoginPage)
when:
login(emplData.username )
then:
at MainMenuPage displayName ==emplData.name
However, I wouldn't add levels of abstraction that don't reduce
duplicate code or clarify the test. My tests often call click()
directly on content, and use locators directly. Abstracting the content
locator in a Page class makes sense if it makes the test easier to read,
and allows for changing multiple uses of the locator in one place in
case the HTML/CSS changes. But, what good would it do to abstract the
click() call? Would it make the test more clear?
def "can get choices of old pay period"() {
given:
assert at(MainMenuPage)
when:'revealing inactive appointments to choose from'
previousAppointmentsLink?.click()
and:'selecting an hourly Appointment with an empty previous period'
$("label",text:contains((String)emplData.plcSummary)).click()
and:'creating for other than the current period (so this spec can use static
dates)' createOtherTimesheetButton.click()
then:
at EmployeeCreateTimesheetForOtherPeriodPage $("#payPeriod\\.id
option").size() >1 }
Cheers,
11011011
On 2017-02-03 03:44 , [email protected] wrote:
Hello everyone,
I'm a little confused about Page Object Pattern implementation at Geb.
I'm talking about *test classes* extended from
GebSpec/GebReportingSpec. I'm very impressed about Page
implementation, especially about static url, content and at field but
according to Martin Fowler blog
https://martinfowler.com/bliki/PageObject.html
<https://martinfowler.com/bliki/PageObject.html> and Simone Stewart
(founder of WebDriver project):
|If you have WebDriver APIs in your test methods, You're Doing It
Wrong|
||
|
Let's talk about this piece of code
source: http://www.gebish.org/pages:
|import geb.BrowserBrowser.drive { to
LoginPageassert at(LoginPage) loginForm.with{ username
="admin" password ="password"}
loginButton.click()assert at(AdminPage)}|
|This example is excellent prove that Geb doesn't implement Page
Object Pattern in obvious way. In my opinion this is not full support
for Page Object Pattern. |
|I think that Martin Fowler is right about:|
The page object should encapsulate the mechanics required to find
and manipulate the data in the gui control itself.
Previously, I was working a lot with pure WebDriver API and Java. When
I started use Groovy I was very impressed for a moment. After that I
realised that dynamically typed language like Groovy is very helpful
but not in this case. I resolved this in inner trait. That's the example:
|
|
|
classMyPage extendsPage {
staticat = { ... }
staticcontent = { element{ ... } }
trait MyPageTrait {
defdoSomethingOnMyElement() {
element.click()
}
}
}
classMyTest extendsGebSpec implementsMyPage.MyPageTrait {
def"do some test"() {
expect:
doSomethingOnMyElement()
}
}
|
|
What do you think about it? I'm open to have discuss. I'm not sure If
I'm right but I've reason to think that Geb does it wrong. Please,
fell free to suggest anything you like.
Ćukasz
-- You received this message because you are subscribed to the Google
Groups "Geb User Mailing List" group. To unsubscribe from this group
and stop receiving emails from it, send an email to
[email protected]
<mailto:[email protected]>. To post to this group,
send email to [email protected]
<mailto:[email protected]>. To view this discussion on the web
visit
https://groups.google.com/d/msgid/geb-user/ac68e36c-d488-4483-9654-ffa5027dfe56%40googlegroups.com
<https://groups.google.com/d/msgid/geb-user/ac68e36c-d488-4483-9654-ffa5027dfe56%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Geb User
Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/geb-user/264f62bf-957c-81d1-a3ac-55bd5dfe97cf%40getsu.com.
For more options, visit https://groups.google.com/d/optout.