@keber/qa-framework 1.1.1 → 1.1.2
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/package.json +1 -1
- package/scripts/init.js +22 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keber/qa-framework",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Reusable spec-driven QA framework for IDE-agent-assisted automated testing. Installable as an npm package. Provides structure, templates, agent instructions, and optional integrations for Playwright and Azure DevOps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"qa",
|
package/scripts/init.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* scripts/init.js
|
|
3
|
+
* scripts/init.js - Scaffold qa/ folder structure from config
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
6
|
* qa-framework init
|
|
@@ -52,7 +52,7 @@ if (explicitConfigPath) {
|
|
|
52
52
|
} else {
|
|
53
53
|
config = buildBootstrapConfig();
|
|
54
54
|
configSource = 'generated defaults';
|
|
55
|
-
|
|
55
|
+
process.stderr.write('[qa-framework/init] No config file found. Bootstrapping with default config.\n');
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const qaRoot = path.resolve(cwd, config.conventions?.qaRoot ?? 'qa');
|
|
@@ -60,7 +60,7 @@ const localConfigPath = path.join(qaRoot, 'qa-framework.config.json');
|
|
|
60
60
|
|
|
61
61
|
// --skip-if-exists: bail out silently when qa/ is already initialised
|
|
62
62
|
if (skipIfExists && fs.existsSync(localConfigPath)) {
|
|
63
|
-
|
|
63
|
+
process.stderr.write('[qa-framework/init] qa/ already initialised - skipping (postinstall).\n');
|
|
64
64
|
process.exit(0);
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -69,11 +69,11 @@ if (!fs.existsSync(localConfigPath)) {
|
|
|
69
69
|
fs.writeFileSync(localConfigPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
70
70
|
console.log(` [created] ${path.relative(cwd, localConfigPath)}`);
|
|
71
71
|
} else {
|
|
72
|
-
console.log(` [exists] ${path.relative(cwd, localConfigPath)}
|
|
72
|
+
console.log(` [exists] ${path.relative(cwd, localConfigPath)} - skipped`);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
process.stderr.write(`[qa-framework/init] Scaffolding qa/ at: ${qaRoot}\n`);
|
|
76
|
+
process.stderr.write(`[qa-framework/init] Using config source: ${configSource}\n`);
|
|
77
77
|
|
|
78
78
|
// --- Top-level folders ---
|
|
79
79
|
const topLevelFolders = [
|
|
@@ -89,7 +89,7 @@ const topLevelFolders = [
|
|
|
89
89
|
for (const folder of topLevelFolders) {
|
|
90
90
|
const fullPath = path.join(qaRoot, folder);
|
|
91
91
|
fs.mkdirSync(fullPath, { recursive: true });
|
|
92
|
-
console.log(` [created] ${path.relative(
|
|
92
|
+
console.log(` [created] ${path.relative(cwd, fullPath)}/`);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
// --- Standards placeholder ---
|
|
@@ -140,9 +140,9 @@ for (const mod of modules) {
|
|
|
140
140
|
} else {
|
|
141
141
|
fs.writeFileSync(dest, `# ${specFile}\n\n> Auto-generated placeholder\n`, 'utf8');
|
|
142
142
|
}
|
|
143
|
-
console.log(` [created] ${path.relative(
|
|
143
|
+
console.log(` [created] ${path.relative(cwd, dest)}`);
|
|
144
144
|
} else {
|
|
145
|
-
console.log(` [exists] ${path.relative(
|
|
145
|
+
console.log(` [exists] ${path.relative(cwd, dest)} - skipped`);
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
@@ -152,7 +152,7 @@ for (const mod of modules) {
|
|
|
152
152
|
const specTs = path.join(e2eDir, `${subKey}.spec.ts`);
|
|
153
153
|
if (!fs.existsSync(specTs)) {
|
|
154
154
|
fs.writeFileSync(specTs, specScaffold(mod.name, sub.name, moduleKey, subKey), 'utf8');
|
|
155
|
-
console.log(` [created] ${path.relative(
|
|
155
|
+
console.log(` [created] ${path.relative(cwd, specTs)}`);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
}
|
|
@@ -164,7 +164,7 @@ for (const file of ['playwright.config.ts', 'global-setup.ts', '.env.example', '
|
|
|
164
164
|
const dest = path.join(automationDir, file);
|
|
165
165
|
if (!fs.existsSync(dest)) {
|
|
166
166
|
fs.copyFileSync(path.join(scaffoldSrc, file), dest);
|
|
167
|
-
console.log(` [created] ${path.relative(
|
|
167
|
+
console.log(` [created] ${path.relative(cwd, dest)}`);
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
const fixturesDir = path.join(automationDir, 'fixtures');
|
|
@@ -173,7 +173,7 @@ for (const file of ['auth.ts', 'test-helpers.ts']) {
|
|
|
173
173
|
const dest = path.join(fixturesDir, file);
|
|
174
174
|
if (!fs.existsSync(dest)) {
|
|
175
175
|
fs.copyFileSync(path.join(scaffoldSrc, 'fixtures', file), dest);
|
|
176
|
-
console.log(` [created] ${path.relative(
|
|
176
|
+
console.log(` [created] ${path.relative(cwd , dest)}`);
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
|
@@ -248,8 +248,8 @@ This project uses \`@keber/qa-framework\` v${config.frameworkVersion ?? '1.0.0'}
|
|
|
248
248
|
## Agent behavior rules
|
|
249
249
|
|
|
250
250
|
1. Before performing any QA task, read the relevant instruction file from \`qa/00-guides/\`
|
|
251
|
-
2. Always save artifacts in the correct \`qa/\` subfolder
|
|
252
|
-
3. Never hardcode credentials
|
|
251
|
+
2. Always save artifacts in the correct \`qa/\` subfolder - refer to \`qa/QA-STRUCTURE-GUIDE.md\`
|
|
252
|
+
3. Never hardcode credentials - always use env vars and \`<PLACEHOLDER>\` in documentation
|
|
253
253
|
4. Follow the naming conventions in \`qa/00-standards/naming-conventions.md\`
|
|
254
254
|
5. Project QA config is at \`qa/qa-framework.config.json\`
|
|
255
255
|
|
|
@@ -268,12 +268,13 @@ This project uses \`@keber/qa-framework\` v${config.frameworkVersion ?? '1.0.0'}
|
|
|
268
268
|
`;
|
|
269
269
|
writeIfMissing(copilotInstrPath, copilotInstrContent);
|
|
270
270
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
271
|
+
process.stderr.write('\n[qa-framework/init] ✅ QA framework scaffold complete!\n');
|
|
272
|
+
process.stderr.write('\nNext steps for the agent:\n');
|
|
273
|
+
process.stderr.write(' 1. If ADO integration is needed, run: npm install @keber/ado-qa\n');
|
|
274
|
+
process.stderr.write(' 2. If Playwright automation is needed, run: npm install @playwright/test\n');
|
|
275
|
+
process.stderr.write(' 3. Edit qa/qa-framework.config.json - add your project modules\n');
|
|
276
|
+
process.stderr.write(' 4. Copy qa/07-automation/.env.example -> qa/07-automation/.env and fill in credentials\n');
|
|
277
|
+
process.stderr.write(' 5. Add qa/07-automation/.env and qa/07-automation/.auth/ to .gitignore\n');
|
|
277
278
|
|
|
278
279
|
// -----------------------------------------------------------------------
|
|
279
280
|
// Helpers
|
|
@@ -282,7 +283,7 @@ function writeIfMissing(filePath, content) {
|
|
|
282
283
|
if (!fs.existsSync(filePath)) {
|
|
283
284
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
284
285
|
fs.writeFileSync(filePath, content, 'utf8');
|
|
285
|
-
console.log(` [created] ${path.relative(
|
|
286
|
+
console.log(` [created] ${path.relative(cwd, filePath)}`);
|
|
286
287
|
}
|
|
287
288
|
}
|
|
288
289
|
|