Skip to main content

HTTP DSL

Architecture

The HTTP DSL allows to use a specialised HTTP proxy (driver) to communicate with target servers so that tests cas be executed anywhere while the driver has access to the target resources.

The DSL provides handy methods to construct the final HTTP request as well as parse the output. There are specialised methods for REST calls with JSON parsing and specialised methods for SOAP calls with XML parsing. A set of methods allow specifying authorization methods including complex authentication flows.

Example:

class TestClass {

@Test
public void sampleTest(
@Capability(key = "browserName", value = "pn5-driver8")
HttpApplication client) {

client
.prepareRestRequest("https://example.com/api/animals", "GET")
.withBasicAuth("user", "password")
.withQueryParam("id", "1")
.sendAndGetResponse()
.assertStatus(200)
.assertPayloadContains("cat");
}

}

On the background Pumpo#5 starts a session on the testing farm by instantiating an image of Driver8-Universal which then plays the role of a proxy.

Wrapping in custom objects

Instead of using the predefined methods in the HttpApplication interface, it is possible to define a custom interface that extends HttpApplication and to wrap the predefined actions into more business oriented.

Example:

class TestClass {

@Test
public void sampleTest(MyCustomHttpApplication client) {

client
.checkThatAnimalIsInTheDirectory("1", "cat")
.checkThatAnimalIsInTheDirectory("2", "dog");

}

}

@Capability(key = "browserName", value = "pn5-driver8")
public interface MyCustomHttpApplication extends HttpApplication {

default MyCustomHttpApplication checkThatAnimalIsInTheDirectory(
String animalId,
String animalName) {

prepareRestRequest("https://example.com/api/animals", "GET")
.withBasicAuth("user", "password")
.withQueryParam("id", animalId)
.sendAndGetResponse()
.assertStatus(200)
.assertPayloadContains(animalName);

return null;
}
}

This pattern is common for all domains handled by Pumpo#5 and is the recommended coding style to keep tests readable also for people not having deeper knowledge of implementation details.

Entry methods

HttpApplication::prepareHttpRequest

ParameterTypeDescription
urlStringThe target url to call
methodStringThe HTTP method to use

Creates a HttpRequestBuilder builder for the specified URL and method. The builder allows then to set various parameters of the request before finally calling sendAndGetResponse().

The HttpRequestBuilder is a generic builder. Usually one will prefer using either RestRequestBuilder of SoapRequestBuilder by using the respective entry methods below.

HttpApplication::prepareRestRequest

ParameterTypeDescription
urlStringThe target url to call
methodStringThe HTTP method to use

Creates a RestRequestBuilder builder for the specified URL and method. This is a specialised builder for REST calls. Next to all methods from HttpRequestBuilder is has additional ones that can work with JSON both in the request and in the response.

HttpApplication::prepareSoapRequest

ParameterTypeDescription
urlStringThe target url to call

Creates a SoapRequestBuilder builder for the specified URL and method. This is a specialised builder for REST calls. Next to all methods from HttpRequestBuilder is has additional ones that can work with XML.

Following specific functionality is implemented for SOAP:

  • HTTP method is inferred to POST automatically.
  • If the header for Content-Type is not set manually it will be set to text/xml; charset=utf-8 once the request is queued.

HTTP request methods

HttpRequestBuilder::withBasicAuth

ParameterTypeDescription
userStringUser name in plain
passwordStringPassword in plain

Instructs the driver to attach a http basic authentication header. The header will be constructed by the driver and will replace any authentication header if already present.

HttpRequestBuilder::withBearerAuth

ParameterTypeDescription
tokenStringToken to be used as bearer token

Instructs the driver to attach a http bearer authentication header. The header will be constructed by the driver and will replace any authentication header if already present.

HttpRequestBuilder::withBearerAuthResolved

ParameterTypeDescription
oAuthEndpointStringURL of the endpoint service access tokens
clientIdStringIdentification of the application
clientSecretStringSecret of the application in plain
scopeStringScope for the access token; please check the documentation of the target API what scope should be specified

Uses the driver to get an access token using an OAuth endpoint and then instructs the driver to attach a http bearer authentication header with the obtained token.

To authenticate to the OAuth endpoint a Basic authentication with client id and client secret will be used.

In this version the token will represent the application only (client credentials grant flow). The client needs to have an admin consent for the final resource upfront.

HttpRequestBuilder::withBearerAuthResolved

ParameterTypeDescription
oAuthEndpointStringURL of the endpoint service access tokens
clientIdStringIdentification of the application
clientSecretStringSecret of the application in plain
scopeStringScope for the access token; please check the documentation of the target API what scope should be specified
userNameStringUsername of the user to impersonate
userPasswordStringPassword of the user to impersonate in plain

Uses the driver to get an access token using an OAuth endpoint and then instructs the driver to attach a http bearer authentication header with the obtained token.

