JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 11
  • Score
    100M100P100Q76281F
  • License MIT

Dynamic load testing tool with intelligent version comparison using K6, pixelmatch, and Sharp

Package Exports

  • synapse-surge
  • synapse-surge/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (synapse-surge) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Synapse - Dynamic Load Testing Tool

npm version License: MIT

Synapse is a powerful command-line tool that generates K6 load testing scripts from simple YAML configurations. It supports dynamic URL construction, multiple parameter types including arrays, CSV data sources, and all K6 features.

๐Ÿš€ Features

  • Dynamic URL Construction - Build URLs with configurable parameters
  • Multiple Parameter Types - Integer, string, array, CSV, and URL parameters
  • Batch Mode - Use pre-built URLs from CSV files
  • K6 Integration - Full K6 feature support with automatic script generation
  • Smart Configuration - Automatic mode detection based on config
  • Performance Metrics - Comprehensive load testing results
  • CLI Interface - Easy-to-use command-line interface
  • MCP Integration - Natural language load testing through LLM conversations
  • ๐Ÿ†• Image/Text Comparison - Compare responses between different versions/environments
  • ๐Ÿ†• Standalone Comparison - Direct CSV-based image/text comparison tool

๐Ÿ“ฆ Installation

npm install -g synapse

Local Installation

npm install synapse
npx synapse --help

๐Ÿƒ Quick Start

Simple Load Test (No Configuration File)

For quick testing without creating a YAML file:

synapse test --url "https://api.example.com" --concurrent 10 --requests 100

Advanced Configuration

1. Initialize Configuration

synapse init --name "My API Test" --url "https://api.example.com"

This creates a synapse.yml file with basic configuration.

2. Customize Configuration

Edit the generated synapse.yml:

name: "API Load Test"
baseUrl: "https://api.example.com/search"
execution:
  mode: "construct"
  concurrent: 10
  iterations: 100
parameters:
  - name: "query"
    type: "array"
    values: ["javascript", "python", "react & vue"]
  - name: "userId"
    type: "integer"
    min: 1000
    max: 9999
  - name: "imageUrl"
    type: "static"
    value: "http://localhost:7900/generated-content/imagen-3_0-generate-002/2025-11-05/imagen.webp"
k6Options:
  thresholds:
    http_req_duration: ["p(95)<500"]

Auto-encoding in action:

  • "react & vue" โ†’ "react%20%26%20vue"
  • Complex image URL โ†’ Automatically URL-encoded
  • userId numbers โ†’ No encoding needed

3. Run Load Test

synapse run

๐Ÿ“‹ Parameter Types

Auto-Encoding: Static and CSV parameters automatically detect and URL-encode special characters and URLs. No manual encoding configuration needed for standard URL encoding.

Static Parameters โญ NEW

Use fixed values with smart auto-encoding for URLs and special characters:

- name: "imageUrl"
  type: "static"
  value: "http://localhost:7900/generated-content/imagen-3_0-generate-002/2025-11-05/imagen-1762381001933-3b19cf6c.webp"
- name: "apiKey"
  type: "static"
  value: "your-api-key-here"
- name: "searchQuery"
  type: "static"
  value: "hello world & special chars!"

Auto-encoding behavior:

  • URLs are automatically URL-encoded when needed
  • Special characters (&, !, spaces, etc.) are encoded
  • Simple strings (like API keys) remain unchanged
  • No configuration required

Integer Parameters

Generate random integers within a specified range:

- name: "userId"
  type: "integer"
  min: 1
  max: 1000000
  length: 10  # pad with zeros

String Parameters

Generate random strings with various character sets:

- name: "sessionId"
  type: "string"
  length: 32
  charset: "alphanumeric"  # or "alpha", "numeric", "custom"
  customChars: "abcdef123456"  # only if charset is "custom"

Array Parameters โญ NEW

Select random values from a predefined array with auto-encoding:

- name: "category"
  type: "array"
  values: ["electronics", "books & media", "home & garden"]
  unique: true  # optional: ensure no duplicates
