diff --git a/README.md b/README.md index 3c03da5b..4a29bfc6 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,30 @@ shortest.afterAll(async ({ page }) => { }); ``` +### Chaining tests + +Shortest supports flexible test chaining patterns: + +```typescript +// Sequential test chain +shortest([ + "user can login with email and password", + "user can modify their account-level refund policy" +]) + +// Reusable test flows +const loginAsLawyer = "login as lawyer with valid credentials" +const loginAsContractor = "login as contractor with valid credentials" +const allAppActions = [ + "send invoice to company", + "view invoices" +] + +// Combine flows with spread operator +shortest([loginAsLawyer, ...allAppActions]) +shortest([loginAsContractor, ...allAppActions]) +``` + ### Running tests ```bash diff --git a/packages/shortest/src/index.ts b/packages/shortest/src/index.ts index cd255842..eb8fe760 100644 --- a/packages/shortest/src/index.ts +++ b/packages/shortest/src/index.ts @@ -110,12 +110,33 @@ export function getConfig(): ShortestConfig { } function createTestChain( - nameOrFn: string | ((context: TestContext) => Promise), + nameOrFn: string | string[] | ((context: TestContext) => Promise), payloadOrFn?: ((context: TestContext) => Promise) | any, fn?: (context: TestContext) => Promise, ): TestChain { const registry = global.__shortest__.registry; + // Handle array of test names + if (Array.isArray(nameOrFn)) { + const tests = nameOrFn.map((name) => { + const test: TestFunction = { + name, + expectations: [], + }; + + registry.tests.set(name, [...(registry.tests.get(name) || []), test]); + registry.currentFileTests.push(test); + return test; + }); + + // Return chain for the last test + const lastTest = tests[tests.length - 1]; + if (!lastTest.name) { + throw new Error("Test name is required"); + } + return createTestChain(lastTest.name, payloadOrFn, fn); + } + // Handle direct execution if (typeof nameOrFn === "function") { registry.directTestCounter++; @@ -182,7 +203,7 @@ function createTestChain( export const test: TestAPI = Object.assign( ( - nameOrFn: string | ((context: TestContext) => Promise), + nameOrFn: string | string[] | ((context: TestContext) => Promise), payloadOrFn?: ((context: TestContext) => Promise) | any, fn?: (context: TestContext) => Promise, ) => createTestChain(nameOrFn, payloadOrFn, fn), diff --git a/packages/shortest/src/types/test.ts b/packages/shortest/src/types/test.ts index 776b85d0..b2be7208 100644 --- a/packages/shortest/src/types/test.ts +++ b/packages/shortest/src/types/test.ts @@ -76,6 +76,7 @@ export type TestChain = { export type TestAPI = { (fn: (context: TestContext) => Promise): TestChain; (name: string): TestChain; + (names: string[]): TestChain; (name: string, fn?: (context: TestContext) => Promise): TestChain; ( name: string, diff --git a/packages/shortest/tests/test-chained.ts b/packages/shortest/tests/test-chained.ts new file mode 100644 index 00000000..e2241798 --- /dev/null +++ b/packages/shortest/tests/test-chained.ts @@ -0,0 +1,4 @@ +import { shortest } from "../src"; + +// Sequential tests +shortest(["Login to the application", "Navigate to invoices", "Send invoice"]);