To authenticate to the OAuth endpoint a Basic authentication with client id and client secret will be used.

In this version a user will be impersonated by specifying users credentials (resource owner password flow). This flow is not supported by all OAuth providers.

HttpRequestBuilder::withNtlmAuth

ParameterTypeDescription
domainStringThe domain of the user authenticated
usernameStringUsername
passwordStringPassword in plain
workstationStringWorkstation - In most cases this will not be verified by the server but should represent the hostname (without domain information) from which the authentication is done

Instructs the driver to proceed with the NTLM authentication flow when accessing the target API. The NTLM authentication flow will be realised on the driver side only.

NTLM authentication involves 3 request/responses exchanged with the server. In case the authentication flow fails at some point the last response will be returned to the client.

HttpRequestBuilder::withClientCertAuth

ParameterTypeDescription
certificateStringEither the path to a file containing an SSL certificate or a chain of certificates, or the file content itself
keyStringEither the path to a file containing a private key, or the file content itself

Instructs the driver to proceed with a client certificate authentication flow when accessing the target API. The client certificate authentication flow will be realised on the driver side only.

In case the authentication flow fails at some point the last response from the server will be returned to the client.

The private key can be either in PKCS1 or PKCS8 format.

HttpRequestBuilder::withHeader

ParameterTypeDescription
keyStringThe header key (e.g. Content-Type)
valueStringThe value of the header as plain (e.g. text/xml; charset=utf-8)

Instructs the driver to attach a http header to the request. Currently, headers are implemented as a Map and do not allow specifying more than one value for a single key. This can be overcome by constructing the value as comma separated list of values. This is compliant with the relevant RFC and should be processed by the target server.

HttpRequestBuilder::withQueryParam

ParameterTypeDescription
keyStringThe parameter name
valueStringThe parameter value

Adds a query parameter to the requested URI. Takes care of the url encoding. In case a parameter is used several times the last value set will be the retained one.

Does not check for the total URI length to not exceed allowed size.

HttpRequestBuilder::withPayload

ParameterTypeDescription
payloadStringThe payload to be sent in plain text

If payload is non-empty it will be sent as body of the HTTP request sent to the target server. If not set manually the HTTP header Content-size will be set to the size of the resulting body.

The payload should be text only otherwise either encode or use the binary safe method.

Will work for whatever HTTP method. Some combinations (e.g. sending body with GET) do not make sense but will still be processed.

HttpRequestBuilder::withBinaryPayload

ParameterTypeDescription
payloadbyte[]The payload to be sent as plain bytes

If payload is non-empty it will be sent as body of the HTTP request sent to the target server. If not set manually the HTTP header Content-size will be set to the size of the resulting body.

The content is immediately encoded in base64 which may affect results of methods such as replaceInPayload. Payload is decoded back to byte array on the driver side. The driver will not set headers such as content-disposition automatically.

Will work for whatever HTTP method. Some combinations (e.g. sending body with GET) do not make sense but will still be processed.

HttpRequestBuilder::withPayloadFromFile

ParameterTypeDescription
pathStringPath of the text file to be loaded

Payload will be loaded from a file (as plain text). To load the file the getResource() of the classloader attached to the HttpApplication is used. Typically, the path should be specified relative to resource folders.

The file should be text only otherwise either encode it or use the binary safe method.

HttpRequestBuilder::withBinaryPayloadFromFile

ParameterTypeDescription
pathStringPath of the binary file to be loaded

Payload will be loaded from a file (as plain bytes). To load the file the getResource() of the classloader attached to the HttpApplication is used. Typically, the path should be specified relative to resource folders.

The content is immediately encoded in base64 which may affect results of methods such as replaceInPayload. Payload is decoded back to byte array on the driver side. The driver will not set headers such as content-disposition automatically.

HttpRequestBuilder::replaceInUrl

ParameterTypeDescription
placeholderStringToken searched in the URL
valueStringValue that will replace the token

Replaces given token in the URL by the provided value. The String::replace method will be used so no regular expressions are allowed here and all occurrences will be replaced.

HttpRequestBuilder::replaceInPayload

Parameter | Type | Description

---|---|---

placeholder | String | Token searched in the payload

value | String | Value that will replace the token

Replaces given token in the payload by the provided value. The String::replace method will be used so no regular expressions are allowed here and all occurrences will be replaced.

In case a binary payload was attached, the replace method will be run over the base64 encoding of the payload.

HttpRequestBuilder::sendAndGetResponse

Completes the builder pattern and sends the request to the driver. Parses the received response as HttpResponse where the fluent interface continues.

REST request methods

RestRequestBuilder inherits all methods from HttpRequestBuilder plus implements the following ones:

RestRequestBuilder::withJsonFromPojoPayload

Parameter | Type | Description

---|---|---

payload | Object | Object to be serialised as JSON