- name: "testUrls"
  type: "array"
  values: [
    "http://localhost:3000/api/test?param=value",
    "https://example.com/search?q=hello world"
  ]

CSV Parameters

Load values from CSV files with smart auto-encoding:

- name: "region"
  type: "csv"
  file: "./data/regions.csv"
  column: "name"

URL Parameters

Load URLs with automatic encoding and optional base64:

- name: "targetUrl"
  type: "url"
  file: "./data/urls.csv"
  column: "url"
  encoding: "base64"  # Optional: only for base64 encoding

Note: URL encoding is automatic. Only specify encoding: "base64" when you need base64 encoding specifically.

๐Ÿ”„ Auto-Encoding Examples

Static Parameters:

# Input
- name: "imageUrl"
  type: "static"
  value: "http://localhost:7900/generated-content/imagen-3_0-generate-002/2025-11-05/imagen.webp"

# Output: Automatically encoded
# http%3A//localhost%3A7900/generated-content/imagen-3_0-generate-002/2025-11-05/imagen.webp

Array Parameters:

# Input
- name: "searchTerm"
  type: "array"
  values: ["hello world", "cats & dogs", "simple-text"]

# Output: Smart encoding
# "hello world" โ†’ "hello%20world"
# "cats & dogs" โ†’ "cats%20%26%20dogs"  
# "simple-text" โ†’ "simple-text" (unchanged)

CSV Data:

# urls.csv
url
http://localhost:3000/api/test?param=value&other=data
https://example.com/search?q=hello world
simple-endpoint
# Configuration
- name: "endpoint"
  type: "csv"
  file: "./urls.csv"
  column: "url"

# Output: Auto-encoded when needed
# Complex URLs โ†’ Encoded
# Simple strings โ†’ Unchanged

๐Ÿ”„ Comparison Features

Load Test with Comparison

Compare different versions/environments during load testing:

name: "Version Comparison Test"
baseUrl: "https://v1.api.example.com"
execution:
  mode: "construct"
  concurrent: 10
  iterations: 100
parameters:
  - name: "userId"
    type: "integer"
    min: 1000
    max: 9999
comparison:
  enabled: true
  type: "image"  # or "text"
  baseUrl2: "https://v2.api.example.com"
  threshold: 0.1
  timeout: 30000

Usage:

# Load test only (default)
synapse run

# Load test + comparison
synapse run --compare

# Comparison only (no load test)
synapse run --compare-only

Standalone Comparison

Compare images/text directly from CSV:

url1,url2
https://v1.api.com/image/1,https://v2.api.com/image/1
https://v1.api.com/image/2,https://v2.api.com/image/2
synapse compare --file comparison.csv --type image

Comparison Reports

Generated reports include:

  • Response times for both URLs
  • HTTP status codes
  • Image dimensions and similarity scores
  • Text match results
  • Error details and timestamps
  • CSV and JSON formats

๐Ÿ”ง CLI Commands

synapse test

Run simple load test without configuration file:

synapse test --url "https://api.example.com" --concurrent 10 --requests 100

Options:

  • -u, --url <url> - Target URL to test (required)
  • -c, --concurrent <number> - Number of concurrent users (required)
  • -r, --requests <number> - Total number of requests (required)
  • -o, --output <path> - Output directory (default: ./output)
  • --dry-run - Generate script without running
  • --keep-script - Keep generated K6 script

synapse run

Run load test from configuration:

synapse run --config synapse.yml --output ./results --dry-run

Options:

  • -c, --config <path> - Configuration file path (default: synapse.yml)
  • -o, --output <path> - Output directory (default: ./output)
  • --dry-run - Generate script without running
  • --keep-script - Keep generated K6 script
  • --compare - Run comparison if enabled in config (opt-in)
  • --compare-only - Generate URLs and run comparison only (skip load test)

synapse validate

Validate configuration file:

synapse validate --config synapse.yml

synapse generate

Generate K6 script without running:

synapse generate --config synapse.yml --output test.js

synapse init

Initialize new configuration:

synapse init --name "My Test" --url "https://api.example.com"

synapse compare

Compare images or text from CSV file:

