@ripplo/testing 0.6.1 → 0.7.0
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/DSL.md +355 -0
- package/LICENSE.md +1 -0
- package/README.md +47 -273
- package/dist/engine-BT7hUouB.d.ts +1095 -0
- package/dist/express.d.ts +7 -9
- package/dist/express.js +422 -48
- package/dist/index.d.ts +122 -59
- package/dist/index.js +1630 -1126
- package/package.json +31 -113
- package/dist/actions.d.ts +0 -260
- package/dist/actions.js +0 -177
- package/dist/assert.d.ts +0 -188
- package/dist/assert.js +0 -111
- package/dist/builder-SsgqYqSC.d.ts +0 -156
- package/dist/chunk-2YLI7VD4.js +0 -65
- package/dist/chunk-4MGIQFAJ.js +0 -16
- package/dist/chunk-DCJBLS2U.js +0 -26
- package/dist/chunk-MGATMMCZ.js +0 -16
- package/dist/chunk-XO36IU66.js +0 -88
- package/dist/chunk-YFOTJIVF.js +0 -134
- package/dist/chunk-YQAEOH5W.js +0 -111
- package/dist/compiler.d.ts +0 -32
- package/dist/compiler.js +0 -8
- package/dist/control.d.ts +0 -45
- package/dist/control.js +0 -17
- package/dist/elysia.d.ts +0 -78
- package/dist/elysia.js +0 -114
- package/dist/engine-BOqzK_go.d.ts +0 -61
- package/dist/fastify.d.ts +0 -14
- package/dist/fastify.js +0 -79
- package/dist/hono.d.ts +0 -19
- package/dist/hono.js +0 -89
- package/dist/koa.d.ts +0 -14
- package/dist/koa.js +0 -135
- package/dist/locators.d.ts +0 -40
- package/dist/locators.js +0 -11
- package/dist/lockfile.d.ts +0 -722
- package/dist/lockfile.js +0 -707
- package/dist/nestjs.d.ts +0 -17
- package/dist/nestjs.js +0 -139
- package/dist/nextjs.d.ts +0 -14
- package/dist/nextjs.js +0 -137
- package/dist/step-De52hTLd.d.ts +0 -19
- package/dist/types-BzZrl65Z.d.ts +0 -115
package/dist/assert.d.ts
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { O as ObserverHandle, a as ObserverInput, P as Primitive, b as ObserverBudgetTier } from './types-BzZrl65Z.js';
|
|
2
|
-
import { Variable, StaticStringRef, VariableRef } from './control.js';
|
|
3
|
-
import { U as UnlabeledStep } from './step-De52hTLd.js';
|
|
4
|
-
import { CheckLocator, AnyLocator } from './locators.js';
|
|
5
|
-
import '@ripplo/spec';
|
|
6
|
-
|
|
7
|
-
type StringOrVariable = string | Variable<string>;
|
|
8
|
-
declare const assert: {
|
|
9
|
-
not: {
|
|
10
|
-
checked(locator: CheckLocator): UnlabeledStep<{
|
|
11
|
-
locator: {
|
|
12
|
-
by: "testId";
|
|
13
|
-
value: string;
|
|
14
|
-
} | {
|
|
15
|
-
by: "role";
|
|
16
|
-
role: string;
|
|
17
|
-
name?: string | undefined;
|
|
18
|
-
};
|
|
19
|
-
type: "assertNotChecked";
|
|
20
|
-
}>;
|
|
21
|
-
enabled(locator: AnyLocator): UnlabeledStep<{
|
|
22
|
-
locator: {
|
|
23
|
-
by: "testId";
|
|
24
|
-
value: string;
|
|
25
|
-
} | {
|
|
26
|
-
by: "role";
|
|
27
|
-
role: string;
|
|
28
|
-
name?: string | undefined;
|
|
29
|
-
};
|
|
30
|
-
type: "assertDisabled";
|
|
31
|
-
}>;
|
|
32
|
-
focused(locator: AnyLocator): UnlabeledStep<{
|
|
33
|
-
locator: {
|
|
34
|
-
by: "testId";
|
|
35
|
-
value: string;
|
|
36
|
-
} | {
|
|
37
|
-
by: "role";
|
|
38
|
-
role: string;
|
|
39
|
-
name?: string | undefined;
|
|
40
|
-
};
|
|
41
|
-
type: "assertNotFocused";
|
|
42
|
-
}>;
|
|
43
|
-
visible(locator: AnyLocator): UnlabeledStep<{
|
|
44
|
-
locator: {
|
|
45
|
-
by: "testId";
|
|
46
|
-
value: string;
|
|
47
|
-
} | {
|
|
48
|
-
by: "role";
|
|
49
|
-
role: string;
|
|
50
|
-
name?: string | undefined;
|
|
51
|
-
};
|
|
52
|
-
type: "assertNotVisible";
|
|
53
|
-
}>;
|
|
54
|
-
};
|
|
55
|
-
attribute(locator: AnyLocator, attribute: string, expected: StringOrVariable): UnlabeledStep<{
|
|
56
|
-
attribute: string;
|
|
57
|
-
expected: StaticStringRef | VariableRef;
|
|
58
|
-
locator: {
|
|
59
|
-
by: "testId";
|
|
60
|
-
value: string;
|
|
61
|
-
} | {
|
|
62
|
-
by: "role";
|
|
63
|
-
role: string;
|
|
64
|
-
name?: string | undefined;
|
|
65
|
-
};
|
|
66
|
-
operator: "equals";
|
|
67
|
-
type: "assertAttribute";
|
|
68
|
-
}>;
|
|
69
|
-
/**
|
|
70
|
-
* Verify a backend side effect by polling an observer. The server-side
|
|
71
|
-
* observer impl returns `ctx.retry(reason)` for transient states (keep
|
|
72
|
-
* polling) and `ctx.fail(reason)` only for invariant violations (stop
|
|
73
|
-
* early). The observer's `.budget()` governs poll interval and timeout.
|
|
74
|
-
*/
|
|
75
|
-
backend<THandle extends ObserverHandle>(observer: THandle, params: ObserverInput<THandle> & Record<string, Primitive>): UnlabeledStep<{
|
|
76
|
-
budget: ObserverBudgetTier;
|
|
77
|
-
observer: string;
|
|
78
|
-
params: Record<string, {
|
|
79
|
-
readonly type: "static";
|
|
80
|
-
readonly value: Primitive;
|
|
81
|
-
}>;
|
|
82
|
-
type: "assertObserver";
|
|
83
|
-
}>;
|
|
84
|
-
checked(locator: CheckLocator): UnlabeledStep<{
|
|
85
|
-
locator: {
|
|
86
|
-
by: "testId";
|
|
87
|
-
value: string;
|
|
88
|
-
} | {
|
|
89
|
-
by: "role";
|
|
90
|
-
role: string;
|
|
91
|
-
name?: string | undefined;
|
|
92
|
-
};
|
|
93
|
-
type: "assertChecked";
|
|
94
|
-
}>;
|
|
95
|
-
count(locator: AnyLocator, expected: number): UnlabeledStep<{
|
|
96
|
-
expected: {
|
|
97
|
-
type: "static";
|
|
98
|
-
value: number;
|
|
99
|
-
};
|
|
100
|
-
locator: {
|
|
101
|
-
by: "testId";
|
|
102
|
-
value: string;
|
|
103
|
-
} | {
|
|
104
|
-
by: "role";
|
|
105
|
-
role: string;
|
|
106
|
-
name?: string | undefined;
|
|
107
|
-
};
|
|
108
|
-
operator: "equals";
|
|
109
|
-
type: "assertCount";
|
|
110
|
-
}>;
|
|
111
|
-
disabled(locator: AnyLocator): UnlabeledStep<{
|
|
112
|
-
locator: {
|
|
113
|
-
by: "testId";
|
|
114
|
-
value: string;
|
|
115
|
-
} | {
|
|
116
|
-
by: "role";
|
|
117
|
-
role: string;
|
|
118
|
-
name?: string | undefined;
|
|
119
|
-
};
|
|
120
|
-
type: "assertDisabled";
|
|
121
|
-
}>;
|
|
122
|
-
enabled(locator: AnyLocator): UnlabeledStep<{
|
|
123
|
-
locator: {
|
|
124
|
-
by: "testId";
|
|
125
|
-
value: string;
|
|
126
|
-
} | {
|
|
127
|
-
by: "role";
|
|
128
|
-
role: string;
|
|
129
|
-
name?: string | undefined;
|
|
130
|
-
};
|
|
131
|
-
type: "assertEnabled";
|
|
132
|
-
}>;
|
|
133
|
-
focused(locator: AnyLocator): UnlabeledStep<{
|
|
134
|
-
locator: {
|
|
135
|
-
by: "testId";
|
|
136
|
-
value: string;
|
|
137
|
-
} | {
|
|
138
|
-
by: "role";
|
|
139
|
-
role: string;
|
|
140
|
-
name?: string | undefined;
|
|
141
|
-
};
|
|
142
|
-
type: "assertFocused";
|
|
143
|
-
}>;
|
|
144
|
-
text(locator: AnyLocator, expected: StringOrVariable): UnlabeledStep<{
|
|
145
|
-
expected: StaticStringRef | VariableRef;
|
|
146
|
-
locator: {
|
|
147
|
-
by: "testId";
|
|
148
|
-
value: string;
|
|
149
|
-
} | {
|
|
150
|
-
by: "role";
|
|
151
|
-
role: string;
|
|
152
|
-
name?: string | undefined;
|
|
153
|
-
};
|
|
154
|
-
operator: "equals";
|
|
155
|
-
type: "assertText";
|
|
156
|
-
}>;
|
|
157
|
-
url(expected: StringOrVariable): UnlabeledStep<{
|
|
158
|
-
expected: StaticStringRef | VariableRef;
|
|
159
|
-
operator: "contains";
|
|
160
|
-
type: "assertUrl";
|
|
161
|
-
}>;
|
|
162
|
-
value(locator: AnyLocator, expected: StringOrVariable): UnlabeledStep<{
|
|
163
|
-
expected: StaticStringRef | VariableRef;
|
|
164
|
-
locator: {
|
|
165
|
-
by: "testId";
|
|
166
|
-
value: string;
|
|
167
|
-
} | {
|
|
168
|
-
by: "role";
|
|
169
|
-
role: string;
|
|
170
|
-
name?: string | undefined;
|
|
171
|
-
};
|
|
172
|
-
operator: "equals";
|
|
173
|
-
type: "assertValue";
|
|
174
|
-
}>;
|
|
175
|
-
visible(locator: AnyLocator): UnlabeledStep<{
|
|
176
|
-
locator: {
|
|
177
|
-
by: "testId";
|
|
178
|
-
value: string;
|
|
179
|
-
} | {
|
|
180
|
-
by: "role";
|
|
181
|
-
role: string;
|
|
182
|
-
name?: string | undefined;
|
|
183
|
-
};
|
|
184
|
-
type: "assertVisible";
|
|
185
|
-
}>;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
export { assert };
|
package/dist/assert.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
readObserverBudget,
|
|
3
|
-
readObserverName
|
|
4
|
-
} from "./chunk-YQAEOH5W.js";
|
|
5
|
-
import {
|
|
6
|
-
toSpecLocator,
|
|
7
|
-
toStringValueRef
|
|
8
|
-
} from "./chunk-2YLI7VD4.js";
|
|
9
|
-
import "./chunk-DCJBLS2U.js";
|
|
10
|
-
import {
|
|
11
|
-
createStep
|
|
12
|
-
} from "./chunk-MGATMMCZ.js";
|
|
13
|
-
import "./chunk-4MGIQFAJ.js";
|
|
14
|
-
|
|
15
|
-
// src/steps/assert.ts
|
|
16
|
-
var assert = {
|
|
17
|
-
not: {
|
|
18
|
-
checked(locator) {
|
|
19
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertNotChecked" });
|
|
20
|
-
},
|
|
21
|
-
enabled(locator) {
|
|
22
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertDisabled" });
|
|
23
|
-
},
|
|
24
|
-
focused(locator) {
|
|
25
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertNotFocused" });
|
|
26
|
-
},
|
|
27
|
-
visible(locator) {
|
|
28
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertNotVisible" });
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
attribute(locator, attribute, expected) {
|
|
32
|
-
return createStep({
|
|
33
|
-
attribute,
|
|
34
|
-
expected: toStringValueRef(expected),
|
|
35
|
-
locator: toSpecLocator(locator),
|
|
36
|
-
operator: "equals",
|
|
37
|
-
type: "assertAttribute"
|
|
38
|
-
});
|
|
39
|
-
},
|
|
40
|
-
// eslint-disable-next-line no-comments/disallowComments
|
|
41
|
-
/**
|
|
42
|
-
* Verify a backend side effect by polling an observer. The server-side
|
|
43
|
-
* observer impl returns `ctx.retry(reason)` for transient states (keep
|
|
44
|
-
* polling) and `ctx.fail(reason)` only for invariant violations (stop
|
|
45
|
-
* early). The observer's `.budget()` governs poll interval and timeout.
|
|
46
|
-
*/
|
|
47
|
-
backend(observer, params) {
|
|
48
|
-
return createStep({
|
|
49
|
-
budget: readObserverBudget(observer),
|
|
50
|
-
observer: readObserverName(observer),
|
|
51
|
-
params: paramsToValueRefs(params),
|
|
52
|
-
type: "assertObserver"
|
|
53
|
-
});
|
|
54
|
-
},
|
|
55
|
-
checked(locator) {
|
|
56
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertChecked" });
|
|
57
|
-
},
|
|
58
|
-
count(locator, expected) {
|
|
59
|
-
return createStep({
|
|
60
|
-
expected: { type: "static", value: expected },
|
|
61
|
-
locator: toSpecLocator(locator),
|
|
62
|
-
operator: "equals",
|
|
63
|
-
type: "assertCount"
|
|
64
|
-
});
|
|
65
|
-
},
|
|
66
|
-
disabled(locator) {
|
|
67
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertDisabled" });
|
|
68
|
-
},
|
|
69
|
-
enabled(locator) {
|
|
70
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertEnabled" });
|
|
71
|
-
},
|
|
72
|
-
focused(locator) {
|
|
73
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertFocused" });
|
|
74
|
-
},
|
|
75
|
-
text(locator, expected) {
|
|
76
|
-
return createStep({
|
|
77
|
-
expected: toStringValueRef(expected),
|
|
78
|
-
locator: toSpecLocator(locator),
|
|
79
|
-
operator: "equals",
|
|
80
|
-
type: "assertText"
|
|
81
|
-
});
|
|
82
|
-
},
|
|
83
|
-
url(expected) {
|
|
84
|
-
return createStep({
|
|
85
|
-
expected: toStringValueRef(expected),
|
|
86
|
-
operator: "contains",
|
|
87
|
-
type: "assertUrl"
|
|
88
|
-
});
|
|
89
|
-
},
|
|
90
|
-
value(locator, expected) {
|
|
91
|
-
return createStep({
|
|
92
|
-
expected: toStringValueRef(expected),
|
|
93
|
-
locator: toSpecLocator(locator),
|
|
94
|
-
operator: "equals",
|
|
95
|
-
type: "assertValue"
|
|
96
|
-
});
|
|
97
|
-
},
|
|
98
|
-
visible(locator) {
|
|
99
|
-
return createStep({ locator: toSpecLocator(locator), type: "assertVisible" });
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
function paramsToValueRefs(params) {
|
|
103
|
-
const out = {};
|
|
104
|
-
Object.entries(params).forEach(([key, value]) => {
|
|
105
|
-
out[key] = { type: "static", value };
|
|
106
|
-
});
|
|
107
|
-
return out;
|
|
108
|
-
}
|
|
109
|
-
export {
|
|
110
|
-
assert
|
|
111
|
-
};
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { P as Primitive, O as ObserverHandle, h as Precondition, m as PreconditionData, j as TestDefinition, f as ObserverDefinition, l as PreconditionDefinition, U as UnimplementedItems, e as ObserverContext, g as ObserverOutcome, S as SetupContext, k as TestValue, T as TeardownContext } from './types-BzZrl65Z.js';
|
|
2
|
-
import { ObserverBudget } from '@ripplo/spec';
|
|
3
|
-
import { S as Step } from './step-De52hTLd.js';
|
|
4
|
-
|
|
5
|
-
interface ObserverNeedsDescription {
|
|
6
|
-
readonly description: (text: string) => ObserverNeedsBudget;
|
|
7
|
-
}
|
|
8
|
-
interface ObserverNeedsBudget {
|
|
9
|
-
/**
|
|
10
|
-
* Polling envelope: interval + total timeout the runner uses when calling
|
|
11
|
-
* `assert.backend()`. Pick by where the side effect lands — fast for
|
|
12
|
-
* same-request DB reads, slow for job-queue settle, async for
|
|
13
|
-
* webhook/email delivery. Too tight = flaky; too loose = slow suite.
|
|
14
|
-
*/
|
|
15
|
-
readonly budget: (tier: ObserverBudget) => ObserverNeedsInput;
|
|
16
|
-
}
|
|
17
|
-
interface ObserverNeedsInput {
|
|
18
|
-
readonly input: <TInput extends Record<string, Primitive>>() => ObserverReady<TInput>;
|
|
19
|
-
}
|
|
20
|
-
interface ObserverReady<TInput extends Record<string, Primitive>> {
|
|
21
|
-
readonly contract: () => ObserverHandle<TInput>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface CoverageRegistry {
|
|
25
|
-
}
|
|
26
|
-
type RegistryKeys = keyof CoverageRegistry;
|
|
27
|
-
type CoverageStatementId = [RegistryKeys] extends [never] ? string : Extract<RegistryKeys, string>;
|
|
28
|
-
|
|
29
|
-
type PreconditionRecord = Record<string, Precondition>;
|
|
30
|
-
type ResolveDeps<TDeps extends PreconditionRecord> = {
|
|
31
|
-
readonly [K in keyof TDeps]: PreconditionData<TDeps[K]>;
|
|
32
|
-
};
|
|
33
|
-
interface PreconditionNeedsSetup {
|
|
34
|
-
readonly contract: <TData extends Record<string, Primitive>>() => Precondition<TData>;
|
|
35
|
-
readonly description: (text: string) => PreconditionNeedsSetup;
|
|
36
|
-
readonly requires: <TDeps extends PreconditionRecord>(deps: TDeps) => PreconditionNeedsSetupWithDeps<TDeps>;
|
|
37
|
-
}
|
|
38
|
-
interface PreconditionNeedsSetupWithDeps<TDeps extends PreconditionRecord> {
|
|
39
|
-
readonly contract: <TData extends Record<string, Primitive>>() => Precondition<TData, ResolveDeps<TDeps>>;
|
|
40
|
-
}
|
|
41
|
-
interface TestNeedsName {
|
|
42
|
-
readonly name: (displayName: string) => TestNeedsRequires;
|
|
43
|
-
}
|
|
44
|
-
interface TestNeedsRequires {
|
|
45
|
-
readonly description: (text: string) => TestNeedsRequires;
|
|
46
|
-
/**
|
|
47
|
-
* Declare the preconditions this test needs. The object keys become the
|
|
48
|
-
* destructured parameter in `.startsAt` / `.steps`, and each precondition's
|
|
49
|
-
* return data flows through as a typed proxy — interpolate proxy fields
|
|
50
|
-
* directly (e.g. `` `/workspaces/${workspace.id}` ``); never hand-write
|
|
51
|
-
* `{{namespace.key}}` template strings (lint blocks this).
|
|
52
|
-
*/
|
|
53
|
-
readonly requires: <TReqs extends PreconditionRecord>(reqs: TReqs) => TestNeedsOutcome<ResolveDeps<TReqs>>;
|
|
54
|
-
}
|
|
55
|
-
interface TestNeedsOutcome<TVars extends Record<string, Record<string, Primitive>>> {
|
|
56
|
-
readonly expectedOutcome: (text: string) => TestNeedsStartsAt<TVars>;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
interface TestNeedsStartsAt<TVars extends Record<string, Record<string, Primitive>>> {
|
|
60
|
-
/**
|
|
61
|
-
* Skip implementation — compiles as a planning stub and is reported in
|
|
62
|
-
* `getUnimplemented()`. The test appears in the lockfile but is not run.
|
|
63
|
-
*/
|
|
64
|
-
readonly notImplemented: () => TestDefinition;
|
|
65
|
-
/**
|
|
66
|
-
* Starting URL for the test, derived from precondition data. The function
|
|
67
|
-
* receives the `.requires()` object destructured as typed proxies; it runs
|
|
68
|
-
* at compile time, not at test-author time.
|
|
69
|
-
*/
|
|
70
|
-
readonly startsAt: (fn: (vars: TVars) => string) => TestNeedsSteps<TVars>;
|
|
71
|
-
}
|
|
72
|
-
interface TestNeedsSteps<TVars extends Record<string, Record<string, Primitive>>> {
|
|
73
|
-
/**
|
|
74
|
-
* Declare the ordered step list. Receives destructured precondition data as
|
|
75
|
-
* typed proxies (same as `.startsAt`). Every step must be labeled with
|
|
76
|
-
* `.as("…")` — lint enforces it.
|
|
77
|
-
*/
|
|
78
|
-
readonly steps: (fn: (vars: TVars) => ReadonlyArray<Step>) => TestNeedsCoverage;
|
|
79
|
-
}
|
|
80
|
-
interface TestNeedsCoverage {
|
|
81
|
-
/**
|
|
82
|
-
* Finalize the test and declare which mutation/AST branches it covers.
|
|
83
|
-
* Coverage IDs feed LLM-driven test scoping on diffs so only relevant tests
|
|
84
|
-
* run for a change. `.coverage()` (or `.notImplemented()`) is the only way
|
|
85
|
-
* to terminate the chain into a runnable `TestDefinition`.
|
|
86
|
-
*/
|
|
87
|
-
readonly coverage: (...ids: ReadonlyArray<CoverageStatementId>) => TestDefinition;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
type PreconditionSetupResult<TData extends Record<string, Primitive>> = {
|
|
91
|
-
readonly [K in keyof TData]: TestValue<TData[K]>;
|
|
92
|
-
};
|
|
93
|
-
interface PreconditionSetupItem<TDeps extends Record<string, Record<string, Primitive>>> {
|
|
94
|
-
readonly ctx: SetupContext;
|
|
95
|
-
readonly deps: TDeps;
|
|
96
|
-
}
|
|
97
|
-
interface PreconditionTeardownItem<TData extends Record<string, Primitive>> {
|
|
98
|
-
readonly ctx: TeardownContext<TData>;
|
|
99
|
-
}
|
|
100
|
-
interface PreconditionImpl<TData extends Record<string, Primitive>, TDeps extends Record<string, Record<string, Primitive>>> {
|
|
101
|
-
readonly setup: (items: ReadonlyArray<PreconditionSetupItem<TDeps>>) => Promise<ReadonlyArray<PreconditionSetupResult<TData>>>;
|
|
102
|
-
readonly teardown: (items: ReadonlyArray<PreconditionTeardownItem<TData>>) => Promise<void>;
|
|
103
|
-
}
|
|
104
|
-
type ObserverImplFn<TInput extends Record<string, Primitive>> = (ctx: ObserverContext, params: TInput) => Promise<ObserverOutcome>;
|
|
105
|
-
interface TestOptions {
|
|
106
|
-
readonly uiOnly?: boolean;
|
|
107
|
-
}
|
|
108
|
-
type PreconditionRegistry = Record<string, Precondition>;
|
|
109
|
-
type ObserverRegistry = Record<string, ObserverHandle<Record<string, Primitive>>>;
|
|
110
|
-
interface RipploRegistries<P extends PreconditionRegistry, O extends ObserverRegistry> {
|
|
111
|
-
readonly observers: O;
|
|
112
|
-
readonly preconditions: P;
|
|
113
|
-
readonly tests: ReadonlyArray<TestDefinition>;
|
|
114
|
-
}
|
|
115
|
-
interface RipploInstance<P extends PreconditionRegistry = PreconditionRegistry, O extends ObserverRegistry = ObserverRegistry> {
|
|
116
|
-
readonly observers: O;
|
|
117
|
-
readonly preconditions: P;
|
|
118
|
-
readonly tests: ReadonlyArray<TestDefinition>;
|
|
119
|
-
readonly getObservers: () => ReadonlyArray<ObserverDefinition>;
|
|
120
|
-
readonly getPreconditions: () => ReadonlyArray<PreconditionDefinition>;
|
|
121
|
-
readonly getTests: () => ReadonlyArray<TestDefinition>;
|
|
122
|
-
readonly getUnimplemented: () => UnimplementedItems;
|
|
123
|
-
}
|
|
124
|
-
type RipploBuilder = RipploInstance;
|
|
125
|
-
/**
|
|
126
|
-
* Declare a precondition — a named, reusable piece of test data setup. Returns
|
|
127
|
-
* a pure handle (no side effects at definition time); the setup/teardown impl
|
|
128
|
-
* is wired once in `createEngine`. Depend on other preconditions via
|
|
129
|
-
* `.requires()` so the DAG can resolve independents in parallel, giving every
|
|
130
|
-
* test a clean, isolated slate.
|
|
131
|
-
*/
|
|
132
|
-
declare function precondition(name: string): PreconditionNeedsSetup;
|
|
133
|
-
/**
|
|
134
|
-
* Declare a backend assertion — checked from tests via `assert.backend()`.
|
|
135
|
-
* The impl runs on your server (where DB/queue access lives) and is polled
|
|
136
|
-
* until pass/fail; `.budget()` picks the polling envelope. Use this instead
|
|
137
|
-
* of sleeps when verifying async side effects (jobs, webhooks, emails, DB rows).
|
|
138
|
-
*/
|
|
139
|
-
declare function observer(name: string): ObserverNeedsDescription;
|
|
140
|
-
/**
|
|
141
|
-
* Start a test definition. `id` is a stable kebab-case key persisted in the
|
|
142
|
-
* lockfile and used for run history — changing it renames the test and loses
|
|
143
|
-
* history. Set `options.uiOnly` only for genuinely read-only flows (no
|
|
144
|
-
* mutations); do not use it to silence observer lint on flows that mutate
|
|
145
|
-
* state — wire the observer instead.
|
|
146
|
-
*/
|
|
147
|
-
declare function test(id: string, options?: TestOptions): TestNeedsName;
|
|
148
|
-
/**
|
|
149
|
-
* The single registration point for the DSL graph. Collects the three
|
|
150
|
-
* registries into an instance consumed both by `ripplo compile` (to write
|
|
151
|
-
* `.ripplo/ripplo.lock`) and by `createEngine` on the server, where
|
|
152
|
-
* TypeScript exhaustiveness-checks that every handle has exactly one impl.
|
|
153
|
-
*/
|
|
154
|
-
declare function createRipplo<P extends PreconditionRegistry, O extends ObserverRegistry>(registries: RipploRegistries<P, O>): RipploInstance<P, O>;
|
|
155
|
-
|
|
156
|
-
export { type CoverageRegistry as C, type ObserverImplFn as O, type PreconditionImpl as P, type ResolveDeps as R, type ObserverRegistry as a, type PreconditionRecord as b, type PreconditionRegistry as c, type PreconditionSetupItem as d, type PreconditionTeardownItem as e, type RipploBuilder as f, type RipploInstance as g, type RipploRegistries as h, createRipplo as i, observer as o, precondition as p, test as t };
|
package/dist/chunk-2YLI7VD4.js
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
readLocator
|
|
3
|
-
} from "./chunk-DCJBLS2U.js";
|
|
4
|
-
import {
|
|
5
|
-
createStep
|
|
6
|
-
} from "./chunk-MGATMMCZ.js";
|
|
7
|
-
|
|
8
|
-
// src/steps/to-spec-locator.ts
|
|
9
|
-
function toSpecLocator(loc) {
|
|
10
|
-
const spec = readLocator(loc);
|
|
11
|
-
switch (spec.by) {
|
|
12
|
-
case "role": {
|
|
13
|
-
return { by: "role", name: spec.name, role: spec.role };
|
|
14
|
-
}
|
|
15
|
-
case "testId": {
|
|
16
|
-
return { by: "testId", value: spec.value };
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// src/steps/control.ts
|
|
22
|
-
function variable(name) {
|
|
23
|
-
return { name };
|
|
24
|
-
}
|
|
25
|
-
function readVariable(v) {
|
|
26
|
-
return v.name;
|
|
27
|
-
}
|
|
28
|
-
function isVariable(v) {
|
|
29
|
-
if (typeof v !== "object" || v == null) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
if (!("name" in v)) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
return typeof v.name === "string";
|
|
36
|
-
}
|
|
37
|
-
function toStringValueRef(value) {
|
|
38
|
-
if (typeof value === "string") {
|
|
39
|
-
return { type: "static", value };
|
|
40
|
-
}
|
|
41
|
-
if (!isVariable(value)) {
|
|
42
|
-
const raw = value;
|
|
43
|
-
const got = raw == null ? String(raw) : typeof raw;
|
|
44
|
-
throw new TypeError(
|
|
45
|
-
`Expected a string or variable() \u2014 got ${got}. Wrap dynamic values with variable("name") and pair them with extract().`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
return { name: readVariable(value), type: "variable" };
|
|
49
|
-
}
|
|
50
|
-
function extract(locator, target) {
|
|
51
|
-
return createStep({
|
|
52
|
-
locator: toSpecLocator(locator),
|
|
53
|
-
type: "extractText",
|
|
54
|
-
variable: readVariable(target)
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export {
|
|
59
|
-
toSpecLocator,
|
|
60
|
-
variable,
|
|
61
|
-
readVariable,
|
|
62
|
-
isVariable,
|
|
63
|
-
toStringValueRef,
|
|
64
|
-
extract
|
|
65
|
-
};
|
package/dist/chunk-4MGIQFAJ.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
-
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
-
if (decorator = decorators[i])
|
|
7
|
-
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
-
if (kind && result) __defProp(target, key, result);
|
|
9
|
-
return result;
|
|
10
|
-
};
|
|
11
|
-
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
12
|
-
|
|
13
|
-
export {
|
|
14
|
-
__decorateClass,
|
|
15
|
-
__decorateParam
|
|
16
|
-
};
|
package/dist/chunk-DCJBLS2U.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// src/locators.ts
|
|
2
|
-
function readLocator(loc) {
|
|
3
|
-
return loc.spec;
|
|
4
|
-
}
|
|
5
|
-
function makeLocator(spec) {
|
|
6
|
-
return { spec };
|
|
7
|
-
}
|
|
8
|
-
function role(ariaRole, name) {
|
|
9
|
-
return makeLocator({
|
|
10
|
-
by: "role",
|
|
11
|
-
name: name ?? void 0,
|
|
12
|
-
role: ariaRole
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
function testId(id) {
|
|
16
|
-
return makeLocator({
|
|
17
|
-
by: "testId",
|
|
18
|
-
value: id
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export {
|
|
23
|
-
readLocator,
|
|
24
|
-
role,
|
|
25
|
-
testId
|
|
26
|
-
};
|
package/dist/chunk-MGATMMCZ.js
DELETED
package/dist/chunk-XO36IU66.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
// src/adapters/shared.ts
|
|
2
|
-
import { Webhook, WebhookVerificationError } from "standardwebhooks";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
function readAdapterWebhookSecret() {
|
|
5
|
-
const value = process.env.RIPPLO_WEBHOOK_SECRET;
|
|
6
|
-
if (value == null || value.length === 0) {
|
|
7
|
-
throw new Error(
|
|
8
|
-
"ripplo: RIPPLO_WEBHOOK_SECRET is not set. The adapter needs it to verify precondition calls. Run `ripplo init` to generate one, or unset `enabled` to disable the adapter."
|
|
9
|
-
);
|
|
10
|
-
}
|
|
11
|
-
return value;
|
|
12
|
-
}
|
|
13
|
-
var primitiveSchema = z.union([z.string(), z.number(), z.boolean()]);
|
|
14
|
-
var dataSchema = z.record(z.string(), z.record(z.string(), primitiveSchema));
|
|
15
|
-
var batchRequestSchema = z.object({
|
|
16
|
-
batch: z.array(
|
|
17
|
-
z.object({
|
|
18
|
-
preconditions: z.array(z.string().min(1)),
|
|
19
|
-
runId: z.string().min(1)
|
|
20
|
-
})
|
|
21
|
-
).min(1)
|
|
22
|
-
});
|
|
23
|
-
var teardownRequestSchema = z.object({
|
|
24
|
-
batch: z.array(
|
|
25
|
-
z.object({
|
|
26
|
-
data: dataSchema,
|
|
27
|
-
preconditions: z.array(z.string().min(1)),
|
|
28
|
-
runId: z.string().min(1)
|
|
29
|
-
})
|
|
30
|
-
).min(1)
|
|
31
|
-
});
|
|
32
|
-
var observerRequestSchema = z.object({
|
|
33
|
-
observer: z.string().min(1).max(200),
|
|
34
|
-
params: z.record(z.string().max(200), primitiveSchema)
|
|
35
|
-
});
|
|
36
|
-
function verifyWebhookSignature(payload, headers, secret) {
|
|
37
|
-
try {
|
|
38
|
-
const wh = new Webhook(secret);
|
|
39
|
-
wh.verify(payload, {
|
|
40
|
-
"webhook-id": headers["webhook-id"] ?? "",
|
|
41
|
-
"webhook-signature": headers["webhook-signature"] ?? "",
|
|
42
|
-
"webhook-timestamp": headers["webhook-timestamp"] ?? ""
|
|
43
|
-
});
|
|
44
|
-
return true;
|
|
45
|
-
} catch (error) {
|
|
46
|
-
if (error instanceof WebhookVerificationError) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function serializeCookie(cookie) {
|
|
53
|
-
return {
|
|
54
|
-
domain: cookie.options?.domain,
|
|
55
|
-
expires: cookie.options?.expires,
|
|
56
|
-
httpOnly: cookie.options?.httpOnly,
|
|
57
|
-
name: cookie.name,
|
|
58
|
-
path: cookie.options?.path,
|
|
59
|
-
sameSite: cookie.options?.sameSite,
|
|
60
|
-
secure: cookie.options?.secure,
|
|
61
|
-
value: cookie.value
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function toBatchRunResults(results) {
|
|
65
|
-
return results.map(
|
|
66
|
-
(r) => r.success ? {
|
|
67
|
-
cookies: r.cookies.map((c) => serializeCookie(c)),
|
|
68
|
-
data: r.data,
|
|
69
|
-
executed: [...r.executed],
|
|
70
|
-
ok: true,
|
|
71
|
-
runId: r.runId
|
|
72
|
-
} : { error: r.error ?? "unknown error", ok: false, runId: r.runId }
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
function toTeardownResults(results) {
|
|
76
|
-
return results.map((r) => ({ error: r.error, ok: r.success, runId: r.runId }));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export {
|
|
80
|
-
readAdapterWebhookSecret,
|
|
81
|
-
batchRequestSchema,
|
|
82
|
-
teardownRequestSchema,
|
|
83
|
-
observerRequestSchema,
|
|
84
|
-
verifyWebhookSignature,
|
|
85
|
-
serializeCookie,
|
|
86
|
-
toBatchRunResults,
|
|
87
|
-
toTeardownResults
|
|
88
|
-
};
|