I have a strange bug I'm trying to re-create with a test. I know what's causing the bug and how to fix it, but I can't figure out how to test it properly.
Scenario:
I tried:
class SamePageHyperlinkSpec extends StatelessUserWebGebSpec {
def 'users is on Foo page and clicks foo link'() {
when:
to FooPage
then:
// navigation.foo is a property in a super class that references
// a particular navigation item
navigation.foo.click()
and:
at FooPage
}
}
...but that gave a false positive because although the browser didn't reload the page, it was already on that page. So, I figured I'd take a look at the PageChangeListener which should allow me to pass/fail on page change:
class SamePageHyperlinkSpec extends StatelessUserWebGebSpec {
def 'users is on Foo page and clicks foo link'() {
given:
def listener = new MyPageChangeListener()
browser.registerPageChangeListener(listener)
when:
to FooPage
and:
listener.changeCount = 0
then:
// navigation.foo is a property in a super class that references
// a particular navigation item
navigation.foo.click()
and:
at FooPage
and:
listener.changeCount == 1
}
}
class MyPageChangeListener implements PageChangeListener {
int changeCount = 0
void pageWillChange(Browser browser, Page oldPage, Page newPage) {
println "browser '$browser' changing page from '$oldPage' to '$newPage'"
changeCount++
}
}
...that fails (as it should) when there is no page reload, however it also fails when there is a page reload, because the page it ends up on is the same, ergo no page change happened.
I also tried duplicating the Page class (and it's "at" closure), however that always passed regardless of whether there was a page reload or not.
So, how do I test that the page has reloaded when I click a link to the current page?
Taking @PaulHarris' lead, the JS approach seems to do the trick:
class SamePageHyperlinkSpec extends StatelessUserWebGebSpec {
def 'users is on Foo page and clicks foo link'() {
when:
to FooPage
and:
browser.js.exec '$(document.body).attr("data-not-reloaded",true);'
then:
// navigation.foo is a property in a super class that references
// a particular navigation item
navigation.foo.click()
and:
at FooPage
and:
browser.js.exec 'return $(document.body).attr("data-not-reloaded") === undefined';
}
}