@ripplo/testing 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,8 +11,8 @@ npm install @ripplo/testing
11
11
  ## Quick Start
12
12
 
13
13
  1. Run `npx ripplo` to authenticate and scaffold a `.ripplo/` directory in your project
14
- 2. Define preconditions in `.ripplo/preconditions.ts` these set up test data (users, projects, etc.)
15
- 3. Write tests in `.ripplo/tests/` each file defines one user flow to test
14
+ 2. Define preconditions in `.ripplo/preconditions/`, then add `import "./preconditions/<file>.js";` to `.ripplo/index.ts`. Exports set up test data (users, projects, etc.)
15
+ 3. Write tests in `.ripplo/tests/`, then add `import "./tests/<id>.js";` to `.ripplo/index.ts`. The CLI only loads what that file imports.
16
16
  4. Run `npx ripplo lint` to validate, `npx ripplo run` to execute
17
17
 
18
18
  Every test gets a clean slate via preconditions — no shared state, no ordering dependencies, fully parallelizable.
@@ -23,7 +23,7 @@ Every test gets a clean slate via preconditions — no shared state, no ordering
23
23
 
24
24
  ```typescript
25
25
  import ripplo from "../ripplo.js";
26
- import { dataProject } from "../preconditions.js";
26
+ import { dataProject } from "../preconditions/index.js";
27
27
 
28
28
  ripplo
29
29
  .test("delete-project")
@@ -221,25 +221,27 @@ ripplo.implement(authLoggedIn, {
221
221
 
222
222
  ```bash
223
223
  ripplo # Launch interactive dashboard
224
- ripplo lint [slugs..] # Compile + lint tests (all or specific slugs)
225
- ripplo run [slugs..] # Run tests in parallel
226
- ripplo list # List tests with status
227
- ripplo flake-detect <slug> --runs=10 # Run N times in parallel to detect flakiness
224
+ ripplo lint [ids..] # Compile + lint tests (all or specific ids)
225
+ ripplo run [ids..] # Run tests in parallel
226
+ ripplo flake-detect <id> --runs=10 # Run N times in parallel to detect flakiness
228
227
  ```
229
228
 
230
229
  ## Server Setup
231
230
 
232
- Your application server must expose the precondition endpoints under a single path prefix (the value you pass to `createRipplo({ preconditionsUrl })`). Pick the adapter that matches your framework — each handles webhook signature verification, cookie forwarding, and request parsing for you. Wrap the mount point behind an env guard (e.g. `ENABLE_RIPPLO_TESTING=true`) so it never ships to production.
231
+ Your application server must expose the precondition endpoints under a single path prefix (the value you pass to `createRipplo({ preconditionsUrl })`). Pick the adapter that matches your framework — each handles webhook signature verification, cookie forwarding, and request parsing for you. Every adapter takes a required `enabled: boolean` flag — bind it to an env var (e.g. `process.env.ENABLE_RIPPLO_TESTING === "true"`) so the endpoints never ship to production. When `enabled` is false the adapter mounts a no-op handler.
233
232
 
234
233
  ### Express
235
234
 
236
235
  ```ts
237
236
  import express from "express";
238
237
  import { createExpressHandler } from "@ripplo/testing/express";
239
- import ripplo from "../.ripplo/ripplo.js";
238
+ import ripplo from "<path to .ripplo/ripplo>"; // import the existing instance — never call createRipplo() outside .ripplo/ripplo.ts
240
239
 
241
240
  const app = express();
242
- app.use("/api/test/preconditions", createExpressHandler({ ripplo }));
241
+ app.use(
242
+ "/ripplo/preconditions",
243
+ createExpressHandler({ enabled: process.env.ENABLE_RIPPLO_TESTING === "true", ripplo }),
244
+ );
243
245
  ```
244
246
 
245
247
  Mounts both `PUT /execute-batch` and `PUT /teardown` under the prefix you choose.
@@ -249,12 +251,13 @@ Mounts both `PUT /execute-batch` and `PUT /teardown` under the prefix you choose
249
251
  ```ts
