QAID Docs

API Testing

API Testing lets you create, organize, and run REST API test collections with assertions and variable chaining.

License: API Testing requires Pro or Enterprise tier.

Overview

API Testing in QAID provides a Postman-like interface for testing REST APIs:

  • Collections group related API requests together
  • Requests define HTTP calls with headers, body, auth, and assertions
  • Variable chaining passes data between requests (e.g., extract a token from login, use it in subsequent requests)
  • Collection runs execute all requests sequentially and track pass/fail results
  • Playwright export generates standalone .spec.ts files for CI/CD integration

Getting Started

Creating a Collection

  1. Navigate to API Testing in the sidebar
  2. Click "New Collection"
  3. Enter:
    • Name (required) — e.g., "User API Tests"
    • Base URL (optional) — e.g., https://api.example.com. Relative request URLs will be appended to this.
  4. Click "Create"

Adding Requests

  1. Open a collection
  2. Click "Add Request" in the left panel
  3. Configure the request (see Request Builder below)
  4. Changes auto-save as you type

Request Builder

The request builder has a URL bar and five configuration tabs.

URL Bar

  • Method dropdown — GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
  • URL field — Full URL (https://api.example.com/users) or relative path (/users)
  • Send button — Quick-test a single request without creating a run

Headers Tab

Key-value editor for custom HTTP headers. Each header has an enable/disable checkbox.

Example:

KeyValue
X-Custom-Headermy-value
Acceptapplication/json

Body Tab

Select a body type:

TypeContent-TypeUse For
NoneGET requests
JSONapplication/jsonAPI payloads
Formapplication/x-www-form-urlencodedForm submissions
Texttext/plainRaw text

Enter the body content in the text area. Supports variable interpolation with {{variableName}} syntax.

Auth Tab

Choose an authentication method:

TypeFieldsHeader Generated
InheritUses collection-level auth
No AuthNo auth header
Bearer TokenTokenAuthorization: Bearer <token>
Basic AuthUsername, PasswordAuthorization: Basic <base64>
API KeyKey name, Value, Add to (Header/Query)Custom header or query param

All auth fields support {{variable}} interpolation.

Assertions Tab

Define checks that run against the response. Each assertion has a type, operator, and expected value.

Status Code

Verify the HTTP status code.

OperatorExample
equalsStatus equals 200
not_equalsStatus not equals 500
>=, >, <=, <Status < 400

JSON Path

Check values in the JSON response body using dot notation.

OperatorPath ExampleExpected
equalsdata.user.name"John"
containsdata.message"success"
existsdata.token
not_existsdata.error
matches (regex)data.email".*@example.com"
length_gtedata.items5

Check response headers (case-insensitive matching).

OperatorHeaderExpected
containscontent-typeapplication/json
existsx-request-id

Response Time

Verify the response completes within a time limit.

OperatorExpected
<=1000 (ms)

Body Contains

Check the raw response body text.

OperatorExpected
contains"success"
not_contains"error"
matches (regex)"id\":\s*\d+"

Variables Tab

Extract values from responses to use in subsequent requests.

Variable NameJSON PathResult
userIddata.user.idExtracts data.user.id from JSON response
authTokendata.tokenExtracts data.token from JSON response

Use extracted variables in other requests with {{userId}} or {{authToken}} in URLs, headers, body, or auth fields.

Variable Chaining

Variable chaining lets you pass data between requests in a collection run.

How It Works

  1. Request 1 (Login) extracts {{token}} from its response
  2. Request 2 (Get User) uses {{token}} in its Bearer auth
  3. Request 2 extracts {{userId}} from its response
  4. Request 3 (Update User) uses both {{token}} and {{userId}}

Variable Scope

Variables are resolved in this order (highest priority first):

  1. Extracted variables from previous requests in the run
  2. Collection-level variables (static, set on the collection)
  3. Initial variables passed when starting the run

Tips

  • Variable names are case-sensitive: {{userId}} is not the same as {{userid}}
  • Unresolved variables stay as literal text (e.g., {{unknown}} is sent as-is)
  • Use dot notation for nested values: data.user.profile.id
  • The left panel shows dependency arrows between requests that share variables

Quick Send vs Collection Run

Quick SendCollection Run
Triggered by"Send" button on a request"Run Collection" button
ScopeSingle requestAll enabled requests
VariablesCollection-level onlyAccumulated across requests
Results saved?No (transient)Yes (in Runs tab)
PurposeDebug/test during designFull integration test

Running a Collection

Starting a Run

  1. Open a collection
  2. Click "Run Collection" in the header
  3. All enabled requests execute sequentially
  4. Results appear in the Runs tab

During Execution

  • Requests run one at a time (sequential, not parallel) to support variable chaining
  • If a request fails, execution continues to the next request (all requests run regardless)
  • Variables accumulate as each request completes

Viewing Results

Switch to the Runs tab to see all past runs. Click a run to see detailed results:

Summary cards:

  • Pass Rate (percentage)
  • Total Time (milliseconds)
  • Requests Passed (count)
  • Assertions Passed (count)

Per-request results:

  • Status icon (pass/fail/error/skipped)
  • HTTP status code badge
  • Response time
  • Assertion count
  • Click to expand for details:
    • Assertion results (each with pass/fail and message)
    • Extracted variables
    • Response body (formatted JSON)
    • Response headers

Result Statuses

StatusMeaning
PassedAll assertions passed
FailedOne or more assertions failed
ErrorNetwork error, timeout, or request failed to execute
SkippedRequest was disabled

Disabling Requests

Toggle the enabled state on a request to skip it during collection runs. Useful for:

  • Temporarily excluding requests that are under development
  • Conditional test flows
  • Reducing run time

Disabled requests are also excluded from Playwright export.

Duplicating Requests

Hover over a request in the left panel and click the copy icon to duplicate it. This creates an exact copy with "(copy)" appended to the name.

Exporting to Playwright

Generate a standalone Playwright test file from your collection:

  1. Open a collection
  2. The export generates a .spec.ts file with:
    • One test() per enabled request
    • Playwright request API calls (GET, POST, etc.)
    • expect() assertions for status codes, JSON paths, and headers
    • Proper Content-Type and auth headers

Example output:

import { test, expect } from '@playwright/test';

test.describe('User API Tests', () => {
  const BASE_URL = 'https://api.example.com';

  test('GET List Users', async ({ request }) => {
    const response = await request.get(`${BASE_URL}/users`);
    expect(response.status()).toBe(200);
    const body = await response.json();
    expect(body.data).toBeDefined();
  });
});

Note: Variable interpolation is not translated to Playwright (assertions use static values). For dynamic flows with variable chaining, use QAID's built-in collection runs.

Collection Settings

Edit collection settings by updating:

  • Name — Collection display name
  • Base URL — Shared base for relative request URLs
  • Auth — Default authentication for all requests (requests can override with "Inherit")
  • Variables — Static key-value pairs available to all requests

Best Practices

Organizing Collections

  • Group related endpoints in one collection (e.g., "Auth API", "User API", "Orders API")
  • Order requests logically — put login/setup first, then operations, then cleanup
  • Use descriptive request names

Variable Chaining

  • Extract tokens and IDs early in the collection
  • Use meaningful variable names (authToken, not t)
  • Check variables with exists assertions to catch extraction failures

Assertions

  • Always assert status codes
  • Use JSON path assertions for response structure validation
  • Add response time assertions for performance monitoring
  • Use contains over equals for values that may change slightly

Authentication

  • Set collection-level auth for shared tokens
  • Use per-request auth overrides only when testing different roles
  • Use variable interpolation for dynamic tokens: {{authToken}}

Troubleshooting

Request Fails with Network Error

  • Check that the URL is correct and the server is reachable
  • If using a relative URL, ensure the collection has a Base URL set
  • Check for CORS issues if testing from a different domain

Variables Not Resolving

  • Verify the JSON path in the Variables tab matches the actual response structure
  • Check that the producing request runs before the consuming request
  • Variable names are case-sensitive

Assertions Failing Unexpectedly

  • Use Quick Send to inspect the actual response
  • Check that JSON paths match the response structure (use dot notation: data.items.0.id)
  • For header assertions, header names are matched case-insensitively

Response Body Truncated

  • Large response bodies may be truncated in stored results
  • Full responses are visible during Quick Send

On this page