@activate-core/test-forge 0.18.5 → 0.18.7

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.
@@ -225,6 +225,18 @@ export function buildPrompt(journey, map, testPath, focus, harnessPath, transpor
225
225
  ` obvious controller, and it may set the field under a different`,
226
226
  ` name. Only when no code path anywhere produces the state is the`,
227
227
  ` scenario imaginary — then drop it and say what you searched.`,
228
+ ` AND IT MUST SATISFY THE SCHEMA, NOT YOUR IDEA OF IT. A row is`,
229
+ ` written by a database, which refuses it outright if a NOT NULL`,
230
+ ` column with no default is missing, or if an id is of the wrong`,
231
+ ` type. Take both from the schema itself. In particular, DO NOT`,
232
+ ` ASSUME ONE ID TYPE COVERS THE PROJECT: a users table keyed by uuid`,
233
+ ` commonly sits beside tables keyed by integer or bigint, and a uuid`,
234
+ ` supplied for one of those is rejected by the database — every test`,
235
+ ` that touches that fixture then fails for a reason that has nothing`,
236
+ ` to do with the product. The same applies to a query: an array cast`,
237
+ ` (\`= ANY($1::uuid[])\`) must name the column's real type. When you`,
238
+ ` invent a fixture id, make it of the column's type, and prefer`,
239
+ ` letting the database assign it and reading it back.`,
228
240
  `(9) A TIMEOUT IS NOT A BUG REPORT — AND IT IS USUALLY YOU WAITING FOR`,
229
241
  ` THE WRONG THING. Before you accept a wait, ask what event actually`,
230
242
  ` arrives. A page whose job is to REDIRECT never fires a load event on`,
@@ -62,6 +62,17 @@ function buildGroundingPrompt(journey, map, srcDir) {
62
62
  ` returns, and the status codes the handler can emit.`,
63
63
  ` DATA — the models/collections written or read, and the fields that`,
64
64
  ` matter to this journey (including enum values where they exist).`,
65
+ ` For each table a test must SEED, record two things exactly as the`,
66
+ ` schema declares them, never as the ORM or another table suggests:`,
67
+ ` * every column that is NOT NULL and has NO default — a seed that`,
68
+ ` omits one is rejected outright, and the row never exists;`,
69
+ ` * the TYPE of the primary key and of every foreign key a test`,
70
+ ` will supply or query by. Do not assume one id type covers the`,
71
+ ` schema: a users table keyed by uuid sits happily beside tables`,
72
+ ` keyed by integer or bigint, and a uuid handed to one of those`,
73
+ ` is refused by the database, not merely unmatched.`,
74
+ ` Read this from the migrations, the schema dump, or the models'`,
75
+ ` declarations — whichever the project actually keeps.`,
65
76
  ` EXTERNALS — any third-party client the code calls, the module name`,
66
77
  ` a test would have to stand in for, and the env var its base URL or`,
67
78
  ` key comes from.`,
@@ -54,6 +54,17 @@ export const HARNESS_CONTRACT = [
54
54
  ` whose default is ''), write WITHOUT update`,
55
55
  ` validators (runValidators:false) rather`,
56
56
  ` than failing the whole seed.`,
57
+ ` READ THE SCHEMA BEFORE WRITING A SEED.`,
58
+ ` A relational database refuses a row that`,
59
+ ` omits a NOT NULL column with no default,`,
60
+ ` so every such column must be supplied —`,
61
+ ` take the list from the migrations or the`,
62
+ ` schema itself, not from the fields the`,
63
+ ` journey happens to mention. And take each`,
64
+ ` id's TYPE from the schema too: one table`,
65
+ ` keyed by uuid does not make them all uuid,`,
66
+ ` and an id of the wrong type is rejected`,
67
+ ` outright rather than simply not matching.`,
57
68
  ` - TEST_IDS: object the stable well-known test ids/handles.`,
58
69
  ` EVERY id MUST be env-overridable: resolve`,
59
70
  ` each as process.env.TEST_<NAME>_ID ||`,
@@ -598,18 +598,23 @@ export async function runGenerate(docsDir, useAI = true, force = false, only, ar
598
598
  // AI can't fall back to an uninstalled convention (e.g. supertest).
599
599
  const allowedModules = installedModules(testDir);
600
600
  const transport = transportHint(testDir, framework);
601
- // Playwright is the one framework whose import is mandatory in every spec
602
- // (jest's describe/it/expect are ambient, so a jest area generates fine
603
- // either way). If it is missing, stop before spending a single AI call.
604
- if (framework === 'playwright' && !allowedModules.has('@playwright/test')) {
601
+ // The area's OWN framework is always allowed, installed or not. Refusing
602
+ // it confuses two different things: output that reached for a module the
603
+ // project does not use (genuinely wrong — still refused), and output that
604
+ // is perfectly correct while the project has simply not installed the
605
+ // runner it is configured to use. The second is an environment gap, and
606
+ // throwing away a correct test for it loses real work — the test is
607
+ // written, and the run says the framework must be installed to run it.
608
+ const frameworkPkg = framework === 'playwright' ? '@playwright/test' : 'jest';
609
+ if (!allowedModules.has(frameworkPkg)) {
610
+ allowedModules.add(frameworkPkg);
605
611
  const blocked = blockedAreas.get(journey.area) ?? {
606
- pkg: '@playwright/test',
612
+ pkg: frameworkPkg,
607
613
  dir: areaDir,
608
614
  count: 0,
609
615
  };
610
616
  blocked.count += 1;
611
617
  blockedAreas.set(journey.area, blocked);
612
- continue;
613
618
  }
614
619
  // F10 — selector grounding (Playwright areas only): the real test-hooks
615
620
  // in this area's components, so a generated UI test can't invent one.
@@ -838,17 +843,17 @@ export async function runGenerate(docsDir, useAI = true, force = false, only, ar
838
843
  });
839
844
  }
840
845
  for (const [area, b] of blockedAreas) {
846
+ const browsers = b.pkg === '@playwright/test' ? ' && npx playwright install' : '';
841
847
  results.push({
842
- journeyName: `${b.count} ${area} journey(s) not attempted — ${b.pkg} is not installed`,
848
+ journeyName: `${area}: tests written, but ${b.pkg} is not installed`,
843
849
  testDir: '',
844
850
  testFiles: [],
845
851
  seedPath: '',
846
852
  status: 'skipped',
847
853
  seedStatus: 'none',
848
854
  warnings: [
849
- `every ${area} spec must import ${b.pkg}, so without it the dependency gate ` +
850
- `refuses each generated file and leaves a deferred stub — hours of AI calls for nothing. ` +
851
- `Install it, then re-run: npm i -D ${b.pkg} && npx playwright install`,
855
+ `${b.count} ${area} journey(s) were generated normally and are complete. They cannot RUN ` +
856
+ `until the runner is installed: npm i -D ${b.pkg}${browsers}`,
852
857
  ],
853
858
  });
854
859
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@activate-core/test-forge",
3
- "version": "0.18.5",
3
+ "version": "0.18.7",
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": {