synapse compare --file urls.csv --type image --column1 url1 --column2 url2

Options:

  • -f, --file <path> - CSV file with URLs to compare (required)
  • -c1, --column1 <name> - First URL column name (default: url1)
  • -c2, --column2 <name> - Second URL column name (default: url2)
  • -t, --type <type> - Comparison type: image or text (default: image)
  • -o, --output <path> - Output directory (default: ./output)
  • --timeout <ms> - Request timeout in milliseconds (default: 30000)
  • --threshold <value> - Image comparison threshold 0-1 (default: 0.1)

๐Ÿ“Š Execution Modes

Construct Mode

Dynamically builds URLs using base URL and parameters:

execution:
  mode: "construct"
  concurrent: 10
  iterations: 100

Batch Mode

Uses pre-built URLs from CSV file:

execution:
  mode: "batch"
  concurrent: 10
  duration: "5m"
batch:
  file: "./data/urls.csv"
  column: "url"

๐ŸŽฏ K6 Integration & Options

Synapse supports all K6 configuration options through the k6Options section. These options control test execution, performance thresholds, and advanced scenarios.

Basic Execution Options

k6Options:
  # Simple load test
  vus: 10              # Virtual users (concurrent connections)
  duration: "30s"      # Test duration
  iterations: 100      # Total number of iterations

๐Ÿ“Š Thresholds - Performance Requirements

Thresholds define pass/fail criteria for your load test:

k6Options:
  thresholds:
    # Response time thresholds
    http_req_duration: ["p(95)<500"]           # 95% of requests under 500ms
    http_req_duration: ["p(99)<1000"]          # 99% of requests under 1s
    http_req_duration: ["avg<200"]             # Average response time under 200ms
    http_req_duration: ["med<150"]             # Median response time under 150ms
    
    # Error rate thresholds
    http_req_failed: ["rate<0.1"]              # Less than 10% failure rate
    http_req_failed: ["rate<0.01"]             # Less than 1% failure rate
    
    # Request rate thresholds
    http_reqs: ["rate>100"]                    # More than 100 requests/second
    
    # Check thresholds (custom validations)
    checks: ["rate>0.95"]                      # 95% of checks must pass
    
    # Data transfer thresholds
    data_received: ["rate<10000"]              # Less than 10KB/s received
    data_sent: ["rate<5000"]                   # Less than 5KB/s sent

Threshold Operators:

  • < - Less than
  • <= - Less than or equal
  • > - Greater than
  • >= - Greater than or equal
  • == - Equal to
  • != - Not equal to

Statistical Functions:

  • avg - Average value
  • min - Minimum value
  • max - Maximum value
  • med - Median (50th percentile)
  • p(90) - 90th percentile
  • p(95) - 95th percentile
  • p(99) - 99th percentile
  • rate - Rate (for counters)
  • count - Total count

๐ŸŽญ Scenarios - Advanced Test Patterns

Per-VU Iterations

Each virtual user runs a specific number of iterations:

k6Options:
  scenarios:
    api_test:
      executor: "per-vu-iterations"
      vus: 10
      iterations: 20        # Each VU runs 20 iterations (200 total)
      maxDuration: "5m"     # Maximum test duration

Shared Iterations

Total iterations shared among all VUs:

k6Options:
  scenarios:
    load_test:
      executor: "shared-iterations"
      vus: 10
      iterations: 1000      # 1000 total iterations shared
      maxDuration: "10m"

Constant VUs

Fixed number of VUs for a duration:

k6Options:
  scenarios:
    steady_load:
      executor: "constant-vus"
      vus: 50
      duration: "5m"

Ramping VUs

Gradually increase/decrease load:

k6Options:
  scenarios:
    ramp_test:
      executor: "ramping-vus"
      startVUs: 0
      stages:
        - duration: "2m"
          target: 10        # Ramp up to 10 VUs
        - duration: "5m"
          target: 50        # Ramp up to 50 VUs
        - duration: "2m"
          target: 0         # Ramp down to 0 VUs

Constant Arrival Rate

Maintain steady request rate:

