Search code examples
seleniumfunctional-testingspockgeb

How do I test that the page has reloaded when I click a link to the current page?


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:

  • My browser is on http://example.com/foo
  • I click a link on that page with href="/foo" (the same page)
  • The browser should reload the same page

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?


Solution

  • 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';
        }
    }