Requests

Making Requests

You can make GET, POST, PUT, PATCH, DELETE and HEAD requests.

Each HTTP verb has a corresponding method defined on session: session.get("/path") or session.post("/users/create").

All requests require at least the request path and can have additional options.

session.get("/users/sign_up", requestOptions);

session.post("/users/create", {
  tag: "create-user",
  payload: {
    name: "Smith",
    email: "smith@stormforger.com",
    password: "secret"
  }
});

Request options
You can specify options for each request. Request options are optional and are specified within each request as a hash.

Read on for a full list of all available options.

Request URL parameters using Placeholder

Use :placeholder keywords in the request URL and fill them with the params key in the request options object:

definition.session("get-url-parameters-session", function(session) {
  session.get("/root/:category/:product_id?view=:view", {
    params: {
      category: "foo",
      view: "FULL",
    }
  });
});

Mind that we replace category and view, but not product_id. The result is a GET request to /root/foo/:product_id?view=FULL.

Note: This feature performs simple string replacement only and does not perform any URL encoding.

Request Options

Payload for POST/PUT/PATCH/DELETE requests

payload can either be:

  • a string, which is send as plain text
  • or an object (key-value pairs), which is encoded and send as application/x-www-form-urlencoded.

Note that some applications might require an application/json Content-Type header for JSON encoded payloads.

{

  // as a plain text string
  payload: "payload string"

  // -OR- as application/x-www-form-urlencoded
  payload: {
    email: user.get("email"),
    password: user.get("password"),
  }

  // -OR- as a JSON string
  payload: JSON.stringify({
    productId: article.get("productId"),
    amount: 1
  })

}

Uploading binary payloads

If you need to upload binary payloads you can use the payload_from_file option:

var picture = session.ds.getRawFile("picture.png");
session.post("/upload", {
  payload_from_file: picture,
  // [more options]
});

In this example, the file picture.png will be loaded from the data sources of your organisation. Make sure to upload it as a Raw File beforehand.

Request Compression

You can request gzip compression for responses. The gzip option will set an Accept-Encoding header to request compressed responses from the server. The default value is false.

Note that the target server has to support that functionality to deliver compressed responses.

{
  // use gzip compression, default: false
  gzip: true
}

HTTP Headers

The headers option is used to set HTTP request headers (key-value pairs).

Note that you cannot set headers beginning with X-StormForger-.

Although allowed by RFC 2616 we currently only support unique header names.

{
  headers: {
    "X-AwesomeApp-Token": user.get("api_token"),
    "X-AwesomeApp-Mail": user.get("mail"),
  }
}

Tag Requests

The tag option specifies an identifier (tag) that is associated with the request. A tag may consist of letters, numbers, underscores and dashes and has to start with a letter.

Tags can be used when analyzing the test run.

{
  tag: "logout"
}

HTTP Basic Authentication

You can use HTTP basic access authentication. The authentication option is providing an HTTP Basic Authentication.

{
  authentication: {
    username: "tisba",
    password: "letmein",
  }
}

Response Extraction

The extraction option is a way to tell StormForger to extract parts of the response body, headers or cookies (see extraction).

{
  // use response content extraction
  extraction: {
    jsonpath: {
      "accessToken": "authorization.token",
    }
  }
}

Cookies

Each StormForger client does automatically manage a cookie jar. Cookies sent by the server in responses to requests (via Set-Cookie header) are automatically added, updated and removed.

You can add a cookie to a request using the additional_cookies option. Note that this cookies will only be set for the specific request.

{
  additional_cookies: [
    {
      name: "csrfToken",
      value: session.getVar("token"),
    },
  ]
}

Response Matching

As of January 2020 the match option is no longer available. You can substitute the behaviour using a regexp content extraction.

match was used to create a simple matching against a requests response to increase a unnamed counter. If you want to see if a response contains a specific content, you can use:

session.get(url, {
  extraction: {
    regexp: {
      match: "Username: (.*)",
    },
});
session.check("match", session.getVar("match"), "!=", "");

Please check the content extraction documentation for details.

XHR-Shorthand

Set the xhr option to true to perform a request with the correct headers for an XHR-Request.

session.get(url, {
  xhr: true
});

This will add the X-Requested-With: XMLHttpRequest header to the current request.

CORS-Shorthand

When performing a request that require a CORS preflight request you can set the following option that will create a preceding OPTIONS-Request that includes the correct Access-Control-Request-Method, Access-Control-Request-Headers and Origin-Headers.

session.get("/api/login", {
  cors: { origin: "https://stormforger.com", tag: "cors-request-tag" }
});
  • origin is required and has to be a valid Origin-Header according to RFC 6454.
  • tag is optional and will default to either the requests tag-value (if provided, see Tag Requests) or the literal "cors"

Abort on Error

The abort_on_error option allows to abort the session if any http status code in the 400 to 500 range is received. This is an alternative to assertions and can also be set as a session default.

Setting Defaults

You can set defaults which will apply to requests like this:

session.defaults.setGzip(true);
session.defaults.setAuthentication({ username: "user", password: "letmein" });
session.defaults.setHeader("Host", "www.example.com");
session.defaults.sendRequestId(false);                        // to deactivate the request-id
session.defaults.sendRequestId({"header": "Correlation-ID"}); // change the request-id header
session.defaults.setAbortOnError(true);

Note that the following rules apply:

  • defaults apply only for requests following the definition of defaults
  • defaults are passed into sub-contexts (e.g. in case of if, times, etc)
  • defaults can be unset (using session.defaults.unset()). This only unsets defaults for the current context! Defaults will apply again if the sub-context has ended
  • defaults defined in sub-contexts do not apply after the sub-context has ended

Request Tracing

All StormForger requests are sent with certain header to help tracing and understanding requests flowing through your infrastructure.

Header Example Value Comment
User-Agent StormForger-X/%VERSION (+https://stormforger.com) The StormForger user agent. The version will change over time.
X-Request-ID sf-{test_run_uid}-{request_id} A unique ID for every request - The test run UID makes it easy to correlate which test run originated the request
X-StormForger-User 154123c:1512415123415123acdf The user that started the test run. Note that is an internal format and users should not rely on a specific value

The X-Request-ID header can be deactivated by setting the request_id option to false. You can also change the header to a different name as follows:

session.get("/", {
  "request_id": {
    "header": "Correlation-ID"
  }
});

Note that this can also be configured in the setting defaults. If you want to provide your own request-ids, just set them via headers - StormForger will not add a request-id if there is a conflict.

Connection Keep-Alive

Connection keep-alive within StormForger only works within a single session. If the test case starts many sessions all doing only one request, no connections will be reused and you also test the number of connections per second.

If you want to actively close a connection after a request, you can simply set the header: Connection: close.

session.lastHttpStatus()

The session.lastHttpStatus() helper returns the status code of the last request performed by the current session. If no status code is available, 999 is returned.

session.post(...);
session.check("checkout", session.lastHttpStatus(), "=", 200);

session.get("/products/:product", {params: {product: randomProductId}});
session.check("product_access_denied", session.lastHttpStatus(), ">=", 400);

NOTE: the lastHttpStatus() function returns the status of the previous request. If you want to keep the status around for longer, you have to save it to variable via setVar().

session.redirectTarget()

session.redirectTarget() returns an URL based the location header of the last request/response performed on the current session. Note that the status code must be a redirect status (3xx, except 304). This function guarantees that the returned URL has a protocol and host by backfilling the missing data from the previous request, if needed.

session.post("http://example.com/login", { abort_on_error:true, ...});
session.assert("redirect_received", session.redirectTarget(), "!=", "");
session.get(session.redirectTarget());

In the example above, we perform a request to /login, aborting the session if we don't receive a status code in the 2xx or 3xx range. Next, we check if we received a redirect target and follow it. Assuming we receive a 307 (temporary redirect) status code and /welcome in the location header, the second request would go against http://example.com/welcome, since session.redirectTarget() returns an URL backfilled with a host and protocol.

Icon Support Are you stuck? Or do you have any feedback? Get in touch with us – we are happy to help you.
Icon Schedule a demo Schedule a personal, customized demo. We'll show you around and introduce you to StormForger.
Icon Talk to a human To build and run reliable applications is complex – we know. Schedule a call and we’ll figure things out.

We are using cookies to give you the best online experience. If you continue to use this site, you agree to our use of cookies. By declining we will disable all but strictly required cookies. Please see our privacy policy for more details.


Accept Decline