250
252
  import Fastify from "fastify";
251
253
  import { registerFastifyHandler } from "@ripplo/testing/fastify";
252
- import ripplo from "../.ripplo/ripplo.js";
254
+ import ripplo from "<path to .ripplo/ripplo>"; // import the existing instance — never call createRipplo() outside .ripplo/ripplo.ts
253
255
 
254
256
  const app = Fastify();
255
- await app.register(registerFastifyHandler({ ripplo }), {
256
- prefix: "/api/test/preconditions",
257
- });
257
+ await app.register(
258
+ registerFastifyHandler({ enabled: process.env.ENABLE_RIPPLO_TESTING === "true", ripplo }),
259
+ { prefix: "/ripplo/preconditions" },
260
+ );
258
261
  ```
259
262
 
260
263
  ### Next.js (App Router)
@@ -262,11 +265,14 @@ await app.register(registerFastifyHandler({ ripplo }), {
262
265
  The Next.js adapter exports a single catch-all handler. Create one dynamic route file:
263
266
 
264
267
  ```ts
265
- // app/api/test/preconditions/[action]/route.ts
268
+ // app/ripplo/preconditions/[action]/route.ts
266
269
  import { createNextHandler } from "@ripplo/testing/nextjs";
267
270
  import ripplo from "@/.ripplo/ripplo";
268
271
 
