Samples

To run a sample, you can edit a file with the sample content, and use Hurl:

$ vi sample.hurl

GET https://example.net

$ hurl sample.hurl

Getting Data

A simple GET:

GET https://example.net

Doc

A simple GET with headers:

GET https://example.net/news
User-Agent: Mozilla/5.0 
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

Doc

Query Params

GET https://example.net/news
[QueryStringParams]
order: newest
search: something to search
count: 100

Or:

GET https://example.net/news?order=newest&search=something%20to%20search&count=100

Doc

Sending Data

Sending HTML Form Datas

POST https://example.net/contact
[FormParams]
default: false
token: {{token}}
email: john.doe@rookie.org
number: 33611223344

Doc

Sending Multipart Form Datas

POST https://example.net/upload
[MultipartFormData]
field1: value1
field2: file,example.txt;
# On can specify the file content type:
field3: file,example.zip; application/zip

Doc

Posting a JSON Body

With an inline JSON:

POST https://api.example.net/tests
{
    "id": "456",
    "evaluate": true
}

Doc

With a local file:

POST https://api.example.net/tests
Content-Type: application/json
file,data.json;

Doc

Templating a JSON / XML Body

Using templates with JSON body or XML body is not currently supported in Hurl. Besides, you can use templates in raw string body with variables to send a JSON or XML body:

PUT https://api.example.net/hits
Content-Type: application/json
```
{
    "key0": "{{a_string}}",
    "key1": {{a_bool}},
    "key2": {{a_null}},
    "key3": {{a_number}}
}
```

Variables can be initialized via command line:

$ hurl --variable key0=apple \
       --variable key1=true \
       --variable key2=null \
       --variable key3=42 \
       test.hurl

Resulting in a PUT request with the following JSON body:

{
    "key0": "apple",
    "key1": true,
    "key2": null,
    "key3": 42
}

Doc

Testing Response

Testing Response Headers

Use implicit response asserts to test header values:

GET http://www.example.org/index.html

HTTP/1.0 200
Set-Cookie: theme=light
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT

Doc

Or use explicit response asserts with predicates:

GET https://example.net

HTTP/1.1 302
[Asserts]
header "Location" contains "www.example.net"

Doc

Testing REST Apis

Asserting JSON body response with JSONPath:

GET https//example.org/order
screencapability: low

HTTP/1.1 200
[Asserts]
jsonpath "$.validated" == true
jsonpath "$.userInfo.firstName" == "Franck"
jsonpath "$.userInfo.lastName" == "Herbert"
jsonpath "$.hasDevice" == false
jsonpath "$.links" count == 12
jsonpath "$.state" != null

Doc

Testing status code:

GET https//example.org/order/435

HTTP/1.1 200

Doc

GET https//example.org/order/435

# Testing status code is in a 200-300 range
HTTP/1.1 *
[Asserts]
status >= 200
status < 300

Doc

Testing HTML Response

GET https://example.com

HTTP/1.1 200
Content-Type: text/html; charset=UTF-8

[Asserts]
xpath "string(/html/head/title)" contains "Example" # Check title
xpath "count(//p)" == 2  # Check the number of p
xpath "//p" count == 2  # Similar assert for p
xpath "boolean(count(//h2))" == false  # Check there is no h2  
xpath "//h2" not exists  # Similar assert for h2

Doc

GET http://myserver.com/home

HTTP/1.0 200
[Asserts]
cookie "JSESSIONID" == "8400BAFE2F66443613DC38AE3D9D6239"
cookie "JSESSIONID[Value]" == "8400BAFE2F66443613DC38AE3D9D6239"
cookie "JSESSIONID[Expires]" contains "Wed, 13 Jan 2021"
cookie "JSESSIONID[Secure]" exists
cookie "JSESSIONID[HttpOnly]" exists
cookie "JSESSIONID[SameSite]" == "Lax"

Doc

Others

Testing Endpoint Performance

GET https://sample.org/helloworld

HTTP/* *
[Asserts]
duration < 1000   # Check that response time is less than one second

Doc

Using SOAP Apis

POST https://example.net/InStock
Content-Type: application/soap+xml; charset=utf-8
SOAPAction: "http://www.w3.org/2003/05/soap-envelope"
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:m="http://www.example.org">
  <soap:Header></soap:Header>
  <soap:Body>
    <m:GetStockPrice>
      <m:StockName>GOOG</m:StockName>
    </m:GetStockPrice>
  </soap:Body>
</soap:Envelope>

HTTP/1.1 200

Doc

Capturing and Using a CSRF Token

GET https://example.net

HTTP/* 200
[Captures]
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"

POST https://example.net/login?user=toto&password=1234
X-CSRF-TOKEN: {{csrf_token}}

HTTP/* 302

Doc

Checking Byte Order Mark (BOM) in Response Body

GET https://example.net/data.bin

HTTP/* 200
[Asserts]
bytes startsWith hex,efbbbf;

Doc