restlyn
v0.1.1
Published
Gherkin-driven REST API and contract testing framework
Downloads
2
Maintainers
Readme
Restlyn
Restlyn is a powerful, Gherkin-based API testing framework for REST and contract testing.
It converts .feature files into executable tests — no need to write step definitions or assertions manually.
🚀 Core Features
REST API Testing (Functional)
- ✨ Write tests in plain Gherkin
- ⚙️ Automatically generates Mocha test code
- ✅ Supports all HTTP methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
- ✅ Token-based authentication, Dynamic token extraction and reuse, multi-step flows
- ✅ Configurable headers and request bodies
- ✅ Response status code assertions
- ✅ Response data assertions (contains key)
- 🔂 Built-in HTTP retry for flaky endpoints
- ✅ CSV / JSON data-driven testing
- 🏷️ Scenario tags:
@skip,@only,@debug,@retry(2) - ✅
restlyn mockserver starter CLI - ✅ Schema matching workflows
- 📊 Generates beautiful HTML & PDF test reports
- 🔧 Extensible via
.restlynrc
Contract Testing
- ✅ JSON Schema and Contract testing (via AJV)
- ✅ Schema validation per step
- ✅ Schemas loaded from external
.schema.jsonfiles
Test Generation
- ✅ Converts Gherkin
.featurefiles into:.stepMap.jsonintermediate structure- Executable Mocha-compatible
.test.jsfiles
- ✅ Supports multi-step scenarios
- ✅ Auto-inserts fallback status assertions if missing
- ✅ Supports token interpolation in body (e.g.,
{{token}}) - ✅ Token assertion auto-added if extracted
CLI Tooling
- ✅
restlyn steps— generates step maps - ✅
restlyn tests— generates test files from step maps - ✅
restlyn verify— runs and summarizes generated tests - ✅
restlyn schema— generate JSON schema from a live API response - ✅ Auto-detects missing
.stepMap.jsonfiles - ✅ JSON report output for CI and warning aggregation
Path & Config Support
- ✅ Reads
.restlynrcfor default paths: features, stepmaps, tests, schemas - ✅ Supports full path fallback if CLI args are not passed
- ✅ Handles:
- Relative and absolute
--filepaths - Comma-separated test file lists
- Glob patterns (e.g.,
token*.test.js)
- Relative and absolute
Usability
- ✅ Dynamic variables like
{{uuid}},{{timestamp}},{{randomEmail}},{{randomInt}} - ✅ Reusable step libraries (e.g., "Given I am logged in")
- ✅ Auto-generate JSON schema from live responses (with optional auto-login)
- ✅ Automatically skips regeneration unless
--overwriteis passed - ✅ Interpolates tokens into future requests
- ✅ Allows partial CLI usage with defaults
- ✅ Helpful log messages for skipped/missing tests
- ✅ CI-friendly: JSON summary + non-zero exit on warnings with
--warn-as-error
📦 Installation
Install the CLI globally (recommended if you’ll use it across projects):
npm install -g restlyn
restlyn --helpOr add it to a project (use with npx):
npm install --save-dev restlyn
npx restlyn --versionAlternatives:
- pnpm:
pnpm add -D restlynorpnpm dlx restlyn --help - yarn:
yarn add -D restlynoryarn dlx restlyn --help
You can also clone the repo and use the CLI via
node restlyn.js ...
🧩 Folder Structure
my-api-project/
├── features/
│ └── login.feature
├── schemas/
│ └── loginResponse.schema.json
├── data/
│ └── loginData.json or .csv
├── .restlynrc
├── generated/
│ ├── stepmaps/
│ └── tests/⚡ Quick Start
- Write a
.featurefile infeatures/ - Generate step maps:
npx restlyn steps- Generate test files:
npx restlyn tests- Run tests and generate report:
npx restlyn verify --report🧪 Minimal Example
This shows the full flow: Gherkin → stepMap.json → generated .test.js → run.
- Create a simple feature file at
features/user.feature:
Feature: Users
Scenario: Get user by id
Given base URL is "https://reqres.in/api"
When I GET "/users/2"
Then response status should be 200
And response body should contain key "data"- Generate the step map(s):
npx restlyn steps --output generated/stepmaps --overwriteThis produces generated/stepmaps/user.stepMap.json similar to:
{
"feature": "Users",
"scenarios": [
{
"name": "Get user by id",
"baseUrl": "https://reqres.in/api",
"requests": [{ "method": "GET", "endpoint": "/users/2" }],
"assertions": [
{ "type": "status", "expected": 200, "requestIndex": 0 },
{ "type": "contains", "key": "data", "requestIndex": 0 }
]
}
]
}- Generate the executable test file(s):
npx restlyn tests --output generated/tests --overwriteThis produces generated/tests/user.test.js. A trimmed snippet looks like:
describe('Users', () => {
it('Get user by id', async function () {
const baseUrl = 'https://reqres.in/api';
let res1;
let config1 = { headers: { 'Content-Type': 'application/json' } };
try {
res1 = await retryRequest(() => get(`${baseUrl}/users/2`, config1));
} catch (err) { res1 = err.response; }
expect(res1.status).to.equal(200);
expect(res1.data).to.have.property("data");
});
});- Run and view a report:
npx restlyn verify --reportYou’ll get a console summary plus an HTML report (and a PDF if puppeteer is installed).
💠 CLI Tooling
restlyn steps
Generate .stepMap.json from .feature files.
restlyn steps --file login.feature --output generated/stepmaps --overwriterestlyn tests
Generate test files from step maps.
restlyn tests --file login.stepMap.json --output generated/tests --overwriteOptions:
--schemas <dir>: schema directory (default:schemasor[paths].schemas).--env <env>:local|mock|prodto override base URL resolution.--strict: fail the run if any referenced data file is missing.--warn-as-error: exit with non‑zero code if warnings occurred (missing schema/data).--quiet: suppress per-file logs; print summary + warnings file path.
restlyn verify
Run tests and generate report.
restlyn verify # will run and print test results on console
restlyn verify --verbose # will run and pring details logs on console
restlyn verify --report # will run all tests and generate .html and .pdf reportsOptions:
--json: also writesrestlyn-report.jsonnext to the HTML/PDF.--verbose: prints full Mocha logs for each test.--generated <path|file|list|glob>: run a folder, a single.test.js, a comma‑separated list, or a glob.--stepmaps <dir>: custom.stepMap.jsondirectory (for scenario metadata in the report).
Outputs (default generated/report):
restlyn-report.json— machine-readable summaryrestlyn-report.html— opens automaticallyrestlyn-report.pdf— portable PDF (no collapsible sections)
Warning file (written next to tests):
restlyn-warnings.json— aggregated missing schemas and data files
Exit codes:
0: success;2: warnings present and--warn-as-errorused
restlyn mock
Starts the mock API server if mock-server.js exists in the project or the package.
restlyn mockrestlyn schema
Generate a JSON Schema from a live API response (saved as <name>.schema.json).
restlyn schema \
--url /users/2 \
--method GET \
--output userProfile \
--env local \
--login-url /login \
--login-body '{"email":"[email protected]","password":"cityslicka"}' \
--login-token-key token✍️ Gherkin Syntax
Feature: Login API
Scenario: Unsuccessful login
Given base URL is "https://reqres.in/api"
When I POST "/login" with:
| email | [email protected] |
| password | wrong |
Then response status should be 401
And response body should contain key "error"🔀 Retries & Tokens
@retry(3)
Scenario: Login with retry
When I POST "/login" with:
| email | [email protected] |
| password | secret |
And I extract token "token"🥪 Schema Validation
Then response should match schema "userProfile"Resolved as: schemas/userProfile.schema.json
📊 HTML & PDF Reports
Run with:
restlyn verify --reportGenerates:
generated/report/restlyn-report.html(opens automatically)generated/report/restlyn-report.pdf
Includes:
- Pass/fail summary
- Scenario logs
- Tags, durations, steps
⚙️ Configuration .restlynrc
Example:
features = "features"
stepmaps = "stepmaps"
tests = "tests"
schemas = "schemas"
testData = "data"
report = "report"
timeout = 5000
localMode = true
RESTLYN_STRICT_DATA=1
RESTLYN_WARN_AS_ERROR=1
[globalHeaders]
Authorization = "Bearer your-hardcoded-or-dynamic-token"
x-api-key = "optional-api-key"
[baseUrls]
local = "http://localhost:4000"
prod = "https://api.example.com"Notes:
- Root keys (
features,tests,schemas, etc.) and[paths]are both supported; root keys remain for backward compatibility. - Use CLI flags
--strictand--warn-as-errorfor CI behavior. The example shows the intent, but these flags are not read as environment variables from the INI. - Set
localMode=trueto prefer[baseUrls].local; use--env prodto override from the CLI.
📝 License
MIT
Made with ❤️ by Amiya Pattanaik
