Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
robotframework-restlibrary
Advanced tools
RESTLibrary provides a feature-rich and extensible infrastructure which is required for making any REST/HTTP call along with all the possible range of features which one might need for doing end-to-end REST API automation using robotframework. All the repetitive tasks which API automation developer has to perform frequently are taken care as part of standard features of the library, like JSON comparison, benchmarking, file upload, file download, authentication, logging/reporting, response channelization, runtime variable resolution etc.
The library exposes a single keyword - Make HTTP Request, which has all the possible parameters to take care of all the features required for end-to-end REST API Automation.
This library is tightly coupled with robotframework and designed/developed for robotframework users only, it is not intended to be used as a standalone python library.
RESTLibrary has following prerequisites:
robotframework>=3.1.2
requests>=2.25.1
jsonpath-ng>=1.5.0
jsonschema>=3.2.0
setuptools>=39.1.0
you can install all the prerequisites either one by one or using the requirements.txt provided with source code:
pip install -r requirements.txt
RESTLibrary can be easily installed using pip with following command:
pip install robotframework-restlibrary
Alternatively it can also be installed from the sourcecode:
python setup.py install
Make HTTP Request is the main keyword of RESTLibrary, it has all the possible parameters which are needed for making any HTTP/REST request along with other parameters needed for various facets of REST API Automation. Rest of the document explains about various parameters of Make HTTP Request and their usage examples.
These are the first two parameters to the keyword and the only mandatory parameters as well, rest all other parameters are optional based on the use case
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Get All Users on First Page
Make HTTP Request get all users https://reqres.in/api/users?page=1
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Create User
Make HTTP Request create a new user https://reqres.in/api/users method=POST requestHeaders={'Content-Type' : 'application/json', 'Accept' : 'application/json'} requestBody={"name":"deepak", "job":"automation developer"} timeout=15
*** Settings ***
Library RESTLibrary
*** Variables ***
${username}= deepak
${password}= Pass1
*** Test Cases ***
Get All Users
# this request will be processed using NoAuth authType which is default
Make HTTP Request get all users https://reqres.in/api/users?page=1
# this request will be processed using Basic authType
Make HTTP Request get all users https://reqres.in/api/users?page=1 authType=Basic
# this request will be processed using Basic authType
Make HTTP Request get all users https://reqres.in/api/users?page=1 authType=Basic username=dchourasia password=Password1
You can also implement custom authentication using a robot keyword or a python function:
*** Settings ***
Library RESTLibrary
*** Variables ***
${username}= deepak
${password}= Pass1
*** Test Cases ***
Get All Users
# this request will be processed using given authType, username and password, custom auth is implemented using a robot keyword in "Keywords" secction
Make HTTP Request get all users with custom auth https://reqres.in/api/users?page=1 authType=set my auth token username=dchourasia password=Password1
*** Keywords ***
set my auth token
[Arguments] ${request info}
# here is the example how you can update the url to include custom auth token for your request
${request info.url}= Set Variable ${request info.url}&token=customAuthToken
# here is the example how you can update the request headers to include custom auth token for your request
Set To Dictionary ${request info.requestHeaders} customAuthHeaderName=customAuthToken
# return final requestInfo object after all the updates
[Return] ${request info}
Response Channelization (RC) is special and unique feature of RESTLibrary, which lets you extract and channelize the data from response of one API call to next API call with least efforts and in scalable manner.
<<<rc, src_request_id, rcType, selector>>> An RC block is always written between <<< and >>> tokens. Here are the details about 4 comma separated parameters inside RC block
rcType | selector | examples | comments |
---|---|---|---|
body | jsonPath | $.id | selecting id |
$.items[?(@.name="user1")].id | selecting id of the item which has name as user1 | ||
json | {"name" : "user1_updated"} | will return entire response body with updated name | |
{"$.items[*].name" : "user1_updated"} | will return entire response body with updated name of every item in the json | ||
{"$.items[*].name" : "<<<DELETE>>>"} | will return entire response body after deleting name node from every item in the json | ||
{} | will return entire response body as is without any changes | ||
header | headerName | etag | will return etag header value from the response headers of the src request |
PS - jsonpath is a language like xpath to select single/multiple nodes from a given json. There are multiple tutorials on web to learn this.
Here are few resources to learn jsonpath:
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Get All Users
Make HTTP Request get all users https://reqres.in/api/users?page=1
Get User
# here we are using RC to chennelize id of the newly created user dynamically from the "create user" response body, id is needed to get the user
Make HTTP Request get user details https://reqres.in/api/users/<<<rc, get all users, body, $.data[0].id>>> method=GET requestHeaders={'Accept' : 'application/json'}
Update User
# here we are using RC to channelize entire response body of "create user" along with a name update, we are also channelizing etag header
Make HTTP Request update the user https://reqres.in/api/users/<<<rc, get all users, body, $.data[0].id>>> method=PUT requestHeaders={'Content-Type' : 'application/json', 'Accept' : 'application/json', 'Etag' : '<<<rc, get user details, header, Etag>>>'} requestBody=<<<rc, get user details, body, {"data" : {"first_name":"deepak", "last_name" : "chourasia"}}>>>
Delete User
# here again we are channelizing user id which is needed to delete the user
Make HTTP Request delete the user https://reqres.in/api/users/<<<rc, get all users, body, $.data[0].id>>> method=DELETE expectedStatusCode=204
This is again a unique feature of RESTLibrary, which allows you to embed robot variables and RCs inside json files (and any other files as well which have text content type), which you might use for storing request payloads and baselines. RESTLibrary will ensure to resolve these variables/RCs at runtime when the request is being processed.
Content of createUser.json file:
{
"name" : "${name}",
"job" : "${job}"
}
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Create Multiple Users
Create User Deepak Automation Developer
Create User Evans UX Designer
Create User Elizabeth Software Developer
Create User Stephen Project Manager
*** Keywords ***
Create User
[Arguments] ${name} ${job}
Make HTTP Request create a new user https://reqres.in/api/users requestBody=${EXECDIR}/inputs/createUser.json method=POST requestHeaders={'Content-Type' : 'application/json', 'Accept' : 'application/json'} expectedStatusCode=201
PS :
RESTLibrary has a special variable : <<<NOW>>>
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Create Unique Users
# All these 4 requests will create users with unique name
Create New User
Create New User
Create New User
Create New User
*** Keywords ***
Create New User
Make HTTP Request create a new user https://reqres.in/api/users requestBody=${EXECDIR}/inputs/createUniqueUser.json method=POST requestHeaders={'Content-Type' : 'application/json', 'Accept' : 'application/json'} expectedStatusCode=201
Content of createUniqueUser.json file:
{
"name" : "user_<<<NOW>>>",
"job" : "Automation Developer"
}
There are set of parameters which allows you to provide benchmark for any rest request. REST API response is automatically compared against these benchmarks and differences are reported in robot report and test is marked as Pass/Fail accordingly.
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Create User
# this example demonstrates a Partial benchmark verification using in-place json along with status code verification
Make HTTP Request create a new user https://reqres.in/api/users method=POST requestBody={"name":"deepak", "job":"automation developer"} expectedStatusCode=201 expectedResponseBody={"id" : "[0-9]{1,6}"} responseVerificationType=Partial
Get all users
# this example demonstrates verificationScheme along with ignoreNodes
Make HTTP Request Get all the users https://reqres.in/api/users?page=1 method=GET verificationScheme=[{"path": "$.data","type": "NotSorted","key": "email"}] ignoreNodes=["$.total", "$.data[*].id"] expectedResponseBody=${EXECDIR}/baselines/getAllUsersBenchmark.json
Get User
# this example demonstrates a Full benchmark comparison using a benchmark json file along with response header verification
Make HTTP Request get the user https://reqres.in/api/users/<<<rc, Get all the users, body, $.data[0].id>>> method=GET requestHeaders={'Accept' : 'application/json'} expectedResponseBody=${EXECDIR}/baselines/getUserBenchmark.json expectedResponseHeaders={'Content-Type' : 'application/json; charset=utf-8'} responseVerificationType=Partial
Content of getUserBenchmark.json file:
{
"data": {
"id": "<<<SKIP>>>",
"email": "<<<rc, Get all the users, body, $.data[0].email>>>",
"first_name": "<<<rc, Get all the users, body, $.data[0].first_name>>>",
"last_name": "<<<rc, Get all the users, body, $.data[0].last_name>>>",
"avatar": "https:\\/\\/(.*)-image.jpg"
}
}
Content of getAllUsersBenchmark.json file:
{
"page": 1,
"per_page": 6,
"total": 12,
"total_pages": 2,
"data": [
{
"id": 1,
"email": "george.bluth@reqres.in",
"first_name": "George",
"last_name": "Bluth",
"avatar": "https://reqres.in/img/faces/1-image.jpg"
},
{
"id": 2,
"email": "janet.weaver@reqres.in",
"first_name": "Janet",
"last_name": "Weaver",
"avatar": "https://reqres.in/img/faces/2-image.jpg"
},
{
"id": 3,
"email": "emma.wong@reqres.in",
"first_name": "Emma",
"last_name": "Wong",
"avatar": "https://reqres.in/img/faces/3-image.jpg"
},
{
"id": 4,
"email": "eve.holt@reqres.in",
"first_name": "Eve",
"last_name": "Holt",
"avatar": "https://reqres.in/img/faces/4-image.jpg"
},
{
"id": 5,
"email": "charles.morris@reqres.in",
"first_name": "Charles",
"last_name": "Morris",
"avatar": "https://reqres.in/img/faces/5-image.jpg"
},
{
"id": 6,
"email": "tracey.ramos@reqres.in",
"first_name": "Tracey",
"last_name": "Ramos",
"avatar": "https://reqres.in/img/faces/6-image.jpg"
}
],
"support": {
"url": "https://reqres.in/#support-heading",
"text": "To keep ReqRes free, contributions towards server costs are appreciated!"
}
}
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Make POST request with text payload
Make HTTP Request create a new user https://reqres.in/api/users method=POST requestBody=I am sending text expectedStatusCode=201
If you have a REST API which downloads a file, then use below parameters:
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Download file
Make HTTP Request download the document https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf method=GET responseDataType=File downloadFilePath=${EXECDIR}/downloads/sample.pdf
If you have a REST API which uploads file(s):
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Upload Image
Make HTTP Request upload image https://images.google.com/searchbyimage/upload method=POST requestDataType=File files={'encoded_image' : ['sample.jpeg', '${EXECDIR}/inputs/sample.jpeg', 'image/jpeg']}
Every Make HTTP Request execution logs all the possible data about the request, its response and benchmarking along with any errors/exceptions.
Below are the major sections/subsections in the report, subsections are displayed based on the request parameters:
If needed you can extract all the response data from "Make HTTP Request" and utilize it later based on your use case
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Create User
${requestInfo}= Make HTTP Request create a new user https://reqres.in/api/users method=POST requestBody={"name":"deepak", "job":"automation developer"} expectedStatusCode=201 expectedResponseBody={"name" : "deepak"} responseVerificationType=Partial expectedStatusCode=201
Log ${requestInfo.responseBody}
Log ${requestInfo.responseHeaders}
Log ${requestInfo.responseStatusCode}
This is second and the last keyword in RESTLibrary.
*** Settings ***
Library RESTLibrary
*** Test Cases ***
Create User
Make HTTP Request create a new user https://reqres.in/api/users method=POST requestBody={"name":"deepak", "job":"automation developer"} expectedStatusCode=201 expectedResponseBody={"name" : "deepak"} responseVerificationType=Partial
${userId}= Execute RC <<<rc, create a new user, body, $.id>>>
Creator and maintainer : Deepak Chourasia
RESTLibrary is open source software provided under the Apache License 2.0
FAQs
A REST API Automation Library for Robot Framework
We found that robotframework-restlibrary demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.