2

Some of requests to my Web Application return data not in HTML format (JSON).

How to handle this correctly?

I wrote the following page definition:

import com.fasterxml.jackson.databind.ObjectMapper
import geb.Page

class JsonResponse extends Page {

    static url = null;

    static at = {
        true;
    }

    static ObjectMapper mapper = new ObjectMapper();

    static content = {

        readTree {
            def jsonString = $("pre").text();
            mapper.readTree(jsonString)
        }

    }

}

and it apparently works. But the question is, how correct it is?

It takes data from inside pre tag. This is because I saw this content inside driver.pageSource. Is this correct? May be it is driver-dependent?

I put null into url, since the page has different url depending on query. Is this correct?

Dims
  • 47,675
  • 117
  • 331
  • 600

3 Answers3

3

Geb is not intended to be used to interact with HTTP API endpoints because it is built on top of WebDriver and hence expects to be used via a browser and on HTML pages.

If you want to test HTTP API endpoints then I would suggest using an http client to back your tests. There are many of them out in the wild, just to name a few in no particular order:

erdi
  • 6,944
  • 18
  • 28
1

I was able to download the content of a PDF in a geb unit test using the Direct Download API. It is handy because it takes all the cookies from the session but does the download separately from the browser.

Example from that documentation:

Browser.drive {
    go "http://myapp.com/login"
 
    // login
    username = "me"
    password = "secret"
    login().click()
 
    // now find the pdf download link
    def downloadLink = $("a.pdf-download-link")
 
    // now get the pdf bytes
    def bytes = downloadBytes(downloadLink.@href)
}

There are different methods for downloading different kinds of data. See the DownloadSupport API docs.

Because geb uses HttpsURLConnection to connect to an https endpoint instead of using the browser you can have problems with self-signed certificates. I solved that using this Stack Overflow answer.

Tom K
  • 430
  • 5
  • 22
0

I agree that Geb is not intended to be used to interact with HTTP API endpoints, but there are some contexts where this can be helpful, so add this snippet here for posterity:

    when: 'I retrieve the JSON transaction list'
    go '/transaction/transactionList'

    then: 'Valid data is retrieved'
    JsonSlurper jsonSlurper = new JsonSlurper()
    Map<String, List> transactionList = jsonSlurper.parseText(driver.pageSource)
    assert transactionList.categories.class == ArrayList