mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-11-23 00:44:55 +03:00
Update doc for 4.2.0
This commit is contained in:
parent
bc13b5f75e
commit
93f9a914e9
@ -1,7 +1,8 @@
|
||||
[4.2.0 (TO BE RELEASED)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#4.2.0)
|
||||
[4.2.0 (2024-01-11)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#4.2.0)
|
||||
========================================================================================================================
|
||||
|
||||
Thanks to
|
||||
[@hi2code](https://github.com/hi2code),
|
||||
[@lambrospetrou](https://github.com/lambrospetrou),
|
||||
[@glb-cblin](https://github.com/glb-cblin),
|
||||
[@moono](https://github.com/moono),
|
||||
@ -44,6 +45,7 @@ Enhancements:
|
||||
|
||||
Bugs Fixed:
|
||||
|
||||
* Add short name -v for verbose option [#2310](https://github.com/Orange-OpenSource/hurl/issues/2310)
|
||||
* Fix unicode surrogate pair decoding in JSON request body [#2235](https://github.com/Orange-OpenSource/hurl/issues/2235)
|
||||
* Better error description for some parse error [#2187](https://github.com/Orange-OpenSource/hurl/issues/2187)
|
||||
* Fix undefined error for various I/O error using --output. [#2156](https://github.com/Orange-OpenSource/hurl/issues/2156)
|
||||
|
25
README.md
25
README.md
@ -21,7 +21,6 @@ Hurl makes it easy to work with <b>HTML</b> content, <b>REST / SOAP / GraphQL</b
|
||||
```hurl
|
||||
# Get home:
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
|
||||
@ -59,7 +58,6 @@ POST https://example.org/api/tests
|
||||
"id": "4568",
|
||||
"evaluate": true
|
||||
}
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "X-Frame-Options" == "SAMEORIGIN"
|
||||
@ -72,7 +70,6 @@ jsonpath "$.id" matches /\d{4}/ # Check the format of the id
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
xpath "normalize-space(//head/title)" == "Hello world!"
|
||||
@ -115,7 +112,6 @@ Hurl can also be used to test the <b>performance</b> of HTTP endpoints
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api/v1/pets
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
duration < 1000 # Duration in ms
|
||||
@ -125,7 +121,6 @@ And check response bytes
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.tar.gz
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
sha256 == hex,039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
|
||||
@ -523,7 +518,6 @@ Use implicit response asserts to test header values:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/index.html
|
||||
|
||||
HTTP 200
|
||||
Set-Cookie: theme=light
|
||||
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT
|
||||
@ -536,7 +530,6 @@ Or use explicit response asserts with [predicates]:
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 302
|
||||
[Asserts]
|
||||
header "Location" contains "www.example.net"
|
||||
@ -552,7 +545,6 @@ Asserting JSON body response (node values, collection count etc...) with [JSONPa
|
||||
```hurl
|
||||
GET https://example.org/order
|
||||
screencapability: low
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.validated" == true
|
||||
@ -572,7 +564,6 @@ Testing status code:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/order/435
|
||||
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
@ -580,7 +571,6 @@ HTTP 200
|
||||
|
||||
```hurl
|
||||
GET https://example.org/order/435
|
||||
|
||||
# Testing status code is in a 200-300 range
|
||||
HTTP *
|
||||
[Asserts]
|
||||
@ -595,10 +585,8 @@ status < 300
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 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
|
||||
@ -614,7 +602,6 @@ xpath "string(//div[1])" matches /Hello.*/
|
||||
|
||||
```hurl
|
||||
GET https://example.org/home
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
cookie "JSESSIONID" == "8400BAFE2F66443613DC38AE3D9D6239"
|
||||
@ -633,7 +620,6 @@ Check the SHA-256 response body hash:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.tar.gz
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
sha256 == hex,039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
|
||||
@ -647,7 +633,6 @@ Check the properties of a SSL certificate:
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
certificate "Subject" == "CN=example.org"
|
||||
@ -679,7 +664,6 @@ Retry request on any errors (asserts, captures, status code, runtime etc...):
|
||||
```hurl
|
||||
# Create a new job
|
||||
POST https://api.example.org/jobs
|
||||
|
||||
HTTP 201
|
||||
[Captures]
|
||||
job_id: jsonpath "$.id"
|
||||
@ -691,7 +675,6 @@ jsonpath "$.state" == "RUNNING"
|
||||
GET https://api.example.org/jobs/{{job_id}}
|
||||
[Options]
|
||||
retry: 10 # maximum number of retry, -1 for unlimited
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.state" == "COMPLETED"
|
||||
@ -705,7 +688,6 @@ jsonpath "$.state" == "COMPLETED"
|
||||
|
||||
```hurl
|
||||
GET https://sample.org/helloworld
|
||||
|
||||
HTTP *
|
||||
[Asserts]
|
||||
duration < 1000 # Check that response time is less than one second
|
||||
@ -728,7 +710,6 @@ SOAPAction: "http://www.w3.org/2003/05/soap-envelope"
|
||||
</m:GetStockPrice>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
@ -738,7 +719,6 @@ HTTP 200
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
|
||||
@ -755,7 +735,6 @@ HTTP 302
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.bin
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
bytes startsWith hex,efbbbf;
|
||||
@ -954,7 +933,7 @@ will follow a redirection only for the second entry.
|
||||
| <a href="#interactive" id="interactive"><code>--interactive</code></a> | Stop between requests.<br><br>This is similar to a break point, You can then continue (Press C) or quit (Press Q).<br> |
|
||||
| <a href="#ipv4" id="ipv4"><code>-4, --ipv4</code></a> | This option tells Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6.<br> |
|
||||
| <a href="#ipv6" id="ipv6"><code>-6, --ipv6</code></a> | This option tells Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4.<br> |
|
||||
| <a href="#json" id="json"><code>--json</code></a> | Output each hurl file result to JSON. The format is very closed to HAR format.<br> |
|
||||
| <a href="#json" id="json"><code>--json</code></a> | Output each Hurl file result to JSON. The format is very closed to HAR format.<br> |
|
||||
| <a href="#key" id="key"><code>--key <KEY></code></a> | Private key file name.<br> |
|
||||
| <a href="#location" id="location"><code>-L, --location</code></a> | Follow redirect. To limit the amount of redirects to follow use the [`--max-redirs`](#max-redirs) option<br> |
|
||||
| <a href="#location-trusted" id="location-trusted"><code>--location-trusted</code></a> | Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.<br>This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).<br> |
|
||||
@ -980,7 +959,7 @@ will follow a redirection only for the second entry.
|
||||
| <a href="#user-agent" id="user-agent"><code>-A, --user-agent <NAME></code></a> | Specify the User-Agent string to send to the HTTP server.<br> |
|
||||
| <a href="#variable" id="variable"><code>--variable <NAME=VALUE></code></a> | Define variable (name/value) to be used in Hurl templates.<br> |
|
||||
| <a href="#variables-file" id="variables-file"><code>--variables-file <FILE></code></a> | Set properties file in which your define your variables.<br><br>Each variable is defined as name=value exactly as with [`--variable`](#variable) option.<br><br>Note that defining a variable twice produces an error.<br> |
|
||||
| <a href="#verbose" id="verbose"><code>--verbose</code></a> | Turn on verbose output on standard error stream.<br>Useful for debugging.<br><br>A line starting with '>' means data sent by Hurl.<br>A line staring with '<' means data received by Hurl.<br>A line starting with '*' means additional info provided by Hurl.<br><br>If you only want HTTP headers in the output, [`-i, --include`](#include) might be the option you're looking for.<br> |
|
||||
| <a href="#verbose" id="verbose"><code>-v, --verbose</code></a> | Turn on verbose output on standard error stream.<br>Useful for debugging.<br><br>A line starting with '>' means data sent by Hurl.<br>A line staring with '<' means data received by Hurl.<br>A line starting with '*' means additional info provided by Hurl.<br><br>If you only want HTTP headers in the output, [`-i, --include`](#include) might be the option you're looking for.<br> |
|
||||
| <a href="#very-verbose" id="very-verbose"><code>--very-verbose</code></a> | Turn on more verbose output on standard error stream.<br><br>In contrast to [`--verbose`](#verbose) option, this option outputs the full HTTP body request and response on standard error. In addition, lines starting with '**' are libcurl debug logs.<br> |
|
||||
| <a href="#help" id="help"><code>-h, --help</code></a> | Usage help. This lists all current command line options with a short description.<br> |
|
||||
| <a href="#version" id="version"><code>-V, --version</code></a> | Prints version information<br> |
|
||||
|
@ -3,12 +3,12 @@
|
||||
## Asserts
|
||||
|
||||
Asserts are used to test various properties of an HTTP response. Asserts can be implicits (such as version, status,
|
||||
headers) or explicit within an `[Asserts]` section.
|
||||
headers) or explicit within an `[Asserts]` section. The delimiter of the request / response is `HTTP <STATUS-CODE>`:
|
||||
after this delimiter, you'll find the implicit asserts, then an `[Asserts]` section with all the explicits checks.
|
||||
|
||||
|
||||
```hurl
|
||||
GET https://api/example.org/cats
|
||||
|
||||
HTTP 200
|
||||
Content-Type: application/json; charset=utf-8 # Implicit assert on Content-Type Hedaer
|
||||
[Asserts] # Explicit asserts section
|
||||
@ -37,7 +37,6 @@ Wildcard keywords `HTTP` and `*` can be used to disable tests on protocol versio
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api/pets
|
||||
|
||||
HTTP *
|
||||
# Check that response status code is > 400 and <= 500
|
||||
[Asserts]
|
||||
@ -60,9 +59,10 @@ Optional list of the expected HTTP response headers that must be in the received
|
||||
|
||||
A header consists of a name, followed by a `:` and a value.
|
||||
|
||||
For each expected header, the received response headers are checked. If the received header is not equal to the expected,
|
||||
or not present, an error is raised. Note that the expected headers list is not fully descriptive: headers present in the response
|
||||
and not in the expected list doesn't raise error.
|
||||
For each expected header, the received response headers are checked. If the received header is not equal to the
|
||||
expected, or not present, an error is raised. The comparison is case-insensitive for the name: expecting a
|
||||
`Content-Type` header is equivalent to a `content-type` one. Note that the expected headers list is not fully
|
||||
descriptive: headers present in the response and not in the expected list doesn't raise error.
|
||||
|
||||
```hurl
|
||||
# Check that user toto is redirected to home after login.
|
||||
@ -70,7 +70,6 @@ POST https://example.org/login
|
||||
[FormParams]
|
||||
user: toto
|
||||
password: 12345678
|
||||
|
||||
HTTP 302
|
||||
Location: https://example.org/home
|
||||
```
|
||||
@ -98,7 +97,6 @@ You can either test the two header values:
|
||||
```hurl
|
||||
GET https://example.org/index.html
|
||||
Host: example.net
|
||||
|
||||
HTTP 200
|
||||
Set-Cookie: theme=light
|
||||
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT
|
||||
@ -109,7 +107,6 @@ Or only one:
|
||||
```hurl
|
||||
GET https://example.org/index.html
|
||||
Host: example.net
|
||||
|
||||
HTTP 200
|
||||
Set-Cookie: theme=light
|
||||
```
|
||||
@ -210,7 +207,6 @@ For instance, to test the presence of a h1 node in an HTML response, the followi
|
||||
|
||||
```hurl
|
||||
GET https://example.org/home
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
xpath "boolean(count(//h1))" == true
|
||||
@ -233,7 +229,6 @@ The following assert will check the value of the `data-visible` attribute:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/home
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
xpath "string(//article/@data-visible)" == "true"
|
||||
@ -248,7 +243,6 @@ be used with strings and bytes, while `matches` only works on string. If a query
|
||||
```hurl
|
||||
# A really well tested web page...
|
||||
GET https://example.org/home
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Content-Type" contains "text/html"
|
||||
@ -266,7 +260,6 @@ function and value.
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP *
|
||||
[Asserts]
|
||||
status < 300
|
||||
@ -275,11 +268,11 @@ status < 300
|
||||
### Header assert
|
||||
|
||||
Check the value of a received HTTP response header. Header assert consists of the keyword `header` followed by the value
|
||||
of the header, a predicate function and a predicate value.
|
||||
of the header, a predicate function and a predicate value. Like [headers implicit asserts], the check is
|
||||
case-insensitive for the name: comparing a `Content-Type` header is equivalent to a `content-type` one.
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 302
|
||||
[Asserts]
|
||||
header "Location" contains "www.example.net"
|
||||
@ -312,7 +305,6 @@ One can use explicit header asserts:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/hello
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Vary" count == 2
|
||||
@ -324,7 +316,6 @@ Or implicit header asserts:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/hello
|
||||
|
||||
HTTP 200
|
||||
Vary: User-Agent
|
||||
Vary: Content-Type
|
||||
@ -339,7 +330,6 @@ Check the last fetched URL. This is most meaningful if you have told Hurl to fol
|
||||
GET https://example.org/redirecting
|
||||
[Options]
|
||||
location: true
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
url == "https://example.org/redirected"
|
||||
@ -358,7 +348,6 @@ Cookie attributes value can be checked by using the following format:
|
||||
|
||||
```hurl
|
||||
GET http://localhost:8000/cookies/set
|
||||
|
||||
HTTP 200
|
||||
|
||||
# Explicit check of Set-Cookie header value. If the attributes are
|
||||
@ -394,7 +383,6 @@ value. The encoding used to decode the body is based on the `charset` value in t
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
body contains "<h1>Welcome!</h1>"
|
||||
@ -403,7 +391,6 @@ body contains "<h1>Welcome!</h1>"
|
||||
```hurl
|
||||
# Our HTML response is encoded with GB 2312 (see https://en.wikipedia.org/wiki/GB_2312)
|
||||
GET https://example.org/cn
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Content-Type" == "text/html; charset=gb2312"
|
||||
@ -419,7 +406,6 @@ bytes.
|
||||
# But, the 'Content-Type' HTTP response header doesn't precise any charset,
|
||||
# so we decode explicitly the bytes.
|
||||
GET https://example.org/cn
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Content-Type" == "text/html"
|
||||
@ -434,7 +420,6 @@ consists of the keyword `bytes` followed by a predicate function and value.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.bin
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
bytes startsWith hex,efbbbf;
|
||||
@ -478,7 +463,6 @@ With Hurl, we can write multiple XPath asserts describing the DOM content:
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
[Asserts]
|
||||
@ -505,7 +489,6 @@ This XML response can be tested with the following Hurl file:
|
||||
|
||||
```hurl
|
||||
GET http://localhost:8000/assert-xpath
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
|
||||
@ -560,7 +543,6 @@ With Hurl, we can write multiple JSONPath asserts describing the DOM content:
|
||||
|
||||
```hurl
|
||||
GET http://httpbin.org/json
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.slideshow.author" == "Yours Truly"
|
||||
@ -579,12 +561,13 @@ the readability:
|
||||
|
||||
```hurl
|
||||
GET https://sample.org/hello
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
|
||||
# Predicate value with matches predicate:
|
||||
jsonpath "$.date" matches "^\\d{4}-\\d{2}-\\d{2}$"
|
||||
jsonpath "$.name" matches "Hello [a-zA-Z]+!"
|
||||
|
||||
# Equivalent syntax:
|
||||
jsonpath "$.date" matches /^\d{4}-\d{2}-\d{2}$/
|
||||
jsonpath "$.name" matches /Hello [a-zA-Z]+!/
|
||||
@ -596,7 +579,6 @@ Check that the HTTP received body, decoded as text, matches a regex pattern.
|
||||
|
||||
```hurl
|
||||
GET https://sample.org/hello
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
regex "^(\\d{4}-\\d{2}-\\d{2})$" == "2018-12-31"
|
||||
@ -616,7 +598,6 @@ Check response body [SHA-256] hash.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.tar.gz
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
sha256 == hex,039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
|
||||
@ -628,7 +609,6 @@ Check response body [MD5] hash.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.tar.gz
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
md5 == hex,ed076287532e86365e841e92bfc50d8c;
|
||||
@ -640,7 +620,6 @@ md5 == hex,ed076287532e86365e841e92bfc50d8c;
|
||||
```hurl
|
||||
# Test that the XML endpoint return 200 pets
|
||||
GET https://example.org/api/pets
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
pets: xpath "//pets"
|
||||
@ -654,7 +633,6 @@ Check the total duration (sending plus receiving time) of the HTTP transaction.
|
||||
|
||||
```hurl
|
||||
GET https://sample.org/helloworld
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
duration < 1000 # Check that response time is less than one second
|
||||
@ -668,7 +646,6 @@ The following attributes are supported: `Subject`, `Issuer`, `Start-Date`, `Expi
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
certificate "Subject" == "CN=example.org"
|
||||
@ -693,7 +670,6 @@ the body byte content to check.
|
||||
```hurl
|
||||
# Get a doggy thing:
|
||||
GET https://example.org/api/dogs/{{dog-id}}
|
||||
|
||||
HTTP 200
|
||||
{
|
||||
"id": 0,
|
||||
@ -710,7 +686,6 @@ JSON response body can be seen as syntactic sugar of [multiline string body] wit
|
||||
~~~hurl
|
||||
# Get a doggy thing:
|
||||
GET https://example.org/api/dogs/{{dog-id}}
|
||||
|
||||
HTTP 200
|
||||
```json
|
||||
{
|
||||
@ -729,7 +704,6 @@ HTTP 200
|
||||
|
||||
~~~hurl
|
||||
GET https://example.org/api/catalog
|
||||
|
||||
HTTP 200
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<catalog>
|
||||
@ -748,7 +722,6 @@ XML response body can be seen as syntactic sugar of [multiline string body] with
|
||||
|
||||
~~~hurl
|
||||
GET https://example.org/api/catalog
|
||||
|
||||
HTTP 200
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@ -770,7 +743,6 @@ HTTP 200
|
||||
|
||||
~~~hurl
|
||||
GET https://example.org/models
|
||||
|
||||
HTTP 200
|
||||
```
|
||||
Year,Make,Model,Description,Price
|
||||
@ -797,7 +769,6 @@ For text based response body that do not contain newlines, one can use oneline s
|
||||
|
||||
~~~hurl
|
||||
POST https://example.org/helloworld
|
||||
|
||||
HTTP 200
|
||||
`Hello world!`
|
||||
~~~
|
||||
@ -811,7 +782,6 @@ ignored on decoding), and `=` padding characters might be added.
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIG
|
||||
FkaXBpc2NpbmcgZWxpdC4gSW4gbWFsZXN1YWRhLCBuaXNsIHZlbCBkaWN0dW0g
|
||||
@ -826,7 +796,6 @@ can be used. File body starts with `file,` and ends with `;``
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
file,data.bin;
|
||||
```
|
||||
@ -857,4 +826,5 @@ of all file nodes.
|
||||
[multiline string body]: #multiline-string-body
|
||||
[filters]: /docs/filters.md
|
||||
[count]: /docs/filters.md#count
|
||||
[`decode` filter]: /docs/filters.md#decode
|
||||
[`decode` filter]: /docs/filters.md#decode
|
||||
[headers implicit asserts]: #headers
|
@ -16,13 +16,11 @@ Variables in a Hurl file can be created from captures or [injected into the sess
|
||||
|
||||
# First GET request to get CSRF token value:
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
# Capture the CSRF token value from html body.
|
||||
[Captures]
|
||||
csrf_token: xpath "normalize-space(//meta[@name='_csrf_token']/@content)"
|
||||
|
||||
|
||||
# Do the login !
|
||||
POST https://acmecorp.net/login?user=toto&password=1234
|
||||
X-CSRF-TOKEN: {{csrf_token}}
|
||||
@ -71,7 +69,6 @@ keyword `status`.
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
my_status: status
|
||||
@ -87,7 +84,6 @@ POST https://example.org/login
|
||||
[FormParams]
|
||||
user: toto
|
||||
password: 12345678
|
||||
|
||||
HTTP 302
|
||||
[Captures]
|
||||
next_url: header "Location"
|
||||
@ -102,7 +98,6 @@ Capture the last fetched URL. This is most meaningful if you have told Hurl to f
|
||||
GET https://example.org/redirecting
|
||||
[Options]
|
||||
location: true
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
landing_url: url
|
||||
@ -116,7 +111,6 @@ and a cookie name.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/cookies/set
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
session-id: cookie "LSID"
|
||||
@ -128,7 +122,6 @@ Cookie attributes value can also be captured by using the following format:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/cookies/set
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
value1: cookie "LSID"
|
||||
@ -150,7 +143,6 @@ is based on the `charset` value in the `Content-Type` header response.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/home
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
my_body: body
|
||||
@ -164,7 +156,6 @@ bytes.
|
||||
# But, the 'Content-Type' HTTP response header doesn't precise any charset,
|
||||
# so we decode explicitly the bytes.
|
||||
GET https://example.org/cn
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
my_body: bytes decode "gb2312"
|
||||
@ -177,7 +168,6 @@ Capture the entire body (as a raw bytestream) from the received HTTP response
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.bin
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
my_data: bytes
|
||||
@ -191,7 +181,6 @@ Currently, only XPath 1.0 expression can be used.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/home
|
||||
|
||||
# Capture the identifier from the dom node <div id="pet0">5646eaf23</div
|
||||
HTTP 200
|
||||
[Captures]
|
||||
@ -208,7 +197,6 @@ valid XPath can be captured and asserted with variable asserts.
|
||||
```hurl
|
||||
# Test that the XML endpoint return 200 pets
|
||||
GET https://example.org/api/pets
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
pets: xpath "//pets"
|
||||
@ -220,7 +208,6 @@ XPath expression can also be evaluated against part of the body with a [`xpath`
|
||||
|
||||
```hurl
|
||||
GET https://example.org/home_cn
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
ped-id: bytes decode "gb2312" xpath "normalize-space(//div[@id='pet0'])"
|
||||
@ -236,7 +223,6 @@ POST https://example.org/api/contact
|
||||
[FormParams]
|
||||
token: {{token}}
|
||||
email: toto@rookie.net
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
contact-id: jsonpath "$['id']"
|
||||
@ -269,7 +255,6 @@ We can capture the following paths:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/captures-json
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
an_object: jsonpath "$['an_object']"
|
||||
@ -289,7 +274,6 @@ Capture a regex pattern from the HTTP received body, decoded as text.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/helloworld
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
id_a: regex "id_a:([0-9]+)"
|
||||
@ -309,7 +293,6 @@ Capture the value of a variable into another.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/helloworld
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
in: body
|
||||
@ -322,7 +305,6 @@ Capture the response time of the request in ms.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/helloworld
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
duration_in_ms: duration
|
||||
@ -336,7 +318,6 @@ The following attributes are supported: `Subject`, `Issuer`, `Start-Date`, `Expi
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
cert_subject: certificate "Subject"
|
||||
|
@ -12,7 +12,6 @@ to [capture values] to perform subsequent requests, or [add asserts to HTTP resp
|
||||
```hurl
|
||||
# First, test home title.
|
||||
GET https://acmecorp.net
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
xpath "normalize-space(//head/title)" == "Hello world!"
|
||||
@ -83,7 +82,6 @@ of the redirection, allowing insertion of asserts in each response.
|
||||
```hurl
|
||||
# First entry, test the redirection (status code and 'Location' header)
|
||||
GET https://google.fr
|
||||
|
||||
HTTP 301
|
||||
Location: https://www.google.fr/
|
||||
|
||||
@ -92,7 +90,7 @@ GET https://www.google.fr
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
Alternatively, one can use [`--location`] option to force redirection
|
||||
Alternatively, one can use [`--location`] / [`--location-trusted`] options to force redirection
|
||||
to be followed. In this case, asserts are executed on the last received response. Optionally, the number of
|
||||
redirections can be limited with [`--max-redirs`].
|
||||
|
||||
@ -102,12 +100,13 @@ GET https://google.fr
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
Finally, you can force redirection on a particular request with an [`[Options]` section][options] and the [`--location` option]:
|
||||
Finally, you can force redirection on a particular request with an [`[Options]` section][options] and the[`--location`]
|
||||
/ [`--location-trusted`] options:
|
||||
|
||||
```hurl
|
||||
GET https://google.fr
|
||||
[Options]
|
||||
location: true
|
||||
location-trusted: true
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
@ -124,7 +123,6 @@ For example, in this Hurl file, first we create a new job, then we poll the new
|
||||
```hurl
|
||||
# Create a new job
|
||||
POST http://api.example.org/jobs
|
||||
|
||||
HTTP 201
|
||||
[Captures]
|
||||
job_id: jsonpath "$.id"
|
||||
@ -136,7 +134,6 @@ jsonpath "$.state" == "RUNNING"
|
||||
GET http://api.example.org/jobs/{{job_id}}
|
||||
[Options]
|
||||
retry: 10 # maximum number of retry, -1 for unlimited
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.state" == "COMPLETED"
|
||||
@ -148,10 +145,10 @@ jsonpath "$.state" == "COMPLETED"
|
||||
[capture values]: /docs/capturing-response.md
|
||||
[add asserts to HTTP responses]: /docs/asserting-response.md
|
||||
[`--location`]: /docs/manual.md#location
|
||||
[`--location-trusted`]: /docs/manual.md#location-trusted
|
||||
[`--max-redirs`]: /docs/manual.md#max-redirs
|
||||
[Options]: /docs/manual.md#options
|
||||
[options]: /docs/request.md#options
|
||||
[`--location` option]: /docs/manual.md#location
|
||||
[headers]: /docs/response.md#headers
|
||||
[status code]: /docs/response.md#version-status
|
||||
[asserts]: /docs/response.md#asserts
|
||||
|
@ -47,7 +47,6 @@ __can be chained__, allowing for fine-grained data extraction.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
name: jsonpath "$user.id" replace /\d/ "x"
|
||||
@ -66,7 +65,6 @@ Counts the number of items in a collection.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.books" count == 12
|
||||
@ -78,7 +76,6 @@ Returns the number of days between now and a date in the future.
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
certificate "Expire-Date" daysAfterNow > 15
|
||||
@ -90,7 +87,6 @@ Returns the number of days between now and a date in the past.
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
certificate "Start-Date" daysBeforeNow < 100
|
||||
@ -104,7 +100,6 @@ Decode bytes to string using encoding.
|
||||
# The 'Content-Type' HTTP response header does not precise the charset 'gb2312'
|
||||
# so body must be decoded explicitly by Hurl before processing any text based assert
|
||||
GET https://exapple.org/hello_china
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Content-Type" == "text/html"
|
||||
@ -118,7 +113,6 @@ Formats a date to a string given [a specification format].
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
cookie "LSID[Expires]" format "%a, %d %b %Y %H:%M:%S" == "Wed, 13 Jan 2021 22:23:01"
|
||||
@ -130,7 +124,6 @@ Converts the characters `&`, `<` and `>` to HTML-safe sequence.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.text" htmlEscape == "a > b"
|
||||
@ -142,19 +135,32 @@ Converts all named and numeric character references (e.g. `>`, `>`, `
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.escaped_html[1]" htmlUnescape == "Foo © bar 𝌆"
|
||||
```
|
||||
|
||||
### jsonpath
|
||||
|
||||
Evaluates a [JSONPath] expression.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api
|
||||
HTTP 200
|
||||
[Captures]
|
||||
books: xpath "string(//body/@data-books)"
|
||||
[Asserts]
|
||||
variable "books" jsonpath "$[0].name" == "Dune"
|
||||
variable "books" jsonpath "$[0].author" == "Franck Herbert"
|
||||
```
|
||||
|
||||
|
||||
### nth
|
||||
|
||||
Returns the element from a collection at a zero-based index.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.books" nth 2 == "Children of Dune"
|
||||
@ -166,7 +172,6 @@ Extracts regex capture group. Pattern must have at least one capture group.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/foo
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
param1: header "header1"
|
||||
@ -180,7 +185,6 @@ Replaces all occurrences of old string with new string.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/foo
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
url: jsonpath "$.url" replace "http://" "https://"
|
||||
@ -194,7 +198,6 @@ Splits to a list of strings around occurrences of the specified delimiter.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/foo
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.ips" split ", " count == 3
|
||||
@ -206,7 +209,6 @@ Converts a string to a date given [a specification format].
|
||||
|
||||
```hurl
|
||||
GET https:///example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Expires" toDate "%a, %d %b %Y %H:%M:%S GMT" daysBeforeNow > 1000
|
||||
@ -217,7 +219,6 @@ ISO 8601 / RFC 3339 date and time format have shorthand format `%+`:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api/books
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.published" == "2023-01-23T18:25:43.511Z"
|
||||
@ -232,7 +233,6 @@ Converts to integer number.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/foo
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.id" toInt == 123
|
||||
@ -244,7 +244,6 @@ Replaces %xx escapes with their single-character equivalent.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/foo
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.encoded_url" urlDecode == "https://mozilla.org/?x=шеллы"
|
||||
@ -256,7 +255,6 @@ Percent-encodes all the characters which are not included in unreserved chars (s
|
||||
|
||||
```hurl
|
||||
GET https://example.org/foo
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.url" urlEncode == "https%3A//mozilla.org/%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"
|
||||
@ -268,7 +266,6 @@ Evaluates a [XPath] expression.
|
||||
|
||||
```hurl
|
||||
GET https://example.org/hello_gb2312
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
bytes decode "gb2312" xpath "string(//body)" == "你好世界"
|
||||
@ -279,4 +276,5 @@ bytes decode "gb2312" xpath "string(//body)" == "你好世界"
|
||||
[asserts]: /docs/asserting-response.md
|
||||
[RFC3986]: https://www.rfc-editor.org/rfc/rfc3986
|
||||
[a specification format]: https://docs.rs/chrono/latest/chrono/format/strftime/index.html
|
||||
[XPath]: https://en.wikipedia.org/wiki/XPath
|
||||
[XPath]: https://en.wikipedia.org/wiki/XPath
|
||||
[JSONPath]: https://goessner.net/articles/JsonPath/
|
@ -15,7 +15,6 @@ Hurl makes it easy to work with <b>HTML</b> content, <b>REST / SOAP / GraphQL</b
|
||||
```hurl
|
||||
# Get home:
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
|
||||
@ -52,7 +51,6 @@ POST https://example.org/api/tests
|
||||
"id": "4568",
|
||||
"evaluate": true
|
||||
}
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "X-Frame-Options" == "SAMEORIGIN"
|
||||
@ -65,7 +63,6 @@ jsonpath "$.id" matches /\d{4}/ # Check the format of the id
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
xpath "normalize-space(//head/title)" == "Hello world!"
|
||||
@ -108,7 +105,6 @@ Hurl can also be used to test the <b>performance</b> of HTTP endpoints
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api/v1/pets
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
duration < 1000 # Duration in ms
|
||||
@ -118,7 +114,6 @@ And check response bytes
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.tar.gz
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
sha256 == hex,039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
|
||||
|
@ -19,7 +19,6 @@ a documentation for HTTP based workflows so it can be useful to be very descript
|
||||
# with tasty comments...
|
||||
GET https://www.sample.net
|
||||
x-app: MY_APP # Add a dummy header
|
||||
|
||||
HTTP 302 # Check that we have a redirection
|
||||
[Asserts]
|
||||
header "Location" exists
|
||||
@ -36,7 +35,6 @@ String can include the following special characters:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api
|
||||
|
||||
HTTP 200
|
||||
# The following assert are equivalent:
|
||||
[Asserts]
|
||||
|
@ -171,7 +171,7 @@ will follow a redirection only for the second entry.
|
||||
| <a href="#interactive" id="interactive"><code>--interactive</code></a> | Stop between requests.<br><br>This is similar to a break point, You can then continue (Press C) or quit (Press Q).<br> |
|
||||
| <a href="#ipv4" id="ipv4"><code>-4, --ipv4</code></a> | This option tells Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6.<br> |
|
||||
| <a href="#ipv6" id="ipv6"><code>-6, --ipv6</code></a> | This option tells Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4.<br> |
|
||||
| <a href="#json" id="json"><code>--json</code></a> | Output each hurl file result to JSON. The format is very closed to HAR format.<br> |
|
||||
| <a href="#json" id="json"><code>--json</code></a> | Output each Hurl file result to JSON. The format is very closed to HAR format.<br> |
|
||||
| <a href="#key" id="key"><code>--key <KEY></code></a> | Private key file name.<br> |
|
||||
| <a href="#location" id="location"><code>-L, --location</code></a> | Follow redirect. To limit the amount of redirects to follow use the [`--max-redirs`](#max-redirs) option<br> |
|
||||
| <a href="#location-trusted" id="location-trusted"><code>--location-trusted</code></a> | Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.<br>This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).<br> |
|
||||
@ -197,7 +197,7 @@ will follow a redirection only for the second entry.
|
||||
| <a href="#user-agent" id="user-agent"><code>-A, --user-agent <NAME></code></a> | Specify the User-Agent string to send to the HTTP server.<br> |
|
||||
| <a href="#variable" id="variable"><code>--variable <NAME=VALUE></code></a> | Define variable (name/value) to be used in Hurl templates.<br> |
|
||||
| <a href="#variables-file" id="variables-file"><code>--variables-file <FILE></code></a> | Set properties file in which your define your variables.<br><br>Each variable is defined as name=value exactly as with [`--variable`](#variable) option.<br><br>Note that defining a variable twice produces an error.<br> |
|
||||
| <a href="#verbose" id="verbose"><code>--verbose</code></a> | Turn on verbose output on standard error stream.<br>Useful for debugging.<br><br>A line starting with '>' means data sent by Hurl.<br>A line staring with '<' means data received by Hurl.<br>A line starting with '*' means additional info provided by Hurl.<br><br>If you only want HTTP headers in the output, [`-i, --include`](#include) might be the option you're looking for.<br> |
|
||||
| <a href="#verbose" id="verbose"><code>-v, --verbose</code></a> | Turn on verbose output on standard error stream.<br>Useful for debugging.<br><br>A line starting with '>' means data sent by Hurl.<br>A line staring with '<' means data received by Hurl.<br>A line starting with '*' means additional info provided by Hurl.<br><br>If you only want HTTP headers in the output, [`-i, --include`](#include) might be the option you're looking for.<br> |
|
||||
| <a href="#very-verbose" id="very-verbose"><code>--very-verbose</code></a> | Turn on more verbose output on standard error stream.<br><br>In contrast to [`--verbose`](#verbose) option, this option outputs the full HTTP body request and response on standard error. In addition, lines starting with '**' are libcurl debug logs.<br> |
|
||||
| <a href="#help" id="help"><code>-h, --help</code></a> | Usage help. This lists all current command line options with a short description.<br> |
|
||||
| <a href="#version" id="version"><code>-V, --version</code></a> | Prints version information<br> |
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH hurl 1 "08 Jan 2024" "hurl 4.2.0-SNAPSHOT" " Hurl Manual"
|
||||
.TH hurl 1 "10 Jan 2024" "hurl 4.2.0-SNAPSHOT" " Hurl Manual"
|
||||
.SH NAME
|
||||
|
||||
hurl - run and test HTTP requests.
|
||||
@ -251,7 +251,7 @@ This option tells Hurl to use IPv6 addresses only when resolving host names, and
|
||||
|
||||
.IP "--json "
|
||||
|
||||
Output each hurl file result to JSON. The format is very closed to HAR format.
|
||||
Output each Hurl file result to JSON. The format is very closed to HAR format.
|
||||
|
||||
.IP "--key <KEY> "
|
||||
|
||||
@ -371,7 +371,7 @@ Each variable is defined as name=value exactly as with \fI--variable\fP option.
|
||||
|
||||
Note that defining a variable twice produces an error.
|
||||
|
||||
.IP "--verbose "
|
||||
.IP "-v, --verbose "
|
||||
|
||||
Turn on verbose output on standard error stream.
|
||||
Useful for debugging.
|
||||
|
@ -270,7 +270,7 @@ This option tells Hurl to use IPv6 addresses only when resolving host names, and
|
||||
|
||||
### --json {#json}
|
||||
|
||||
Output each hurl file result to JSON. The format is very closed to HAR format.
|
||||
Output each Hurl file result to JSON. The format is very closed to HAR format.
|
||||
|
||||
### --key <KEY> {#key}
|
||||
|
||||
@ -390,7 +390,7 @@ Each variable is defined as name=value exactly as with [`--variable`](#variable)
|
||||
|
||||
Note that defining a variable twice produces an error.
|
||||
|
||||
### --verbose {#verbose}
|
||||
### -v, --verbose {#verbose}
|
||||
|
||||
Turn on verbose output on standard error stream.
|
||||
Useful for debugging.
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH hurl 1 "08 Jan 2024" "hurl 4.2.0-SNAPSHOT" " Hurl Manual"
|
||||
.TH hurl 1 "10 Jan 2024" "hurl 4.2.0-SNAPSHOT" " Hurl Manual"
|
||||
.SH NAME
|
||||
|
||||
hurlfmt - format Hurl files
|
||||
|
@ -638,12 +638,16 @@ GET https://example.org
|
||||
# An options section, each option is optional and applied only to this request...
|
||||
[Options]
|
||||
aws-sigv4: aws:amz:sts # generate AWS SigV4 Authorization header
|
||||
cacert: /etc/cert.pem # a custom certificate file
|
||||
cacert: /etc/cert.pem # custom certificate file
|
||||
compressed: true # request a compressed response
|
||||
insecure: true # allows insecure SSL connections and transfers
|
||||
http3: true # use HTTP/3 protocol version
|
||||
insecure: true # allow insecure SSL connections and transfers
|
||||
ipv6: true # use IPv6 addresses
|
||||
location: true # follow redirection for this request
|
||||
max-redirs: 10 # maximum number of redirections
|
||||
path-as-is: true # tell curl to not handle sequences of /../ or /./ in the given URL path
|
||||
output: out.html # dump the response to this file
|
||||
path-as-is: true # do not handle sequences of /../ or /./ in URL path
|
||||
unix-socket: sock # use Unix socket for transfer
|
||||
variable: country=Italy # define variable country
|
||||
variable: planet=Earth # define variable planet
|
||||
verbose: true # allow verbose output
|
||||
|
@ -14,7 +14,6 @@ in the following entries.
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
|
||||
[Asserts]
|
||||
|
@ -270,7 +270,6 @@ Use implicit response asserts to test header values:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/index.html
|
||||
|
||||
HTTP 200
|
||||
Set-Cookie: theme=light
|
||||
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT
|
||||
@ -283,7 +282,6 @@ Or use explicit response asserts with [predicates]:
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 302
|
||||
[Asserts]
|
||||
header "Location" contains "www.example.net"
|
||||
@ -299,7 +297,6 @@ Asserting JSON body response (node values, collection count etc...) with [JSONPa
|
||||
```hurl
|
||||
GET https://example.org/order
|
||||
screencapability: low
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.validated" == true
|
||||
@ -319,7 +316,6 @@ Testing status code:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/order/435
|
||||
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
@ -327,7 +323,6 @@ HTTP 200
|
||||
|
||||
```hurl
|
||||
GET https://example.org/order/435
|
||||
|
||||
# Testing status code is in a 200-300 range
|
||||
HTTP *
|
||||
[Asserts]
|
||||
@ -342,10 +337,8 @@ status < 300
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 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
|
||||
@ -361,7 +354,6 @@ xpath "string(//div[1])" matches /Hello.*/
|
||||
|
||||
```hurl
|
||||
GET https://example.org/home
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
cookie "JSESSIONID" == "8400BAFE2F66443613DC38AE3D9D6239"
|
||||
@ -380,7 +372,6 @@ Check the SHA-256 response body hash:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.tar.gz
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
sha256 == hex,039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
|
||||
@ -394,7 +385,6 @@ Check the properties of a SSL certificate:
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
certificate "Subject" == "CN=example.org"
|
||||
@ -426,7 +416,6 @@ Retry request on any errors (asserts, captures, status code, runtime etc...):
|
||||
```hurl
|
||||
# Create a new job
|
||||
POST https://api.example.org/jobs
|
||||
|
||||
HTTP 201
|
||||
[Captures]
|
||||
job_id: jsonpath "$.id"
|
||||
@ -438,7 +427,6 @@ jsonpath "$.state" == "RUNNING"
|
||||
GET https://api.example.org/jobs/{{job_id}}
|
||||
[Options]
|
||||
retry: 10 # maximum number of retry, -1 for unlimited
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.state" == "COMPLETED"
|
||||
@ -452,7 +440,6 @@ jsonpath "$.state" == "COMPLETED"
|
||||
|
||||
```hurl
|
||||
GET https://sample.org/helloworld
|
||||
|
||||
HTTP *
|
||||
[Asserts]
|
||||
duration < 1000 # Check that response time is less than one second
|
||||
@ -475,7 +462,6 @@ SOAPAction: "http://www.w3.org/2003/05/soap-envelope"
|
||||
</m:GetStockPrice>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
@ -485,7 +471,6 @@ HTTP 200
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
|
||||
@ -502,7 +487,6 @@ HTTP 302
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.bin
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
bytes startsWith hex,efbbbf;
|
||||
|
@ -3,4 +3,4 @@ long: json
|
||||
help: Output each Hurl file result to JSON
|
||||
conflict: no_output
|
||||
---
|
||||
Output each hurl file result to JSON. The format is very closed to HAR format.
|
||||
Output each Hurl file result to JSON. The format is very closed to HAR format.
|
||||
|
@ -177,8 +177,21 @@ HTTP 200
|
||||
|
||||
## Templating Body
|
||||
|
||||
Using templates with [JSON body] or [XML body] is not currently supported in Hurl.
|
||||
Besides, you can use templates in [multiline string body] with variables to send a JSON or XML body:
|
||||
Variables can be used in [JSON body]:
|
||||
|
||||
~~~hurl
|
||||
PUT https://example.org/api/hits
|
||||
{
|
||||
"key0": "{{a_string}}",
|
||||
"key1": {{a_bool}},
|
||||
"key2": {{a_null}},
|
||||
"key3": {{a_number}}
|
||||
}
|
||||
~~~
|
||||
|
||||
Note that [XML body] can't use variables directly, for the moment. In order to templatize a XML body, you can use
|
||||
[multiline string body] with variables. The multiline string body allows to templatize any text based body (JSON, XML,
|
||||
CSV etc...):
|
||||
|
||||
~~~hurl
|
||||
PUT https://example.org/api/hits
|
||||
|
@ -37,7 +37,8 @@ Options:
|
||||
-L, --location
|
||||
Follow redirects
|
||||
--location-trusted
|
||||
Follow redirects but allows sending the name + password to all hosts that the site may redirect to.
|
||||
Follow redirects but allows sending the name + password to all hosts that the site may
|
||||
redirect to.
|
||||
--glob <GLOB>
|
||||
Specify input files that match the given GLOB. Multiple glob flags may be used
|
||||
-0, --http1.0
|
||||
@ -57,9 +58,11 @@ Options:
|
||||
--interactive
|
||||
Turn on interactive mode
|
||||
-4, --ipv4
|
||||
Tell Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6
|
||||
Tell Hurl to use IPv4 addresses only when resolving host names, and not for example try
|
||||
IPv6
|
||||
-6, --ipv6
|
||||
Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4
|
||||
Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try
|
||||
IPv4
|
||||
--json
|
||||
Output each Hurl file result to JSON
|
||||
--max-redirs <NUM>
|
||||
@ -91,8 +94,8 @@ Options:
|
||||
--retry-interval <MILLISECONDS>
|
||||
Interval in milliseconds before a retry [default: 1000]
|
||||
--ssl-no-revoke
|
||||
(Windows) Tell Hurl to disable certificate revocation checks. WARNING: this option loosens the SSL security, and by using this flag you ask for
|
||||
exactly that.
|
||||
(Windows) Tell Hurl to disable certificate revocation checks. WARNING: this option loosens
|
||||
the SSL security, and by using this flag you ask for exactly that.
|
||||
--test
|
||||
Activate test mode
|
||||
--to-entry <ENTRY_NUMBER>
|
||||
|
@ -17,7 +17,6 @@ Hurl makes it easy to work with <b>HTML</b> content, <b>REST / SOAP / GraphQL</b
|
||||
```hurl
|
||||
# Get home:
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
|
||||
@ -55,7 +54,6 @@ POST https://example.org/api/tests
|
||||
"id": "4568",
|
||||
"evaluate": true
|
||||
}
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "X-Frame-Options" == "SAMEORIGIN"
|
||||
@ -68,7 +66,6 @@ jsonpath "$.id" matches /\d{4}/ # Check the format of the id
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
xpath "normalize-space(//head/title)" == "Hello world!"
|
||||
@ -111,7 +108,6 @@ Hurl can also be used to test the <b>performance</b> of HTTP endpoints
|
||||
|
||||
```hurl
|
||||
GET https://example.org/api/v1/pets
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
duration < 1000 # Duration in ms
|
||||
@ -121,7 +117,6 @@ And check response bytes
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.tar.gz
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
sha256 == hex,039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
|
||||
@ -515,7 +510,6 @@ Use implicit response asserts to test header values:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/index.html
|
||||
|
||||
HTTP 200
|
||||
Set-Cookie: theme=light
|
||||
Set-Cookie: sessionToken=abc123; Expires=Wed, 09 Jun 2021 10:18:14 GMT
|
||||
@ -528,7 +522,6 @@ Or use explicit response asserts with [predicates]:
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 302
|
||||
[Asserts]
|
||||
header "Location" contains "www.example.net"
|
||||
@ -544,7 +537,6 @@ Asserting JSON body response (node values, collection count etc...) with [JSONPa
|
||||
```hurl
|
||||
GET https://example.org/order
|
||||
screencapability: low
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.validated" == true
|
||||
@ -564,7 +556,6 @@ Testing status code:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/order/435
|
||||
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
@ -572,7 +563,6 @@ HTTP 200
|
||||
|
||||
```hurl
|
||||
GET https://example.org/order/435
|
||||
|
||||
# Testing status code is in a 200-300 range
|
||||
HTTP *
|
||||
[Asserts]
|
||||
@ -587,10 +577,8 @@ status < 300
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 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
|
||||
@ -606,7 +594,6 @@ xpath "string(//div[1])" matches /Hello.*/
|
||||
|
||||
```hurl
|
||||
GET https://example.org/home
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
cookie "JSESSIONID" == "8400BAFE2F66443613DC38AE3D9D6239"
|
||||
@ -625,7 +612,6 @@ Check the SHA-256 response body hash:
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.tar.gz
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
sha256 == hex,039058c6f2c0cb492c533b0a4d14ef77cc0f78abccced5287d84a1a2011cfb81;
|
||||
@ -639,7 +625,6 @@ Check the properties of a SSL certificate:
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
certificate "Subject" == "CN=example.org"
|
||||
@ -671,7 +656,6 @@ Retry request on any errors (asserts, captures, status code, runtime etc...):
|
||||
```hurl
|
||||
# Create a new job
|
||||
POST https://api.example.org/jobs
|
||||
|
||||
HTTP 201
|
||||
[Captures]
|
||||
job_id: jsonpath "$.id"
|
||||
@ -683,7 +667,6 @@ jsonpath "$.state" == "RUNNING"
|
||||
GET https://api.example.org/jobs/{{job_id}}
|
||||
[Options]
|
||||
retry: 10 # maximum number of retry, -1 for unlimited
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.state" == "COMPLETED"
|
||||
@ -697,7 +680,6 @@ jsonpath "$.state" == "COMPLETED"
|
||||
|
||||
```hurl
|
||||
GET https://sample.org/helloworld
|
||||
|
||||
HTTP *
|
||||
[Asserts]
|
||||
duration < 1000 # Check that response time is less than one second
|
||||
@ -720,7 +702,6 @@ SOAPAction: "http://www.w3.org/2003/05/soap-envelope"
|
||||
</m:GetStockPrice>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
|
||||
HTTP 200
|
||||
```
|
||||
|
||||
@ -730,7 +711,6 @@ HTTP 200
|
||||
|
||||
```hurl
|
||||
GET https://example.org
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
|
||||
@ -747,7 +727,6 @@ HTTP 302
|
||||
|
||||
```hurl
|
||||
GET https://example.org/data.bin
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
bytes startsWith hex,efbbbf;
|
||||
@ -946,7 +925,7 @@ will follow a redirection only for the second entry.
|
||||
| <a href="#interactive" id="interactive"><code>--interactive</code></a> | Stop between requests.<br><br>This is similar to a break point, You can then continue (Press C) or quit (Press Q).<br> |
|
||||
| <a href="#ipv4" id="ipv4"><code>-4, --ipv4</code></a> | This option tells Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6.<br> |
|
||||
| <a href="#ipv6" id="ipv6"><code>-6, --ipv6</code></a> | This option tells Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4.<br> |
|
||||
| <a href="#json" id="json"><code>--json</code></a> | Output each hurl file result to JSON. The format is very closed to HAR format.<br> |
|
||||
| <a href="#json" id="json"><code>--json</code></a> | Output each Hurl file result to JSON. The format is very closed to HAR format.<br> |
|
||||
| <a href="#key" id="key"><code>--key <KEY></code></a> | Private key file name.<br> |
|
||||
| <a href="#location" id="location"><code>-L, --location</code></a> | Follow redirect. To limit the amount of redirects to follow use the [`--max-redirs`](#max-redirs) option<br> |
|
||||
| <a href="#location-trusted" id="location-trusted"><code>--location-trusted</code></a> | Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.<br>This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).<br> |
|
||||
@ -972,7 +951,7 @@ will follow a redirection only for the second entry.
|
||||
| <a href="#user-agent" id="user-agent"><code>-A, --user-agent <NAME></code></a> | Specify the User-Agent string to send to the HTTP server.<br> |
|
||||
| <a href="#variable" id="variable"><code>--variable <NAME=VALUE></code></a> | Define variable (name/value) to be used in Hurl templates.<br> |
|
||||
| <a href="#variables-file" id="variables-file"><code>--variables-file <FILE></code></a> | Set properties file in which your define your variables.<br><br>Each variable is defined as name=value exactly as with [`--variable`](#variable) option.<br><br>Note that defining a variable twice produces an error.<br> |
|
||||
| <a href="#verbose" id="verbose"><code>--verbose</code></a> | Turn on verbose output on standard error stream.<br>Useful for debugging.<br><br>A line starting with '>' means data sent by Hurl.<br>A line staring with '<' means data received by Hurl.<br>A line starting with '*' means additional info provided by Hurl.<br><br>If you only want HTTP headers in the output, [`-i, --include`](#include) might be the option you're looking for.<br> |
|
||||
| <a href="#verbose" id="verbose"><code>-v, --verbose</code></a> | Turn on verbose output on standard error stream.<br>Useful for debugging.<br><br>A line starting with '>' means data sent by Hurl.<br>A line staring with '<' means data received by Hurl.<br>A line starting with '*' means additional info provided by Hurl.<br><br>If you only want HTTP headers in the output, [`-i, --include`](#include) might be the option you're looking for.<br> |
|
||||
| <a href="#very-verbose" id="very-verbose"><code>--very-verbose</code></a> | Turn on more verbose output on standard error stream.<br><br>In contrast to [`--verbose`](#verbose) option, this option outputs the full HTTP body request and response on standard error. In addition, lines starting with '**' are libcurl debug logs.<br> |
|
||||
| <a href="#help" id="help"><code>-h, --help</code></a> | Usage help. This lists all current command line options with a short description.<br> |
|
||||
| <a href="#version" id="version"><code>-V, --version</code></a> | Prints version information<br> |
|
||||
|
Loading…
Reference in New Issue
Block a user