@jevitate/cli 0.1.0 → 0.2.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/README.md +23 -0
- package/dist/ai-cli.js +40 -30
- package/dist/ai-cli.js.map +1 -1
- package/dist/author-journey-cli.d.ts +4 -0
- package/dist/author-journey-cli.js +109 -0
- package/dist/author-journey-cli.js.map +1 -0
- package/dist/bin.js +58077 -22454
- package/dist/bin.js.map +1 -1
- package/dist/browser-run-options.d.ts +58 -0
- package/dist/browser-run-options.js +106 -0
- package/dist/browser-run-options.js.map +1 -0
- package/dist/build-info.generated.d.ts +2 -0
- package/dist/build-info.generated.js +10 -0
- package/dist/build-info.generated.js.map +1 -0
- package/dist/check-api.d.ts +5 -0
- package/dist/check-api.js +233 -0
- package/dist/check-api.js.map +1 -0
- package/dist/check-budget.d.ts +26 -0
- package/dist/check-budget.js +89 -0
- package/dist/check-budget.js.map +1 -0
- package/dist/check-cli.d.ts +31 -0
- package/dist/check-cli.js +109 -0
- package/dist/check-cli.js.map +1 -0
- package/dist/check-execute.d.ts +25 -0
- package/dist/check-execute.js +385 -0
- package/dist/check-execute.js.map +1 -0
- package/dist/check-plan.d.ts +113 -0
- package/dist/check-plan.js +448 -0
- package/dist/check-plan.js.map +1 -0
- package/dist/check-suite.d.ts +171 -0
- package/dist/check-suite.js +515 -0
- package/dist/check-suite.js.map +1 -0
- package/dist/check-types.d.ts +181 -0
- package/dist/check-types.js +35 -0
- package/dist/check-types.js.map +1 -0
- package/dist/cli-args.d.ts +26 -0
- package/dist/cli-args.js +50 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-output.d.ts +102 -0
- package/dist/cli-output.js +516 -0
- package/dist/cli-output.js.map +1 -0
- package/dist/cli-reference.d.ts +3 -0
- package/dist/cli-reference.js +81 -0
- package/dist/cli-reference.js.map +1 -0
- package/dist/cli-refusal.d.ts +12 -0
- package/dist/cli-refusal.js +52 -0
- package/dist/cli-refusal.js.map +1 -0
- package/dist/cli-shared.d.ts +330 -0
- package/dist/cli-shared.js +492 -0
- package/dist/cli-shared.js.map +1 -0
- package/dist/cli-surface.d.ts +33 -0
- package/dist/cli-surface.js +48 -0
- package/dist/cli-surface.js.map +1 -0
- package/dist/conversation-options.d.ts +15 -0
- package/dist/conversation-options.js +10 -0
- package/dist/conversation-options.js.map +1 -0
- package/dist/credentials-file.d.ts +15 -0
- package/dist/credentials-file.js +56 -0
- package/dist/credentials-file.js.map +1 -0
- package/dist/data-dir.d.ts +1 -1
- package/dist/data-dir.js +1 -1
- package/dist/defect-evidence.d.ts +141 -0
- package/dist/defect-evidence.js +502 -0
- package/dist/defect-evidence.js.map +1 -0
- package/dist/demo-aspect-api.d.ts +209 -0
- package/dist/demo-aspect-api.js +397 -0
- package/dist/demo-aspect-api.js.map +1 -0
- package/dist/demo-aspect-cli.d.ts +3 -0
- package/dist/demo-aspect-cli.js +241 -0
- package/dist/demo-aspect-cli.js.map +1 -0
- package/dist/demo-capture.d.ts +108 -0
- package/dist/demo-capture.js +438 -0
- package/dist/demo-capture.js.map +1 -0
- package/dist/engine.d.ts +35 -0
- package/dist/engine.js +25 -0
- package/dist/engine.js.map +1 -0
- package/dist/environments.d.ts +155 -0
- package/dist/environments.js +364 -0
- package/dist/environments.js.map +1 -0
- package/dist/exit-codes.d.ts +46 -0
- package/dist/exit-codes.js +91 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/explore-adversarial.d.ts +137 -0
- package/dist/explore-adversarial.js +218 -0
- package/dist/explore-adversarial.js.map +1 -0
- package/dist/explore-api.d.ts +7 -187
- package/dist/explore-api.js +7 -301
- package/dist/explore-api.js.map +1 -1
- package/dist/explore-author.d.ts +79 -0
- package/dist/explore-author.js +86 -0
- package/dist/explore-author.js.map +1 -0
- package/dist/explore-cli.d.ts +7 -0
- package/dist/explore-cli.js +963 -0
- package/dist/explore-cli.js.map +1 -0
- package/dist/explore-coverage.d.ts +158 -0
- package/dist/explore-coverage.js +240 -0
- package/dist/explore-coverage.js.map +1 -0
- package/dist/explore-feature.d.ts +127 -0
- package/dist/explore-feature.js +220 -0
- package/dist/explore-feature.js.map +1 -0
- package/dist/explore-goal.d.ts +253 -0
- package/dist/explore-goal.js +374 -0
- package/dist/explore-goal.js.map +1 -0
- package/dist/explore-shared.d.ts +152 -0
- package/dist/explore-shared.js +129 -0
- package/dist/explore-shared.js.map +1 -0
- package/dist/explore-specs.d.ts +53 -0
- package/dist/explore-specs.js +333 -0
- package/dist/explore-specs.js.map +1 -0
- package/dist/findings-filing.d.ts +64 -0
- package/dist/findings-filing.js +108 -0
- package/dist/findings-filing.js.map +1 -0
- package/dist/fixture-auth.d.ts +52 -0
- package/dist/fixture-auth.js +82 -0
- package/dist/fixture-auth.js.map +1 -0
- package/dist/fixture-cli.d.ts +70 -0
- package/dist/fixture-cli.js +178 -0
- package/dist/fixture-cli.js.map +1 -0
- package/dist/github-issue-filer.d.ts +62 -0
- package/dist/github-issue-filer.js +188 -0
- package/dist/github-issue-filer.js.map +1 -0
- package/dist/host-health-run.d.ts +24 -0
- package/dist/host-health-run.js +27 -0
- package/dist/host-health-run.js.map +1 -0
- package/dist/http-5xx-outcome.d.ts +6 -0
- package/dist/http-5xx-outcome.js +39 -0
- package/dist/http-5xx-outcome.js.map +1 -0
- package/dist/inbox-cli.d.ts +7 -0
- package/dist/inbox-cli.js +197 -0
- package/dist/inbox-cli.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init-cli.d.ts +4 -0
- package/dist/init-cli.js +127 -0
- package/dist/init-cli.js.map +1 -0
- package/dist/init-keys.d.ts +19 -2
- package/dist/init-keys.js +15 -4
- package/dist/init-keys.js.map +1 -1
- package/dist/init-next-steps.d.ts +35 -0
- package/dist/init-next-steps.js +79 -0
- package/dist/init-next-steps.js.map +1 -0
- package/dist/invariants-file.d.ts +34 -0
- package/dist/invariants-file.js +68 -0
- package/dist/invariants-file.js.map +1 -0
- package/dist/invariants-validate.d.ts +30 -0
- package/dist/invariants-validate.js +105 -0
- package/dist/invariants-validate.js.map +1 -0
- package/dist/journey-annotate-api.d.ts +76 -0
- package/dist/journey-annotate-api.js +256 -0
- package/dist/journey-annotate-api.js.map +1 -0
- package/dist/journey-annotate-cli.d.ts +9 -0
- package/dist/journey-annotate-cli.js +179 -0
- package/dist/journey-annotate-cli.js.map +1 -0
- package/dist/journey-api.d.ts +79 -2
- package/dist/journey-api.js +136 -19
- package/dist/journey-api.js.map +1 -1
- package/dist/journey-cli.d.ts +4 -0
- package/dist/journey-cli.js +370 -0
- package/dist/journey-cli.js.map +1 -0
- package/dist/journey-demo-api.d.ts +112 -0
- package/dist/journey-demo-api.js +392 -0
- package/dist/journey-demo-api.js.map +1 -0
- package/dist/journey-demo-cli.d.ts +10 -0
- package/dist/journey-demo-cli.js +155 -0
- package/dist/journey-demo-cli.js.map +1 -0
- package/dist/kill-signal.d.ts +193 -0
- package/dist/kill-signal.js +284 -0
- package/dist/kill-signal.js.map +1 -0
- package/dist/launch-armed.d.ts +37 -0
- package/dist/launch-armed.js +31 -0
- package/dist/launch-armed.js.map +1 -0
- package/dist/ledger-api.d.ts +106 -0
- package/dist/ledger-api.js +237 -0
- package/dist/ledger-api.js.map +1 -0
- package/dist/ledger-cli.d.ts +18 -0
- package/dist/ledger-cli.js +107 -0
- package/dist/ledger-cli.js.map +1 -0
- package/dist/load-api.d.ts +29 -11
- package/dist/load-api.js +23 -15
- package/dist/load-api.js.map +1 -1
- package/dist/load-cli.d.ts +4 -0
- package/dist/load-cli.js +97 -0
- package/dist/load-cli.js.map +1 -0
- package/dist/log-correlation.d.ts +147 -0
- package/dist/log-correlation.js +325 -0
- package/dist/log-correlation.js.map +1 -0
- package/dist/log-lines.d.ts +131 -0
- package/dist/log-lines.js +389 -0
- package/dist/log-lines.js.map +1 -0
- package/dist/log-sources.d.ts +71 -0
- package/dist/log-sources.js +235 -0
- package/dist/log-sources.js.map +1 -0
- package/dist/logs-cli.d.ts +3 -0
- package/dist/logs-cli.js +51 -0
- package/dist/logs-cli.js.map +1 -0
- package/dist/logs-retention.d.ts +28 -0
- package/dist/logs-retention.js +84 -0
- package/dist/logs-retention.js.map +1 -0
- package/dist/mcp-api.d.ts +89 -1
- package/dist/mcp-api.js +472 -18
- package/dist/mcp-api.js.map +1 -1
- package/dist/mcp-args.d.ts +38 -0
- package/dist/mcp-args.js +131 -0
- package/dist/mcp-args.js.map +1 -0
- package/dist/mcp-cli-bridge.d.ts +34 -0
- package/dist/mcp-cli-bridge.js +62 -0
- package/dist/mcp-cli-bridge.js.map +1 -0
- package/dist/mcp-cli-runner.d.ts +29 -0
- package/dist/mcp-cli-runner.js +44 -0
- package/dist/mcp-cli-runner.js.map +1 -0
- package/dist/mcp-cli-tools.d.ts +125 -0
- package/dist/mcp-cli-tools.js +680 -0
- package/dist/mcp-cli-tools.js.map +1 -0
- package/dist/mcp-paths.d.ts +28 -0
- package/dist/mcp-paths.js +76 -0
- package/dist/mcp-paths.js.map +1 -0
- package/dist/mission-actors.d.ts +40 -0
- package/dist/mission-actors.js +72 -0
- package/dist/mission-actors.js.map +1 -0
- package/dist/mission-api.d.ts +35 -0
- package/dist/mission-api.js +58 -2
- package/dist/mission-api.js.map +1 -1
- package/dist/mission-cli.d.ts +4 -0
- package/dist/mission-cli.js +247 -0
- package/dist/mission-cli.js.map +1 -0
- package/dist/mission-exit.d.ts +22 -0
- package/dist/mission-exit.js +26 -0
- package/dist/mission-exit.js.map +1 -0
- package/dist/mission-fixtures.d.ts +225 -0
- package/dist/mission-fixtures.js +828 -0
- package/dist/mission-fixtures.js.map +1 -0
- package/dist/mission-journal.d.ts +60 -0
- package/dist/mission-journal.js +115 -0
- package/dist/mission-journal.js.map +1 -0
- package/dist/mission-queue-cli.d.ts +10 -0
- package/dist/mission-queue-cli.js +198 -0
- package/dist/mission-queue-cli.js.map +1 -0
- package/dist/mission-queue-runner.d.ts +126 -0
- package/dist/mission-queue-runner.js +397 -0
- package/dist/mission-queue-runner.js.map +1 -0
- package/dist/multi-run-cli.d.ts +37 -0
- package/dist/multi-run-cli.js +110 -0
- package/dist/multi-run-cli.js.map +1 -0
- package/dist/multi-run.d.ts +339 -0
- package/dist/multi-run.js +619 -0
- package/dist/multi-run.js.map +1 -0
- package/dist/openrouter-call.d.ts +22 -0
- package/dist/openrouter-call.js +63 -0
- package/dist/openrouter-call.js.map +1 -0
- package/dist/profile-cli.d.ts +4 -0
- package/dist/profile-cli.js +57 -0
- package/dist/profile-cli.js.map +1 -0
- package/dist/program.d.ts +3 -75
- package/dist/program.js +119 -1921
- package/dist/program.js.map +1 -1
- package/dist/project-dir.d.ts +96 -0
- package/dist/project-dir.js +220 -0
- package/dist/project-dir.js.map +1 -0
- package/dist/record-api.d.ts +10 -6
- package/dist/record-api.js +39 -28
- package/dist/record-api.js.map +1 -1
- package/dist/record-cli.d.ts +4 -0
- package/dist/record-cli.js +64 -0
- package/dist/record-cli.js.map +1 -0
- package/dist/recording-cli.d.ts +4 -0
- package/dist/recording-cli.js +248 -0
- package/dist/recording-cli.js.map +1 -0
- package/dist/regression-api.d.ts +101 -0
- package/dist/regression-api.js +384 -5
- package/dist/regression-api.js.map +1 -1
- package/dist/regression-cli.d.ts +4 -0
- package/dist/regression-cli.js +232 -0
- package/dist/regression-cli.js.map +1 -0
- package/dist/report-api.d.ts +146 -0
- package/dist/report-api.js +430 -0
- package/dist/report-api.js.map +1 -0
- package/dist/report-cli.d.ts +12 -0
- package/dist/report-cli.js +147 -0
- package/dist/report-cli.js.map +1 -0
- package/dist/result-schema.d.ts +22 -0
- package/dist/result-schema.js +28 -0
- package/dist/result-schema.js.map +1 -0
- package/dist/run-index.d.ts +29 -0
- package/dist/run-index.js +70 -0
- package/dist/run-index.js.map +1 -0
- package/dist/run-screenshots.d.ts +123 -0
- package/dist/run-screenshots.js +229 -0
- package/dist/run-screenshots.js.map +1 -0
- package/dist/runtime-env.d.ts +8 -0
- package/dist/runtime-env.js +22 -0
- package/dist/runtime-env.js.map +1 -0
- package/dist/secret-args.d.ts +23 -0
- package/dist/secret-args.js +45 -0
- package/dist/secret-args.js.map +1 -0
- package/dist/serve-cli.d.ts +4 -0
- package/dist/serve-cli.js +95 -0
- package/dist/serve-cli.js.map +1 -0
- package/dist/server-log-verify.d.ts +34 -0
- package/dist/server-log-verify.js +115 -0
- package/dist/server-log-verify.js.map +1 -0
- package/dist/session-check.d.ts +14 -0
- package/dist/session-check.js +44 -0
- package/dist/session-check.js.map +1 -0
- package/dist/site-cli.d.ts +4 -0
- package/dist/site-cli.js +127 -0
- package/dist/site-cli.js.map +1 -0
- package/dist/site-gate-cli.d.ts +28 -0
- package/dist/site-gate-cli.js +58 -0
- package/dist/site-gate-cli.js.map +1 -0
- package/dist/source-api.js +18 -3
- package/dist/source-api.js.map +1 -1
- package/dist/source-cli.d.ts +4 -0
- package/dist/source-cli.js +284 -0
- package/dist/source-cli.js.map +1 -0
- package/dist/source-run-api.d.ts +27 -1
- package/dist/source-run-api.js +22 -11
- package/dist/source-run-api.js.map +1 -1
- package/dist/storage-state-snapshot.d.ts +50 -0
- package/dist/storage-state-snapshot.js +87 -0
- package/dist/storage-state-snapshot.js.map +1 -0
- package/dist/suite-explore-options.d.ts +289 -0
- package/dist/suite-explore-options.js +140 -0
- package/dist/suite-explore-options.js.map +1 -0
- package/dist/target-config.d.ts +109 -0
- package/dist/target-config.js +216 -0
- package/dist/target-config.js.map +1 -0
- package/dist/transcript-file.d.ts +12 -0
- package/dist/transcript-file.js +23 -0
- package/dist/transcript-file.js.map +1 -0
- package/dist/ui-api.d.ts +3 -0
- package/dist/ui-api.js +7 -1
- package/dist/ui-api.js.map +1 -1
- package/dist/usability-capture.d.ts +43 -0
- package/dist/usability-capture.js +326 -0
- package/dist/usability-capture.js.map +1 -0
- package/dist/usage-config.d.ts +36 -0
- package/dist/usage-config.js +114 -0
- package/dist/usage-config.js.map +1 -0
- package/dist/ux-api.d.ts +3 -75
- package/dist/ux-api.js +3 -220
- package/dist/ux-api.js.map +1 -1
- package/dist/ux-cli.d.ts +4 -0
- package/dist/ux-cli.js +102 -0
- package/dist/ux-cli.js.map +1 -0
- package/dist/ux-config.d.ts +29 -0
- package/dist/ux-config.js +103 -0
- package/dist/ux-config.js.map +1 -0
- package/dist/ux-evidence.d.ts +54 -0
- package/dist/ux-evidence.js +197 -0
- package/dist/ux-evidence.js.map +1 -0
- package/dist/ux-review.d.ts +112 -0
- package/dist/ux-review.js +151 -0
- package/dist/ux-review.js.map +1 -0
- package/dist/ux-usability.d.ts +238 -0
- package/dist/ux-usability.js +494 -0
- package/dist/ux-usability.js.map +1 -0
- package/dist/verify-fix-api.d.ts +173 -0
- package/dist/verify-fix-api.js +454 -0
- package/dist/verify-fix-api.js.map +1 -0
- package/dist/verify-fix-cli.d.ts +4 -0
- package/dist/verify-fix-cli.js +110 -0
- package/dist/verify-fix-cli.js.map +1 -0
- package/package.json +19 -14
- package/skills/jevitate-ci-check/SKILL.md +77 -0
- package/skills/jevitate-demo/SKILL.md +61 -0
- package/skills/jevitate-explore/SKILL.md +88 -87
- package/skills/jevitate-getting-started/SKILL.md +88 -0
- package/skills/jevitate-load-test/SKILL.md +11 -2
- package/skills/jevitate-mission-scope/SKILL.md +19 -11
- package/skills/jevitate-record/SKILL.md +23 -5
- package/skills/jevitate-run-journey/SKILL.md +61 -17
- package/skills/jevitate-sources/SKILL.md +57 -14
- package/skills/jevitate-ux-review/SKILL.md +106 -16
- package/skills/jevitate-verify-fix/SKILL.md +76 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/** Wiring shared by every explore strategy runner (goal, coverage, adversarial, feature): server-log and declared-invariant result fields, storageState persistence, drafts/filing context. */
|
|
2
|
+
import { chmod, writeFile } from "node:fs/promises";
|
|
3
|
+
import { assertSessionFileOutsideProject } from "./project-dir.js";
|
|
4
|
+
import { CastActor, BrowseTheWeb } from "@jevitate/screenplay";
|
|
5
|
+
import { currentEnvironment, isLoginLikeUrl, } from "@jevitate/explore";
|
|
6
|
+
import { readCliVersion } from "./version.js";
|
|
7
|
+
export function serverLogResult(runtimeResult) {
|
|
8
|
+
if (runtimeResult === undefined)
|
|
9
|
+
return {};
|
|
10
|
+
return { serverLogs: runtimeResult.summary, ...(runtimeResult.defects.length > 0 ? { serverLogDefects: runtimeResult.defects } : {}) };
|
|
11
|
+
}
|
|
12
|
+
/** The viewport/device emulation actually applied to a session — recorded on the Recording (#149). */
|
|
13
|
+
export function recordingEmulation(resolved) {
|
|
14
|
+
if (resolved === undefined)
|
|
15
|
+
return undefined;
|
|
16
|
+
return {
|
|
17
|
+
viewport: resolved.viewport,
|
|
18
|
+
...(resolved.device === undefined ? {} : { device: resolved.device }),
|
|
19
|
+
...(resolved.deviceScaleFactor === undefined ? {} : { deviceScaleFactor: resolved.deviceScaleFactor }),
|
|
20
|
+
...(resolved.isMobile === undefined ? {} : { isMobile: resolved.isMobile }),
|
|
21
|
+
...(resolved.hasTouch === undefined ? {} : { hasTouch: resolved.hasTouch }),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Filing is off by default: drafts only, never a tracker call. */
|
|
25
|
+
export const DRAFTS_ONLY = { enabled: false, jevitateRepo: "matt-cochran/jevitate" };
|
|
26
|
+
export const NO_FILER = () => {
|
|
27
|
+
throw new Error("issue filing is enabled but no filer was configured");
|
|
28
|
+
};
|
|
29
|
+
export function draftContext(origin, journal, secrets, browserVersion, engine) {
|
|
30
|
+
return {
|
|
31
|
+
environment: currentEnvironment(origin, {
|
|
32
|
+
jevitateVersion: readCliVersion(),
|
|
33
|
+
commit: engine.commit,
|
|
34
|
+
builtAt: engine.builtAt,
|
|
35
|
+
...(browserVersion === undefined ? {} : { browser: browserVersion }),
|
|
36
|
+
}),
|
|
37
|
+
recordingPath: journal.recordingPath,
|
|
38
|
+
transcriptPath: journal.transcriptPath,
|
|
39
|
+
secrets,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Opens a FRESH browser session for replays (hang reproduction): a new context from the same port
|
|
44
|
+
* and options — same authenticated storageState, never the session the finding was made in.
|
|
45
|
+
*/
|
|
46
|
+
export function freshSessionOpener(portFactory, launch, allowlist) {
|
|
47
|
+
return async () => {
|
|
48
|
+
const session = await portFactory().open(launch);
|
|
49
|
+
const actor = CastActor.named("replay").whoCan(new BrowseTheWeb(session, [...allowlist]));
|
|
50
|
+
return { page: session.page, actor, close: () => session.close() };
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** `session.page.url()`, or `undefined` when reading it throws (a closed/crashed page/context). */
|
|
54
|
+
export function currentUrlSafe(session) {
|
|
55
|
+
try {
|
|
56
|
+
return session.page.url();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Writes the browser context's storageState (cookies + origin storage) to `file` when the caller
|
|
64
|
+
* asked for one (CLI `--save-storage-state`, #82) — so a rotating refresh token stays usable across
|
|
65
|
+
* runs instead of the `--storage-state` file it started from going stale on first use. Called from
|
|
66
|
+
* every mission's `finally`, so a thrown error still reaches it (#159) — the context is still open at
|
|
67
|
+
* that point, whatever failed inside the mission itself. A no-op when `file` is undefined.
|
|
68
|
+
*
|
|
69
|
+
* #159 — never persists a lost/logged-out session over a good file: when the CURRENT page looks
|
|
70
|
+
* login-like (`isLoginLikeUrl`, the #82 signal), a live capture is skipped in favor of `snapshotter`'s
|
|
71
|
+
* last known-good in-memory snapshot (refreshed after each settled step — see
|
|
72
|
+
* `storage-state-snapshot.ts` — and itself never updated from a login-like page, so it always holds
|
|
73
|
+
* the most recent GOOD state). The same fallback covers a live capture that simply fails (a
|
|
74
|
+
* crashed/closed context after the page url could still be read). If neither a safe live capture nor
|
|
75
|
+
* a snapshot is available, nothing is written — any existing file at `file` is left untouched. There
|
|
76
|
+
* is no flag today for an operator to force the write anyway; see `saveStorageState`'s own doc.
|
|
77
|
+
*
|
|
78
|
+
* The file holds live session credentials: written with mode 0600 (owner read/write only), and its
|
|
79
|
+
* contents are never logged either way.
|
|
80
|
+
*/
|
|
81
|
+
/**
|
|
82
|
+
* #195: refused BEFORE a browser opens — a `saveStorageState` inside a repo's `.jevitate/` (which
|
|
83
|
+
* never holds sessions or secrets). `persistStorageState` re-checks at the write itself.
|
|
84
|
+
*/
|
|
85
|
+
export function assertSaveStorageStateOutsideProject(file) {
|
|
86
|
+
if (file !== undefined)
|
|
87
|
+
assertSessionFileOutsideProject(file, "saveStorageState");
|
|
88
|
+
}
|
|
89
|
+
export async function persistStorageState(session, file, snapshotter) {
|
|
90
|
+
if (file === undefined)
|
|
91
|
+
return;
|
|
92
|
+
// #195: the final chokepoint for every caller — nothing is written inside a repo's .jevitate/;
|
|
93
|
+
// the refusal is thrown (the run reports it), never swallowed.
|
|
94
|
+
assertSessionFileOutsideProject(file, "saveStorageState");
|
|
95
|
+
const url = currentUrlSafe(session);
|
|
96
|
+
if (url === undefined || !isLoginLikeUrl(url)) {
|
|
97
|
+
try {
|
|
98
|
+
await session.saveStorageState(file);
|
|
99
|
+
await chmod(file, 0o600);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// A crashed/closed context, or a mid-write failure — fall back to the last known-good snapshot.
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const fallback = snapshotter?.snapshot();
|
|
107
|
+
if (fallback === undefined)
|
|
108
|
+
return;
|
|
109
|
+
await writeFile(file, fallback, { encoding: "utf8", mode: 0o600 });
|
|
110
|
+
}
|
|
111
|
+
export function browserVersionOf(page) {
|
|
112
|
+
try {
|
|
113
|
+
return page.context().browser()?.version();
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The declared-invariant fields of a persisted result (#86): the defects (top-level `defects`, where
|
|
121
|
+
* `verify-fix` looks), the per-invariant report, and the spec itself so a later `verify-fix`
|
|
122
|
+
* re-checks exactly what the run checked. Nothing at all when the run had no `--invariants`.
|
|
123
|
+
*/
|
|
124
|
+
export function declaredResult(spec, defects, report) {
|
|
125
|
+
if (spec === undefined)
|
|
126
|
+
return {};
|
|
127
|
+
return { defects: [...(defects ?? [])], invariants: [...(report ?? [])], invariantSpec: spec };
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=explore-shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore-shared.js","sourceRoot":"","sources":["../src/explore-shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** The compact `--success`/assertion/descriptor spec parsers and the explore allowlist resolution behind the explore CLI flags. */
|
|
2
|
+
import { type Assertion } from "@jevitate/recording";
|
|
3
|
+
import { type SuccessCheck } from "@jevitate/explore";
|
|
4
|
+
/**
|
|
5
|
+
* Compact assertion spec parser (a recording `Assertion`, checked on a page). Supported forms:
|
|
6
|
+
* urlIncludes:<text>
|
|
7
|
+
* visible:<descriptor>
|
|
8
|
+
* textIncludes:<descriptor>|<text> — case-insensitive (#113): matches regardless of case, or of a
|
|
9
|
+
* CSS text-transform (a badge whose DOM text is "Approved" but
|
|
10
|
+
* renders `uppercase` still matches `|Approved`)
|
|
11
|
+
* count:<descriptor>|min=<n>,max=<n>
|
|
12
|
+
* valueEquals:<descriptor>|<value> — a form control's VALUE (input, textarea, select), exactly
|
|
13
|
+
* and the visual-state kinds (#148), decided by code from fixed page reads:
|
|
14
|
+
* style:<descriptor>|<prop><op><value> — the COMPUTED style of EVERY match (at least one);
|
|
15
|
+
* <prop> is an allowlisted CSS property, optionally one
|
|
16
|
+
* channel of it: alpha(background-color)>0, px(outline-width)>=2;
|
|
17
|
+
* <op> is = != > >= < <= (= compares colors as colors).
|
|
18
|
+
* `styleMatches:` is an alias.
|
|
19
|
+
* inViewport:<descriptor>[|min=<ratio>] — each match's visible fraction (0..1, default 0.5)
|
|
20
|
+
* box:<descriptor>|minWidth=<n>,maxWidth=<n>,minHeight=<n>,maxHeight=<n> — each match's size (px)
|
|
21
|
+
* overlaps:<descriptor>|<descriptor2> / noOverlap:<descriptor>|<descriptor2> — the first matches' boxes
|
|
22
|
+
* attr:<descriptor>|<name>=<value> | attr:<descriptor>|<name> (present) | attr:<descriptor>|!<name> (absent)
|
|
23
|
+
* flashed:<descriptor>|class=<cls>|attr=<name>|animation [|withinMs=<n>] — a match GAINED the
|
|
24
|
+
* class / attribute / an animation after the last user input
|
|
25
|
+
* where <descriptor> is `k=v` pairs joined by `;` over testId/role/name/label/text/css
|
|
26
|
+
* (`css=h1`, `label=Display name`, `role=button;name=Save`) — key=value always wins, so a `=` is
|
|
27
|
+
* never read as CSS or text. With no `=` at all, a descriptor starting with `[`, `#` or `.` is CSS
|
|
28
|
+
* verbatim (`[data-testid=x]` becomes `testId=x`); any OTHER bare descriptor is read as CSS too, but
|
|
29
|
+
* only when it is a lowercase-only, syntactically valid CSS selector (#213: `h1`, `main h1`, `body`,
|
|
30
|
+
* `div.card`, `ul > li` — tag names, combinators, classes, ids, attributes, pseudo-classes; every
|
|
31
|
+
* character lowercase is what tells a real selector apart from an accessible-name phrase like
|
|
32
|
+
* `Display name`, which is never guessed at as either CSS or text). Anything that is not a valid
|
|
33
|
+
* key=value spec and not a lowercase CSS selector is refused with a hint naming the key=value forms
|
|
34
|
+
* (`css=`, `label=`, `testId=`, `role=`, `text=`) and an example. In `textIncludes` / `valueEquals`
|
|
35
|
+
* the LAST `|` separates the descriptor from the text.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseAssertionSpec(spec: string): Assertion;
|
|
38
|
+
/**
|
|
39
|
+
* The goal mission's `--success` spec parser (repeatable: every check must hold). Besides every
|
|
40
|
+
* page assertion `parseAssertionSpec` reads:
|
|
41
|
+
* reloadThen:<assertion> — reload the page, then check (persistence)
|
|
42
|
+
* requestMade:<METHOD> <path-glob> — the run issued this request
|
|
43
|
+
* responseStatus:<METHOD> <path-glob>=<2xx|4xx|code> — and it got this status
|
|
44
|
+
* `<path-glob>` uses the route-glob syntax (`*` within a segment, `**` across segments) against
|
|
45
|
+
* the request's path; `*` as METHOD matches any method.
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseSuccessSpec(spec: string): SuccessCheck;
|
|
48
|
+
/**
|
|
49
|
+
* The authorized-origins allowlist for a run: explicit `--allow` origins when
|
|
50
|
+
* given, otherwise the target URL's own origin (you asked to explore it). An
|
|
51
|
+
* unparseable URL yields an empty allowlist → the guard fails closed.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveExploreAllowlist(url: string, allow: readonly string[]): string[];
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/** The compact `--success`/assertion/descriptor spec parsers and the explore allowlist resolution behind the explore CLI flags. */
|
|
2
|
+
import { AssertionSchema, STYLE_CHANNELS, STYLE_PROPERTIES, COMPARE_OPS, } from "@jevitate/recording";
|
|
3
|
+
import { normalizeAllowlist } from "@jevitate/explore";
|
|
4
|
+
/**
|
|
5
|
+
* Compact assertion spec parser (a recording `Assertion`, checked on a page). Supported forms:
|
|
6
|
+
* urlIncludes:<text>
|
|
7
|
+
* visible:<descriptor>
|
|
8
|
+
* textIncludes:<descriptor>|<text> — case-insensitive (#113): matches regardless of case, or of a
|
|
9
|
+
* CSS text-transform (a badge whose DOM text is "Approved" but
|
|
10
|
+
* renders `uppercase` still matches `|Approved`)
|
|
11
|
+
* count:<descriptor>|min=<n>,max=<n>
|
|
12
|
+
* valueEquals:<descriptor>|<value> — a form control's VALUE (input, textarea, select), exactly
|
|
13
|
+
* and the visual-state kinds (#148), decided by code from fixed page reads:
|
|
14
|
+
* style:<descriptor>|<prop><op><value> — the COMPUTED style of EVERY match (at least one);
|
|
15
|
+
* <prop> is an allowlisted CSS property, optionally one
|
|
16
|
+
* channel of it: alpha(background-color)>0, px(outline-width)>=2;
|
|
17
|
+
* <op> is = != > >= < <= (= compares colors as colors).
|
|
18
|
+
* `styleMatches:` is an alias.
|
|
19
|
+
* inViewport:<descriptor>[|min=<ratio>] — each match's visible fraction (0..1, default 0.5)
|
|
20
|
+
* box:<descriptor>|minWidth=<n>,maxWidth=<n>,minHeight=<n>,maxHeight=<n> — each match's size (px)
|
|
21
|
+
* overlaps:<descriptor>|<descriptor2> / noOverlap:<descriptor>|<descriptor2> — the first matches' boxes
|
|
22
|
+
* attr:<descriptor>|<name>=<value> | attr:<descriptor>|<name> (present) | attr:<descriptor>|!<name> (absent)
|
|
23
|
+
* flashed:<descriptor>|class=<cls>|attr=<name>|animation [|withinMs=<n>] — a match GAINED the
|
|
24
|
+
* class / attribute / an animation after the last user input
|
|
25
|
+
* where <descriptor> is `k=v` pairs joined by `;` over testId/role/name/label/text/css
|
|
26
|
+
* (`css=h1`, `label=Display name`, `role=button;name=Save`) — key=value always wins, so a `=` is
|
|
27
|
+
* never read as CSS or text. With no `=` at all, a descriptor starting with `[`, `#` or `.` is CSS
|
|
28
|
+
* verbatim (`[data-testid=x]` becomes `testId=x`); any OTHER bare descriptor is read as CSS too, but
|
|
29
|
+
* only when it is a lowercase-only, syntactically valid CSS selector (#213: `h1`, `main h1`, `body`,
|
|
30
|
+
* `div.card`, `ul > li` — tag names, combinators, classes, ids, attributes, pseudo-classes; every
|
|
31
|
+
* character lowercase is what tells a real selector apart from an accessible-name phrase like
|
|
32
|
+
* `Display name`, which is never guessed at as either CSS or text). Anything that is not a valid
|
|
33
|
+
* key=value spec and not a lowercase CSS selector is refused with a hint naming the key=value forms
|
|
34
|
+
* (`css=`, `label=`, `testId=`, `role=`, `text=`) and an example. In `textIncludes` / `valueEquals`
|
|
35
|
+
* the LAST `|` separates the descriptor from the text.
|
|
36
|
+
*/
|
|
37
|
+
export function parseAssertionSpec(spec) {
|
|
38
|
+
const ci = spec.indexOf(":");
|
|
39
|
+
if (ci === -1)
|
|
40
|
+
throw new Error(`invalid --success spec ${JSON.stringify(spec)}; expected "<kind>:<...>"`);
|
|
41
|
+
const kind = spec.slice(0, ci);
|
|
42
|
+
const rest = spec.slice(ci + 1);
|
|
43
|
+
switch (kind) {
|
|
44
|
+
case "urlIncludes": {
|
|
45
|
+
if (rest === "")
|
|
46
|
+
throw new Error("urlIncludes requires a text (urlIncludes:/path)");
|
|
47
|
+
return { kind: "urlIncludes", text: rest };
|
|
48
|
+
}
|
|
49
|
+
case "visible":
|
|
50
|
+
return { kind: "visible", target: parseDescriptorSpec(rest) };
|
|
51
|
+
case "textIncludes": {
|
|
52
|
+
const bar = rest.lastIndexOf("|");
|
|
53
|
+
if (bar === -1)
|
|
54
|
+
throw new Error('textIncludes requires "<descriptor>|<text>"');
|
|
55
|
+
return { kind: "textIncludes", target: parseDescriptorSpec(rest.slice(0, bar)), text: rest.slice(bar + 1) };
|
|
56
|
+
}
|
|
57
|
+
case "valueEquals": {
|
|
58
|
+
const bar = rest.lastIndexOf("|");
|
|
59
|
+
if (bar === -1)
|
|
60
|
+
throw new Error('valueEquals requires "<descriptor>|<value>"');
|
|
61
|
+
return { kind: "valueEquals", target: parseDescriptorSpec(rest.slice(0, bar)), value: rest.slice(bar + 1) };
|
|
62
|
+
}
|
|
63
|
+
case "count": {
|
|
64
|
+
const bar = rest.indexOf("|");
|
|
65
|
+
const descPart = bar === -1 ? rest : rest.slice(0, bar);
|
|
66
|
+
const bounds = bar === -1 ? "" : rest.slice(bar + 1);
|
|
67
|
+
const target = parseDescriptorSpec(descPart);
|
|
68
|
+
const out = { kind: "count", target };
|
|
69
|
+
for (const pair of bounds.split(",")) {
|
|
70
|
+
const [k, v] = pair.split("=");
|
|
71
|
+
if (k === "min" && v)
|
|
72
|
+
out.min = Number(v);
|
|
73
|
+
if (k === "max" && v)
|
|
74
|
+
out.max = Number(v);
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
case "style":
|
|
79
|
+
case "styleMatches":
|
|
80
|
+
case "inViewport":
|
|
81
|
+
case "box":
|
|
82
|
+
case "overlaps":
|
|
83
|
+
case "noOverlap":
|
|
84
|
+
case "attr":
|
|
85
|
+
case "flashed":
|
|
86
|
+
return parseVisualSpec(kind, rest);
|
|
87
|
+
default:
|
|
88
|
+
throw new Error(`unsupported assertion kind ${JSON.stringify(kind)}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** A finite number from a spec, or a precise error. */
|
|
92
|
+
function specNumber(kind, key, v) {
|
|
93
|
+
const n = v === undefined || v.trim() === "" ? Number.NaN : Number(v);
|
|
94
|
+
if (!Number.isFinite(n))
|
|
95
|
+
throw new Error(`${kind}: ${key} must be a number, got ${JSON.stringify(v ?? "")}`);
|
|
96
|
+
return n;
|
|
97
|
+
}
|
|
98
|
+
/** `<descriptor>|<rest>` split at the FIRST `|`; `rest` required unless `optional`. */
|
|
99
|
+
function splitDescriptor(kind, spec, shape, optional = false) {
|
|
100
|
+
const bar = spec.indexOf("|");
|
|
101
|
+
if (bar === -1 && !optional)
|
|
102
|
+
throw new Error(`${kind} requires "${shape}"`);
|
|
103
|
+
return [parseDescriptorSpec(bar === -1 ? spec : spec.slice(0, bar)), bar === -1 ? "" : spec.slice(bar + 1)];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The visual-state assertion specs (#148) — see `parseAssertionSpec`. Validated through the
|
|
107
|
+
* recording `AssertionSchema` (the allowlisted properties, a closed set of ops/channels), so a typo
|
|
108
|
+
* fails here, before any browser work.
|
|
109
|
+
*/
|
|
110
|
+
/** `<prop><op><value>` / `<channel>(<prop>)<op><value>` — ops from the shared `COMPARE_OPS` (longest first). */
|
|
111
|
+
const STYLE_CHECK_RE = new RegExp(String.raw `^\s*(?:([a-z]+)\(\s*([a-z-]+)\s*\)|([a-z-]+))\s*(${COMPARE_OPS.join("|")})\s*(.*)$`);
|
|
112
|
+
function parseVisualSpec(kind, rest) {
|
|
113
|
+
let out;
|
|
114
|
+
switch (kind) {
|
|
115
|
+
case "style":
|
|
116
|
+
case "styleMatches": {
|
|
117
|
+
// The descriptor ends at the LAST `|` (a style value never contains one).
|
|
118
|
+
const bar = rest.lastIndexOf("|");
|
|
119
|
+
if (bar === -1)
|
|
120
|
+
throw new Error(`${kind} requires "<descriptor>|<prop><op><value>", e.g. ${kind}:[data-heat]|alpha(background-color)>0`);
|
|
121
|
+
const target = parseDescriptorSpec(rest.slice(0, bar));
|
|
122
|
+
const m = STYLE_CHECK_RE.exec(rest.slice(bar + 1));
|
|
123
|
+
if (m === null)
|
|
124
|
+
throw new Error(`${kind}: expected <prop><op><value> (op = != > >= < <=), got ${JSON.stringify(rest.slice(bar + 1))}`);
|
|
125
|
+
const channel = m[1];
|
|
126
|
+
const property = m[2] ?? m[3] ?? "";
|
|
127
|
+
if (channel !== undefined && !STYLE_CHANNELS.includes(channel)) {
|
|
128
|
+
throw new Error(`${kind}: unknown channel ${JSON.stringify(channel)} (one of ${STYLE_CHANNELS.join(", ")})`);
|
|
129
|
+
}
|
|
130
|
+
if (!STYLE_PROPERTIES.includes(property)) {
|
|
131
|
+
throw new Error(`${kind}: property ${JSON.stringify(property)} is not allowlisted (one of ${STYLE_PROPERTIES.join(", ")})`);
|
|
132
|
+
}
|
|
133
|
+
out = {
|
|
134
|
+
kind: "style",
|
|
135
|
+
target,
|
|
136
|
+
property: property,
|
|
137
|
+
...(channel === undefined ? {} : { channel: channel }),
|
|
138
|
+
op: m[4],
|
|
139
|
+
value: (m[5] ?? "").trim(),
|
|
140
|
+
};
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case "inViewport": {
|
|
144
|
+
const [target, opts] = splitDescriptor(kind, rest, "<descriptor>[|min=<ratio>]", true);
|
|
145
|
+
out = { kind: "inViewport", target };
|
|
146
|
+
for (const pair of opts.split(",").filter((p) => p !== "")) {
|
|
147
|
+
const [k, v] = pair.split("=");
|
|
148
|
+
if (k !== "min")
|
|
149
|
+
throw new Error(`inViewport: unknown option ${JSON.stringify(k)} (only min=<ratio>)`);
|
|
150
|
+
out = { ...out, min: specNumber(kind, "min", v) };
|
|
151
|
+
}
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
case "box": {
|
|
155
|
+
const [target, opts] = splitDescriptor(kind, rest, "<descriptor>|minWidth=<n>,maxWidth=<n>,minHeight=<n>,maxHeight=<n>");
|
|
156
|
+
const bounds = {};
|
|
157
|
+
for (const pair of opts.split(",").filter((p) => p !== "")) {
|
|
158
|
+
const [k, v] = pair.split("=");
|
|
159
|
+
if (k !== "minWidth" && k !== "maxWidth" && k !== "minHeight" && k !== "maxHeight") {
|
|
160
|
+
throw new Error(`box: unknown bound ${JSON.stringify(k)} (minWidth, maxWidth, minHeight, maxHeight)`);
|
|
161
|
+
}
|
|
162
|
+
bounds[k] = specNumber(kind, k, v);
|
|
163
|
+
}
|
|
164
|
+
if (Object.keys(bounds).length === 0)
|
|
165
|
+
throw new Error("box needs at least one bound");
|
|
166
|
+
out = { kind: "box", target, ...bounds };
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case "overlaps":
|
|
170
|
+
case "noOverlap": {
|
|
171
|
+
const [target, other] = splitDescriptor(kind, rest, "<descriptor>|<descriptor2>");
|
|
172
|
+
out = { kind: "overlap", target, other: parseDescriptorSpec(other), overlapping: kind === "overlaps" };
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
case "attr": {
|
|
176
|
+
const [target, spec] = splitDescriptor(kind, rest, "<descriptor>|<name>[=<value>] or <descriptor>|!<name>");
|
|
177
|
+
if (spec.startsWith("!"))
|
|
178
|
+
out = { kind: "attr", target, name: spec.slice(1), absent: true };
|
|
179
|
+
else {
|
|
180
|
+
const eq = spec.indexOf("=");
|
|
181
|
+
out = eq === -1 ? { kind: "attr", target, name: spec } : { kind: "attr", target, name: spec.slice(0, eq), value: spec.slice(eq + 1) };
|
|
182
|
+
}
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
case "flashed": {
|
|
186
|
+
const [target, opts] = splitDescriptor(kind, rest, "<descriptor>|class=<cls> (or attr=<name>, animation)[|withinMs=<n>]");
|
|
187
|
+
let f = { kind: "flashed", target };
|
|
188
|
+
for (const part of opts.split("|").filter((p) => p !== "")) {
|
|
189
|
+
const eq = part.indexOf("=");
|
|
190
|
+
const k = eq === -1 ? part : part.slice(0, eq);
|
|
191
|
+
const v = eq === -1 ? "" : part.slice(eq + 1);
|
|
192
|
+
if (k === "class")
|
|
193
|
+
f = { ...f, className: v };
|
|
194
|
+
else if (k === "attr")
|
|
195
|
+
f = { ...f, attr: v };
|
|
196
|
+
else if (k === "animation" && eq === -1)
|
|
197
|
+
f = { ...f, animation: true };
|
|
198
|
+
else if (k === "withinMs")
|
|
199
|
+
f = { ...f, withinMs: specNumber(kind, "withinMs", v) };
|
|
200
|
+
else
|
|
201
|
+
throw new Error(`flashed: unknown option ${JSON.stringify(part)} (class=<cls>, attr=<name>, animation, withinMs=<n>)`);
|
|
202
|
+
}
|
|
203
|
+
out = f;
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
default:
|
|
207
|
+
throw new Error(`unsupported assertion kind ${JSON.stringify(kind)}`);
|
|
208
|
+
}
|
|
209
|
+
const parsed = AssertionSchema.safeParse(out);
|
|
210
|
+
if (!parsed.success) {
|
|
211
|
+
throw new Error(`invalid ${kind} spec: ${parsed.error.issues.map((i) => i.message).join("; ")}`);
|
|
212
|
+
}
|
|
213
|
+
return parsed.data;
|
|
214
|
+
}
|
|
215
|
+
const HTTP_METHOD = /^(?:[A-Za-z]+|\*)$/;
|
|
216
|
+
/**
|
|
217
|
+
* `<METHOD> <path-glob>` — the request half of a network check. Two distinct
|
|
218
|
+
* failure modes get two distinct messages: a missing/malformed method (or no
|
|
219
|
+
* space at all) doesn't match the shape at all, while a present-but-unrooted
|
|
220
|
+
* path glob is the far more common mistake (issue #83) and deserves to say
|
|
221
|
+
* exactly what's wrong instead of re-printing the whole shape as if nothing
|
|
222
|
+
* was recognized.
|
|
223
|
+
*/
|
|
224
|
+
function parseRequestSpec(kind, text) {
|
|
225
|
+
const sp = text.indexOf(" ");
|
|
226
|
+
const method = sp === -1 ? "" : text.slice(0, sp);
|
|
227
|
+
const pathGlob = sp === -1 ? "" : text.slice(sp + 1).trim();
|
|
228
|
+
if (!HTTP_METHOD.test(method) || pathGlob.length === 0) {
|
|
229
|
+
throw new Error(`${kind} requires "<METHOD> <path-glob>", e.g. ${kind}:PUT /api/profile/*`);
|
|
230
|
+
}
|
|
231
|
+
if (!pathGlob.startsWith("/")) {
|
|
232
|
+
throw new Error(`${kind}: path glob must start with "/" (got ${JSON.stringify(pathGlob)})`);
|
|
233
|
+
}
|
|
234
|
+
return { method: method.toUpperCase(), pathGlob };
|
|
235
|
+
}
|
|
236
|
+
function parseStatusSpec(text) {
|
|
237
|
+
if (/^[1-5]xx$/i.test(text))
|
|
238
|
+
return { class: Number(text[0]) };
|
|
239
|
+
if (/^[1-5]\d\d$/.test(text))
|
|
240
|
+
return { code: Number(text) };
|
|
241
|
+
throw new Error(`responseStatus expects 2xx, 4xx … or a status code, got ${JSON.stringify(text)}`);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The goal mission's `--success` spec parser (repeatable: every check must hold). Besides every
|
|
245
|
+
* page assertion `parseAssertionSpec` reads:
|
|
246
|
+
* reloadThen:<assertion> — reload the page, then check (persistence)
|
|
247
|
+
* requestMade:<METHOD> <path-glob> — the run issued this request
|
|
248
|
+
* responseStatus:<METHOD> <path-glob>=<2xx|4xx|code> — and it got this status
|
|
249
|
+
* `<path-glob>` uses the route-glob syntax (`*` within a segment, `**` across segments) against
|
|
250
|
+
* the request's path; `*` as METHOD matches any method.
|
|
251
|
+
*/
|
|
252
|
+
export function parseSuccessSpec(spec) {
|
|
253
|
+
const ci = spec.indexOf(":");
|
|
254
|
+
const kind = ci === -1 ? spec : spec.slice(0, ci);
|
|
255
|
+
const rest = ci === -1 ? "" : spec.slice(ci + 1);
|
|
256
|
+
switch (kind) {
|
|
257
|
+
case "reloadThen":
|
|
258
|
+
if (rest.startsWith("reloadThen:"))
|
|
259
|
+
throw new Error("reloadThen cannot be nested");
|
|
260
|
+
return { kind: "reloadThen", assertion: parseAssertionSpec(rest) };
|
|
261
|
+
case "requestMade":
|
|
262
|
+
return { kind: "requestMade", ...parseRequestSpec(kind, rest) };
|
|
263
|
+
case "responseStatus": {
|
|
264
|
+
const eq = rest.lastIndexOf("=");
|
|
265
|
+
if (eq === -1)
|
|
266
|
+
throw new Error('responseStatus requires "<METHOD> <path-glob>=<2xx|4xx|code>"');
|
|
267
|
+
return { kind: "responseStatus", ...parseRequestSpec(kind, rest.slice(0, eq)), status: parseStatusSpec(rest.slice(eq + 1)) };
|
|
268
|
+
}
|
|
269
|
+
default:
|
|
270
|
+
return { kind: "page", assertion: parseAssertionSpec(spec) };
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function parseDescriptorSpec(s) {
|
|
274
|
+
const raw = s.trim();
|
|
275
|
+
if (/^[[#.]/.test(raw)) {
|
|
276
|
+
// A CSS selector. The common test-id attribute form becomes a test-id descriptor (the most
|
|
277
|
+
// stable rung); anything else is used as CSS verbatim.
|
|
278
|
+
const testId = /^\[data-testid=(?:"([^"]*)"|'([^']*)'|([^\]"']*))\]$/.exec(raw);
|
|
279
|
+
const id = testId === null ? undefined : (testId[1] ?? testId[2] ?? testId[3]);
|
|
280
|
+
if (id !== undefined && id !== "")
|
|
281
|
+
return { testId: id };
|
|
282
|
+
return { css: raw };
|
|
283
|
+
}
|
|
284
|
+
const d = {};
|
|
285
|
+
const keys = ["testId", "role", "name", "label", "text", "css"];
|
|
286
|
+
for (const pair of s.split(";")) {
|
|
287
|
+
const eq = pair.indexOf("=");
|
|
288
|
+
if (eq === -1)
|
|
289
|
+
continue;
|
|
290
|
+
const k = pair.slice(0, eq);
|
|
291
|
+
const v = pair.slice(eq + 1);
|
|
292
|
+
if (keys.includes(k) && v !== "") {
|
|
293
|
+
d[k] = v;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (d.testId || d.role || d.label || d.text || d.css)
|
|
297
|
+
return d;
|
|
298
|
+
// #213: no key=value pair matched — a bare, lowercase, syntactically valid CSS selector (a tag
|
|
299
|
+
// name or a combination of them) is read as CSS; anything else is refused with a hint, never a
|
|
300
|
+
// silent guess between CSS and text.
|
|
301
|
+
if (looksLikeBareCssSelector(raw))
|
|
302
|
+
return { css: raw };
|
|
303
|
+
throw new Error(`descriptor spec ${JSON.stringify(s)} has no usable selector — ${DESCRIPTOR_HINT}`);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* The authorized-origins allowlist for a run: explicit `--allow` origins when
|
|
307
|
+
* given, otherwise the target URL's own origin (you asked to explore it). An
|
|
308
|
+
* unparseable URL yields an empty allowlist → the guard fails closed.
|
|
309
|
+
*/
|
|
310
|
+
export function resolveExploreAllowlist(url, allow) {
|
|
311
|
+
if (allow.length > 0)
|
|
312
|
+
return [...allow];
|
|
313
|
+
return normalizeAllowlist([url]);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* A conservative CSS-selector grammar check for a BARE (no `=`, no leading `[`/`#`/`.`) `--success`
|
|
317
|
+
* descriptor (#213). It deliberately does not implement the full CSS grammar — its only job is to
|
|
318
|
+
* tell a genuine selector (`h1`, `main h1`, `body`, `div.card`, `ul > li`) apart from a plain
|
|
319
|
+
* accessible-name phrase (`Display name`). HTML tag names, classes, ids and pseudo-classes are
|
|
320
|
+
* conventionally lowercase; requiring the WHOLE string to be lowercase is the disambiguator — a
|
|
321
|
+
* descriptor with any uppercase letter is never read as CSS, no matter its shape.
|
|
322
|
+
*/
|
|
323
|
+
const CSS_IDENT = "[a-z][a-z0-9-]*";
|
|
324
|
+
const CSS_ATTR = `\\[${CSS_IDENT}(?:[~^$*|]?=(?:"[^"]*"|'[^']*'|${CSS_IDENT}))?\\]`;
|
|
325
|
+
const CSS_PSEUDO = `::?${CSS_IDENT}(?:\\([^()]*\\))?`;
|
|
326
|
+
const CSS_QUALIFIER = `(?:\\.${CSS_IDENT}|#${CSS_IDENT}|${CSS_ATTR}|${CSS_PSEUDO})`;
|
|
327
|
+
const CSS_COMPOUND = `(?:(?:\\*|${CSS_IDENT})${CSS_QUALIFIER}*|${CSS_QUALIFIER}+)`;
|
|
328
|
+
const BARE_CSS_SELECTOR_RE = new RegExp(`^${CSS_COMPOUND}(?:(?:\\s*[>+~]\\s*|\\s+)${CSS_COMPOUND})*$`);
|
|
329
|
+
function looksLikeBareCssSelector(raw) {
|
|
330
|
+
return raw !== "" && !/[^\x20-\x7e]/.test(raw) && !/[A-Z]/.test(raw) && BARE_CSS_SELECTOR_RE.test(raw);
|
|
331
|
+
}
|
|
332
|
+
const DESCRIPTOR_HINT = 'use css=<selector>, label=<text>, testId=<id>, role=<role>;name=<name>, or text=<text> (e.g. "css=h1" or "label=Display name")';
|
|
333
|
+
//# sourceMappingURL=explore-specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore-specs.js","sourceRoot":"","sources":["../src/explore-specs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type FilingConfig, type FilingOutcome, type IssueDraft, type IssueFilerPort } from "@jevitate/domain";
|
|
2
|
+
/**
|
|
3
|
+
* Where a run's findings go (owner ruling 3). Drafts are ALWAYS written next to the Recording
|
|
4
|
+
* (`<stem>.issues/<fingerprint>.md`); they are filed only when filing is enabled AND a destination
|
|
5
|
+
* repo is configured. jevitate stays solution-agnostic: the system-under-test repo is configured
|
|
6
|
+
* PER TARGET (by origin) in `~/.jevitate/filing.json` or per run with `--issue-repo`, never
|
|
7
|
+
* hardcoded.
|
|
8
|
+
*
|
|
9
|
+
* `~/.jevitate/filing.json`:
|
|
10
|
+
* ```json
|
|
11
|
+
* { "enabled": false,
|
|
12
|
+
* "jevitateRepo": "matt-cochran/jevitate",
|
|
13
|
+
* "targets": { "https://app.example.test": { "repo": "acme/app" } } }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export interface FilingFileConfig {
|
|
17
|
+
readonly enabled?: boolean;
|
|
18
|
+
readonly jevitateRepo?: string;
|
|
19
|
+
readonly targets?: Readonly<Record<string, {
|
|
20
|
+
readonly repo: string;
|
|
21
|
+
}>>;
|
|
22
|
+
}
|
|
23
|
+
export declare class FilingConfigError extends Error {
|
|
24
|
+
readonly code: "E_FILING_CONFIG";
|
|
25
|
+
}
|
|
26
|
+
/** `owner/name`, or a config error — a malformed repo is never silently used. */
|
|
27
|
+
export declare function assertRepo(repo: string, where: string): string;
|
|
28
|
+
/** Reads `~/.jevitate/filing.json`; a missing file is "no filing config". Anything malformed fails closed. */
|
|
29
|
+
export declare function loadFilingFileConfig(path?: string): FilingFileConfig;
|
|
30
|
+
export interface FilingFlags {
|
|
31
|
+
/** `--file-issues`: enable filing for this run. */
|
|
32
|
+
readonly fileIssues?: boolean;
|
|
33
|
+
/** `--issue-repo`: the system-under-test repo for this run's target. */
|
|
34
|
+
readonly issueRepo?: string;
|
|
35
|
+
/** `--jevitate-repo`: override where engine findings go. */
|
|
36
|
+
readonly jevitateRepo?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Flags win over the file; the target repo is looked up by the run's origin. */
|
|
39
|
+
export declare function resolveFilingConfig(file: FilingFileConfig, flags: FilingFlags, targetOrigin: string): FilingConfig;
|
|
40
|
+
/** `<dir>/<stem>.json` → `<dir>/<stem>.issues/`. */
|
|
41
|
+
export declare function issuesDirFor(recordingPath: string): string;
|
|
42
|
+
export interface WrittenDraft {
|
|
43
|
+
readonly fingerprint: string;
|
|
44
|
+
readonly title: string;
|
|
45
|
+
readonly attribution: IssueDraft["attribution"];
|
|
46
|
+
readonly targets: IssueDraft["targets"];
|
|
47
|
+
/** #250: kept so a draft can be filed later (after its evidence was attached). */
|
|
48
|
+
readonly labels?: readonly string[];
|
|
49
|
+
readonly path: string;
|
|
50
|
+
}
|
|
51
|
+
/** Writes each draft as `<fingerprint>.md` (title heading + body) next to the Recording. */
|
|
52
|
+
export declare function writeIssueDrafts(recordingPath: string, drafts: readonly IssueDraft[]): WrittenDraft[];
|
|
53
|
+
export interface FindingsIssues {
|
|
54
|
+
readonly drafts: WrittenDraft[];
|
|
55
|
+
readonly filing: Array<{
|
|
56
|
+
readonly fingerprint: string;
|
|
57
|
+
readonly outcomes: FilingOutcome[];
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Writes every draft, then files them per the config. The filer is created ONLY when filing is
|
|
62
|
+
* enabled (so a disabled run never even looks for `gh` or a token).
|
|
63
|
+
*/
|
|
64
|
+
export declare function processIssueDrafts(recordingPath: string, drafts: readonly IssueDraft[], config: FilingConfig, makeFiler: () => IssueFilerPort, nowIso: string): Promise<FindingsIssues>;
|