@venturekit/testing
v0.0.11
Published
Integration & end-to-end test harness for VentureKit apps — launch the local API stack, mint cognito-local users, reset the database, and drive a typed API client.
Downloads
2,512
Maintainers
Readme
@venturekit/testing
Integration & end-to-end test harness for VentureKit apps. It owns the hard, framework-specific plumbing so your project only has to write the actual test scenarios:
- Launch a real local stack —
startTestStack()runsvk migratethenvk dev, and waits until the server is ready. - Gate on readiness —
waitForReady()polls the dev server's/_dev/healthprobe (the same liveness endpointvktooling uses). - Seed auth —
createTestUser()provisions a cognito-local user with a permanent password over thevk devadmin API (no AWS SDK needed);loginAs()additionally mints real JWTs for API-level tests. - Reset the database —
truncateAllTables()clears app tables between specs while preserving the VentureKit migration/seed bookkeeping. - Drive the API —
createApiClient()is a typedfetchwrapper that understands VentureKit's{ data }/{ error }envelope.
It's UI-framework agnostic: pair it with Playwright, Cypress, or plain vitest. The scenarios (selectors, flows, assertions) stay in your project.
Requires Docker (for the local Postgres / MinIO / cognito-local stack), so run these on macOS / Linux / CI — not over a Windows UNC share.
Install
pnpm add -D @venturekit/testing
# Optional peers (only if you use the matching helpers):
# @venturekit/data -> truncate* DB helpers
# @aws-sdk/client-cognito-identity-provider -> signInWithPassword / loginAsPlaywright: globalSetup pattern
Let Playwright's webServer own the vk dev process and use the harness
for migration, auth seeding, and readiness:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './e2e',
globalSetup: './e2e/global-setup.ts',
use: { baseURL: 'http://localhost:3005' }, // your UI
webServer: [
{
command: 'vk dev --stage test --port 4001 --no-watch',
url: 'http://localhost:4001/_dev/health',
reuseExistingServer: !process.env.CI,
timeout: 120_000,
},
{
command: 'pnpm --filter @your/admin dev',
url: 'http://localhost:3005',
reuseExistingServer: !process.env.CI,
},
],
});// e2e/global-setup.ts
import { createTestUser, truncateAllTables, waitForReady } from '@venturekit/testing';
const API = 'http://localhost:4001';
export default async function globalSetup() {
await waitForReady({ baseUrl: API });
await truncateAllTables(); // needs DATABASE_URL / DB_* in env
await createTestUser({
baseUrl: API,
email: '[email protected]',
password: 'Passw0rd!',
attributes: { tenantId: 'global' },
});
}Your specs then log in through the real UI (the most faithful E2E):
// e2e/login.spec.ts
import { test, expect } from '@playwright/test';
test('logs in and lands on the dashboard', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('[email protected]');
await page.getByLabel('Password').fill('Passw0rd!');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL(/\/(inbox|dashboard)/);
});API-level integration tests (vitest)
No browser — boot the stack, mint a token, and hit the API directly:
import { afterAll, beforeAll, expect, test } from 'vitest';
import { startTestStack, loginAs, createApiClient, type TestStack } from '@venturekit/testing';
let stack: TestStack;
beforeAll(async () => {
stack = await startTestStack({ port: 4100, seed: true });
}, 180_000);
afterAll(async () => {
await stack?.stop();
});
test('GET /tenant returns the current tenant', async () => {
const { idToken } = await loginAs({
baseUrl: stack.baseUrl,
email: '[email protected]',
password: 'Passw0rd!',
});
const api = createApiClient({ baseUrl: stack.baseUrl, token: idToken });
const res = await api.get<{ slug: string }>('/tenant');
expect(res.status).toBe(200);
expect(res.data.slug).toBeDefined();
});API reference
| Export | Purpose |
| --- | --- |
| startTestStack(opts) | Migrate + boot vk dev; returns { baseUrl, port, stop() }. |
| waitForReady(opts) | Poll until ready (default /_dev/health). vkDevServerReady asserts the vk discriminator. |
| createApiClient(opts) | Typed fetch client; unwraps { data }, throws ApiError on non-2xx. |
| createTestUser(opts) | Idempotently create a cognito-local user with a permanent password. |
| setTestUserAttributes / deleteTestUser / getDevPools | Manage cognito-local users / inspect pools. |
| signInWithPassword(opts) / loginAs(opts) | Mint real JWTs for a user (needs the Cognito SDK peer). |
| truncateAllTables(opts) / truncateTables / listTables | Reset the DB between specs (needs @venturekit/data). |
| buildTruncateSql / filterTruncatableTables / quoteIdent | Pure SQL builders (reusable / testable). |
Notes
startTestStackdefaults to stagetest, which targets a separate local database (<dbname>_test) so your tests never clobbervk devdata.vk devdoes not auto-migrate —startTestStackrunsvk migratefor you (passmigrate: falseto skip,seed: trueto also seed).- DB helpers read the same
DATABASE_URL/DB_*env the app uses.
