npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

restshooter

v1.12.0

Published

Tools to shoot a scenario on a server only using REST call

Downloads

12

Readme

RestShooter

Rest Shooter is a node module able to take a list of scenario of URLs to call and check the response. A Scenario is a list of steps, a step is a URL with parameter and checks (optional)

  • Run HTTP and HTTPS
  • Run POST,GET,DELETE,PUT
  • Check global field for a scenario
  • Check specific field for a step
  • Support only JSON and XML
  • Allows to propagate a session along a scenario
  • Allows to hook on request

By default Session is retrieved from the cookie and store in the cookie as:

  • JSESSIONID (J2EE)
  • PHPSESSID (PHP)

(Contact me if you want me to put other default id)

How to use it

Installation

npm install -g restshooter

Then create a script in your package.json to let it run in NPM context rather that bash context.

Sample Project

Checkout the sample folder. You can run from this folder

restshooter weather.cfg

Configuration file

First we have to define the configuration, one per platform to target. Lets call it integration.cfg

{
	"server":"localhost",
	"port":9091,
	"baseUrl":"/rest",
	"protocol":"https",
	"scenario":[
		"login.scn"
	],
	"content":"JSON",
	"getSession":function(response,data,stepConfig,previousSession){},
	"setSession":function(requestOptions,stepConfig,previousSession){},
	"preRequest":function(requestOptions,stepConfig){},
	"postRequest":function(response,data,stepConfig){},
	"report":"myreport.log",
	"parseInput":function(data,stepConfig){},
	"debug":true
}

server is the server to target in our exemple it is localhost (no HTTP, no port, only server name)

port is the port to use to contact the server

baseUrl will be added in front of all URL to call (Usualy if you have a REST service on a dedicated path) you can leave blank

scenario is an array of scenario to run, files that will be loaded independently

getSession (optional) JavaScript function that allows to extract the session from the server response, it receive the data and the response

setSession JavaScript function that allows to set the session in the header request options (Cookie), the step config (URL parameter for instance) and also the previous session so it can be propagated

preRequest (optional) JavaScript function that allows to performe some changed in the request options before sending.

requestOptions Object:

{
  hostname: port: path: method: headers: {
  }
}

postRequest (optional) JavaScript function that allows to clean up the response data or parse it if needed. It should returned a cleaned JSON version of the data.

Report is the file where is report will be written at the end of the test

debug (optional) If set to true it will output more information on the console.

content is the content type received.

protocol Use this property to target your server in HTTP or HTTPS, becareful to use the right port (see know issue section)

parseInput function that will format the input parameter of a step into a JSON, this will allow to reuse the input parameter across all the steps with the following syntax

&q=${in.ByCity.q}

First Step

You need to create file, by convention we will give it an '.stp' extension. The following exemple is for a login which must be reusable so it is the first one to create as a step. Lets call it login.stp.

{
	"name":"Login",
	"url":"/login",
	"method":"POST",
	"data":"{\"login\":\"olivier\",\"password\":\"mypass\"}",
	"checks":[{
		"path":"response.answer",
		"test":"exist|ok"
	}]
}

name will be used in report and error to help investigation must be unique per step.

url will be added to the base url previously presented in the configuration.

method is for now POST or GET.

extend is a string to another steps to inherit from (ie: extend:'basicstep.stp').

data is the data object to be sent. Always a string, it will be used as it is in POST and will be escaped for GET.

checks is a list of checks to perform once the response is coming back from the server.

  • path is the path into the JSON returned to be checked (ie {response:{answer:ok}}).
  • test this is a set of test for a node like exist or notempty separated by a |.

preRequest can be setup at step level and will have the same signature as the global one, it will be called after the global.

postRequest can be setup at step level and will have the same signature as the global one, it will be called after the global but will have the priority to the global.

getSession can be setup at step level and will have the same signature as the global one, it will be called after the global but will have the priority to the global.

setSession can be setup at step level and will have the same signature as the global one, it will be called after the global.

Here after the list of test:

| Name | Behavior | | ------------ | --------------------------------------------------------------------------------------------------------------- | | notexist | Fail if the node is existing in the answer | | exist | Fail if the node is not existing in the answer | | existnotnull | Fail if the node is existing but null | | notempty | Fail if the node is string empty or null | | empty | Fail if the node is string not empty | | struct | Fail if the json response is not structurly the same as the reference (path contains the path to the reference) | | default | All value not listed above will be value comparison |

Second Step

You need to create a file that represent the scenario. By convention we are using the '.scn' extension. Lets call it login.scn.

{
	"name":"Login",
	"steps":[
		"login.stp"
	],
	"checks":[{
		"path":"message",
		"test":""
	},
	{
		"path":"code",
		"test":0
	}]
}

name is the identifier of the scenario for the report and the log in the console.

steps is the list of the steps to run for the scenario execution.

checks is the list of validation to perform on each request.

Run the script

restshooter integration.cfg

Variable Replacement

The idea is to take something from the response and to inject into the next request

Imagine that the previous step was the login (name:'login' in the step configuration file) and the answer was something like

{
	"user":{
		"name":'Olivier',
		"ref":1234567
	}
}

Then in the payload of the next step, lets call it getPreference, I can write something like

...
"data":"/${login.user.ref}/"
...

getting a value in an list of value

...
"data":"/${login.preferences[0].ref}/"
...

So the system will replace the variable by the value from the previous request and we will get the parameter of the logged user.

${} is the syntax for the replacement

login is the name of the step

user.ref is the path to the variable in the JSON returned by the previous script

Hooks

You can add hooks preRequest and postRequest, for scenario preRun and postRun that last will override the default parsing so you must do a parsing in addition to other code. You can also do some reference to libraries, you just have to install them in your node modules folder with npm and then access it like that

...
"preRequest":function(){
	var btoa = require('btoa');
	console.log(btoa("Pre Request Processing"));
}
...
...
"preRun":function(scenario){
    //If you return a promise the process will be stopped until the promise is resolved and fully stopped if rejected
    //The object returned by the promise will be part of the initial data as well can be interesting for data injection
    // and later replacement
    console.log("################### Scenario "+scenario.name+" Started #############################");
  },
...

Note that you can install globally and it will work using simply require('btoa');

Unit test

karma start karma.conf.js

Known Issues

On OSX we have to link node installation as it is in linux system.

sudo ln -s /usr/local/bin/node /usr/bin/node

You can get this error : SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol Check that you specify the right port (443 instead of 80)