hurl
hurl copied to clipboard
plan for pre-scripting or post-scripting?
I may need some computation like extracting a field in a JSON, and then parsing it from a base64 string and checking the content in it, or encoding a data structure into base64 before I send it. But I haven't found similar features in the document nor in the issue board. Is it planned or Someone has any walk-around advice?
Hello, we plan to add some function/helpers to apply to a variable (similar to https://github.com/Orange-OpenSource/hurl/issues/606). Your use case seems interesting, can you please give us an example?
can you please give us an example?
Here is an example for my use case:
POST {{host}}/login
{
"data": {
"phone": "{{developer_phone}}",
}
}
[BeforeSend]
# encrypt data before sending
python = "
req_body = request.body
req_body.encrypted = my_encrypt(req_body.data) # my_encrypt function defined in the outside cipher.py file
del req_body.data
request.body = req_body
"
HTTP/1.1 200
[BeforeAsserts]
# data decrypted before asserting
python = "
res_body = my_decrypt(respone.body) # my_decrypt function defined in the outside cipher.py file
respone.user_name = res_body.user
"
[Asserts]
variable "user_name" == "Bob"
[AfterAsserts]
py = "
# do something like collect into a html report file
"
while the details can be adjusted, What I really want, is a machanics like postman's pre-requests
and tests
that can manuplate the body or headers etc:
- reuse code sinppet or file
- do anything before or after asserts that can be programming
Alternatives
a plugin that can manuplate body/headers/cookies and make assertations in hurls. For example, a JWT decoded by the plugin and extract the user
field for assert.
I don't think I make it clear. In our system, we have a collection of test cases in Postman, where some computation need to be done before sending a request and after receiving a response. However, Postman's export is not so easy to manuplate, while I want to make all the test cases readable and managed in text format, so that I could make it managed in a git repo. Hurl is very suitable for my sense, except the lack of complex computation.
Thanks for your use case. That makes the discussion a lot more concrete.
We agree that plugging a programming language is more powerful, and thus very attractive. But it does not really fit well with Hurl declarative, simplicity and performance objectives.
It does not mean that we should not support your use case. We plan to add simple function/helpers in the template and add additional sections ([xxx]) that could make possible.
We could encrypt the request body as follow:
POST {{host}}/login
[Variables]
iv: {{random(16)}}
key: ABCDEF
body: {"data": {"phone": "{{developer_phone}}" }}
{{body | encrypt_aes iv key)}}
To process/decrypt the response, we could add a query/subquery. For example
[Captures]
decrypted_body: {{ body | decrypt_aes key}}
[Asserts]
variable "decrypted_body" jsonpath "$.user_name" == "Bob"
For the time-being, you can send your request body from an external file
POST {{host}}/login
file,encrypted_data.bin;
But adding an assert on the response is not that easy. We should therfore probably try to support that first.
{{body | encrypt_aes iv key)}}
I think encrypt_aes
make sense, still I may needs more different utils, maybe MD5, BASE64, DES, some "custom" flow. Would you mind giving a supported utils plan?
yes, it makes sense to support all these common encoding MD5, base64, DES. we can start by one of them and see how good/useful it is.
start by one of them
my priority is,first DES and base64(non-url-safe version),then MD5,RSA. How to start the work?
We've not started working on spec for this (see https://github.com/Orange-OpenSource/hurl/issues/312). We need more design thinking/input before jumping to implementation!
I have similar case. In order to test one API, I need to send a file to an AWS S3 bucket first. Right now I need to run the command first followed by the Hurl commands to test the API. Would be nice to run the script/command inside Hurl like the options bellow:
- Option with the script on the Hurl file
GET {{host}}/status
[BeforeSend]
sh= "
aws s3 cp my-file.txt s3://my-bucket
"
HTTP/1.1 200
[Asserts]
jsonpath "$.status" == "proceed"
- Option calling a external script
GET {{host}}/status
Authorization:
[BeforeSend]
sh=./upload.sh
HTTP/1.1 200
[Asserts]
jsonpath "$.status" == "proceed"
Another option would be use the AWS S3 REST API to upload the file. However, the request would need to be authenticated and is not a easy authorization. It would require a script or native support to do it as you can see on the AWS instructions to Signing and authenticating REST requests. Example:
POST {{awsHost}}/s3/my-bucket
[BeforeSend]
python = "
request.header["Authorization"]= aws_authorize(request)
"
GET {{host}}/status
HTTP/1.1 200
[Asserts]
jsonpath "$.status" == "proceed"
I think give the option of executing scripts would give flexibility for many different cases. Maybe shell, python or go templates would be good options
A solution to scripts that need to run beforehand is using environment variables. At least in the interim. I have a use case where I want to use Azure Service Bus to send an event but it requires the current date and uri encoded value, e.g. (run in JS),
var CryptoJS = require("crypto-js");
var encoded = encodeURIComponent(pm.variables.get("ServiceBusHost"));
var now = new Date();
var week = 60*60*24*7;
var ttl = Math.round(now.getTime() / 1000) + week;
var signature = encoded + '\n' + ttl;
var signatureUTF8 = signature;
var hash = CryptoJS.HmacSHA256(signatureUTF8, pm.variables.get("ServiceBusSharedAccessKey"));
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
pm.environment.set("SharedAccessSignature", 'sr=' + encoded + '&sig=' + encodeURIComponent(hashInBase64) + '&se=' + ttl + '&skn=RootManageSharedAccessKey');
I'm not sure how to do that in Hurl directly, but I can do that before in another scripting language and just set the environment variable (HURL_myenvironmentvariable).
Just a thought for others working on this problem.
Something like this would be useful our use-case. We're using Hurl for e2e testing our API and would like to re-seed/reset our test database after some operations. We can run the tests one file at a time re-seeding where necessary, however, it would be nice if we could just add a command to run ay any point in the hurl file and then run all of our test files with hurl --test --glob
. That way we can have aggregated test results.
Relating to aggregating results, note that all the reports generated by Hurl (JUnit, HTML, TAP) aggregate results by default.
True, that is a good point.
But it would simplify my workflow to be able to just run the tests with --glob
and not have to maintain a script for running them. It could be that being able to run a command from a .hurl
file is too out of scope, but I think it's at least worth considering.
We're using Hurl for e2e testing our API and would like to re-seed/reset our test database after some operations
That's my use case too, currently I'm doing it with a bash script, but it would be cool to have some kind of support in a hurl file
I think this is a non issue. Just use your favorite scripting language that runs your hurl files and do any environment work outside of HURL. It works really nicely and gives a lot of flexibility.