Test client
@seedalina/test-client is a typed Node client for ordering, pooling, and releasing
Seedalina test data entities from Playwright (or any Node-based test suite).
Install
pnpm add -D @seedalina/test-client
Quick start
import { SeedalinaClient } from '@seedalina/test-client';
const seedalina = new SeedalinaClient({
baseUrl: process.env.SEEDALINA_API_URL!, // e.g. "https://seedalina.internal/api"
token: process.env.SEEDALINA_TOKEN!, // a pre-obtained JWT bearer token
});
test('checkout with an overdue invoice', async ({ page }) => {
const order = await seedalina.orderAndWait({
templateKey: 'customer.with-overdue-invoice',
parameters: { country: 'CH' },
});
const customer = order.businessObjects[0].assets[0].data;
// ... use customer in the test ...
await seedalina.release(order.id);
});
Auth
The client expects a pre-obtained JWT — it does not perform login itself. How you obtain that token (service account, CI secret, etc.) is up to your pipeline.
Ordering entities
Use orders when you need Seedalina to generate fresh data for a test run.
| Method | What it does |
|--------|-------------|
| order(input) | Places an order and returns immediately (REQUESTED/PROCESSING). |
| getOrder(id) | Fetches the current order state, including generated assets once ready. |
| orderAndWait(input, opts?) | Places an order and polls until READY. Throws SeedalinaOrderFailedError on FAILED or SeedalinaOrderTimeoutError past the deadline. Defaults: 30 s timeout, 1 s poll interval. |
| executeOrder(orderId) | Kicks off generation for an order that has not run yet. |
| waitForOrder(orderId, opts?) | Polls an order you already have an id for (unlike orderAndWait, no new order is placed). |
| release(id) | Marks the order as released so its test data can be cleaned up. |
| businessObjectsFromOrder(order) | Flattens an order's nested outputs into plain camelCased records. Pure helper — no API call. |
Pulling pooled test data
For parametrized tests where you want whatever Seedalina already has on hand rather than placing a new order each time:
const users = await seedalina.getTestDataPool('test-user', 'qa');
for (const user of users) {
test(`logs in as ${user.username}`, async ({ page }) => { /* ... */ });
}
| Method | What it does |
|--------|-------------|
| getTestData(templateKey, variantKey, opts?) | Returns the pooled NEW object for that variant (camelCased data plus lifecycle methods). Falls back to the template's static variant values when the pool is empty. Options: lock, newState, consume. |
| getTestDataPool(templateKey, environmentKey, opts?) | All pooled objects for a template/environment, flattened. Default status: 'NEW'. |
| getTestDataObjectFromPool(templateKey, variantKey, status?) | One pooled object for a specific variant; undefined if none match. |
| lockBusinessObject(id) | Locks a business object by id. |
| releaseBusinessObject(id) | Releases a locked business object. |
| consumeBusinessObject(id) | Marks a business object as consumed. |
| setBusinessObjectStatus(id, status) | Sets an arbitrary lifecycle status directly. |
| savePoolEntry(templateKey, variantKey, environmentKey, data, status?) | Saves a plain object straight into the pool as a new business object. data is stored as-given, unvalidated. status defaults to 'NEW'. Pass variantKey: undefined for no variant. |
await seedalina.savePoolEntry(
'studiengang', 'Variant2', 'integration',
{ name: 'Computer Science', code: 'CS-101' },
);
Static template variants
When a template is configured with no pool orders — fixed reference data such
as login credentials or lookup rows — read its variants: directly:
const users = await seedalina.getBOAllVariants('user');
const admin = await seedalina.getBOVariant('user', 'AC5-Admin');
const base = await seedalina.getBOVariant('user'); // template's base property defaults
| Method | What it does |
|--------|-------------|
| getBOAllVariants(templateKey) | Every variant, flattened to plain camelCased records. id is the variant key. |
| getBOVariant(templateKey, variantKey?) | One variant by key, or the template's base properties[].default values when the key is omitted. Returns undefined when the key does not match. |
Reporting from executor scripts
When Seedalina launches your script as a template step (executor: playwright),
the runner injects short-lived env vars — there is no client to construct yet.
Use the standalone functions instead:
import { saveTestData, seedParams, shouldSaveTestData } from '@seedalina/test-client';
const { country } = seedParams<{ country: string }>();
// ... generate data ...
await saveTestData({ username, password, customerId });
| Function | What it does |
|----------|-------------|
| seedParams<T>() | Parses SEEDALINA_PARAMS (template scriptParams) as JSON. |
| shouldSaveTestData() | true only when the script was launched by Seedalina (SEEDALINA_REPORT === 'true'). |
| saveTestData(outputs, opts?) | Reports generated outputs back. Silent no-op when run standalone (npx playwright test), so scripts work in both contexts. Pass { force: true } to bypass the on/off switch — SEEDALINA_BUSINESS_OBJECT_ID and SEEDALINA_STEP_KEY are still required. |
All methods throw SeedalinaApiError (with a status field) on non-2xx responses.