@descryy/mcp 0.9.1 → 0.11.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/dist/browser/auth.d.ts +76 -0
- package/dist/browser/auth.d.ts.map +1 -0
- package/dist/browser/auth.js +223 -0
- package/dist/browser/auth.js.map +1 -0
- package/dist/browser/capability-probe.d.ts +109 -0
- package/dist/browser/capability-probe.d.ts.map +1 -0
- package/dist/browser/capability-probe.js +201 -0
- package/dist/browser/capability-probe.js.map +1 -0
- package/dist/browser/driver.d.ts +342 -4
- package/dist/browser/driver.d.ts.map +1 -1
- package/dist/browser/driver.js +79 -1
- package/dist/browser/driver.js.map +1 -1
- package/dist/browser/evidence.d.ts +3 -0
- package/dist/browser/evidence.d.ts.map +1 -1
- package/dist/browser/evidence.js +6 -1
- package/dist/browser/evidence.js.map +1 -1
- package/dist/browser/fake-driver.d.ts +65 -8
- package/dist/browser/fake-driver.d.ts.map +1 -1
- package/dist/browser/fake-driver.js +235 -8
- package/dist/browser/fake-driver.js.map +1 -1
- package/dist/browser/fault-attribution.d.ts +178 -0
- package/dist/browser/fault-attribution.d.ts.map +1 -0
- package/dist/browser/fault-attribution.js +266 -0
- package/dist/browser/fault-attribution.js.map +1 -0
- package/dist/browser/identity-graph-write.d.ts +55 -0
- package/dist/browser/identity-graph-write.d.ts.map +1 -0
- package/dist/browser/identity-graph-write.js +45 -0
- package/dist/browser/identity-graph-write.js.map +1 -0
- package/dist/browser/page-probe.d.ts +81 -0
- package/dist/browser/page-probe.d.ts.map +1 -0
- package/dist/browser/page-probe.js +202 -0
- package/dist/browser/page-probe.js.map +1 -0
- package/dist/browser/playwright-driver.d.ts +79 -0
- package/dist/browser/playwright-driver.d.ts.map +1 -1
- package/dist/browser/playwright-driver.js +1138 -180
- package/dist/browser/playwright-driver.js.map +1 -1
- package/dist/browser/reach-recording-session.d.ts +44 -0
- package/dist/browser/reach-recording-session.d.ts.map +1 -0
- package/dist/browser/reach-recording-session.js +143 -0
- package/dist/browser/reach-recording-session.js.map +1 -0
- package/dist/browser/reachability.d.ts +168 -0
- package/dist/browser/reachability.d.ts.map +1 -0
- package/dist/browser/reachability.js +294 -0
- package/dist/browser/reachability.js.map +1 -0
- package/dist/browser/registry.d.ts +24 -0
- package/dist/browser/registry.d.ts.map +1 -1
- package/dist/browser/registry.js +21 -2
- package/dist/browser/registry.js.map +1 -1
- package/dist/browser/scenario-provenance.d.ts +1 -1
- package/dist/browser/scenario-provenance.d.ts.map +1 -1
- package/dist/browser/scenario-provenance.js +15 -1
- package/dist/browser/scenario-provenance.js.map +1 -1
- package/dist/browser/scenario-runner.d.ts +10 -2
- package/dist/browser/scenario-runner.d.ts.map +1 -1
- package/dist/browser/scenario-runner.js +77 -9
- package/dist/browser/scenario-runner.js.map +1 -1
- package/dist/browser/tool-support.d.ts +5 -1
- package/dist/browser/tool-support.d.ts.map +1 -1
- package/dist/browser/tool-support.js +80 -4
- package/dist/browser/tool-support.js.map +1 -1
- package/dist/browser/wait-target.d.ts +37 -0
- package/dist/browser/wait-target.d.ts.map +1 -0
- package/dist/browser/wait-target.js +54 -0
- package/dist/browser/wait-target.js.map +1 -0
- package/dist/heap.d.ts +61 -0
- package/dist/heap.d.ts.map +1 -0
- package/dist/heap.js +82 -0
- package/dist/heap.js.map +1 -0
- package/dist/heartbeat.d.ts +46 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +66 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/planner/predict-then-propose.d.ts +101 -0
- package/dist/planner/predict-then-propose.d.ts.map +1 -0
- package/dist/planner/predict-then-propose.js +88 -0
- package/dist/planner/predict-then-propose.js.map +1 -0
- package/dist/planner/propose-journey.d.ts +60 -0
- package/dist/planner/propose-journey.d.ts.map +1 -0
- package/dist/planner/propose-journey.js +96 -0
- package/dist/planner/propose-journey.js.map +1 -0
- package/dist/registry.d.ts +10 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +5 -1
- package/dist/registry.js.map +1 -1
- package/dist/render.d.ts +4 -4
- package/dist/render.js +3 -3
- package/dist/scenarios/browser-run-plan-projection.d.ts +143 -0
- package/dist/scenarios/browser-run-plan-projection.d.ts.map +1 -0
- package/dist/scenarios/browser-run-plan-projection.js +228 -0
- package/dist/scenarios/browser-run-plan-projection.js.map +1 -0
- package/dist/scenarios/credential-ref.d.ts +102 -0
- package/dist/scenarios/credential-ref.d.ts.map +1 -0
- package/dist/scenarios/credential-ref.js +148 -0
- package/dist/scenarios/credential-ref.js.map +1 -0
- package/dist/scenarios/index.d.ts +4 -1
- package/dist/scenarios/index.d.ts.map +1 -1
- package/dist/scenarios/index.js +4 -1
- package/dist/scenarios/index.js.map +1 -1
- package/dist/scenarios/parse.d.ts.map +1 -1
- package/dist/scenarios/parse.js +42 -9
- package/dist/scenarios/parse.js.map +1 -1
- package/dist/scenarios/scenario.d.ts +39 -5
- package/dist/scenarios/scenario.d.ts.map +1 -1
- package/dist/scenarios/scenario.js +15 -2
- package/dist/scenarios/scenario.js.map +1 -1
- package/dist/scenarios/secret-ref.d.ts +86 -0
- package/dist/scenarios/secret-ref.d.ts.map +1 -0
- package/dist/scenarios/secret-ref.js +125 -0
- package/dist/scenarios/secret-ref.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +8 -4
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +19 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +36 -0
- package/dist/session.js.map +1 -1
- package/dist/tools/analyze-workspace.d.ts +52 -0
- package/dist/tools/analyze-workspace.d.ts.map +1 -0
- package/dist/tools/analyze-workspace.js +207 -0
- package/dist/tools/analyze-workspace.js.map +1 -0
- package/dist/tools/analyze.d.ts +50 -4
- package/dist/tools/analyze.d.ts.map +1 -1
- package/dist/tools/analyze.js +225 -5
- package/dist/tools/analyze.js.map +1 -1
- package/dist/tools/browser-close-session.d.ts +21 -1
- package/dist/tools/browser-close-session.d.ts.map +1 -1
- package/dist/tools/browser-close-session.js +71 -7
- package/dist/tools/browser-close-session.js.map +1 -1
- package/dist/tools/browser-navigate.d.ts +1 -1
- package/dist/tools/browser-navigate.d.ts.map +1 -1
- package/dist/tools/browser-navigate.js +5 -3
- package/dist/tools/browser-navigate.js.map +1 -1
- package/dist/tools/browser-run-scenario.d.ts.map +1 -1
- package/dist/tools/browser-run-scenario.js +6 -1
- package/dist/tools/browser-run-scenario.js.map +1 -1
- package/dist/tools/browser-save-scenario.d.ts.map +1 -1
- package/dist/tools/browser-save-scenario.js +84 -4
- package/dist/tools/browser-save-scenario.js.map +1 -1
- package/dist/tools/browser-select.d.ts +20 -0
- package/dist/tools/browser-select.d.ts.map +1 -0
- package/dist/tools/browser-select.js +120 -0
- package/dist/tools/browser-select.js.map +1 -0
- package/dist/tools/browser-snapshot.d.ts +17 -1
- package/dist/tools/browser-snapshot.d.ts.map +1 -1
- package/dist/tools/browser-snapshot.js +18 -5
- package/dist/tools/browser-snapshot.js.map +1 -1
- package/dist/tools/browser-start-session.d.ts.map +1 -1
- package/dist/tools/browser-start-session.js +161 -9
- package/dist/tools/browser-start-session.js.map +1 -1
- package/dist/tools/browser-submit.d.ts +18 -0
- package/dist/tools/browser-submit.d.ts.map +1 -0
- package/dist/tools/browser-submit.js +106 -0
- package/dist/tools/browser-submit.js.map +1 -0
- package/dist/tools/browser-wait-for.d.ts +41 -0
- package/dist/tools/browser-wait-for.d.ts.map +1 -0
- package/dist/tools/browser-wait-for.js +148 -0
- package/dist/tools/browser-wait-for.js.map +1 -0
- package/dist/tools/chain.d.ts +41 -0
- package/dist/tools/chain.d.ts.map +1 -0
- package/dist/tools/chain.js +105 -0
- package/dist/tools/chain.js.map +1 -0
- package/dist/tools/draw-conclusion.d.ts +44 -0
- package/dist/tools/draw-conclusion.d.ts.map +1 -0
- package/dist/tools/draw-conclusion.js +250 -0
- package/dist/tools/draw-conclusion.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/kit.d.ts +17 -0
- package/dist/tools/kit.d.ts.map +1 -1
- package/dist/tools/kit.js.map +1 -1
- package/dist/tools/observe-runtime.d.ts +17 -0
- package/dist/tools/observe-runtime.d.ts.map +1 -1
- package/dist/tools/observe-runtime.js +174 -10
- package/dist/tools/observe-runtime.js.map +1 -1
- package/dist/tools/predict-reach.d.ts +57 -0
- package/dist/tools/predict-reach.d.ts.map +1 -0
- package/dist/tools/predict-reach.js +159 -0
- package/dist/tools/predict-reach.js.map +1 -0
- package/dist/tools/propagation.d.ts +8 -3
- package/dist/tools/propagation.d.ts.map +1 -1
- package/dist/tools/propagation.js +16 -9
- package/dist/tools/propagation.js.map +1 -1
- package/dist/tools/propose-journey.d.ts +16 -0
- package/dist/tools/propose-journey.d.ts.map +1 -0
- package/dist/tools/propose-journey.js +121 -0
- package/dist/tools/propose-journey.js.map +1 -0
- package/dist/tools/runtime-journey-drive.d.ts +102 -0
- package/dist/tools/runtime-journey-drive.d.ts.map +1 -0
- package/dist/tools/runtime-journey-drive.js +247 -0
- package/dist/tools/runtime-journey-drive.js.map +1 -0
- package/dist/tools/scope.d.ts +3 -0
- package/dist/tools/scope.d.ts.map +1 -1
- package/dist/tools/scope.js +33 -6
- package/dist/tools/scope.js.map +1 -1
- package/dist/workspace-index.d.ts +164 -0
- package/dist/workspace-index.d.ts.map +1 -0
- package/dist/workspace-index.js +381 -0
- package/dist/workspace-index.js.map +1 -0
- package/package.json +32 -31
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `${credential:NAME}` — a scenario step names a stored credential by
|
|
3
|
+
* reference; the credential store holds the value. Lane A1, item 4 of
|
|
4
|
+
* `documents/plans/runtime-gap-closure.md` ("Sign-in as a first-class
|
|
5
|
+
* step"). Appended to `DEC-NEXT-scenario-format-needs-a-secret-reference.md`
|
|
6
|
+
* rather than rewriting it — see that file's own note.
|
|
7
|
+
*
|
|
8
|
+
* ## Why a second module, not a second branch inside `secret-ref.ts`
|
|
9
|
+
*
|
|
10
|
+
* `secret-ref.ts`'s own header already reserves this extension point:
|
|
11
|
+
* *"A keychain becomes a second scheme with its own prefix and its own
|
|
12
|
+
* refusal, not a fallback behind the first one. Nothing about the stored
|
|
13
|
+
* file changes when it arrives."* This module is that second scheme,
|
|
14
|
+
* `credential:` rather than `keychain:` because the store it resolves
|
|
15
|
+
* against (`descry-runtime`'s `CredentialStore`, an at-rest encrypted file
|
|
16
|
+
* store today, a real OS keychain later behind the same three-method
|
|
17
|
+
* interface) is named for what it is, not for today's backend. Kept in its
|
|
18
|
+
* own file rather than added as a branch inside `readSecretRef` so the two
|
|
19
|
+
* schemes stay independently resolvable — a caller that only has an
|
|
20
|
+
* environment map (`resolveSecretText`) and one that only has a credential
|
|
21
|
+
* store (`resolveCredentialText`, here) each fail closed on the scheme they
|
|
22
|
+
* cannot serve, rather than one function silently depending on both.
|
|
23
|
+
*
|
|
24
|
+
* ## What this does not attempt
|
|
25
|
+
*
|
|
26
|
+
* A step naming `${credential:NAME}` still types the resolved value into a
|
|
27
|
+
* field with `type`/`fill`/`select` — the same verbs, the same replay path,
|
|
28
|
+
* the same "whole field or none of it" and "empty is refused" rules as
|
|
29
|
+
* `secret-ref.ts`. It does **not** add a session-seeding step that logs a
|
|
30
|
+
* whole browser context in via a saved storage state mid-replay — that
|
|
31
|
+
* would need a driver-level primitive (`packages/mcp/src/browser/driver.ts`,
|
|
32
|
+
* `playwright-driver.ts`) to inject cookies into a session already in
|
|
33
|
+
* progress, and this lane does not own those files. `auth.ts`'s
|
|
34
|
+
* `loadStorageStateFile` already seeds a **new** session at
|
|
35
|
+
* `browser_start_session` time; wiring a credential-store-backed profile
|
|
36
|
+
* into that call is a smaller, real gap, and is recorded as a handoff in
|
|
37
|
+
* `DEC-NEXT-scenario-format-needs-a-secret-reference.md` rather than built
|
|
38
|
+
* here by touching a port this lane does not own.
|
|
39
|
+
*
|
|
40
|
+
* Rule 1: an environment variable is a fact about a process; a credential
|
|
41
|
+
* reference is a fact about a name a person chose. Neither module needs to
|
|
42
|
+
* know what kind of secret it resolves to.
|
|
43
|
+
*/
|
|
44
|
+
import { resolveSecretText } from "./secret-ref.js";
|
|
45
|
+
/** `${credential:NAME}` — the credential name is deliberately permissive
|
|
46
|
+
* (letters, digits, `-`, `_`, `.`) because a credential ref is a name a
|
|
47
|
+
* person or a store assigns, not a POSIX environment variable. */
|
|
48
|
+
const REFERENCE = /^\$\{credential:([A-Za-z0-9_.-]+)\}$/;
|
|
49
|
+
const LOOKS_LIKE_REFERENCE = /^\$\{credential:[^}]*\}$/;
|
|
50
|
+
/** Reads one stored `text` field for the `credential:` scheme alone. A `${env:...}` reference is
|
|
51
|
+
* a literal as far as this function is concerned — `secret-ref.ts`'s `readSecretRef` is what
|
|
52
|
+
* resolves that scheme, and a caller resolving both composes the two (see `resolveEitherRef`). */
|
|
53
|
+
export function readCredentialRef(text) {
|
|
54
|
+
const matched = REFERENCE.exec(text);
|
|
55
|
+
if (matched !== null)
|
|
56
|
+
return { kind: "ref", name: matched[1] };
|
|
57
|
+
if (LOOKS_LIKE_REFERENCE.test(text)) {
|
|
58
|
+
return {
|
|
59
|
+
kind: "malformed",
|
|
60
|
+
message: `${JSON.stringify(text)} is written like a credential reference and is not one. The only form is ` +
|
|
61
|
+
'"${credential:NAME}", whole field, with the name made of letters, digits, "-", "_" or ".", no other ' +
|
|
62
|
+
"text around it. It is refused rather than stored as text on purpose, for the same reason a malformed " +
|
|
63
|
+
"${env:...} reference is: typed verbatim into a login form, it would be reported as the application's defect.",
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return { kind: "literal", text };
|
|
67
|
+
}
|
|
68
|
+
export function isCredentialRef(text) {
|
|
69
|
+
return readCredentialRef(text).kind === "ref";
|
|
70
|
+
}
|
|
71
|
+
/** What to write into a file so `name` is resolved from the credential store at replay. */
|
|
72
|
+
export function credentialRefFor(name) {
|
|
73
|
+
return `\${credential:${name}}`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Turns one stored `text` into the string to type, or says why it cannot —
|
|
77
|
+
* `secret-ref.ts`'s `resolveSecretText`, restated against a credential store
|
|
78
|
+
* instead of an environment map. An unset name and an empty stored value are
|
|
79
|
+
* both refusals, for the same reason `resolveSecretText` refuses an empty
|
|
80
|
+
* environment variable: an empty password produces a failed login that
|
|
81
|
+
* reads exactly like a broken application.
|
|
82
|
+
*/
|
|
83
|
+
export async function resolveCredentialText(text, store) {
|
|
84
|
+
const ref = readCredentialRef(text);
|
|
85
|
+
if (ref.kind === "literal")
|
|
86
|
+
return { resolved: true, value: ref.text };
|
|
87
|
+
if (ref.kind === "malformed")
|
|
88
|
+
return { resolved: false, reason: ref.message };
|
|
89
|
+
const value = await store.retrieve(ref.name);
|
|
90
|
+
if (value === null) {
|
|
91
|
+
return {
|
|
92
|
+
resolved: false,
|
|
93
|
+
reason: `this step needs the credential "${ref.name}", and nothing is stored under that name. The scenario was ` +
|
|
94
|
+
"saved with a reference instead of the value on purpose — the value is a credential and a scenario is a " +
|
|
95
|
+
`committed file. Store it under "${ref.name}" before replaying. Nothing was typed and the replay stopped ` +
|
|
96
|
+
"here: a step that types the literal text of its own reference would fail against the application and be " +
|
|
97
|
+
"reported as the application's defect.",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (value === "") {
|
|
101
|
+
return {
|
|
102
|
+
resolved: false,
|
|
103
|
+
reason: `the credential "${ref.name}" is stored and empty. An empty value is refused rather than typed: an empty ` +
|
|
104
|
+
"password produces a failed login that reads exactly like a broken application.",
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return { resolved: true, value };
|
|
108
|
+
}
|
|
109
|
+
/** Every credential name a scenario's steps reference, in order, deduplicated — the `${credential:...}` counterpart to `secret-ref.ts`'s `referencedVariables`. */
|
|
110
|
+
export function referencedCredentials(texts) {
|
|
111
|
+
const out = [];
|
|
112
|
+
for (const text of texts) {
|
|
113
|
+
if (text === null)
|
|
114
|
+
continue;
|
|
115
|
+
const ref = readCredentialRef(text);
|
|
116
|
+
if (ref.kind === "ref" && !out.includes(ref.name))
|
|
117
|
+
out.push(ref.name);
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resolves a step's stored text against **both** schemes: `${credential:NAME}` checked first
|
|
123
|
+
* (this module owns that shape and nothing else recognises it), `${env:VAR}` and plain literals
|
|
124
|
+
* delegated to `resolveSecretText` otherwise. One entry point so a caller (`scenario-runner.ts`)
|
|
125
|
+
* never has to decide which resolver a given step's text needs — the reference's own prefix
|
|
126
|
+
* decides. `store` is optional: a scenario naming `${credential:NAME}` with no store configured
|
|
127
|
+
* refuses by name rather than falling through to `resolveSecretText`, which would report it as a
|
|
128
|
+
* malformed `${env:...}` reference — a true statement about that resolver and a confusing one
|
|
129
|
+
* about this file's own scheme.
|
|
130
|
+
*/
|
|
131
|
+
export async function resolveEitherRef(text, env, store) {
|
|
132
|
+
const asCredential = readCredentialRef(text);
|
|
133
|
+
if (asCredential.kind === "ref") {
|
|
134
|
+
if (store === undefined) {
|
|
135
|
+
return {
|
|
136
|
+
resolved: false,
|
|
137
|
+
reason: `this step needs the credential "${asCredential.name}", and no credential store is configured for this ` +
|
|
138
|
+
"replay. Sign-in-as-profile steps need a credential store wired in by the caller (browser_run_scenario's " +
|
|
139
|
+
"own runner); nothing was typed.",
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return resolveCredentialText(text, store);
|
|
143
|
+
}
|
|
144
|
+
if (asCredential.kind === "malformed")
|
|
145
|
+
return { resolved: false, reason: asCredential.message };
|
|
146
|
+
return resolveSecretText(text, env);
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=credential-ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-ref.js","sourceRoot":"","sources":["../../src/scenarios/credential-ref.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export { SCENARIO_SCHEMA_VERSION, isUnverifying, type Scenario, type ScenarioStep, type ScenarioAssertion, type ScenarioAssertionKind, type ScenarioActionKind, type TargetDescriptor, } from "./scenario.ts";
|
|
1
|
+
export { MIN_READABLE_SCHEMA_VERSION, SCENARIO_SCHEMA_VERSION, isUnverifying, type Scenario, type ScenarioStep, type ScenarioAssertion, type ScenarioAssertionKind, type ScenarioActionKind, type TargetDescriptor, } from "./scenario.ts";
|
|
2
2
|
export { parseScenario, serializeScenario, type ScenarioParseResult } from "./parse.ts";
|
|
3
|
+
export { isSecretRef, readSecretRef, referencedVariables, resolveSecretText, secretRefFor, type SecretEnvironment, type SecretRef, type SecretResolution, } from "./secret-ref.ts";
|
|
3
4
|
export { scenariosDirectory, scenarioPath, listScenarios, ScenarioListError, readScenario, writeScenario, } from "./storage.ts";
|
|
5
|
+
export { readCredentialRef, isCredentialRef, credentialRefFor, resolveCredentialText, resolveEitherRef, referencedCredentials, type CredentialRef, type CredentialStoreLike, type CredentialResolution, } from "./credential-ref.ts";
|
|
6
|
+
export { projectScenarioToRunPlan, projectRunPlanToScenario, type ProjectedStep, type ProjectedStepKind, type ProjectedBrowserRunPlan, type ProjectionRefusal, type ScenarioProjection, type PlanProjection, type RawProjectedStep, type ScenarioMeta, } from "./browser-run-plan-projection.ts";
|
|
4
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,aAAa,GACd,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,EACL,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,GAClB,MAAM,kCAAkC,CAAC"}
|
package/dist/scenarios/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export { SCENARIO_SCHEMA_VERSION, isUnverifying, } from "./scenario.js";
|
|
1
|
+
export { MIN_READABLE_SCHEMA_VERSION, SCENARIO_SCHEMA_VERSION, isUnverifying, } from "./scenario.js";
|
|
2
2
|
export { parseScenario, serializeScenario } from "./parse.js";
|
|
3
|
+
export { isSecretRef, readSecretRef, referencedVariables, resolveSecretText, secretRefFor, } from "./secret-ref.js";
|
|
3
4
|
export { scenariosDirectory, scenarioPath, listScenarios, ScenarioListError, readScenario, writeScenario, } from "./storage.js";
|
|
5
|
+
export { readCredentialRef, isCredentialRef, credentialRefFor, resolveCredentialText, resolveEitherRef, referencedCredentials, } from "./credential-ref.js";
|
|
6
|
+
export { projectScenarioToRunPlan, projectRunPlanToScenario, } from "./browser-run-plan-projection.js";
|
|
4
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,aAAa,GAOd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAA4B,MAAM,YAAY,CAAC;AACxF,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,aAAa,GACd,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scenarios/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,aAAa,GAOd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAA4B,MAAM,YAAY,CAAC;AACxF,OAAO,EACL,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,GAIb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,GAItB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GASzB,MAAM,kCAAkC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/scenarios/parse.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/scenarios/parse.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAGL,KAAK,QAAQ,EAMd,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAgJpE,qNAAqN;AACrN,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,mBAAmB,CAwE/D;AAED,2HAA2H;AAC3H,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAE5D"}
|
package/dist/scenarios/parse.js
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
* point. Refuses rather than repairs: coercing a missing field to a default
|
|
4
4
|
* would let a scenario keep loading after it stopped describing the app, silently, in CI where nobody's watching. Problems collect in one pass, not one throw at a time.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import { readSecretRef } from "./secret-ref.js";
|
|
7
|
+
import { readCredentialRef } from "./credential-ref.js";
|
|
8
|
+
import { MIN_READABLE_SCHEMA_VERSION, SCENARIO_SCHEMA_VERSION, } from "./scenario.js";
|
|
9
|
+
const ACTIONS = ["navigate", "click", "type", "fill", "select", "submit"];
|
|
8
10
|
const ASSERTION_KINDS = [
|
|
9
11
|
"elementVisible",
|
|
10
12
|
"textEquals",
|
|
@@ -13,9 +15,11 @@ const ASSERTION_KINDS = [
|
|
|
13
15
|
"noFailedRequests",
|
|
14
16
|
];
|
|
15
17
|
/** Actions that act on an element, and therefore require a target. `navigate` acts on the page. */
|
|
16
|
-
const ELEMENT_ACTIONS = ["click", "type", "fill"];
|
|
17
|
-
/** Actions that
|
|
18
|
-
|
|
18
|
+
const ELEMENT_ACTIONS = ["click", "type", "fill", "select", "submit"];
|
|
19
|
+
/** Actions that carry a value in `text`, and therefore require one. `select` is here because the
|
|
20
|
+
* option it chooses is the same kind of stored string as typed text — see `ScenarioStep.text`.
|
|
21
|
+
* `submit` is not: it acts on a form through the form's own submit control and names nothing. */
|
|
22
|
+
const TEXT_ACTIONS = ["type", "fill", "select"];
|
|
19
23
|
function isRecord(value) {
|
|
20
24
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21
25
|
}
|
|
@@ -69,10 +73,32 @@ function readStep(raw, index, problems) {
|
|
|
69
73
|
}
|
|
70
74
|
const text = raw["text"] ?? null;
|
|
71
75
|
if (TEXT_ACTIONS.includes(kind) && typeof text !== "string") {
|
|
72
|
-
problems.push(
|
|
76
|
+
problems.push(kind === "select"
|
|
77
|
+
? `${where}: select chooses an option and needs its value stored in text`
|
|
78
|
+
: `${where}: ${kind} enters text and needs it stored`);
|
|
73
79
|
}
|
|
74
80
|
if (!TEXT_ACTIONS.includes(kind) && text !== null) {
|
|
75
|
-
problems.push(`${where}: only
|
|
81
|
+
problems.push(`${where}: only ${TEXT_ACTIONS.join(", ")} carry text`);
|
|
82
|
+
}
|
|
83
|
+
// A secret or credential reference with a typo in it is refused here rather than at replay.
|
|
84
|
+
// Stored text is typed verbatim, so `${ENV:PASSWORD}` or `${credential:NAME }` would reach the
|
|
85
|
+
// login form as those characters and the page's rejection of them would be reported as the
|
|
86
|
+
// application's defect. `credential:` is checked first — a well-formed credential reference
|
|
87
|
+
// (`credential-ref.ts`, RG-1(4) / lane "delivery") must never be flagged malformed by a
|
|
88
|
+
// validator that only knew the `env:` scheme when it was written; `readSecretRef`'s own
|
|
89
|
+
// `LOOKS_LIKE_REFERENCE` matches any `${...}` shape generically, so without this check first,
|
|
90
|
+
// every valid `${credential:NAME}` step failed here before a scenario could ever be read.
|
|
91
|
+
if (typeof text === "string") {
|
|
92
|
+
const credentialRef = readCredentialRef(text);
|
|
93
|
+
if (credentialRef.kind === "malformed") {
|
|
94
|
+
problems.push(`${where}: ${credentialRef.message}`);
|
|
95
|
+
}
|
|
96
|
+
else if (credentialRef.kind === "literal") {
|
|
97
|
+
const ref = readSecretRef(text);
|
|
98
|
+
if (ref.kind === "malformed")
|
|
99
|
+
problems.push(`${where}: ${ref.message}`);
|
|
100
|
+
}
|
|
101
|
+
// credentialRef.kind === "ref": a well-formed ${credential:NAME}, nothing to flag.
|
|
76
102
|
}
|
|
77
103
|
return {
|
|
78
104
|
action: kind,
|
|
@@ -127,12 +153,19 @@ export function parseScenario(raw) {
|
|
|
127
153
|
],
|
|
128
154
|
};
|
|
129
155
|
}
|
|
130
|
-
if (schemaVersion <
|
|
156
|
+
if (schemaVersion < MIN_READABLE_SCHEMA_VERSION) {
|
|
131
157
|
return {
|
|
132
158
|
valid: false,
|
|
133
|
-
problems: [
|
|
159
|
+
problems: [
|
|
160
|
+
`schemaVersion ${schemaVersion} is older than ${MIN_READABLE_SCHEMA_VERSION}, the oldest this reader still accepts, and no migration exists — re-save the scenario.`,
|
|
161
|
+
],
|
|
134
162
|
};
|
|
135
163
|
}
|
|
164
|
+
// Between MIN_READABLE and current: read as-is. Version 1 is a strict subset of 2 — every
|
|
165
|
+
// field means what it meant — so the migration is the identity and a scenario saved before the
|
|
166
|
+
// `select`/`submit` verbs and the secret reference existed keeps replaying untouched. The
|
|
167
|
+
// stored number is kept rather than rewritten to the current one: it is provenance for which
|
|
168
|
+
// reader wrote the file, and a re-save is what updates it.
|
|
136
169
|
for (const field of ["name", "targetUrl", "savedAt", "savedAtCommit"]) {
|
|
137
170
|
if (typeof raw[field] !== "string")
|
|
138
171
|
problems.push(`${field} is required`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/scenarios/parse.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,uBAAuB,GAOxB,MAAM,eAAe,CAAC;AAMvB,MAAM,OAAO,GAAkC,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/scenarios/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,21 @@
|
|
|
3
3
|
* is the runner's separate question. A step stores a `TargetDescriptor`, never a `ref`
|
|
4
4
|
* (refs are snapshot-scoped, stale by replay). All 3 descriptor fields are required
|
|
5
5
|
* together — a fallback chain would quietly substitute a match instead of disagreeing. */
|
|
6
|
-
/** Bumped when a stored scenario's shape changes. An integer, never semver: one repository, one reader, nothing to argue about.
|
|
7
|
-
|
|
6
|
+
/** Bumped when a stored scenario's shape changes. An integer, never semver: one repository, one reader, nothing to argue about.
|
|
7
|
+
*
|
|
8
|
+
* 2 adds the `select` and `submit` verbs and the `${env:VAR}` secret reference. The bump is
|
|
9
|
+
* about the *reference*, not the verbs: an older reader meeting an unknown verb already refuses
|
|
10
|
+
* it by name, but an older reader meeting `${env:PASSWORD}` in a `text` field would type that
|
|
11
|
+
* literal string into a login form and report the resulting failure as the application's. Rule
|
|
12
|
+
* 7 forbids that, so the version gate is what stops it — a version 2 file is refused whole by a
|
|
13
|
+
* version 1 reader, with a message that says to upgrade. */
|
|
14
|
+
export declare const SCENARIO_SCHEMA_VERSION = 2;
|
|
15
|
+
/** The oldest stored version this reader still accepts. Version 1 is a strict subset of 2 —
|
|
16
|
+
* every field means what it meant, so the migration is the identity and a scenario saved before
|
|
17
|
+
* this change keeps replaying untouched. Read in the other direction from
|
|
18
|
+
* `SCENARIO_SCHEMA_VERSION`: that one stops a new file being misread by an old reader, this one
|
|
19
|
+
* stops an old file being refused by a new one for no reason. */
|
|
20
|
+
export declare const MIN_READABLE_SCHEMA_VERSION = 1;
|
|
8
21
|
/** How a step names its element. Re-resolved at replay against a fresh snapshot,
|
|
9
22
|
* must match exactly one — zero/ambiguous/partial each refuse, naming what disagreed. */
|
|
10
23
|
export interface TargetDescriptor {
|
|
@@ -12,15 +25,36 @@ export interface TargetDescriptor {
|
|
|
12
25
|
readonly name: string;
|
|
13
26
|
readonly selector: string;
|
|
14
27
|
}
|
|
15
|
-
/** Mirrors the port's `BrowserActionKind`, restated rather than imported: the format must be
|
|
16
|
-
|
|
28
|
+
/** Mirrors the port's `BrowserActionKind`, restated rather than imported: the format must be
|
|
29
|
+
* readable without a browser in the process. `waitFor` is absent from both for the same reason —
|
|
30
|
+
* it performs nothing. */
|
|
31
|
+
export type ScenarioActionKind = "navigate" | "click" | "type" | "fill" | "select" | "submit";
|
|
17
32
|
export interface ScenarioStep {
|
|
18
33
|
readonly action: ScenarioActionKind;
|
|
19
34
|
/** The element to act on. Null for `navigate`, which acts on the page — and required for everything else, because a step with nothing to resolve cannot be replayed. */
|
|
20
35
|
readonly target: TargetDescriptor | null;
|
|
21
36
|
/** Where to go. Present for `navigate` alone. */
|
|
22
37
|
readonly url: string | null;
|
|
23
|
-
/** What to enter
|
|
38
|
+
/** What to enter, or for `select` which option to choose. Present for `type`, `fill` and
|
|
39
|
+
* `select` alone — `submit` acts on a form through its own submit control and carries nothing,
|
|
40
|
+
* and `navigate` acts on the page.
|
|
41
|
+
*
|
|
42
|
+
* `type` appends, `fill` replaces — the runtime's two text verbs, kept distinct here because
|
|
43
|
+
* the stored artifact must say which one a replay should perform.
|
|
44
|
+
*
|
|
45
|
+
* For `select` this is the option's **stored value**, not the label a person reads. Three
|
|
46
|
+
* reasons, in order of weight. (1) The driver already records `matched.value` in
|
|
47
|
+
* `PerformedStep`, so a scenario storing the label could never match its own session's
|
|
48
|
+
* provenance record and every saved `select` would fall back to a later snapshot check.
|
|
49
|
+
* (2) A label changes when copy changes — a rewording, a translation — and a scenario that
|
|
50
|
+
* breaks on a rewording is a scenario a team turns off. A value changes when the backend's
|
|
51
|
+
* option set changes, and a scenario breaking *then* is the scenario doing its job. (3) The
|
|
52
|
+
* replay verb matches by value first and label second, exactly as the live verb does, so a
|
|
53
|
+
* stored value that has since become a label still resolves rather than refusing. That
|
|
54
|
+
* fallback is inside the option matcher and is not the descriptor fallback rule 2 forbids: it
|
|
55
|
+
* never substitutes a *different* element, only recognises the same option named the other way.
|
|
56
|
+
*
|
|
57
|
+
* May carry a secret reference — `${env:VAR}` — instead of a literal. See `secret-ref.ts`. */
|
|
24
58
|
readonly text: string | null;
|
|
25
59
|
}
|
|
26
60
|
/** What the scenario claims. Kept small, derived only from what a snapshot/run
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../../src/scenarios/scenario.ts"],"names":[],"mappings":"AAAA;;;;0FAI0F;AAE1F
|
|
1
|
+
{"version":3,"file":"scenario.d.ts","sourceRoot":"","sources":["../../src/scenarios/scenario.ts"],"names":[],"mappings":"AAAA;;;;0FAI0F;AAE1F;;;;;;;6DAO6D;AAC7D,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;kEAIkE;AAClE,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C;0FAC0F;AAC1F,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;2BAE2B;AAC3B,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9F,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,wKAAwK;IACxK,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACzC,iDAAiD;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;mGAmB+F;IAC/F,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;iGAEiG;AACjG,MAAM,MAAM,qBAAqB,GAC7B,gBAAgB,GAChB,YAAY,GACZ,WAAW,GACX,iBAAiB,GACjB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,gLAAgL;IAChL,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACzC,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;0FAEsF;IACtF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC;;qFAEiF;IACjF,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACnD;AAED;;oBAEoB;AACpB,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAEzD"}
|
|
@@ -3,8 +3,21 @@
|
|
|
3
3
|
* is the runner's separate question. A step stores a `TargetDescriptor`, never a `ref`
|
|
4
4
|
* (refs are snapshot-scoped, stale by replay). All 3 descriptor fields are required
|
|
5
5
|
* together — a fallback chain would quietly substitute a match instead of disagreeing. */
|
|
6
|
-
/** Bumped when a stored scenario's shape changes. An integer, never semver: one repository, one reader, nothing to argue about.
|
|
7
|
-
|
|
6
|
+
/** Bumped when a stored scenario's shape changes. An integer, never semver: one repository, one reader, nothing to argue about.
|
|
7
|
+
*
|
|
8
|
+
* 2 adds the `select` and `submit` verbs and the `${env:VAR}` secret reference. The bump is
|
|
9
|
+
* about the *reference*, not the verbs: an older reader meeting an unknown verb already refuses
|
|
10
|
+
* it by name, but an older reader meeting `${env:PASSWORD}` in a `text` field would type that
|
|
11
|
+
* literal string into a login form and report the resulting failure as the application's. Rule
|
|
12
|
+
* 7 forbids that, so the version gate is what stops it — a version 2 file is refused whole by a
|
|
13
|
+
* version 1 reader, with a message that says to upgrade. */
|
|
14
|
+
export const SCENARIO_SCHEMA_VERSION = 2;
|
|
15
|
+
/** The oldest stored version this reader still accepts. Version 1 is a strict subset of 2 —
|
|
16
|
+
* every field means what it meant, so the migration is the identity and a scenario saved before
|
|
17
|
+
* this change keeps replaying untouched. Read in the other direction from
|
|
18
|
+
* `SCENARIO_SCHEMA_VERSION`: that one stops a new file being misread by an old reader, this one
|
|
19
|
+
* stops an old file being refused by a new one for no reason. */
|
|
20
|
+
export const MIN_READABLE_SCHEMA_VERSION = 1;
|
|
8
21
|
/** True when a scenario claims nothing, so verifies nothing. A clean replay still
|
|
9
22
|
* proves the steps resolve — real info, not "the app is behaving". Reported as
|
|
10
23
|
* `unverified`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenario.js","sourceRoot":"","sources":["../../src/scenarios/scenario.ts"],"names":[],"mappings":"AAAA;;;;0FAI0F;AAE1F
|
|
1
|
+
{"version":3,"file":"scenario.js","sourceRoot":"","sources":["../../src/scenarios/scenario.ts"],"names":[],"mappings":"AAAA;;;;0FAI0F;AAE1F;;;;;;;6DAO6D;AAC7D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC;;;;kEAIkE;AAClE,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAiF7C;;oBAEoB;AACpB,MAAM,UAAU,aAAa,CAAC,QAAkB;IAC9C,OAAO,QAAQ,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A step's text without the secret in it — `${env:VAR}` in place of a literal, resolved from
|
|
3
|
+
* the environment at replay.
|
|
4
|
+
*
|
|
5
|
+
* ## Why the format needs this at all
|
|
6
|
+
*
|
|
7
|
+
* A saved scenario is a committed file. `ScenarioStep.text` stores what was typed. Logging in
|
|
8
|
+
* by hand once and saving the session is the documented way to reach a gated screen, and the
|
|
9
|
+
* act of logging in is the act of typing a password — so the format's ordinary, intended use
|
|
10
|
+
* writes a credential into git. The guard that existed before this catches only a value the
|
|
11
|
+
* session was *also* seeded with, because that is the only value a session can prove is a
|
|
12
|
+
* credential; a password the agent simply typed was still written.
|
|
13
|
+
*
|
|
14
|
+
* ## Why there is no detector
|
|
15
|
+
*
|
|
16
|
+
* Nothing at the moment of typing distinguishes a password from a fixture value. `type="password"`
|
|
17
|
+
* is a hint: plenty of credential fields are not typed that way, and plenty of password fields
|
|
18
|
+
* hold throwaway values that are *useful* committed. A heuristic wrong in one direction commits a
|
|
19
|
+
* credential; wrong in the other it silently breaks a scenario somebody wrote on purpose. So a
|
|
20
|
+
* value is a secret because it is written as a reference, and for no other reason.
|
|
21
|
+
*
|
|
22
|
+
* ## Whole field, never embedded
|
|
23
|
+
*
|
|
24
|
+
* A reference is the entire `text` or none of it. `"Bearer ${env:TOKEN}"` is refused rather than
|
|
25
|
+
* interpolated. A partially-resolved string is the failure this module exists to prevent wearing
|
|
26
|
+
* a different hat: half of it came from the environment and half of it is in the file, and
|
|
27
|
+
* nothing in the artifact says which half. If a page needs a prefix, put the prefix in the
|
|
28
|
+
* variable.
|
|
29
|
+
*
|
|
30
|
+
* ## Escaping
|
|
31
|
+
*
|
|
32
|
+
* `$${env:X}` is the literal text `${env:X}`. A form that legitimately takes that string — a
|
|
33
|
+
* template editor, a config field — must stay writable, and an escape is cheaper than a special
|
|
34
|
+
* case later.
|
|
35
|
+
*
|
|
36
|
+
* Rule 1: an environment variable is a fact about a process, not about a language.
|
|
37
|
+
*/
|
|
38
|
+
export type SecretRef =
|
|
39
|
+
/** Store and type this exactly. `text` is already unescaped. */
|
|
40
|
+
{
|
|
41
|
+
readonly kind: "literal";
|
|
42
|
+
readonly text: string;
|
|
43
|
+
}
|
|
44
|
+
/** Resolve `variable` from the environment at replay; never store its value. */
|
|
45
|
+
| {
|
|
46
|
+
readonly kind: "ref";
|
|
47
|
+
readonly variable: string;
|
|
48
|
+
}
|
|
49
|
+
/** Meant as a reference and is not one. Refused at parse, save and replay alike. */
|
|
50
|
+
| {
|
|
51
|
+
readonly kind: "malformed";
|
|
52
|
+
readonly message: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Reads one stored `text` field. Never throws and never resolves — resolution is a separate
|
|
56
|
+
* call, so the format module stays readable with no environment in the process.
|
|
57
|
+
*/
|
|
58
|
+
export declare function readSecretRef(text: string): SecretRef;
|
|
59
|
+
/** True when this stored text would be resolved rather than typed. Cheap enough to call anywhere. */
|
|
60
|
+
export declare function isSecretRef(text: string): boolean;
|
|
61
|
+
/** What to write into a file so `variable` is resolved at replay. The one place the syntax is built. */
|
|
62
|
+
export declare function secretRefFor(variable: string): string;
|
|
63
|
+
export type SecretResolution = {
|
|
64
|
+
readonly resolved: true;
|
|
65
|
+
readonly value: string;
|
|
66
|
+
}
|
|
67
|
+
/** `reason` is already a whole sentence for a person, and never carries a value. */
|
|
68
|
+
| {
|
|
69
|
+
readonly resolved: false;
|
|
70
|
+
readonly reason: string;
|
|
71
|
+
};
|
|
72
|
+
/** Where a reference resolves from. A map, not `process.env` directly, so a replay can be given
|
|
73
|
+
* one — and so this file names no process global that a test would then have to mutate. */
|
|
74
|
+
export type SecretEnvironment = Readonly<Record<string, string | undefined>>;
|
|
75
|
+
/**
|
|
76
|
+
* Turns one stored `text` into the string to type, or says why it cannot.
|
|
77
|
+
*
|
|
78
|
+
* An unset variable and an empty one are both refusals. An empty variable is the shape a
|
|
79
|
+
* mistyped export takes — `PASSWORD=` in a `.env` that was never filled in — and typing an empty
|
|
80
|
+
* string into a login form produces a failed login that reads exactly like a broken application.
|
|
81
|
+
*/
|
|
82
|
+
export declare function resolveSecretText(text: string, env: SecretEnvironment): SecretResolution;
|
|
83
|
+
/** Every variable a scenario's steps reference, in order, deduplicated. What a preflight names
|
|
84
|
+
* to a developer, and what a runner checks before it opens a browser it will not be able to use. */
|
|
85
|
+
export declare function referencedVariables(texts: readonly (string | null)[]): readonly string[];
|
|
86
|
+
//# sourceMappingURL=secret-ref.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-ref.d.ts","sourceRoot":"","sources":["../../src/scenarios/secret-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAaH,MAAM,MAAM,SAAS;AACnB,gEAAgE;AAC9D;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACrD,gFAAgF;GAC9E;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AACrD,oFAAoF;GAClF;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAsBrD;AAED,qGAAqG;AACrG,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wGAAwG;AACxG,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACrD,oFAAoF;GAClF;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D;4FAC4F;AAC5F,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAE7E;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,GAAG,gBAAgB,CA2BxF;AAED;qGACqG;AACrG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,SAAS,MAAM,EAAE,CAQxF"}
|