@gherkle/runner 0.1.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 +482 -0
- package/bin/gherkle-runner.js +111 -0
- package/dist/__tests__/agent-executor-selection.test.d.ts +15 -0
- package/dist/__tests__/agent-executor-selection.test.d.ts.map +1 -0
- package/dist/__tests__/agent-executor-selection.test.js +192 -0
- package/dist/__tests__/agent-executor-selection.test.js.map +1 -0
- package/dist/__tests__/envelope-mapper.test.d.ts +17 -0
- package/dist/__tests__/envelope-mapper.test.d.ts.map +1 -0
- package/dist/__tests__/envelope-mapper.test.js +217 -0
- package/dist/__tests__/envelope-mapper.test.js.map +1 -0
- package/dist/__tests__/gherkin-parser.test.d.ts +2 -0
- package/dist/__tests__/gherkin-parser.test.d.ts.map +1 -0
- package/dist/__tests__/gherkin-parser.test.js +375 -0
- package/dist/__tests__/gherkin-parser.test.js.map +1 -0
- package/dist/__tests__/integration-fork.test.d.ts +16 -0
- package/dist/__tests__/integration-fork.test.d.ts.map +1 -0
- package/dist/__tests__/integration-fork.test.js +141 -0
- package/dist/__tests__/integration-fork.test.js.map +1 -0
- package/dist/__tests__/tmpdir-materialization.test.d.ts +18 -0
- package/dist/__tests__/tmpdir-materialization.test.d.ts.map +1 -0
- package/dist/__tests__/tmpdir-materialization.test.js +177 -0
- package/dist/__tests__/tmpdir-materialization.test.js.map +1 -0
- package/dist/agent.d.ts +71 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +312 -0
- package/dist/agent.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +165 -0
- package/dist/config.js.map +1 -0
- package/dist/frameworks/cucumber-subprocess.d.ts +129 -0
- package/dist/frameworks/cucumber-subprocess.d.ts.map +1 -0
- package/dist/frameworks/cucumber-subprocess.js +469 -0
- package/dist/frameworks/cucumber-subprocess.js.map +1 -0
- package/dist/frameworks/playwright.d.ts +22 -0
- package/dist/frameworks/playwright.d.ts.map +1 -0
- package/dist/frameworks/playwright.js +234 -0
- package/dist/frameworks/playwright.js.map +1 -0
- package/dist/gherkin-parser.d.ts +22 -0
- package/dist/gherkin-parser.d.ts.map +1 -0
- package/dist/gherkin-parser.js +148 -0
- package/dist/gherkin-parser.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/step-registry.d.ts +30 -0
- package/dist/step-registry.d.ts.map +1 -0
- package/dist/step-registry.js +160 -0
- package/dist/step-registry.js.map +1 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/workers/cucumber-worker.d.ts +29 -0
- package/dist/workers/cucumber-worker.d.ts.map +1 -0
- package/dist/workers/cucumber-worker.js +191 -0
- package/dist/workers/cucumber-worker.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tests for CucumberSubprocessExecutor.prepareTmpdir ā the on-disk layout
|
|
4
|
+
* the forked Cucumber.js worker reads.
|
|
5
|
+
*
|
|
6
|
+
* Tmpdir layout under verification:
|
|
7
|
+
* <tmpdir>/
|
|
8
|
+
* features/<feature_id>.feature
|
|
9
|
+
* steps/<filename>
|
|
10
|
+
* support/world.{js|ts}
|
|
11
|
+
* cucumber.cjs
|
|
12
|
+
* .use-ts (only when any step-def is TypeScript)
|
|
13
|
+
*
|
|
14
|
+
* The runtime call site is private to executeAll(); this test calls
|
|
15
|
+
* prepareTmpdir directly and asserts the filesystem state. Each test cleans
|
|
16
|
+
* up the directory it created.
|
|
17
|
+
*/
|
|
18
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
21
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
22
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
23
|
+
}
|
|
24
|
+
Object.defineProperty(o, k2, desc);
|
|
25
|
+
}) : (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
o[k2] = m[k];
|
|
28
|
+
}));
|
|
29
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
31
|
+
}) : function(o, v) {
|
|
32
|
+
o["default"] = v;
|
|
33
|
+
});
|
|
34
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
35
|
+
var ownKeys = function(o) {
|
|
36
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
51
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
const vitest_1 = require("vitest");
|
|
53
|
+
const fs = __importStar(require("node:fs/promises"));
|
|
54
|
+
const path = __importStar(require("node:path"));
|
|
55
|
+
const cucumber_subprocess_1 = require("../frameworks/cucumber-subprocess");
|
|
56
|
+
const cleanupPaths = [];
|
|
57
|
+
(0, vitest_1.afterEach)(async () => {
|
|
58
|
+
while (cleanupPaths.length) {
|
|
59
|
+
const p = cleanupPaths.pop();
|
|
60
|
+
try {
|
|
61
|
+
await fs.rm(p, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
/* best-effort */
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
function track(p) {
|
|
69
|
+
cleanupPaths.push(p);
|
|
70
|
+
return p;
|
|
71
|
+
}
|
|
72
|
+
const featureFactory = (id, name = 'demo') => ({
|
|
73
|
+
id,
|
|
74
|
+
name: `features/${name}.feature`,
|
|
75
|
+
path: `features/${name}.feature`,
|
|
76
|
+
content: `Feature: ${name}\n Scenario: it works\n Given a thing\n`,
|
|
77
|
+
});
|
|
78
|
+
const stepDefFactory = (featureId, filename, language = 'javascript') => ({
|
|
79
|
+
featureId,
|
|
80
|
+
filename,
|
|
81
|
+
content: `// step defs for ${featureId}\n`,
|
|
82
|
+
language,
|
|
83
|
+
});
|
|
84
|
+
(0, vitest_1.describe)('CucumberSubprocessExecutor.prepareTmpdir', () => {
|
|
85
|
+
(0, vitest_1.it)('creates features/, steps/, support/ directories and cucumber.cjs', async () => {
|
|
86
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
87
|
+
const tmpdir = track(await exec.prepareTmpdir([featureFactory('feat-a')], [stepDefFactory('feat-a', 'steps.js')]));
|
|
88
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, 'features'))).resolves.toBeUndefined();
|
|
89
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, 'steps'))).resolves.toBeUndefined();
|
|
90
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, 'support'))).resolves.toBeUndefined();
|
|
91
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, 'cucumber.cjs'))).resolves.toBeUndefined();
|
|
92
|
+
});
|
|
93
|
+
(0, vitest_1.it)('writes each feature at features/<feature_id>.feature (NOT the DB path)', async () => {
|
|
94
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
95
|
+
const tmpdir = track(await exec.prepareTmpdir([featureFactory('uuid-1234')], [stepDefFactory('uuid-1234', 'steps.js')]));
|
|
96
|
+
// Stored by feature_id, NOT by the DB-side path. This is what lets the
|
|
97
|
+
// envelope mapper recover feature_id from pickle.uri.
|
|
98
|
+
const featurePath = path.join(tmpdir, 'features', 'uuid-1234.feature');
|
|
99
|
+
const content = await fs.readFile(featurePath, 'utf8');
|
|
100
|
+
(0, vitest_1.expect)(content).toContain('Feature: demo');
|
|
101
|
+
});
|
|
102
|
+
(0, vitest_1.it)('renames colliding step-def filenames with feature_id suffix', async () => {
|
|
103
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
104
|
+
const tmpdir = track(await exec.prepareTmpdir([featureFactory('feat-a'), featureFactory('feat-b')], [
|
|
105
|
+
stepDefFactory('feat-a', 'steps.js'),
|
|
106
|
+
// Same filename ā must be renamed, not silently overwritten.
|
|
107
|
+
stepDefFactory('feat-b', 'steps.js'),
|
|
108
|
+
]));
|
|
109
|
+
const stepsDir = await fs.readdir(path.join(tmpdir, 'steps'));
|
|
110
|
+
(0, vitest_1.expect)(stepsDir).toContain('steps.js');
|
|
111
|
+
(0, vitest_1.expect)(stepsDir).toContain('steps-feat-b.js');
|
|
112
|
+
(0, vitest_1.expect)(stepsDir).toHaveLength(2);
|
|
113
|
+
});
|
|
114
|
+
(0, vitest_1.it)('emits world.js + NO .use-ts marker when all step-defs are JavaScript', async () => {
|
|
115
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
116
|
+
const tmpdir = track(await exec.prepareTmpdir([featureFactory('feat-a')], [stepDefFactory('feat-a', 'steps.js', 'javascript')]));
|
|
117
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, 'support', 'world.js'))).resolves.toBeUndefined();
|
|
118
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, 'support', 'world.ts'))).rejects.toThrow();
|
|
119
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, '.use-ts'))).rejects.toThrow();
|
|
120
|
+
});
|
|
121
|
+
(0, vitest_1.it)('emits world.ts + .use-ts marker when ANY step-def is TypeScript', async () => {
|
|
122
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
123
|
+
const tmpdir = track(await exec.prepareTmpdir([featureFactory('feat-a'), featureFactory('feat-b')], [
|
|
124
|
+
// Mixed: one JS, one TS ā still triggers TS path (ts-node handles both)
|
|
125
|
+
stepDefFactory('feat-a', 'a.js', 'javascript'),
|
|
126
|
+
stepDefFactory('feat-b', 'b.ts', 'typescript'),
|
|
127
|
+
]));
|
|
128
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, 'support', 'world.ts'))).resolves.toBeUndefined();
|
|
129
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, 'support', 'world.js'))).rejects.toThrow();
|
|
130
|
+
await (0, vitest_1.expect)(fs.access(path.join(tmpdir, '.use-ts'))).resolves.toBeUndefined();
|
|
131
|
+
});
|
|
132
|
+
(0, vitest_1.it)('cucumber.cjs require glob matches chosen language extension', async () => {
|
|
133
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
134
|
+
const jsTmp = track(await exec.prepareTmpdir([featureFactory('feat-a')], [stepDefFactory('feat-a', 'steps.js', 'javascript')]));
|
|
135
|
+
const jsConfig = await fs.readFile(path.join(jsTmp, 'cucumber.cjs'), 'utf8');
|
|
136
|
+
(0, vitest_1.expect)(jsConfig).toContain("'steps/**/*.js'");
|
|
137
|
+
(0, vitest_1.expect)(jsConfig).toContain("requireModule: []");
|
|
138
|
+
const tsTmp = track(await exec.prepareTmpdir([featureFactory('feat-b')], [stepDefFactory('feat-b', 'steps.ts', 'typescript')]));
|
|
139
|
+
const tsConfig = await fs.readFile(path.join(tsTmp, 'cucumber.cjs'), 'utf8');
|
|
140
|
+
(0, vitest_1.expect)(tsConfig).toContain("'steps/**/*.ts'");
|
|
141
|
+
(0, vitest_1.expect)(tsConfig).toContain("requireModule: ['ts-node/register/transpile-only']");
|
|
142
|
+
});
|
|
143
|
+
(0, vitest_1.it)('world.ts includes ICustomWorld interface export (matches AI prompt import)', async () => {
|
|
144
|
+
// The AI prompt at apps/web/.../route.ts emits:
|
|
145
|
+
// import { ICustomWorld } from '../support/world'
|
|
146
|
+
// The generated world.ts must export ICustomWorld for that import to resolve.
|
|
147
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
148
|
+
const tmpdir = track(await exec.prepareTmpdir([featureFactory('feat-a')], [stepDefFactory('feat-a', 'steps.ts', 'typescript')]));
|
|
149
|
+
const world = await fs.readFile(path.join(tmpdir, 'support', 'world.ts'), 'utf8');
|
|
150
|
+
(0, vitest_1.expect)(world).toContain('export interface ICustomWorld');
|
|
151
|
+
(0, vitest_1.expect)(world).toContain('AfterAll'); // browser close ā codex finding #2 regression guard
|
|
152
|
+
});
|
|
153
|
+
(0, vitest_1.it)('world.js (JS variant) also registers AfterAll for browser close', async () => {
|
|
154
|
+
// Regression guard for codex P1 #2: without AfterAll the chromium browser
|
|
155
|
+
// stays alive, the worker never exits, and the parent hangs.
|
|
156
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
157
|
+
const tmpdir = track(await exec.prepareTmpdir([featureFactory('feat-a')], [stepDefFactory('feat-a', 'steps.js', 'javascript')]));
|
|
158
|
+
const world = await fs.readFile(path.join(tmpdir, 'support', 'world.js'), 'utf8');
|
|
159
|
+
(0, vitest_1.expect)(world).toContain('AfterAll');
|
|
160
|
+
(0, vitest_1.expect)(world).toContain('browser.close()');
|
|
161
|
+
});
|
|
162
|
+
(0, vitest_1.it)('writes step-def content verbatim', async () => {
|
|
163
|
+
const exec = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
164
|
+
const customCode = `const { Given } = require('@cucumber/cucumber');\nGiven('a thing', () => {});\n`;
|
|
165
|
+
const tmpdir = track(await exec.prepareTmpdir([featureFactory('feat-a')], [
|
|
166
|
+
{
|
|
167
|
+
featureId: 'feat-a',
|
|
168
|
+
filename: 'auth.steps.js',
|
|
169
|
+
content: customCode,
|
|
170
|
+
language: 'javascript',
|
|
171
|
+
},
|
|
172
|
+
]));
|
|
173
|
+
const written = await fs.readFile(path.join(tmpdir, 'steps', 'auth.steps.js'), 'utf8');
|
|
174
|
+
(0, vitest_1.expect)(written).toBe(customCode);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
//# sourceMappingURL=tmpdir-materialization.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmpdir-materialization.test.js","sourceRoot":"","sources":["../../src/__tests__/tmpdir-materialization.test.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GherkleAgent - Main agent class for connecting to Gherkle and executing tests
|
|
3
|
+
*/
|
|
4
|
+
import { AgentConfig } from './config';
|
|
5
|
+
export declare class GherkleAgent {
|
|
6
|
+
private config;
|
|
7
|
+
private ws;
|
|
8
|
+
private runnerId;
|
|
9
|
+
private status;
|
|
10
|
+
private currentRunId;
|
|
11
|
+
private currentCucumberExecutor;
|
|
12
|
+
private heartbeatInterval;
|
|
13
|
+
private reconnectTimeout;
|
|
14
|
+
private shouldReconnect;
|
|
15
|
+
constructor(config: AgentConfig);
|
|
16
|
+
/**
|
|
17
|
+
* Start the agent and connect to Gherkle
|
|
18
|
+
*/
|
|
19
|
+
start(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Stop the agent and disconnect
|
|
22
|
+
*/
|
|
23
|
+
stop(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Connect to Gherkle WebSocket server
|
|
26
|
+
*/
|
|
27
|
+
private connect;
|
|
28
|
+
/**
|
|
29
|
+
* Handle incoming messages from Gherkle
|
|
30
|
+
*/
|
|
31
|
+
private handleMessage;
|
|
32
|
+
/**
|
|
33
|
+
* Send a message to Gherkle
|
|
34
|
+
*/
|
|
35
|
+
private send;
|
|
36
|
+
/**
|
|
37
|
+
* Start heartbeat interval
|
|
38
|
+
*/
|
|
39
|
+
private startHeartbeat;
|
|
40
|
+
/**
|
|
41
|
+
* Stop heartbeat interval
|
|
42
|
+
*/
|
|
43
|
+
private stopHeartbeat;
|
|
44
|
+
/**
|
|
45
|
+
* Execute a test run.
|
|
46
|
+
*
|
|
47
|
+
* Two paths:
|
|
48
|
+
* - stepDefinitions non-empty ā CucumberSubprocessExecutor (default).
|
|
49
|
+
* The server has already gathered AI-generated step-def code; the
|
|
50
|
+
* runner ships it into a forked Cucumber.js process. No local
|
|
51
|
+
* dependencies on the runner machine beyond what @gherkle/runner
|
|
52
|
+
* itself bundles.
|
|
53
|
+
* - stepDefinitions empty AND testConfig.stepDefinitionsPath set ā
|
|
54
|
+
* legacy PlaywrightExecutor (BYO: user keeps step defs on disk).
|
|
55
|
+
* - Otherwise ā error the run with a clear message. The server already
|
|
56
|
+
* hard-fails dispatch in this case (D9); this is defense in depth.
|
|
57
|
+
*/
|
|
58
|
+
private executeRun;
|
|
59
|
+
/**
|
|
60
|
+
* Cancel an in-progress run. SIGTERMs the Cucumber subprocess (with a 5s
|
|
61
|
+
* SIGKILL fallback) so the run terminates promptly. The executeRun()
|
|
62
|
+
* promise then resolves naturally: its 'exit' handler returns the
|
|
63
|
+
* partial scenarios it had accumulated, and run:completed flows as usual.
|
|
64
|
+
*/
|
|
65
|
+
private cancelRun;
|
|
66
|
+
/**
|
|
67
|
+
* Get the appropriate executor for the framework
|
|
68
|
+
*/
|
|
69
|
+
private getExecutor;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAgBvC,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,YAAY,CAAuB;IAG3C,OAAO,CAAC,uBAAuB,CAA2C;IAC1E,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,eAAe,CAAQ;gBAEnB,MAAM,EAAE,WAAW;IAI/B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB3B;;OAEG;YACW,OAAO;IA4CrB;;OAEG;YACW,aAAa;IA+B3B;;OAEG;IACH,OAAO,CAAC,IAAI;IAMZ;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;;;;;;;;;;;;OAaG;YACW,UAAU;IA6IxB;;;;;OAKG;YACW,SAAS;IASvB;;OAEG;IACH,OAAO,CAAC,WAAW;CASpB"}
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GherkleAgent - Main agent class for connecting to Gherkle and executing tests
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.GherkleAgent = void 0;
|
|
10
|
+
const ws_1 = __importDefault(require("ws"));
|
|
11
|
+
const playwright_1 = require("./frameworks/playwright");
|
|
12
|
+
const cucumber_subprocess_1 = require("./frameworks/cucumber-subprocess");
|
|
13
|
+
const HEARTBEAT_INTERVAL = 30000; // 30 seconds
|
|
14
|
+
const RECONNECT_DELAY = 5000; // 5 seconds
|
|
15
|
+
class GherkleAgent {
|
|
16
|
+
config;
|
|
17
|
+
ws = null;
|
|
18
|
+
runnerId = null;
|
|
19
|
+
status = 'offline';
|
|
20
|
+
currentRunId = null;
|
|
21
|
+
// Held only while a cucumber-subprocess run is in flight so a 'cancel'
|
|
22
|
+
// ServerMessage can kill the child cleanly.
|
|
23
|
+
currentCucumberExecutor = null;
|
|
24
|
+
heartbeatInterval = null;
|
|
25
|
+
reconnectTimeout = null;
|
|
26
|
+
shouldReconnect = true;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.config = config;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Start the agent and connect to Gherkle
|
|
32
|
+
*/
|
|
33
|
+
async start() {
|
|
34
|
+
console.log(`š Starting Gherkle Runner: ${this.config.name}`);
|
|
35
|
+
console.log(` Connecting to: ${this.config.apiUrl}`);
|
|
36
|
+
await this.connect();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Stop the agent and disconnect
|
|
40
|
+
*/
|
|
41
|
+
async stop() {
|
|
42
|
+
console.log('š Stopping Gherkle Runner...');
|
|
43
|
+
this.shouldReconnect = false;
|
|
44
|
+
if (this.heartbeatInterval) {
|
|
45
|
+
clearInterval(this.heartbeatInterval);
|
|
46
|
+
this.heartbeatInterval = null;
|
|
47
|
+
}
|
|
48
|
+
if (this.reconnectTimeout) {
|
|
49
|
+
clearTimeout(this.reconnectTimeout);
|
|
50
|
+
this.reconnectTimeout = null;
|
|
51
|
+
}
|
|
52
|
+
if (this.ws) {
|
|
53
|
+
this.ws.close();
|
|
54
|
+
this.ws = null;
|
|
55
|
+
}
|
|
56
|
+
this.status = 'offline';
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Connect to Gherkle WebSocket server
|
|
60
|
+
*/
|
|
61
|
+
async connect() {
|
|
62
|
+
const wsUrl = this.config.apiUrl
|
|
63
|
+
.replace('https://', 'wss://')
|
|
64
|
+
.replace('http://', 'ws://');
|
|
65
|
+
const url = `${wsUrl}/api/runners/ws`;
|
|
66
|
+
// Send the runner token in the Authorization header, not the URL query
|
|
67
|
+
// string ā query strings leak into proxy logs, traces, and browser history.
|
|
68
|
+
this.ws = new ws_1.default(url, {
|
|
69
|
+
headers: { Authorization: `Bearer ${this.config.token}` },
|
|
70
|
+
});
|
|
71
|
+
this.ws.on('open', () => {
|
|
72
|
+
console.log('ā
Connected to Gherkle');
|
|
73
|
+
this.status = 'online';
|
|
74
|
+
this.startHeartbeat();
|
|
75
|
+
});
|
|
76
|
+
this.ws.on('message', (data) => {
|
|
77
|
+
try {
|
|
78
|
+
const message = JSON.parse(data.toString());
|
|
79
|
+
this.handleMessage(message);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
console.error('Failed to parse message:', err);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
this.ws.on('close', () => {
|
|
86
|
+
console.log('š Disconnected from Gherkle');
|
|
87
|
+
this.status = 'offline';
|
|
88
|
+
this.stopHeartbeat();
|
|
89
|
+
if (this.shouldReconnect) {
|
|
90
|
+
console.log(` Reconnecting in ${RECONNECT_DELAY / 1000}s...`);
|
|
91
|
+
this.reconnectTimeout = setTimeout(() => this.connect(), RECONNECT_DELAY);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
this.ws.on('error', (err) => {
|
|
95
|
+
console.error('ā WebSocket error:', err.message);
|
|
96
|
+
this.status = 'error';
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Handle incoming messages from Gherkle
|
|
101
|
+
*/
|
|
102
|
+
async handleMessage(message) {
|
|
103
|
+
switch (message.type) {
|
|
104
|
+
case 'connected':
|
|
105
|
+
this.runnerId = message.runnerId;
|
|
106
|
+
console.log(` Runner ID: ${this.runnerId}`);
|
|
107
|
+
break;
|
|
108
|
+
case 'ack':
|
|
109
|
+
// Heartbeat acknowledged
|
|
110
|
+
break;
|
|
111
|
+
case 'execute':
|
|
112
|
+
await this.executeRun(message.runId, message.features, message.stepDefinitions ?? [], message.env ?? {}, message.config);
|
|
113
|
+
break;
|
|
114
|
+
case 'cancel':
|
|
115
|
+
await this.cancelRun(message.runId);
|
|
116
|
+
break;
|
|
117
|
+
case 'error':
|
|
118
|
+
console.error('Server error:', message.message);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Send a message to Gherkle
|
|
124
|
+
*/
|
|
125
|
+
send(message) {
|
|
126
|
+
if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
|
|
127
|
+
this.ws.send(JSON.stringify(message));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Start heartbeat interval
|
|
132
|
+
*/
|
|
133
|
+
startHeartbeat() {
|
|
134
|
+
this.heartbeatInterval = setInterval(() => {
|
|
135
|
+
this.send({
|
|
136
|
+
type: 'heartbeat',
|
|
137
|
+
status: this.status,
|
|
138
|
+
currentRun: this.currentRunId || undefined,
|
|
139
|
+
});
|
|
140
|
+
}, HEARTBEAT_INTERVAL);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Stop heartbeat interval
|
|
144
|
+
*/
|
|
145
|
+
stopHeartbeat() {
|
|
146
|
+
if (this.heartbeatInterval) {
|
|
147
|
+
clearInterval(this.heartbeatInterval);
|
|
148
|
+
this.heartbeatInterval = null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Execute a test run.
|
|
153
|
+
*
|
|
154
|
+
* Two paths:
|
|
155
|
+
* - stepDefinitions non-empty ā CucumberSubprocessExecutor (default).
|
|
156
|
+
* The server has already gathered AI-generated step-def code; the
|
|
157
|
+
* runner ships it into a forked Cucumber.js process. No local
|
|
158
|
+
* dependencies on the runner machine beyond what @gherkle/runner
|
|
159
|
+
* itself bundles.
|
|
160
|
+
* - stepDefinitions empty AND testConfig.stepDefinitionsPath set ā
|
|
161
|
+
* legacy PlaywrightExecutor (BYO: user keeps step defs on disk).
|
|
162
|
+
* - Otherwise ā error the run with a clear message. The server already
|
|
163
|
+
* hard-fails dispatch in this case (D9); this is defense in depth.
|
|
164
|
+
*/
|
|
165
|
+
async executeRun(runId, features, stepDefinitions, env, testConfig) {
|
|
166
|
+
// Defensive busy-guard. The server-side dispatch is the proper place
|
|
167
|
+
// to enforce one-run-at-a-time per runner (TODOS P1: per-runner busy
|
|
168
|
+
// reservation in pollAndDispatch). Until that lands, if a second
|
|
169
|
+
// 'execute' arrives mid-run, return an error rather than silently
|
|
170
|
+
// clobbering currentRunId + the in-flight executor handle.
|
|
171
|
+
if (this.currentRunId !== null) {
|
|
172
|
+
console.warn(`ā ļø Refusing concurrent run ${runId}: runner is busy with ${this.currentRunId}`);
|
|
173
|
+
this.send({
|
|
174
|
+
type: 'error',
|
|
175
|
+
runId,
|
|
176
|
+
message: `Runner busy with run ${this.currentRunId}; dispatched without busy-check (TODOS P1).`,
|
|
177
|
+
});
|
|
178
|
+
this.send({
|
|
179
|
+
type: 'run:completed',
|
|
180
|
+
runId,
|
|
181
|
+
summary: { total: 0, passed: 0, failed: 0, skipped: 0, durationMs: 0 },
|
|
182
|
+
});
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
console.log(`\nš§Ŗ Starting test run: ${runId}`);
|
|
186
|
+
console.log(` Features: ${features.length}`);
|
|
187
|
+
console.log(` Framework: ${testConfig.framework}`);
|
|
188
|
+
console.log(` Step-defs: ${stepDefinitions.length} (${stepDefinitions.length > 0 ? 'cucumber-subprocess' : 'BYO playwright'})`);
|
|
189
|
+
this.status = 'busy';
|
|
190
|
+
this.currentRunId = runId;
|
|
191
|
+
this.send({ type: 'run:started', runId });
|
|
192
|
+
const summary = {
|
|
193
|
+
total: 0,
|
|
194
|
+
passed: 0,
|
|
195
|
+
failed: 0,
|
|
196
|
+
skipped: 0,
|
|
197
|
+
durationMs: 0,
|
|
198
|
+
};
|
|
199
|
+
const startTime = Date.now();
|
|
200
|
+
const onScenarioStart = (scenarioId, scenarioName, featureName) => {
|
|
201
|
+
this.send({
|
|
202
|
+
type: 'scenario:started',
|
|
203
|
+
runId,
|
|
204
|
+
scenarioId,
|
|
205
|
+
scenarioName,
|
|
206
|
+
featureName,
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
const onStepComplete = (scenarioId, step) => {
|
|
210
|
+
this.send({ type: 'step:completed', runId, scenarioId, step });
|
|
211
|
+
};
|
|
212
|
+
const onScenarioComplete = (scenarioId, status, durationMs, error) => {
|
|
213
|
+
summary.total++;
|
|
214
|
+
if (status === 'passed')
|
|
215
|
+
summary.passed++;
|
|
216
|
+
else if (status === 'failed')
|
|
217
|
+
summary.failed++;
|
|
218
|
+
else if (status === 'skipped')
|
|
219
|
+
summary.skipped++;
|
|
220
|
+
this.send({ type: 'scenario:completed', runId, scenarioId, status, durationMs, error });
|
|
221
|
+
};
|
|
222
|
+
try {
|
|
223
|
+
if (stepDefinitions.length > 0) {
|
|
224
|
+
const executor = new cucumber_subprocess_1.CucumberSubprocessExecutor();
|
|
225
|
+
this.currentCucumberExecutor = executor;
|
|
226
|
+
const results = await executor.executeAll(features, stepDefinitions, env, {
|
|
227
|
+
onScenarioStart,
|
|
228
|
+
onStepComplete,
|
|
229
|
+
onScenarioComplete,
|
|
230
|
+
});
|
|
231
|
+
this.currentCucumberExecutor = null;
|
|
232
|
+
for (const result of results) {
|
|
233
|
+
if (result.artifacts) {
|
|
234
|
+
for (const artifact of result.artifacts) {
|
|
235
|
+
this.send({ type: 'artifact:upload', runId, scenarioId: result.scenarioId, artifact });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else if (testConfig.stepDefinitionsPath) {
|
|
241
|
+
// BYO fallback: user has step-def code on the runner's local disk.
|
|
242
|
+
const executor = this.getExecutor(testConfig.framework);
|
|
243
|
+
for (const feature of features) {
|
|
244
|
+
const results = await executor.execute(feature, testConfig, {
|
|
245
|
+
onScenarioStart: (scenarioId, scenarioName) => onScenarioStart(scenarioId, scenarioName, feature.name),
|
|
246
|
+
onStepComplete,
|
|
247
|
+
onScenarioComplete,
|
|
248
|
+
});
|
|
249
|
+
for (const result of results) {
|
|
250
|
+
if (result.artifacts) {
|
|
251
|
+
for (const artifact of result.artifacts) {
|
|
252
|
+
this.send({ type: 'artifact:upload', runId, scenarioId: result.scenarioId, artifact });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
throw new Error('No step definitions: run carried no generated step-defs and no local stepDefinitionsPath is configured.');
|
|
260
|
+
}
|
|
261
|
+
summary.durationMs = Date.now() - startTime;
|
|
262
|
+
console.log(`\nā
Test run complete: ${runId}`);
|
|
263
|
+
console.log(` Passed: ${summary.passed}/${summary.total}`);
|
|
264
|
+
console.log(` Duration: ${summary.durationMs}ms`);
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
const error = err;
|
|
268
|
+
console.error(`\nā Test run failed: ${runId}`, error.message);
|
|
269
|
+
this.send({
|
|
270
|
+
type: 'error',
|
|
271
|
+
runId,
|
|
272
|
+
message: error.message,
|
|
273
|
+
});
|
|
274
|
+
summary.durationMs = Date.now() - startTime;
|
|
275
|
+
}
|
|
276
|
+
finally {
|
|
277
|
+
this.currentCucumberExecutor = null;
|
|
278
|
+
}
|
|
279
|
+
this.send({ type: 'run:completed', runId, summary });
|
|
280
|
+
this.status = 'online';
|
|
281
|
+
this.currentRunId = null;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Cancel an in-progress run. SIGTERMs the Cucumber subprocess (with a 5s
|
|
285
|
+
* SIGKILL fallback) so the run terminates promptly. The executeRun()
|
|
286
|
+
* promise then resolves naturally: its 'exit' handler returns the
|
|
287
|
+
* partial scenarios it had accumulated, and run:completed flows as usual.
|
|
288
|
+
*/
|
|
289
|
+
async cancelRun(runId) {
|
|
290
|
+
if (this.currentRunId !== runId)
|
|
291
|
+
return;
|
|
292
|
+
console.log(`š« Canceling run: ${runId}`);
|
|
293
|
+
if (this.currentCucumberExecutor) {
|
|
294
|
+
this.currentCucumberExecutor.cancel();
|
|
295
|
+
}
|
|
296
|
+
// Status/currentRunId reset in executeRun's finally block.
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Get the appropriate executor for the framework
|
|
300
|
+
*/
|
|
301
|
+
getExecutor(framework) {
|
|
302
|
+
switch (framework) {
|
|
303
|
+
case 'playwright':
|
|
304
|
+
return new playwright_1.PlaywrightExecutor(this.config);
|
|
305
|
+
// TODO: Add Cypress, Cucumber executors
|
|
306
|
+
default:
|
|
307
|
+
throw new Error(`Unsupported framework: ${framework}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
exports.GherkleAgent = GherkleAgent;
|
|
312
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration loading and validation for @gherkle/runner
|
|
3
|
+
*/
|
|
4
|
+
import { Framework } from './types';
|
|
5
|
+
export interface AgentConfig {
|
|
6
|
+
token: string;
|
|
7
|
+
apiUrl: string;
|
|
8
|
+
name: string;
|
|
9
|
+
labels: string[];
|
|
10
|
+
framework: Framework;
|
|
11
|
+
featuresPath: string;
|
|
12
|
+
stepDefinitionsPath: string;
|
|
13
|
+
supportPath: string;
|
|
14
|
+
browsers: string[];
|
|
15
|
+
headless: boolean;
|
|
16
|
+
testTimeout: number;
|
|
17
|
+
stepTimeout: number;
|
|
18
|
+
screenshots: 'always' | 'on-failure' | 'never';
|
|
19
|
+
video: 'always' | 'on-failure' | 'never';
|
|
20
|
+
baseUrl?: string;
|
|
21
|
+
env: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load configuration from file and environment
|
|
25
|
+
*/
|
|
26
|
+
export declare function loadConfig(cliOptions?: Partial<AgentConfig>): AgentConfig;
|
|
27
|
+
/**
|
|
28
|
+
* Generate a sample config file
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateSampleConfig(): string;
|
|
31
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,MAAM,WAAW,WAAW;IAE1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IAGf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IAGjB,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IAGpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAGlB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAGpB,WAAW,EAAE,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;IAC/C,KAAK,EAAE,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC;IAGzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AA2BD;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA4D7E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAqC7C"}
|