k6Options:
  scenarios:
    constant_rate:
      executor: "constant-arrival-rate"
      rate: 100            # 100 iterations/second
      duration: "5m"
      preAllocatedVUs: 10  # Pre-allocated VUs
      maxVUs: 50           # Maximum VUs if needed

Ramping Arrival Rate

Variable request rate over time:

k6Options:
  scenarios:
    variable_rate:
      executor: "ramping-arrival-rate"
      startRate: 10        # Start at 10 iter/sec
      stages:
        - duration: "2m"
          target: 50       # Ramp to 50 iter/sec
        - duration: "5m"
          target: 100      # Ramp to 100 iter/sec
        - duration: "2m"
          target: 0        # Ramp down to 0
      preAllocatedVUs: 20
      maxVUs: 100

๐Ÿ”ง Advanced Options

k6Options:
  # Global settings
  userAgent: "MyApp LoadTest/1.0"
  
  # HTTP settings
  http:
    timeout: "60s"
    keepAlive: true
  
  # TLS settings
  tlsAuth:
    - domains: ["example.com"]
      cert: "client.crt"
      key: "client.key"
  
  # DNS settings
  dns:
    ttl: "5m"
    select: "random"      # or "roundRobin", "first"
  
  # Rate limiting
  rps: 500               # Requests per second limit
  
  # Batch settings
  batch: 10              # Batch HTTP requests
  batchPerHost: 5        # Batch per host
  
  # Connection settings
  maxRedirects: 10
  userAgent: "k6/0.45.0"
  
  # Output settings
  summaryTrendStats: ["avg", "min", "med", "max", "p(90)", "p(95)", "p(99)"]

๐Ÿ“ˆ Complete Example

name: "Production API Load Test"
baseUrl: "https://api.example.com"
execution:
  mode: "construct"
  concurrent: 50
  iterations: 5000

parameters:
  - name: "userId"
    type: "integer"
    min: 1000
    max: 9999

k6Options:
  # Performance requirements
  thresholds:
    http_req_duration: ["p(95)<500", "p(99)<1000"]
    http_req_failed: ["rate<0.01"]
    http_reqs: ["rate>200"]
    checks: ["rate>0.99"]
  
  # Load pattern
  scenarios:
    normal_load:
      executor: "ramping-vus"
      stages:
        - duration: "5m"
          target: 10      # Warm up
        - duration: "10m"
          target: 50      # Normal load
        - duration: "5m"
          target: 100     # Peak load
        - duration: "10m"
          target: 50      # Back to normal
        - duration: "5m"
          target: 0       # Cool down
  
  # Global settings
  userAgent: "LoadTest/1.0"
  maxRedirects: 5
  
  # HTTP configuration
  http:
    timeout: "30s"
    keepAlive: true

๐Ÿšจ Common Threshold Patterns

API Performance:

thresholds:
  http_req_duration: ["p(95)<200", "p(99)<500"]
  http_req_failed: ["rate<0.01"]

High Throughput:

thresholds:
  http_reqs: ["rate>1000"]
  http_req_duration: ["p(95)<100"]

Reliability Focus:

thresholds:
  http_req_failed: ["rate<0.001"]  # 99.9% success rate
  checks: ["rate>0.999"]

๐Ÿ“ Project Structure

synapse/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ generators/          # Parameter and script generators
โ”‚   โ”œโ”€โ”€ validators/          # Configuration validators
โ”‚   โ”œโ”€โ”€ types/              # TypeScript interfaces
โ”‚   โ””โ”€โ”€ cli.ts              # CLI interface
โ”œโ”€โ”€ examples/               # Example configurations
โ”œโ”€โ”€ docs/                   # Documentation
โ””โ”€โ”€ tests/                  # Test files

๐Ÿงช Testing

Run the test suite:

npm test

Run with coverage:

npm run test -- --coverage

๐Ÿ“š Documentation

Full documentation is available at: Synapse Docs

Or serve locally:

npm run docs:serve

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit changes: git commit -m 'Add amazing feature'
  4. Push to branch: git push origin feature/amazing-feature
  5. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments

๐Ÿ› Issues & Support