Sebastian Flückiger
Sebastian Flückiger

Reputation: 5555

Grails Gebish Functional Tests for page created with javascript

i am writing a test class

class ListOfProjectsSpec extends GebReportingSpec{

    def "project dashboard filters are instantiated correctly" () {
        given:
        at ProjectIndexPage

        expect:
        projectTable != null
    }

}

to test functionality of my ProjectIndexPage.

class ProjectIndexPage extends ProjectsCategoryPage{

    static at = {
        $("title").text() == "Title"
    }

    static content = {
        projectTable {
            $("table.dynamic-projectTable")
        }  
    }
}

(i cleaned up a lot of code to show the simplest case only).

complication

the class dynamic-projectTable is added at runtime to the table with jquery/javascript in as an acessor for filters on the page.

<g:javascript>
    $(
        $('#projectTable').addClass('dynamic-projectTable');
    });
</g:javascript>

error

junit.framework.AssertionFailedError: geb.error.RequiredPageContentNotPresent: 
The required page content 'projectTable- SimplePageContent (owner: ProjectIndexPage, args: [],
value: null)' is not present

additional info

when looking at the html output of the spock test it is clear that the dynamic-projectTable class is not added (as are all other actions performed by the $() jquery call - i removed them here to make the example more readable)

i tried

// calling the document.ready function explicitly in my test cases
when:
$("document").ready() 

enabled javascript

driver = {
    HtmlUnitDriver driver = new HtmlUnitDriver();
    driver.setJavascriptEnabled(true);
    driver
}

but nothing seems to work. any input?

Upvotes: 1

Views: 561

Answers (3)

twinj
twinj

Reputation: 2039

To avoid issues like this it is better to define more applicable at checks.

In your example you have used:

 static at = {
     $("title").text() == "Title"
 }

Try checking for something which will be used in the tests. E.g A form element. I would also use a waitFor closure in the at checker so all pages after a to call will be ready for testing.

static at = {
     waitFor { $('#projectTable')[email protected]("dynamic-projectTable") }
 }

Upvotes: 0

John Flinchbaugh
John Flinchbaugh

Reputation: 2338

Pages built by javascript often require Geb to wait for the content to be rendered. See http://www.gebish.org/async for details.

Basically, I'd try explicitly waiting in your spec code:

waitFor { projectTable }

Waits can also be configured on the page content:

projectTable(wait: true) {
    $("table.dynamic-projectTable")
}

Upvotes: 1

Sebastian Fl&#252;ckiger
Sebastian Fl&#252;ckiger

Reputation: 5555

i was able to solve it by explicityly re-enabling javascript in the testSpec:

def setup() {
    if (driver instanceof HtmlUnitDriver) {
        driver.javascriptEnabled = true
    }
}

Upvotes: 0

Related Questions