@elench/testkit 0.1.81 → 0.1.83
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 +64 -27
- package/lib/cli/agents/index.mjs +64 -0
- package/lib/cli/agents/investigate.mjs +75 -0
- package/lib/cli/agents/investigation-context.mjs +102 -0
- package/lib/cli/agents/investigation-context.test.mjs +144 -0
- package/lib/cli/agents/prompt-builder.mjs +25 -0
- package/lib/cli/agents/providers/claude.mjs +74 -0
- package/lib/cli/agents/providers/claude.test.mjs +95 -0
- package/lib/cli/agents/providers/codex.mjs +83 -0
- package/lib/cli/agents/providers/codex.test.mjs +93 -0
- package/lib/cli/agents/providers/shared.mjs +134 -0
- package/lib/cli/command-helpers.mjs +53 -25
- package/lib/cli/command-helpers.test.mjs +122 -0
- package/lib/cli/commands/investigate.mjs +87 -0
- package/lib/cli/commands/investigate.test.mjs +83 -0
- package/lib/cli/entrypoint.mjs +3 -0
- package/lib/cli/presentation/colors.mjs +12 -0
- package/lib/cli/presentation/events-reporter.mjs +135 -0
- package/lib/cli/presentation/events-reporter.test.mjs +73 -0
- package/lib/cli/presentation/summary-box.mjs +11 -11
- package/lib/cli/presentation/summary-box.test.mjs +17 -0
- package/lib/cli/presentation/tree-reporter.mjs +159 -0
- package/lib/cli/presentation/tree-reporter.test.mjs +166 -0
- package/lib/cli/tui/run-app.mjs +1 -0
- package/lib/cli/tui/run-session-app.mjs +370 -0
- package/lib/cli/tui/run-session-app.test.mjs +50 -0
- package/lib/cli/tui/run-session-state.mjs +481 -0
- package/lib/cli/tui/run-tree-state.mjs +1 -0
- package/lib/cli/tui/run-tree-state.test.mjs +324 -0
- package/lib/config-api/auth-fixtures.mjs +767 -0
- package/lib/config-api/index.d.ts +92 -108
- package/lib/config-api/index.mjs +22 -12
- package/lib/config-api/index.test.mjs +103 -210
- package/lib/discovery/index.mjs +1 -1
- package/lib/index.d.ts +34 -10
- package/lib/runner/orchestrator.mjs +1 -0
- package/lib/runtime/index.d.ts +177 -27
- package/lib/runtime/index.mjs +68 -3
- package/lib/runtime-src/k6/http-assertions.js +31 -1
- package/lib/runtime-src/k6/http-checks.js +120 -0
- package/lib/runtime-src/k6/http-checks.test.mjs +120 -0
- package/lib/runtime-src/k6/http-suite-runtime.js +151 -0
- package/lib/runtime-src/k6/http.js +285 -56
- package/lib/runtime-src/k6/http.test.mjs +205 -0
- package/lib/runtime-src/k6/scenario-suite.js +13 -110
- package/lib/runtime-src/k6/suite.js +13 -107
- package/lib/runtime-src/shared/error-body.mjs +42 -0
- package/lib/runtime-src/shared/http-parsing.mjs +68 -0
- package/lib/runtime-src/shared/http-parsing.test.mjs +69 -0
- package/node_modules/@elench/next-analysis/package.json +1 -1
- package/node_modules/@elench/testkit-bridge/package.json +2 -2
- package/node_modules/@elench/testkit-protocol/package.json +1 -1
- package/node_modules/@elench/ts-analysis/package.json +1 -1
- package/package.json +5 -5
- package/lib/config-api/profiles.mjs +0 -640
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import {
|
|
3
|
+
auth,
|
|
3
4
|
app,
|
|
4
5
|
database,
|
|
5
6
|
defineConfig,
|
|
6
7
|
defineFile,
|
|
7
|
-
profiles,
|
|
8
8
|
toolchain,
|
|
9
9
|
} from "./index.mjs";
|
|
10
10
|
import { clearRuntimeContext, registerRuntimeContext } from "./runtime.mjs";
|
|
@@ -16,27 +16,7 @@ describe("config api", () => {
|
|
|
16
16
|
});
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
it("builds
|
|
20
|
-
const profile = profiles.raw({
|
|
21
|
-
headers: {
|
|
22
|
-
contentTypeJson: true,
|
|
23
|
-
forwardedFor: "deterministic",
|
|
24
|
-
values: { "X-Testkit-Mode": "raw" },
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const headers = profile.headers?.(null, { env: { BASE: "http://api.test" } });
|
|
29
|
-
const rawHeaders = profile.rawHeaders?.(null, { env: { BASE: "http://api.test" } });
|
|
30
|
-
|
|
31
|
-
expect(headers).toMatchObject({
|
|
32
|
-
"Content-Type": "application/json",
|
|
33
|
-
"X-Testkit-Mode": "raw",
|
|
34
|
-
});
|
|
35
|
-
expect(headers["X-Forwarded-For"]).toMatch(/^10\.\d+\.\d+\.\d+$/);
|
|
36
|
-
expect(rawHeaders).toEqual(headers);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("builds session profiles that perform bootstrap/login and derive auth/session headers", () => {
|
|
19
|
+
it("builds generated auth fixture profiles with actor-aware sessions and headers", () => {
|
|
40
20
|
const requests = [];
|
|
41
21
|
registerRuntimeContext({
|
|
42
22
|
env: {
|
|
@@ -45,100 +25,13 @@ describe("config api", () => {
|
|
|
45
25
|
},
|
|
46
26
|
http: {
|
|
47
27
|
post(url, body, params) {
|
|
48
|
-
requests.push({ url, body, params });
|
|
49
|
-
if (url.endsWith("/signup")) {
|
|
50
|
-
return {
|
|
51
|
-
status: 201,
|
|
52
|
-
body: JSON.stringify({ data: { organizations: [{ id: "org-signup" }] } }),
|
|
53
|
-
headers: {
|
|
54
|
-
"set-cookie": ["fixture_session=signup-token; Path=/", "fixture_refresh=signup-refresh; Path=/"],
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
status: 200,
|
|
60
|
-
body: JSON.stringify({ data: { organizations: [{ id: "org-123" }] } }),
|
|
61
|
-
headers: {
|
|
62
|
-
"set-cookie": ["fixture_session=jwt-123; Path=/", "fixture_refresh=refresh-123; Path=/"],
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
const profile = profiles.session({
|
|
70
|
-
actor: {
|
|
71
|
-
bootstrap: {
|
|
72
|
-
path: "/signup",
|
|
73
|
-
expect: [201, 409],
|
|
74
|
-
body: ({ actor }) => ({ email: `${actor}@example.com` }),
|
|
75
|
-
},
|
|
76
|
-
login: {
|
|
77
|
-
path: "/login",
|
|
78
|
-
expect: 200,
|
|
79
|
-
body: ({ actor }) => ({ email: `${actor}@example.com` }),
|
|
80
|
-
},
|
|
81
|
-
session: {
|
|
82
|
-
cookies: {
|
|
83
|
-
jwt: "fixture_session",
|
|
84
|
-
refreshToken: "fixture_refresh",
|
|
85
|
-
},
|
|
86
|
-
fields: {
|
|
87
|
-
organizationId: "data.organizations[0].id",
|
|
88
|
-
},
|
|
89
|
-
auth: {
|
|
90
|
-
source: { key: "jwt" },
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
headers: {
|
|
95
|
-
contentTypeJson: true,
|
|
96
|
-
forwardedFor: "deterministic",
|
|
97
|
-
fromSession: [{ header: "X-Organization-Id", field: "organizationId" }],
|
|
98
|
-
values: ({ actor }) => ({ "X-Testkit-Actor": actor || "primary" }),
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const session = profile.auth.setup({
|
|
103
|
-
env: { BASE: "http://api.test", routeParams: { "x-route": "route-a" } },
|
|
104
|
-
});
|
|
105
|
-
const authHeaders = profile.auth.headers(session, { env: { BASE: "http://api.test" } });
|
|
106
|
-
const requestHeaders = profile.headers(session, { env: { BASE: "http://api.test" } });
|
|
107
|
-
|
|
108
|
-
expect(requests).toHaveLength(2);
|
|
109
|
-
expect(requests[0].params.headers["x-route"]).toBe("route-a");
|
|
110
|
-
expect(session).toEqual({
|
|
111
|
-
jwt: "jwt-123",
|
|
112
|
-
refreshToken: "refresh-123",
|
|
113
|
-
organizationId: "org-123",
|
|
114
|
-
});
|
|
115
|
-
expect(authHeaders).toEqual({
|
|
116
|
-
Authorization: "Bearer jwt-123",
|
|
117
|
-
});
|
|
118
|
-
expect(requestHeaders).toMatchObject({
|
|
119
|
-
"Content-Type": "application/json",
|
|
120
|
-
"X-Organization-Id": "org-123",
|
|
121
|
-
"X-Testkit-Actor": "primary",
|
|
122
|
-
});
|
|
123
|
-
expect(requestHeaders["X-Forwarded-For"]).toMatch(/^10\.\d+\.\d+\.\d+$/);
|
|
124
|
-
clearRuntimeContext();
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it("builds local-json profile presets that derive session, multi-actor, and raw variants", () => {
|
|
128
|
-
const requests = [];
|
|
129
|
-
registerRuntimeContext({
|
|
130
|
-
env: {
|
|
131
|
-
BASE: "http://api.test",
|
|
132
|
-
},
|
|
133
|
-
http: {
|
|
134
|
-
post(url, body) {
|
|
135
28
|
const payload = JSON.parse(body);
|
|
136
|
-
requests.push({ url, payload });
|
|
137
|
-
const actor = payload.email.
|
|
138
|
-
? "
|
|
139
|
-
: payload.email.
|
|
140
|
-
? "
|
|
141
|
-
: "
|
|
29
|
+
requests.push({ url, payload, params });
|
|
30
|
+
const actor = payload.email.includes(".user-a@")
|
|
31
|
+
? "userA"
|
|
32
|
+
: payload.email.includes(".user-b@")
|
|
33
|
+
? "userB"
|
|
34
|
+
: "primary";
|
|
142
35
|
return {
|
|
143
36
|
status: url.endsWith("/signup") ? 201 : 200,
|
|
144
37
|
body: JSON.stringify({
|
|
@@ -157,68 +50,71 @@ describe("config api", () => {
|
|
|
157
50
|
},
|
|
158
51
|
});
|
|
159
52
|
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
identities: {
|
|
163
|
-
primary: {
|
|
164
|
-
email: "primary@example.com",
|
|
165
|
-
name: "Primary User",
|
|
166
|
-
organizationName: "Primary Org",
|
|
167
|
-
},
|
|
168
|
-
userA: {
|
|
169
|
-
email: "user-a@example.com",
|
|
170
|
-
name: "User A",
|
|
171
|
-
organizationName: "Org A",
|
|
172
|
-
},
|
|
173
|
-
userB: {
|
|
174
|
-
email: "user-b@example.com",
|
|
175
|
-
name: "User B",
|
|
176
|
-
organizationName: "Org B",
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
session: {
|
|
53
|
+
const fixture = auth.fixture({
|
|
54
|
+
contract: auth.contracts.jsonSession({
|
|
180
55
|
authCookie: "fixture_session",
|
|
181
56
|
refreshCookie: "fixture_refresh",
|
|
182
57
|
organizationIdPath: "data.organizations[0].id",
|
|
183
|
-
},
|
|
184
|
-
headers: {
|
|
185
|
-
contentTypeJson: true,
|
|
186
58
|
forwardedFor: "deterministic",
|
|
187
|
-
|
|
188
|
-
},
|
|
59
|
+
organizationHeader: "X-Organization-Id",
|
|
60
|
+
}),
|
|
61
|
+
topology: auth.topologies.crossOrg({
|
|
62
|
+
namespace: "fixture",
|
|
63
|
+
actors: {
|
|
64
|
+
primary: { org: "primary" },
|
|
65
|
+
userA: { org: "primary" },
|
|
66
|
+
userB: { org: "secondary" },
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
189
69
|
});
|
|
190
70
|
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
71
|
+
const builtProfiles = fixture.profiles({
|
|
72
|
+
default: auth.profile.actor("primary", {
|
|
73
|
+
headers: {
|
|
74
|
+
values: ({ actor }) => ({ "X-Testkit-Actor": actor || "primary" }),
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
dual: auth.profile.actors({
|
|
78
|
+
primaryActor: "userA",
|
|
79
|
+
actors: ["userA", "userB"],
|
|
80
|
+
}),
|
|
81
|
+
raw: auth.profile.raw({
|
|
82
|
+
headers: {
|
|
83
|
+
values: {
|
|
84
|
+
"X-Testkit-Mode": "raw",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
197
88
|
});
|
|
198
|
-
|
|
89
|
+
|
|
90
|
+
expect(fixture.topology.actors.primary.email).toBe("testkit+fixture.primary@example.test");
|
|
91
|
+
expect(fixture.topology.actors.userA.name).toBe("Testkit Fixture User A");
|
|
92
|
+
expect(fixture.topology.actors.userB.organizationName).toBe("Testkit Fixture Secondary Org");
|
|
93
|
+
|
|
94
|
+
const defaultSetup = builtProfiles.default.auth.setup({ env: { BASE: "http://api.test", routeParams: { "x-route": "route-a" } } });
|
|
95
|
+
expect(defaultSetup.actors.primary.organizationId).toBe("org-primary");
|
|
96
|
+
expect(builtProfiles.default.auth.headers(defaultSetup, { env: { BASE: "http://api.test" } })).toEqual({
|
|
199
97
|
Authorization: "Bearer jwt-primary",
|
|
200
98
|
});
|
|
201
|
-
expect(
|
|
99
|
+
expect(builtProfiles.default.headers(defaultSetup, { env: { BASE: "http://api.test" } })).toMatchObject({
|
|
202
100
|
"Content-Type": "application/json",
|
|
203
101
|
"X-Organization-Id": "org-primary",
|
|
102
|
+
"X-Testkit-Actor": "primary",
|
|
204
103
|
});
|
|
205
104
|
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const dualSetup = dualProfile.auth.setup({ env: { BASE: "http://api.test" } });
|
|
211
|
-
expect(dualSetup.userA.organizationId).toBe("org-userA");
|
|
212
|
-
expect(dualSetup.userB.organizationId).toBe("org-userB");
|
|
213
|
-
expect(dualProfile.auth.headers(dualSetup)).toEqual({
|
|
105
|
+
const dualSetup = builtProfiles.dual.auth.setup({ env: { BASE: "http://api.test" } });
|
|
106
|
+
expect(dualSetup.actors.userA.organizationId).toBe("org-userA");
|
|
107
|
+
expect(dualSetup.actors.userB.organizationId).toBe("org-userB");
|
|
108
|
+
expect(builtProfiles.dual.auth.headers(dualSetup)).toEqual({
|
|
214
109
|
Authorization: "Bearer jwt-userA",
|
|
215
110
|
});
|
|
216
111
|
|
|
217
|
-
|
|
218
|
-
expect(rawProfile.rawHeaders(null, { env: { BASE: "http://api.test" } })).toMatchObject({
|
|
112
|
+
expect(builtProfiles.raw.rawHeaders(null, { env: { BASE: "http://api.test" } })).toMatchObject({
|
|
219
113
|
"Content-Type": "application/json",
|
|
114
|
+
"X-Testkit-Mode": "raw",
|
|
220
115
|
});
|
|
221
116
|
|
|
117
|
+
expect(requests[0].params.headers["x-route"]).toBe("route-a");
|
|
222
118
|
expect(requests.map((entry) => entry.url)).toEqual([
|
|
223
119
|
"http://api.test/api/v1/auth/signup",
|
|
224
120
|
"http://api.test/api/v1/auth/login",
|
|
@@ -230,71 +126,68 @@ describe("config api", () => {
|
|
|
230
126
|
clearRuntimeContext();
|
|
231
127
|
});
|
|
232
128
|
|
|
233
|
-
it("builds
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
};
|
|
129
|
+
it("builds a single-org topology with deterministic defaults", () => {
|
|
130
|
+
const topology = auth.topologies.singleOrg({
|
|
131
|
+
namespace: "sample-app",
|
|
132
|
+
actors: ["primary", "reviewer"],
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
expect(topology.actors.primary.email).toBe("testkit+sample-app.primary@example.test");
|
|
136
|
+
expect(topology.actors.reviewer.name).toBe("Testkit Sample App Reviewer");
|
|
137
|
+
expect(topology.actors.primary.organizationName).toBe("Testkit Sample App Primary Org");
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("treats signup as best-effort when login still succeeds", () => {
|
|
246
141
|
registerRuntimeContext({
|
|
247
142
|
env: {
|
|
248
143
|
BASE: "http://api.test",
|
|
144
|
+
routeParams: {},
|
|
249
145
|
},
|
|
250
146
|
http: {
|
|
251
|
-
post(
|
|
147
|
+
post(url, body) {
|
|
252
148
|
const payload = JSON.parse(body);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
149
|
+
if (url.endsWith("/signup")) {
|
|
150
|
+
return {
|
|
151
|
+
status: 500,
|
|
152
|
+
body: JSON.stringify({ error: "Failed to create account" }),
|
|
153
|
+
headers: {},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
257
156
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
auth: { source: { key: "jwt" } },
|
|
270
|
-
},
|
|
271
|
-
},
|
|
272
|
-
userB: {
|
|
273
|
-
login: {
|
|
274
|
-
path: "/login",
|
|
275
|
-
body: () => ({ email: "beta@example.com" }),
|
|
276
|
-
},
|
|
277
|
-
session: {
|
|
278
|
-
cookies: { jwt: "fixture_session" },
|
|
279
|
-
fields: { organizationId: "data.organizations[0].id" },
|
|
280
|
-
auth: { source: { key: "jwt" } },
|
|
281
|
-
},
|
|
157
|
+
return {
|
|
158
|
+
status: 200,
|
|
159
|
+
body: JSON.stringify({
|
|
160
|
+
data: {
|
|
161
|
+
organizations: [{ id: "org-primary" }],
|
|
162
|
+
},
|
|
163
|
+
}),
|
|
164
|
+
headers: {
|
|
165
|
+
"set-cookie": ["fixture_session=jwt-primary; Path=/"],
|
|
166
|
+
},
|
|
167
|
+
};
|
|
282
168
|
},
|
|
283
169
|
},
|
|
284
|
-
headers: {
|
|
285
|
-
fromSession: [{ header: "X-Organization-Id", field: "organizationId" }],
|
|
286
|
-
},
|
|
287
170
|
});
|
|
288
171
|
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
172
|
+
const fixture = auth.fixture({
|
|
173
|
+
contract: auth.contracts.jsonSession({
|
|
174
|
+
authCookie: "fixture_session",
|
|
175
|
+
organizationIdPath: "data.organizations[0].id",
|
|
176
|
+
}),
|
|
177
|
+
topology: auth.topologies.singleOrg({
|
|
178
|
+
namespace: "signup-race",
|
|
179
|
+
actors: ["primary"],
|
|
180
|
+
}),
|
|
294
181
|
});
|
|
295
|
-
|
|
296
|
-
|
|
182
|
+
|
|
183
|
+
const profiles = fixture.profiles({
|
|
184
|
+
default: auth.profile.actor("primary"),
|
|
297
185
|
});
|
|
186
|
+
|
|
187
|
+
const setup = profiles.default.auth.setup({ env: { BASE: "http://api.test", routeParams: {} } });
|
|
188
|
+
expect(setup.actors.primary.organizationId).toBe("org-primary");
|
|
189
|
+
expect(setup.actors.primary.jwt).toBe("jwt-primary");
|
|
190
|
+
|
|
298
191
|
clearRuntimeContext();
|
|
299
192
|
});
|
|
300
193
|
|
package/lib/discovery/index.mjs
CHANGED
|
@@ -494,7 +494,7 @@ function normalizePath(filePath) {
|
|
|
494
494
|
return String(filePath).split(path.sep).join("/").replace(/^\.\/+/, "");
|
|
495
495
|
}
|
|
496
496
|
|
|
497
|
-
function fileDisplayName(filePath) {
|
|
497
|
+
export function fileDisplayName(filePath) {
|
|
498
498
|
const base = path.posix
|
|
499
499
|
.basename(filePath)
|
|
500
500
|
.replace(/(\.int|\.e2e|\.scenario|\.dal|\.load|\.pw)\.testkit\.ts$/, "");
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
ActorRequestClient,
|
|
2
3
|
HttpClient,
|
|
3
4
|
HttpClientConfig,
|
|
5
|
+
RawRequestClient,
|
|
4
6
|
RuntimeDb,
|
|
5
7
|
RuntimeDalContext,
|
|
6
8
|
RuntimeEnv,
|
|
@@ -16,6 +18,7 @@ export interface TestkitSuite<TSetup = unknown> {
|
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export interface HeaderBuilderContext {
|
|
21
|
+
actor?: string | null;
|
|
19
22
|
env: RuntimeEnv;
|
|
20
23
|
}
|
|
21
24
|
|
|
@@ -29,13 +32,34 @@ export interface AuthAdapter<TSetup = unknown> {
|
|
|
29
32
|
headers?: HeaderBuilder<TSetup>;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
export interface
|
|
35
|
+
export interface SuiteActor<TSession = Record<string, unknown>> {
|
|
36
|
+
email: string | null;
|
|
37
|
+
headers: RuntimeHeaders;
|
|
38
|
+
index: number;
|
|
39
|
+
key: string;
|
|
40
|
+
name: string | null;
|
|
41
|
+
organizationKey: string | null;
|
|
42
|
+
organizationName: string | null;
|
|
43
|
+
rawHeaders: RuntimeHeaders;
|
|
44
|
+
rawReq: RawRequestClient;
|
|
45
|
+
req: ActorRequestClient;
|
|
46
|
+
session: TSession | null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface SuiteActors<TSession = Record<string, unknown>> {
|
|
50
|
+
readonly names: string[];
|
|
51
|
+
readonly primary: SuiteActor<TSession> | null;
|
|
52
|
+
get(name: string): SuiteActor<TSession>;
|
|
53
|
+
has(name: string): boolean;
|
|
54
|
+
list(): SuiteActor<TSession>[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface HttpSuiteContext<TSession = Record<string, unknown>> {
|
|
58
|
+
actor: SuiteActor<TSession> | null;
|
|
59
|
+
actors: SuiteActors<TSession>;
|
|
33
60
|
env: RuntimeEnv;
|
|
34
|
-
req: HttpClient<
|
|
35
|
-
rawReq:
|
|
36
|
-
getWithHeaders: HttpClient<TSetup>["getWithHeaders"];
|
|
37
|
-
setupData: TSetup | null;
|
|
38
|
-
session: TSetup | null;
|
|
61
|
+
req: HttpClient<TSession>;
|
|
62
|
+
rawReq: RawRequestClient;
|
|
39
63
|
}
|
|
40
64
|
|
|
41
65
|
export interface ScenarioStepResult {
|
|
@@ -83,14 +107,14 @@ export interface ScenarioRuntime {
|
|
|
83
107
|
};
|
|
84
108
|
}
|
|
85
109
|
|
|
86
|
-
export interface ScenarioSuiteContext<
|
|
110
|
+
export interface ScenarioSuiteContext<TSession = Record<string, unknown>> extends HttpSuiteContext<TSession> {
|
|
87
111
|
scenario: ScenarioRuntime;
|
|
88
112
|
}
|
|
89
113
|
|
|
90
|
-
export interface HttpSuiteConfig<
|
|
91
|
-
auth?: AuthAdapter<
|
|
114
|
+
export interface HttpSuiteConfig<TSession = unknown> {
|
|
115
|
+
auth?: AuthAdapter<TSession> | null;
|
|
92
116
|
env?: RuntimeEnv;
|
|
93
|
-
headers?: HeaderBuilder<
|
|
117
|
+
headers?: HeaderBuilder<TSession>;
|
|
94
118
|
profile?: string;
|
|
95
119
|
rawHeaders?: HeaderBuilder<never>;
|
|
96
120
|
options?: RuntimeOptions;
|
|
@@ -85,6 +85,7 @@ export async function runAll(configs, typeValues, suiteSelectors, opts, allConfi
|
|
|
85
85
|
execution,
|
|
86
86
|
reporter
|
|
87
87
|
);
|
|
88
|
+
reporter?.setServicePlans?.(servicePlans);
|
|
88
89
|
const trackers = buildServiceTrackers(servicePlans, startedAt);
|
|
89
90
|
let writeLiveSnapshot = () => {};
|
|
90
91
|
const setupRegistry = createSetupOperationRegistry({ logRegistry, onChange: () => writeLiveSnapshot() });
|