0

I am trying to implement the to() checker on the Page Object for the case when clicking a button may stay on the page if there is an error or go to a new page if there are no errors.

When I use a List to provide all the possible Page Classes only the first Page is at() checked and then the validation fails. It never checks the other Pages in the List. My implementation is almost exactly like the Geb Manual.

class LandingPage extends Page {
    static at = { title == "Welcome" }
    static content = {
        loginBtn(to: [AccountPage, LandingPage]) { $("button", id: "login") }
    }

class AccountPage extends Page {
    static at = { title == "My Account" }
    static content = {
        // Page Contents
    }

class LoginTest() extends GebReportingTest {
    @Test
    public void checkErrorDisplayed() {
        to LandingPage
        loginBtn.click()
    }
}

In the example above the browser goes to the Landing Page and when you click the button without any fields filled in it should display an error and remain on the LandingPage. But with the current implementation of LandingPage it attempts to do an at() check on AccountPage and then fails. If I switch the placement of [AccountPage, LandingPage] in the to() statement for loginBtn, then the negative test case will pass, but the good path will fail.

Any ideas?

http://www.gebish.org/manual/current/pages.html#to

EDIT: Including stack trace

title.contains("My Account")
|     |
|     false
Welcome

    at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:398)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:646)
    at com.website.pages.AccountPage$__clinit__closure1.doCall(AccountPage.groovy:10)
    at com.website.pages.AccountPage$__clinit__closure1.doCall(AccountPage.groovy)
    at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at geb.waiting.Wait.waitFor(Wait.groovy:117)
    ... 90 more
user3517049
  • 826
  • 1
  • 6
  • 9
  • What's the exact error (stacktrace) you're getting? – erdi Apr 24 '14 at 19:50
  • It is an assert error because it is failing to verify the first at() case. In the example above it would be something like - Assertion error: expected "My Account" but actual is "Welcome" – user3517049 Apr 24 '14 at 20:38
  • I'm after the full stacktrace. Are you using "at check waiting" by any chance? – erdi Apr 25 '14 at 14:05
  • Yes, atCheckWaiting is set to true in the build options. I disabled it and retested and I still get an error. The last stack trace had a reference to waitFor condition failed, this one just says Page verification failed. So I don't think that's the issue. – user3517049 Apr 25 '14 at 14:17
  • I don't think I can help any further without seeing the stacktrace... – erdi Apr 25 '14 at 14:30
  • Included the stack trace. – user3517049 Apr 25 '14 at 14:55
  • It's not a full stacktrace but anyway. I can still see that you have waiting in there. Is there a `WaitTimeoutException` anywhere in the stacktrace? – erdi Apr 25 '14 at 15:26
  • The other stack trace is about 100 lines long so I won't include it here, but it is a geb.waiting.WaitTimeoutException. If implementing this feature works for you then it is obviously something I have set up here, but whenever I configure it for one Page object or even if I pass a Page object in the .click() call it works fine. If it's not an issue with the (to: [AccountPage, LandingPage]) I have no idea what else it could be. – user3517049 Apr 25 '14 at 20:39
  • Also, it's a geb.waiting.WaitTimeoutException because I have atCheckWaiting = true. When I make atCheckWaiting = false the error still occurs in the same place but is then a geb.error.UnexpectedPageException. – user3517049 Apr 25 '14 at 20:44
  • I can see that this is tested in Geb source and it passes ([here](https://github.com/geb/geb/blob/8c1f68f859ce1c4d630ef5d390233c483753b3c9/module/geb-core/src/test/groovy/geb/PageOrientedSpec.groovy#L151) and [here](https://github.com/geb/geb/blob/8c1f68f859ce1c4d630ef5d390233c483753b3c9/module/geb-core/src/test/groovy/geb/PageOrientedSpec.groovy#L283)) so I have to assume it's something with your setup. Does your at checker throw an exception? Seriously, a full stacktrace would make it way easier. Even if it's a 100 lines long. – erdi Apr 26 '14 at 09:51

1 Answers1

0

I am not sure whether you can recursively use the same class name inside it (you did it inside LandingPage Class). Use the following three classes and it should work, I believe!

class LandingPage extends Page {
    static at = { title == "Welcome" }
    static content = {
        loginBtn(to: AccountPage) { $("button", id: "login") }
    }
}

class AccountPage extends Page {
    static at = { title == "My Account" }
    static content = {
        // Page Contents
    }
}

class LoginTest() extends GebReportingTest {
    @Test
    public void checkErrorDisplayed() {
        to LandingPage
        loginBtn.click()
    }
}
Sharif Mamun
  • 3,508
  • 5
  • 32
  • 51
  • You can reference the same Page Object within that same class. This does not solve the problem. Even if I have 'loginBtn(to: [AccountPage, SomeOtherPage])' It will still only check the first class, AccountPage. If I switch the class position to 'loginBtn(to: [SomeOtherPage, AccountPage])' it will only check SomeOtherPage. – user3517049 Apr 22 '14 at 14:38