@activate-core/test-forge 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +24 -1
- package/dist/core/env-template.js +31 -5
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -22,6 +22,8 @@ import { runInit } from '../core/init.js';
|
|
|
22
22
|
import { runSetup } from '../core/setup.js';
|
|
23
23
|
import { runUpdate } from '../core/update.js';
|
|
24
24
|
import { runEnvTemplate } from '../core/env-template.js';
|
|
25
|
+
import { loadConfig } from '../core/config.js';
|
|
26
|
+
import { dirname } from 'node:path';
|
|
25
27
|
const command = process.argv[2];
|
|
26
28
|
const useBasic = process.argv.includes('--basic');
|
|
27
29
|
const force = process.argv.includes('--force');
|
|
@@ -39,6 +41,22 @@ function flagValue(name) {
|
|
|
39
41
|
function sourceOptions() {
|
|
40
42
|
return { reference: flagValue('--reference'), source: flagValue('--source') };
|
|
41
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* The output dirs to scan for env vars the GENERATED suite reads (test
|
|
46
|
+
* output dirs + their sibling helpers/ + the seed dir). Shared by the
|
|
47
|
+
* `generate` and `env` commands so the example always reflects the suite.
|
|
48
|
+
*/
|
|
49
|
+
function generatedScanDirs() {
|
|
50
|
+
const cfg = loadConfig();
|
|
51
|
+
const dirs = new Set();
|
|
52
|
+
for (const out of Object.values(cfg.testOutput ?? {})) {
|
|
53
|
+
dirs.add(out);
|
|
54
|
+
dirs.add(dirname(out));
|
|
55
|
+
}
|
|
56
|
+
if (cfg.seedOutput)
|
|
57
|
+
dirs.add(cfg.seedOutput);
|
|
58
|
+
return [...dirs];
|
|
59
|
+
}
|
|
42
60
|
function printUsage() {
|
|
43
61
|
console.log(`testforge v${VERSION}`);
|
|
44
62
|
console.log('');
|
|
@@ -87,7 +105,7 @@ async function main() {
|
|
|
87
105
|
console.log('then run `testforge generate`.');
|
|
88
106
|
}
|
|
89
107
|
else if (command === 'env') {
|
|
90
|
-
runEnvTemplate('docs', '.env.testing.example');
|
|
108
|
+
runEnvTemplate('docs', '.env.testing.example', '.', generatedScanDirs());
|
|
91
109
|
}
|
|
92
110
|
else if (command === 'generate') {
|
|
93
111
|
const useAI = !useBasic;
|
|
@@ -130,6 +148,11 @@ async function main() {
|
|
|
130
148
|
if (seedFailures > 0) {
|
|
131
149
|
console.log(`Warning: ${seedFailures} seed file(s) could not be generated — see notes above.`);
|
|
132
150
|
}
|
|
151
|
+
// Auto-refresh the env template so running `generate` on its own (not
|
|
152
|
+
// just `setup`) tells the developer exactly which credentials the
|
|
153
|
+
// generated suite needs — including vars the tests themselves read.
|
|
154
|
+
console.log('');
|
|
155
|
+
runEnvTemplate('docs', '.env.testing.example', '.', generatedScanDirs());
|
|
133
156
|
}
|
|
134
157
|
}
|
|
135
158
|
else {
|
|
@@ -55,7 +55,8 @@ const SOURCE_EXT = /\.(c|m)?[jt]sx?$/i;
|
|
|
55
55
|
* skipping vendored/build/test output, with a file cap so a huge repo
|
|
56
56
|
* can't stall the run.
|
|
57
57
|
*/
|
|
58
|
-
function scanSourceEnvVars(srcDir,
|
|
58
|
+
function scanSourceEnvVars(srcDir, opts = {}) {
|
|
59
|
+
const { includeTests = false, maxFiles = 4000 } = opts;
|
|
59
60
|
const vars = new Set();
|
|
60
61
|
let seen = 0;
|
|
61
62
|
const walk = (dir) => {
|
|
@@ -78,8 +79,10 @@ function scanSourceEnvVars(srcDir, maxFiles = 4000) {
|
|
|
78
79
|
walk(full);
|
|
79
80
|
}
|
|
80
81
|
else if (SOURCE_EXT.test(entry.name)) {
|
|
81
|
-
//
|
|
82
|
-
|
|
82
|
+
// App-source scan skips test files; the generated-suite scan
|
|
83
|
+
// (includeTests) WANTS them — that is where the tests' own env
|
|
84
|
+
// vars (tokens, ids, base URLs) live.
|
|
85
|
+
if (!includeTests && /\.(test|spec)\./i.test(entry.name))
|
|
83
86
|
continue;
|
|
84
87
|
seen++;
|
|
85
88
|
try {
|
|
@@ -108,7 +111,7 @@ function areaAndJourney(file) {
|
|
|
108
111
|
// Fallback: flat file with no area folder.
|
|
109
112
|
return { area: 'general', journey: noExt };
|
|
110
113
|
}
|
|
111
|
-
export function runEnvTemplate(docsDir, outPath, srcDir = '.') {
|
|
114
|
+
export function runEnvTemplate(docsDir, outPath, srcDir = '.', testDirs = []) {
|
|
112
115
|
if (!existsSync(docsDir)) {
|
|
113
116
|
console.log(`No docs found at "${docsDir}". Run \`testforge setup\` first.`);
|
|
114
117
|
return;
|
|
@@ -153,7 +156,21 @@ export function runEnvTemplate(docsDir, outPath, srcDir = '.') {
|
|
|
153
156
|
}
|
|
154
157
|
const sourceVars = scanSourceEnvVars(srcDir);
|
|
155
158
|
const bootVars = [...sourceVars].filter((v) => !knownFromDocs.has(v)).sort();
|
|
156
|
-
|
|
159
|
+
// Vars the GENERATED suite (tests + seeds + testkit) actually reads —
|
|
160
|
+
// scanned from the output dirs, INCLUDING test files. This is what
|
|
161
|
+
// captures tokens/ids/base-URLs the generated code needs but that no
|
|
162
|
+
// doc/source mentioned.
|
|
163
|
+
const suiteScan = new Set();
|
|
164
|
+
for (const d of testDirs) {
|
|
165
|
+
for (const v of scanSourceEnvVars(d, { includeTests: true })) {
|
|
166
|
+
suiteScan.add(v);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const alreadyShown = new Set([...knownFromDocs, ...bootVars]);
|
|
170
|
+
const suiteVars = [...suiteScan]
|
|
171
|
+
.filter((v) => !alreadyShown.has(v))
|
|
172
|
+
.sort();
|
|
173
|
+
if (byArea.size === 0 && bootVars.length === 0 && suiteVars.length === 0) {
|
|
157
174
|
console.log('No environment variables found in the docs or source.');
|
|
158
175
|
return;
|
|
159
176
|
}
|
|
@@ -167,6 +184,15 @@ export function runEnvTemplate(docsDir, outPath, srcDir = '.') {
|
|
|
167
184
|
'# Keep .env.testing OUT of version control.',
|
|
168
185
|
'',
|
|
169
186
|
];
|
|
187
|
+
if (suiteVars.length > 0) {
|
|
188
|
+
lines.push(`# ${'='.repeat(40)}`);
|
|
189
|
+
lines.push('# GENERATED SUITE (env the generated tests/testkit read)');
|
|
190
|
+
lines.push(`# ${'='.repeat(40)}`);
|
|
191
|
+
for (const v of suiteVars) {
|
|
192
|
+
lines.push(`${v}= # used by: generated tests`);
|
|
193
|
+
}
|
|
194
|
+
lines.push('');
|
|
195
|
+
}
|
|
170
196
|
if (bootVars.length > 0) {
|
|
171
197
|
lines.push(`# ${'='.repeat(40)}`);
|
|
172
198
|
lines.push('# APP (read directly from source — REQUIRED to boot)');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@activate-core/test-forge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "AI-powered QA automation. Scans a project, drafts journey docs, and generates seeded Jest/Playwright tests. Works in any project, with any AI CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|