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

Parameter | Type | Description

---|---|---

url | String | The target url to call

method | String | The 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

Parameter | Type | Description

---|---|---

url | String | The target url to call

method | String | The 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

Parameter | Type | Description

---|---|---

url | String | The 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

Parameter | Type | Description

---|---|---

user | String | User name in plain

password | String | Password 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

Parameter | Type | Description

---|---|---

token | String | Token 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

Parameter | Type | Description

---|---|---

oAuthEndpoint | String | URL of the endpoint service access tokens

clientId | String | Identification of the application

clientSecret | String | Secret of the application in plain

scope | String | Scope 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

Parameter | Type | Description

---|---|---

oAuthEndpoint | String | URL of the endpoint service access tokens

clientId | String | Identification of the application

clientSecret | String | Secret of the application in plain

scope | String | Scope for the access token; please check the documentation of the target API what scope should be specified

userName | String | Username of the user to impersonate

userPassword | String | Password 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

Parameter | Type | Description

---|---|---

domain | String | The domain of the user authenticated

username | String | Username

password | String | Password in plain

workstation | String | Workstation - 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

Parameter | Type | Description

---|---|---

certificate | String | Either the path to a file containing an SSL certificate or a chain of certificates, or the file content itself

key | String | Either 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

Parameter | Type | Description

---|---|---

key | String | The header key (e.g. Content-Type)

value | String | The 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

Parameter | Type | Description

---|---|---

key | String | The parameter name

value | String | The 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

Parameter | Type | Description

---|---|---

payload | String | The 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

Parameter | Type | Description

---|--------|---

payload | byte[] | 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

Parameter | Type | Description

---|---|---

path | String | Path 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

Parameter | Type | Description

---|---|---

path | String | Path 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

Parameter | Type | Description

---|---|---

placeholder | String | Token searched in the URL

value | String | Value 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.