Serialises the provided object to JSON using a jackson ObjectMapper with no additional settings. The provided object class may have JSON mappings specified by jackson annotations. Then attaches the resulting JSON as payload (body) to the http request.

RestRequestBuilder::sendAndGetResponse

Completes the builder pattern and sends the request to the driver. Parses the received response as RestResponse where the fluent interface continues.

SOAP request methods

SoapRequestBuilder inherits all methods from HttpRequestBuilder plus implements the following ones:

SoapRequestBuilder::withAction

Parameter | Type | Description

---|---|---

soapAction | Object | Action to be set in the header

Adds or replaces the header with key SOAPAction with the provided value.

SoapRequestBuilder::withXmlFromPojoPayload

Parameter | Type | Description

---|---|---

payload | Object | Object to be serialised as XML

Serialises the provided object to XML using a JAXB marshaller and puts it as body of a SOAP envelope. Then attaches the resulting JSON as payload (body) to the http request. The JAXB marshaller is able to correctly process namespaces and requires this to be specified in XmlElement annotations at all levels. Usually SOAP servers are permissive and do not require the namespaces to be set correctly at all levels.

SoapRequestBuilder::sendAndGetResponse

Completes the builder pattern and sends the request to the driver. Parses the received response as SoapResponse where the fluent interface continues.

HTTP Response members

Some methods of HttpResponse allow continuing the fluent interface while others return specific objects that need to be processed apart. There are also public attributes accessible for manual processing and code simplification.

List of public attributes:

Attribute | Type | Description

---|---|---

initialRequest | InitialHttpRequest | Initial request with additional public attributes (url, method, headers, payload)

status | int | Status code of the response

headers | Map<String,String> | Map of headers where header names are keys

payload | String | Body of the response, may be null

HttpResponse::assertStatus

Parameter | Type | Description

---|---|---

status | int | Expected status code

Asserts that the received response has provided status code.

HttpResponse::assertBodyIsNotEmpty

Asserts that the received response has non-empty body.

HttpResponse::assertPayloadContains

Parameter | Type | Description

---|---|---

needle | String | Searched text in the payload

Asserts that the received response payload (body) contains at least one occurrence of the provided string. No regular expressions are allowed in this case.

HttpResponse::assertHeaderReceived

Parameter | Type | Description

---|---|---

headerName | String | Name of the header to search

Asserts that the received response headers contain at least one with the provided name.

HttpResponse::assertHeaderContains

Parameter | Type | Description

---|---|---

headerName | String | Key of the header to search

value | String | Value to search in the header

Asserts that the received response has a header with the provided name and that the header content contains the provided value. No regular expressions are allowed here.

HttpResponse::printRequest

Prints the initial request to stdout for debug purposes

HttpResponse::printResponse

Prints the response to stdout for debug purposes

HttpResponse::andThen

Returns to the initial state where entry methods can be used for next request without breaking the fluent interface.

REST Response members

RestResponse inherits all members of HttpResponse plus adds a few more methods enabling to work with the response payload as JSON.

RestResponse::payloadAs

Parameter | Type | Description

---|---|---

poJoClass | Class | Class to use when mapping the JSON to an object

Returns an object of type PoJoClass deserialised using a Jackson ObjectMapper.

RestResponse::assertThatPayload

Parameter | Type | Description

---|---|---

poJoClass | Class | Class to use when mapping the JSON to an object

Returns an object of type ObjectAssert<PoJoClass> from the AssertJ library that allows running various assertions on the object after deseralising to PoJoClass using Jackson.

RestResponse::payloadBinaryAsByteArray

Returns the payload as plain bytes decoded from Base64.

This method should be used only when the response payload is detected to be binary (e.g. image, document etc) and therefore was encoded to Base64 using a heuristic approach.

SOAP Response members

SoapResponse inherits all members of HttpResponse plus adds a few more methods enabling to work with the response payload as XML.

SoapResponse::payloadAs

Parameter | Type | Description

---|---|--- poJoClass | Class | Class to use when mapping the XML to an object

Returns an object of type PoJoClass deserialised using a Jackson XmlMapper.

SoapResponse::payloadXmlAs

Parameter | Type | Description

---|---|---

poJoClass | Class | Class to use when mapping the XML to an object

Returns an object of type PoJoClass deserialised using a JAXB unmarshaller. Unlike previous method where JsonProperty annotations can be used to map XML Elements to PoJo attributes and where XML namespaces are ignored, JAXB requires XmlElement annotations with namespace matching the namespace used inside the XML at any level which requires more work to be done but can be more accurate in some cases.

RestResponse::assertThatPayload

Parameter | Type | Description

---|---|---

poJoClass | Class | Class to use when mapping the XML to an object

Returns an object of type ObjectAssert<PoJoClass> from the AssertJ library that allows running various assertions on the object after deseralising to PoJoClass using Jackson XmlMapper.