@hasna/testers 0.0.56 → 0.0.57
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 +3 -2
- package/dist/cli/index.js +59 -3
- package/dist/lib/workflow-fanout.d.ts +16 -0
- package/dist/lib/workflow-fanout.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,9 +39,10 @@ testers workflow create "Projects CRUD" \
|
|
|
39
39
|
|
|
40
40
|
testers workflow fanout --project alumia --workers 6 --url https://preview.example.com
|
|
41
41
|
testers workflow fanout wf_abc,wf_def wf_xyz --workers 12 --url https://preview.example.com --json
|
|
42
|
+
testers workflow fanout --project alumia --tag action-specific --workers 6 --batch-size 12 --batch 1 --url https://preview.example.com
|
|
42
43
|
```
|
|
43
44
|
|
|
44
|
-
`--workers` is bounded to 1-12 concurrent sandboxes. Fanout preflights provider credentials, required sandbox environment references, `rsync`, and app source directories before launching workers. Use `--dry-run` to inspect the remote commands, upload plans, and preflight checks without spawning sandboxes.
|
|
45
|
+
`--workers` is bounded to 1-12 concurrent sandboxes. Use `--batch-size` with a 1-based `--batch` to run large workflow corpora in deterministic waves, or `--offset` for a manual selected-workflow cursor. Fanout preflights provider credentials, required sandbox environment references, `rsync`, and app source directories before launching workers. Use `--dry-run` to inspect the remote commands, upload plans, and preflight checks without spawning sandboxes.
|
|
45
46
|
|
|
46
47
|
### Next.js Route and Action Inventory
|
|
47
48
|
|
|
@@ -63,7 +64,7 @@ testers inventory next /path/to/app \
|
|
|
63
64
|
--sandbox-app-wait-url http://127.0.0.1:3000/health \
|
|
64
65
|
--sandbox-env-optional OPENAI_API_KEY
|
|
65
66
|
|
|
66
|
-
testers workflow fanout --project alumia --tag action-specific --workers 6 --url https://preview.example.com --dry-run
|
|
67
|
+
testers workflow fanout --project alumia --tag action-specific --workers 6 --batch-size 12 --batch 1 --url https://preview.example.com --dry-run
|
|
67
68
|
```
|
|
68
69
|
|
|
69
70
|
Use `--action-workflow-grouping action` for one workflow per discovered action, `route` for route-specific workflows, or `area-kind` for broader workflows such as commerce buttons or admin API methods. Add the `--sandbox-app-*` flags when the sandbox should rsync, install, start, and test the app source instead of only testing an already-running URL.
|
package/dist/cli/index.js
CHANGED
|
@@ -60628,6 +60628,7 @@ var exports_workflow_fanout = {};
|
|
|
60628
60628
|
__export(exports_workflow_fanout, {
|
|
60629
60629
|
runWorkflowFanout: () => runWorkflowFanout,
|
|
60630
60630
|
resolveWorkflowFanoutSelection: () => resolveWorkflowFanoutSelection,
|
|
60631
|
+
resolveWorkflowFanoutBatch: () => resolveWorkflowFanoutBatch,
|
|
60631
60632
|
normalizeFanoutWorkerCount: () => normalizeFanoutWorkerCount,
|
|
60632
60633
|
checkWorkflowFanoutReadiness: () => checkWorkflowFanoutReadiness
|
|
60633
60634
|
});
|
|
@@ -60643,6 +60644,33 @@ function normalizeFanoutWorkerCount(value) {
|
|
|
60643
60644
|
}
|
|
60644
60645
|
return workers;
|
|
60645
60646
|
}
|
|
60647
|
+
function resolveWorkflowFanoutBatch(workflows, options = {}) {
|
|
60648
|
+
const batchSize = normalizeOptionalPositiveInteger(options.batchSize, "workflow fanout batch size");
|
|
60649
|
+
const batch = normalizeOptionalPositiveInteger(options.batch, "workflow fanout batch");
|
|
60650
|
+
const offset = normalizeOptionalNonNegativeInteger(options.offset, "workflow fanout offset");
|
|
60651
|
+
if (batch !== undefined && offset !== undefined) {
|
|
60652
|
+
throw new Error("workflow fanout batch and offset cannot both be set");
|
|
60653
|
+
}
|
|
60654
|
+
if (batch !== undefined && batchSize === undefined) {
|
|
60655
|
+
throw new Error("workflow fanout batch requires batch size");
|
|
60656
|
+
}
|
|
60657
|
+
const resolvedOffset = batch !== undefined && batchSize !== undefined ? (batch - 1) * batchSize : offset ?? 0;
|
|
60658
|
+
const limit = batchSize;
|
|
60659
|
+
const selected = workflows.slice(resolvedOffset, limit === undefined ? undefined : resolvedOffset + limit);
|
|
60660
|
+
if (selected.length === 0) {
|
|
60661
|
+
throw new Error(`No testing workflows matched the fanout batch selection (matched ${workflows.length}, offset ${resolvedOffset})`);
|
|
60662
|
+
}
|
|
60663
|
+
return {
|
|
60664
|
+
workflows: selected,
|
|
60665
|
+
selection: {
|
|
60666
|
+
matched: workflows.length,
|
|
60667
|
+
offset: resolvedOffset,
|
|
60668
|
+
...limit !== undefined ? { limit } : {},
|
|
60669
|
+
...batch !== undefined ? { batch } : {},
|
|
60670
|
+
...batchSize !== undefined ? { batchSize, totalBatches: Math.ceil(workflows.length / batchSize) } : {}
|
|
60671
|
+
}
|
|
60672
|
+
};
|
|
60673
|
+
}
|
|
60646
60674
|
function resolveWorkflowFanoutSelection(options) {
|
|
60647
60675
|
const ids = splitWorkflowIds(options.workflowIds);
|
|
60648
60676
|
const workflows = ids.length > 0 ? ids.map((id) => {
|
|
@@ -60762,7 +60790,8 @@ async function mapWithConcurrency(items, limit, worker) {
|
|
|
60762
60790
|
}
|
|
60763
60791
|
async function runWorkflowFanout(options, dependencies = {}) {
|
|
60764
60792
|
const workers = normalizeFanoutWorkerCount(options.workers);
|
|
60765
|
-
const
|
|
60793
|
+
const matchedWorkflows = resolveWorkflowFanoutSelection(options);
|
|
60794
|
+
const { workflows, selection } = resolveWorkflowFanoutBatch(matchedWorkflows, options);
|
|
60766
60795
|
const {
|
|
60767
60796
|
runTestingWorkflow: runOne = runTestingWorkflow,
|
|
60768
60797
|
preflight: preflightOverride,
|
|
@@ -60783,6 +60812,7 @@ async function runWorkflowFanout(options, dependencies = {}) {
|
|
|
60783
60812
|
return {
|
|
60784
60813
|
status: "failed",
|
|
60785
60814
|
workers,
|
|
60815
|
+
selection,
|
|
60786
60816
|
total: workflows.length,
|
|
60787
60817
|
passed: 0,
|
|
60788
60818
|
failed: workflows.length,
|
|
@@ -60838,6 +60868,7 @@ async function runWorkflowFanout(options, dependencies = {}) {
|
|
|
60838
60868
|
return {
|
|
60839
60869
|
status: dryRun ? "dry-run" : failed > 0 ? "failed" : "passed",
|
|
60840
60870
|
workers,
|
|
60871
|
+
selection,
|
|
60841
60872
|
total: items.length,
|
|
60842
60873
|
passed,
|
|
60843
60874
|
failed,
|
|
@@ -60871,6 +60902,24 @@ function defaultCommandExists(command) {
|
|
|
60871
60902
|
const result = spawnSync2(command, ["--version"], { encoding: "utf8" });
|
|
60872
60903
|
return !result.error && result.status === 0;
|
|
60873
60904
|
}
|
|
60905
|
+
function normalizeOptionalPositiveInteger(value, label) {
|
|
60906
|
+
if (value === undefined)
|
|
60907
|
+
return;
|
|
60908
|
+
const normalized = Math.floor(value);
|
|
60909
|
+
if (!Number.isFinite(normalized) || normalized < 1) {
|
|
60910
|
+
throw new Error(`${label} must be a positive integer`);
|
|
60911
|
+
}
|
|
60912
|
+
return normalized;
|
|
60913
|
+
}
|
|
60914
|
+
function normalizeOptionalNonNegativeInteger(value, label) {
|
|
60915
|
+
if (value === undefined)
|
|
60916
|
+
return;
|
|
60917
|
+
const normalized = Math.floor(value);
|
|
60918
|
+
if (!Number.isFinite(normalized) || normalized < 0) {
|
|
60919
|
+
throw new Error(`${label} must be a non-negative integer`);
|
|
60920
|
+
}
|
|
60921
|
+
return normalized;
|
|
60922
|
+
}
|
|
60874
60923
|
function collectMissingSandboxEnvRefs(workflows, env, credentialResolver) {
|
|
60875
60924
|
const requiredMissing = [];
|
|
60876
60925
|
const optionalMissing = [];
|
|
@@ -95575,7 +95624,7 @@ import chalk6 from "chalk";
|
|
|
95575
95624
|
// package.json
|
|
95576
95625
|
var package_default = {
|
|
95577
95626
|
name: "@hasna/testers",
|
|
95578
|
-
version: "0.0.
|
|
95627
|
+
version: "0.0.57",
|
|
95579
95628
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
95580
95629
|
type: "module",
|
|
95581
95630
|
main: "dist/index.js",
|
|
@@ -102360,7 +102409,7 @@ workflowCmd.command("run <id>").description("Run a saved testing workflow").requ
|
|
|
102360
102409
|
workflowCmd.command("fanout [ids...]").description("Run multiple saved sandbox workflows concurrently").requiredOption("-u, --url <url>", "Target URL").option("--project <id>", "Project ID").option("--tag <tag>", "Workflow scenario tag filter (repeatable)", (val, acc) => {
|
|
102361
102410
|
acc.push(val);
|
|
102362
102411
|
return acc;
|
|
102363
|
-
}, []).option("--all", "Include disabled workflows when selecting by project/tag", false).option("--workers <n>", "Concurrent sandboxes, 1-12 (default: 6)", "6").option("-m, --model <model>", "AI model").option("--headed", "Run headed", false).option("--parallel <n>", "Parallel browser workers inside each sandbox").option("--timeout <ms>", "Override workflow timeout").option("--dry-run", "Print resolved sandbox plans without spawning sandboxes", false).option("--json", "Output as JSON", false).action(async (ids, opts) => {
|
|
102412
|
+
}, []).option("--all", "Include disabled workflows when selecting by project/tag", false).option("--workers <n>", "Concurrent sandboxes, 1-12 (default: 6)", "6").option("--batch-size <n>", "Limit this run to a batch of selected workflows").option("--batch <n>", "1-based batch number to run with --batch-size").option("--offset <n>", "0-based selected-workflow offset for staged fanout").option("-m, --model <model>", "AI model").option("--headed", "Run headed", false).option("--parallel <n>", "Parallel browser workers inside each sandbox").option("--timeout <ms>", "Override workflow timeout").option("--dry-run", "Print resolved sandbox plans without spawning sandboxes", false).option("--json", "Output as JSON", false).action(async (ids, opts) => {
|
|
102364
102413
|
try {
|
|
102365
102414
|
const { runWorkflowFanout: runWorkflowFanout2 } = await Promise.resolve().then(() => (init_workflow_fanout(), exports_workflow_fanout));
|
|
102366
102415
|
const result = await runWorkflowFanout2({
|
|
@@ -102369,6 +102418,9 @@ workflowCmd.command("fanout [ids...]").description("Run multiple saved sandbox w
|
|
|
102369
102418
|
tags: opts.tag,
|
|
102370
102419
|
includeDisabled: opts.all,
|
|
102371
102420
|
workers: opts.workers ? parseInt(opts.workers, 10) : undefined,
|
|
102421
|
+
batchSize: opts.batchSize ? parseInt(opts.batchSize, 10) : undefined,
|
|
102422
|
+
batch: opts.batch ? parseInt(opts.batch, 10) : undefined,
|
|
102423
|
+
offset: opts.offset ? parseInt(opts.offset, 10) : undefined,
|
|
102372
102424
|
url: opts.url,
|
|
102373
102425
|
model: opts.model,
|
|
102374
102426
|
headed: opts.headed,
|
|
@@ -102392,6 +102444,10 @@ workflowCmd.command("fanout [ids...]").description("Run multiple saved sandbox w
|
|
|
102392
102444
|
log(` ${chalk6.yellow("warning")} ${check2.message}`);
|
|
102393
102445
|
}
|
|
102394
102446
|
}
|
|
102447
|
+
if (result.selection.matched !== result.total) {
|
|
102448
|
+
const batch = result.selection.batch !== undefined && result.selection.totalBatches !== undefined ? ` batch ${result.selection.batch}/${result.selection.totalBatches}` : "";
|
|
102449
|
+
log(chalk6.dim(`Selected ${result.total}/${result.selection.matched} workflow(s) from offset ${result.selection.offset}${batch}.`));
|
|
102450
|
+
}
|
|
102395
102451
|
const status = result.status === "passed" ? chalk6.green("passed") : chalk6.red("failed");
|
|
102396
102452
|
log(chalk6.bold(`Sandbox workflow fanout ${status}: ${result.passed}/${result.total} passed with ${result.workers} worker(s)`));
|
|
102397
102453
|
for (const item of result.items) {
|
|
@@ -6,6 +6,9 @@ export interface WorkflowFanoutOptions extends WorkflowRunOptions {
|
|
|
6
6
|
tags?: string[];
|
|
7
7
|
includeDisabled?: boolean;
|
|
8
8
|
workers?: number;
|
|
9
|
+
batchSize?: number;
|
|
10
|
+
batch?: number;
|
|
11
|
+
offset?: number;
|
|
9
12
|
}
|
|
10
13
|
export interface WorkflowFanoutItem {
|
|
11
14
|
workflowId: string;
|
|
@@ -22,6 +25,7 @@ export interface WorkflowFanoutItem {
|
|
|
22
25
|
export interface WorkflowFanoutResult {
|
|
23
26
|
status: "passed" | "failed" | "dry-run";
|
|
24
27
|
workers: number;
|
|
28
|
+
selection: WorkflowFanoutSelection;
|
|
25
29
|
total: number;
|
|
26
30
|
passed: number;
|
|
27
31
|
failed: number;
|
|
@@ -48,6 +52,14 @@ export interface WorkflowFanoutPreflightResult {
|
|
|
48
52
|
ok: boolean;
|
|
49
53
|
checks: WorkflowFanoutPreflightCheck[];
|
|
50
54
|
}
|
|
55
|
+
export interface WorkflowFanoutSelection {
|
|
56
|
+
matched: number;
|
|
57
|
+
offset: number;
|
|
58
|
+
limit?: number;
|
|
59
|
+
batch?: number;
|
|
60
|
+
batchSize?: number;
|
|
61
|
+
totalBatches?: number;
|
|
62
|
+
}
|
|
51
63
|
interface WorkflowFanoutPreflightDependencies {
|
|
52
64
|
providerApiKeyResolver?: WorkflowFanoutDependencies["providerApiKeyResolver"];
|
|
53
65
|
commandExists?: WorkflowFanoutDependencies["commandExists"];
|
|
@@ -55,6 +67,10 @@ interface WorkflowFanoutPreflightDependencies {
|
|
|
55
67
|
env?: Record<string, string | undefined>;
|
|
56
68
|
}
|
|
57
69
|
export declare function normalizeFanoutWorkerCount(value: number | undefined): number;
|
|
70
|
+
export declare function resolveWorkflowFanoutBatch(workflows: TestingWorkflow[], options?: Pick<WorkflowFanoutOptions, "batchSize" | "batch" | "offset">): {
|
|
71
|
+
workflows: TestingWorkflow[];
|
|
72
|
+
selection: WorkflowFanoutSelection;
|
|
73
|
+
};
|
|
58
74
|
export declare function resolveWorkflowFanoutSelection(options: Pick<WorkflowFanoutOptions, "workflowIds" | "projectId" | "tags" | "includeDisabled">): TestingWorkflow[];
|
|
59
75
|
export declare function checkWorkflowFanoutReadiness(workflows: TestingWorkflow[], dependencies?: WorkflowFanoutPreflightDependencies): Promise<WorkflowFanoutPreflightResult>;
|
|
60
76
|
export declare function runWorkflowFanout(options: WorkflowFanoutOptions, dependencies?: WorkflowFanoutDependencies): Promise<WorkflowFanoutResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-fanout.d.ts","sourceRoot":"","sources":["../../src/lib/workflow-fanout.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAEpH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"workflow-fanout.d.ts","sourceRoot":"","sources":["../../src/lib/workflow-fanout.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "@hasna/testers",
|
|
55
|
-
version: "0.0.
|
|
55
|
+
version: "0.0.57",
|
|
56
56
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
57
57
|
type: "module",
|
|
58
58
|
main: "dist/index.js",
|
package/dist/server/index.js
CHANGED
|
@@ -47090,7 +47090,7 @@ import { join as join14 } from "path";
|
|
|
47090
47090
|
// package.json
|
|
47091
47091
|
var package_default = {
|
|
47092
47092
|
name: "@hasna/testers",
|
|
47093
|
-
version: "0.0.
|
|
47093
|
+
version: "0.0.57",
|
|
47094
47094
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
47095
47095
|
type: "module",
|
|
47096
47096
|
main: "dist/index.js",
|