269
- export const PUT = createNextHandler({ ripplo });
272
+ export const PUT = createNextHandler({
273
+ enabled: process.env.ENABLE_RIPPLO_TESTING === "true",
274
+ ripplo,
275
+ });
270
276
  ```
271
277
 
272
278
  The handler dispatches on the last URL segment (`execute-batch` or `teardown`) and returns 404 for anything else. It depends only on the Web `Request` / `Response` types, so it runs on both the Node and Edge runtimes — no `next` import required.
@@ -282,12 +288,12 @@ import {
282
288
  serializeCookie,
283
289
  verifyWebhookSignature,
284
290
  } from "@ripplo/testing";
285
- import ripplo from "../.ripplo/ripplo.js";
291
+ import ripplo from "<path to .ripplo/ripplo>"; // import the existing instance — never call createRipplo() outside .ripplo/ripplo.ts
286
292
 
287
293
  const engine = createEngine(ripplo);
288
294
  const webhookSecret = ripplo.getConfig().webhookSecret;
289
295
 
290
- // PUT /api/test/preconditions/execute-batch
296
+ // PUT /ripplo/preconditions/execute-batch
291
297
  async function executeBatch(req: Request): Promise<Response> {
292
298
  const body = await req.text();
293
299
  const verified = verifyWebhookSignature(
@@ -314,7 +320,7 @@ async function executeBatch(req: Request): Promise<Response> {
314
320
  return new Response(JSON.stringify(result), { headers });
315
321
  }
316
322
 
317
- // PUT /api/test/preconditions/teardown
323
+ // PUT /ripplo/preconditions/teardown
318
324
  async function teardown(req: Request): Promise<Response> {
319
325
  // ... same verify pattern, then:
320
326
  // await engine.teardown(parsed.preconditions, parsed.data);
@@ -338,7 +344,7 @@ import { createRipplo } from "@ripplo/testing";
338
344
 
339
345
  export default createRipplo({
340
346
  appUrl: process.env.APP_URL,
341
- preconditionsUrl: `${process.env.APP_URL}/api/test/preconditions`,
347
+ preconditionsUrl: `${process.env.APP_URL}/ripplo/preconditions`,
342
348
  projectId: "...",
343
349
  webhookSecret: process.env.RIPPLO_WEBHOOK_SECRET,
344
350
  });
package/dist/express.d.ts CHANGED
@@ -5,8 +5,9 @@ import './step-DLfkKI3V.js';
5
5
  import '@ripplo/spec';
6
6
 
7
7
  interface CreateExpressHandlerParams {
8
+ readonly enabled: boolean;
8
9
  readonly ripplo: RipploBuilder;
9
10
  }
10
- declare function createExpressHandler({ ripplo }: CreateExpressHandlerParams): Router;
11
+ declare function createExpressHandler({ enabled, ripplo }: CreateExpressHandlerParams): Router;
11
12
 
12
13
  export { type CreateExpressHandlerParams, createExpressHandler };
package/dist/express.js CHANGED
@@ -8,10 +8,13 @@ import {
8
8
 
9
9
  // src/adapters/express.ts
10
10
  import { Router, json } from "express";
11
- function createExpressHandler({ ripplo }) {
11
+ function createExpressHandler({ enabled, ripplo }) {
12
+ const router = Router();
13
+ if (!enabled) {
14
+ return router;
15
+ }
12
16
  const engine = createEngine(ripplo);
13
17
  const webhookSecret = ripplo.getConfig().webhookSecret;
14
- const router = Router();
15
18
  router.use(json());
16
19
  router.use((req, res, next) => {
17
20
  if (webhookSecret.length === 0) {
package/dist/fastify.d.ts CHANGED
@@ -5,8 +5,9 @@ import './step-DLfkKI3V.js';
5
5
  import '@ripplo/spec';
6
6
 
7
7
  interface RegisterFastifyHandlerParams {
8
+ readonly enabled: boolean;
8
9
  readonly ripplo: RipploBuilder;
9
10
  }
10
- declare function registerFastifyHandler({ ripplo, }: RegisterFastifyHandlerParams): (fastify: FastifyInstance) => Promise<void>;
11
+ declare function registerFastifyHandler({ enabled, ripplo, }: RegisterFastifyHandlerParams): (fastify: FastifyInstance) => Promise<void>;
11
12
 
12
13
  export { type RegisterFastifyHandlerParams, registerFastifyHandler };
package/dist/fastify.js CHANGED
@@ -9,8 +9,13 @@ import {
9
9
 
10
10
  // src/adapters/fastify.ts
11
11
  function registerFastifyHandler({
12
+ enabled,
12
13
  ripplo
13
14
  }) {
15
+ if (!enabled) {
16
+ return async () => {
17
+ };
18
+ }
14
19
  const engine = createEngine(ripplo);
15
20
  const webhookSecret = ripplo.getConfig().webhookSecret;
16
21
  return async (fastify) => {
package/dist/nextjs.d.ts CHANGED
@@ -4,9 +4,10 @@ import './step-DLfkKI3V.js';
4
4
  import '@ripplo/spec';
5
5
 
6
6
  interface CreateNextHandlerParams {
7
+ readonly enabled: boolean;
7
8
  readonly ripplo: RipploBuilder;
8
9
  }
9
10
  type NextHandler = (req: Request) => Promise<Response>;
10
- declare function createNextHandler({ ripplo }: CreateNextHandlerParams): NextHandler;
11
+ declare function createNextHandler({ enabled, ripplo }: CreateNextHandlerParams): NextHandler;
11
12
 
12
13
  export { type CreateNextHandlerParams, createNextHandler };
package/dist/nextjs.js CHANGED
@@ -8,7 +8,10 @@ import {
8
8
  } from "./chunk-KWUKVAGI.js";
9
9
 
10
10
  // src/adapters/nextjs.ts
11
- function createNextHandler({ ripplo }) {
11
+ function createNextHandler({ enabled, ripplo }) {
12
+ if (!enabled) {
13
+ return async () => jsonResponse({ error: "Not found" }, 404);
14
+ }
12
15
  const engine = createEngine(ripplo);
13
16
  const webhookSecret = ripplo.getConfig().webhookSecret;
14
17
  return async function handler(req) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ripplo/testing",
3
3
  "description": "TypeScript DSL for defining and running Ripplo e2e workflow tests",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"