@activate-core/test-forge 0.17.0 → 0.18.1

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/core/lint.js CHANGED
@@ -16,11 +16,18 @@
16
16
  * repository, not to impose a preference.
17
17
  */
18
18
  import { spawnSync } from 'node:child_process';
19
+ import { resolve } from 'node:path';
19
20
  import { existsSync } from 'node:fs';
20
21
  import { join, dirname } from 'node:path';
21
22
  /** Walk up from a file to the nearest package that has ESLint installed. */
22
23
  function eslintFor(file) {
23
- let dir = dirname(file);
24
+ // Absolute throughout. The binary is spawned WITH cwd set to the package that
25
+ // owns it, so a relative bin path is re-resolved from there:
26
+ // "packages/api/node_modules/.bin/eslint" becomes
27
+ // "packages/api/packages/api/node_modules/.bin/eslint", the spawn fails with
28
+ // ENOENT, stdout is empty, and the empty JSON parses as zero problems. The
29
+ // gate then reported every generated file clean without ever running.
30
+ let dir = dirname(resolve(file));
24
31
  for (let i = 0; i < 8; i++) {
25
32
  const bin = join(dir, 'node_modules', '.bin', 'eslint');
26
33
  if (existsSync(bin))
@@ -48,7 +55,13 @@ export function lintGenerated(files) {
48
55
  if (!found)
49
56
  continue;
50
57
  const g = groups.get(found.cwd) || { bin: found.bin, files: [] };
51
- g.files.push(f);
58
+ // ABSOLUTE, always. ESLint runs with cwd set to the package that owns it,
59
+ // so a path relative to the repo root ("packages/api/helpers/x.js")
60
+ // resolved there becomes "packages/api/packages/api/helpers/x.js" — a file
61
+ // that does not exist. With --no-error-on-unmatched-pattern that is not an
62
+ // error, it is silence: the gate reported zero problems on files it had
63
+ // never opened, and the lint errors it exists to stop reached CI anyway.
64
+ g.files.push(resolve(f));
52
65
  groups.set(found.cwd, g);
53
66
  }
54
67
  if (!groups.size) {
@@ -114,6 +114,29 @@ export function checkTestGates(content, _ext, ctx) {
114
114
  }
115
115
  }
116
116
  }
117
+ // F12 — "same host" is not a reason to abandon a dependency. A skip that
118
+ // blames the dependency for sharing a hostname with the app, without saying
119
+ // what else was tried, is the generator giving up on a stub it could have
120
+ // scoped. A service on another PORT is a different origin; one under its own
121
+ // PATH prefix is separable too; failing both, a predicate on the request
122
+ // itself usually is. Left unchecked this costs whole areas: sixty-four checks
123
+ // in one journey skipped on this wording alone, against a dependency sitting
124
+ // on a plainly different port.
125
+ //
126
+ // The rule still allows the genuine case — a dependency that truly cannot be
127
+ // told apart — but the reason has to show the work: name the port, the path,
128
+ // or the request property you checked.
129
+ {
130
+ const sameHost = /\b(?:skip|fixme)\s*\([^)]{0,400}?same\s+host(?:name)?[^)]{0,400}?\)/is;
131
+ const showedWork = /\b(?:port|origin|path\s*prefix|prefix|resource\s*type|header|predicate)\b/i;
132
+ const m = content.match(sameHost);
133
+ if (m && !showedWork.test(m[0])) {
134
+ return ('a test is skipped because the dependency "shares a host" with the app, ' +
135
+ 'without saying what else was checked — a different port is a different ' +
136
+ 'origin, and a path prefix or a request predicate usually separates them ' +
137
+ 'too; scope the stub to one of those, or name the ones you ruled out');
138
+ }
139
+ }
117
140
  // F10 — selector grounding: a RUNNABLE (non-skipped) UI test must not lean
118
141
  // on a guessed selector. Unchecked, the generator invents plausible
119
142
  // data-testids that time out at runtime — the journey is never really
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@activate-core/test-forge",
3
- "version": "0.17.0",
3
+ "version": "0.18.1",
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": {