REST Steps

The REST steps are a lightweight, short-form HTTP client for your scenarios. They let a feature file set request headers, fire a request at any endpoint, and assert on the status code and body - all without leaving the cucumber-js runtime or opening a browser page. They cover the same backend territory as the longer API steps group, but with terser phrasings that read well inside mixed UI-plus-API scenarios.

Reach for this group when you need a quick smoke check against an endpoint - "does /api/health answer 200?", "does creating a user return the new name?" - or when a UI scenario should be confirmed at the HTTP level. Requests are sent with axios, not through the browser, so they are fast and unaffected by page state. Relative URLs (anything not starting with http) are resolved against the project's launchUrl world parameter, so "/api/users" targets the same site the browser steps do; absolute URLs are used as-is, letting one scenario hit external services too.

Two implementation details worth knowing: headers registered with the header step accumulate and are re-sent on every subsequent REST request in the same scenario, and every request accepts any status code (via validateStatus) - a 404 or 500 never throws, it simply becomes the response you assert on. That makes negative testing of error responses first-class.

Quick reference

StepWhat it does
Given a REST header "Authorization" with value "Bearer abc123"Add an HTTP header to all subsequent REST requests.
When I send a REST "GET" request to "/api/users"Send an HTTP request without a body.
When I send a REST "POST" request to "/api/users" with body:Send an HTTP request with a doc-string body (raw text, JSON, or form-encoded).
Then the REST response status code should be 200Assert the most recent REST response carried an expected status code.
Then the REST response should contain "Alice"Assert the most recent REST response body contains a substring.

Steps in detail

Given a REST header "Authorization" with value "Bearer abc123"

Registers a header by name and value. Headers are stored in per-scenario state and attached to every REST request that follows, so you set them once at the top of the scenario. Setting the same header name again overwrites the previous value. Typical uses are Authorization, Accept, Content-Type, and correlation headers such as X-Request-ID.

Given a REST header "Authorization" with value "Bearer abc123"
  And a REST header "Accept" with value "application/json"
 When I send a REST "GET" request to "/api/me"
 Then the REST response status code should be 200

When I send a REST "GET" request to "/api/users"

Sends a body-less request with any HTTP method - GET, DELETE, HEAD, and so on. The URL is resolved against launchUrl unless it already starts with http, in which case it is used verbatim (handy for third-party health checks). The response - whatever its status - is captured for the assertion steps below. The pronoun is flexible: I send, we send, or plain send all match.

When I send a REST "GET" request to "/api/users"
 And we send a REST "GET" request to "https://example.com/api/health"
When I send a REST "DELETE" request to "/api/cart/items/42"
Then the REST response status code should be 200

When I send a REST "POST" request to "/api/users" with body:

Sends a request whose payload is the Gherkin doc string that follows the step. The body is passed through untouched, so it can be JSON, form-encoded key/value pairs, XML, or any raw text - pair it with a matching Content-Type header so the server parses it correctly. Works with POST, PUT, PATCH, or any other method that accepts a body.

Given a REST header "Content-Type" with value "application/json"
 When I send a REST "POST" request to "/api/users" with body:
      """
      {"name": "Alice"}
      """
 Then the REST response status code should be 201
  And the REST response should contain "Alice"

Then the REST response status code should be 200

Asserts the status of the most recent REST request, using a strict integer comparison. Because requests never throw on non-2xx statuses, this step is equally at home asserting 401 for a missing token or 404 for a deleted resource as it is confirming 200 or 201. It fails with "No REST response captured." if no request step ran first.

When I send a REST "GET" request to "/api/orders/999999"
Then the REST response status code should be 404

Then the REST response should contain "Alice"

Asserts the response body contains a substring. If the server returned JSON, the parsed object is serialized back to a string before the check, so you can match on any key or value fragment (for example "id" or "shipped") without worrying about whitespace or key ordering. The failure message names the missing text.

When I send a REST "GET" request to "/api/users"
Then the REST response status code should be 200
 And the REST response should contain "id"
 And the REST response should contain "Alice"

Complete example

Feature: Short-form REST checks against the site API
  As a tester,
  I want to exercise API endpoints with terse REST steps
  so that backend behavior is verified alongside UI scenarios.

  Scenario: Authenticated user listing and update round-trip
    Given a REST header "Authorization" with value "Bearer abc123"
      And a REST header "Content-Type" with value "application/json"
     When I send a REST "GET" request to "/api/users"
     Then the REST response status code should be 200
      And the REST response should contain "Alice"
     When I send a REST "PUT" request to "/api/users/1" with body:
          """
          {"role": "admin"}
          """
     Then the REST response status code should be 200
      And the REST response should contain "admin"

  Scenario: Missing token is rejected
     When I send a REST "GET" request to "/api/me"
     Then the REST response status code should be 401

Tips

  • Relative paths are prefixed with the launchUrl world parameter from cucumber.js (for example http://localhost:8080), so REST steps and browser steps target the same site by default.
  • Headers persist for the whole scenario; there is no removal step, so start a fresh scenario when you need a clean header set.
  • For richer API workflows - capturing values between requests, JSON-path assertions, response-time checks - use the full API steps group described in the API testing guide.
  • The browser context's cookie jar is shared with the runtime, so a UI login can be followed by REST-level assertions in the same scenario.

Back to all step groups