@ia-qa/pal 0.2.0 → 0.4.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/run.js ADDED
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.TourAlreadyRunning = exports.logFile = exports.runFile = exports.runDir = void 0;
37
+ exports.isAlive = isAlive;
38
+ exports.readRun = readRun;
39
+ exports.activeRun = activeRun;
40
+ exports.trackedTour = trackedTour;
41
+ exports.startBackground = startBackground;
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const child_process_1 = require("child_process");
45
+ const tour_1 = require("./tour");
46
+ const runDir = (dir) => path.join(dir, '.ia-qa', 'pal');
47
+ exports.runDir = runDir;
48
+ const runFile = (dir) => path.join((0, exports.runDir)(dir), 'run.json');
49
+ exports.runFile = runFile;
50
+ const logFile = (dir) => path.join((0, exports.runDir)(dir), 'run.log');
51
+ exports.logFile = logFile;
52
+ function isAlive(pid) {
53
+ try {
54
+ process.kill(pid, 0);
55
+ return true;
56
+ }
57
+ catch (err) {
58
+ return err.code === 'EPERM';
59
+ }
60
+ }
61
+ const pause = (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
62
+ /**
63
+ * Atomic when it can be. On Windows a rename over a file another process is reading fails with
64
+ * EPERM/EBUSY — and something is always reading this one: `status`, or an agent polling
65
+ * `pal_status`. Measured: that failure, thrown from a progress write, killed the tour it was
66
+ * reporting on. So the rename is retried, and a direct write is the last resort.
67
+ */
68
+ function write(dir, record) {
69
+ fs.mkdirSync((0, exports.runDir)(dir), { recursive: true });
70
+ const body = JSON.stringify(record, null, 2);
71
+ const tmp = `${(0, exports.runFile)(dir)}.${process.pid}.tmp`;
72
+ fs.writeFileSync(tmp, body);
73
+ for (let attempt = 0; attempt < 20; attempt++) {
74
+ try {
75
+ fs.renameSync(tmp, (0, exports.runFile)(dir));
76
+ return;
77
+ }
78
+ catch (err) {
79
+ const code = err.code;
80
+ if (code !== 'EPERM' && code !== 'EBUSY' && code !== 'EACCES')
81
+ throw err;
82
+ pause(25);
83
+ }
84
+ }
85
+ fs.writeFileSync((0, exports.runFile)(dir), body);
86
+ fs.rmSync(tmp, { force: true });
87
+ }
88
+ /** Progress is a courtesy to whoever is watching; it must never cost the tour. */
89
+ function tryWrite(dir, record) {
90
+ try {
91
+ write(dir, record);
92
+ }
93
+ catch {
94
+ /* the next event, or the final record, writes it */
95
+ }
96
+ }
97
+ function readRun(dir) {
98
+ if (!fs.existsSync((0, exports.runFile)(dir)))
99
+ return null;
100
+ let record = null;
101
+ for (let attempt = 0; attempt < 10 && !record; attempt++) {
102
+ try {
103
+ record = JSON.parse(fs.readFileSync((0, exports.runFile)(dir), 'utf8'));
104
+ }
105
+ catch {
106
+ pause(20);
107
+ }
108
+ }
109
+ if (!record)
110
+ return null;
111
+ if (record.status === 'running' && !isAlive(record.pid)) {
112
+ return { ...record, status: 'interrupted', interrupted: true };
113
+ }
114
+ return record;
115
+ }
116
+ /** The running tour on this project, if one is alive. */
117
+ function activeRun(dir) {
118
+ const run = readRun(dir);
119
+ return run && run.status === 'running' ? run : null;
120
+ }
121
+ const newId = () => `${new Date().toISOString().replace(/[-:.TZ]/g, '').slice(0, 14)}-${process.pid}`;
122
+ class TourAlreadyRunning extends Error {
123
+ run;
124
+ constructor(run) {
125
+ super(`A tour is already running on this project (pid ${run.pid}, started ${run.startedAt}). Follow it with: ia-qa-pal status`);
126
+ this.run = run;
127
+ }
128
+ }
129
+ exports.TourAlreadyRunning = TourAlreadyRunning;
130
+ /** Run a tour with the lock held and the record kept current. */
131
+ async function trackedTour(opts) {
132
+ const dir = path.resolve(opts.dir);
133
+ const running = activeRun(dir);
134
+ if (running && running.pid !== process.pid)
135
+ throw new TourAlreadyRunning(running);
136
+ const now = () => new Date().toISOString();
137
+ const record = {
138
+ id: running?.id ?? newId(),
139
+ pid: process.pid,
140
+ status: 'running',
141
+ startedAt: running?.startedAt ?? now(),
142
+ updatedAt: now(),
143
+ options: { more: !!opts.more, suite: !!opts.suite, ...(opts.batch ? { batch: opts.batch } : {}) },
144
+ };
145
+ if (fs.existsSync(path.join(dir, '.ia-qa', 'config.json')))
146
+ write(dir, record);
147
+ try {
148
+ const report = await (0, tour_1.runTour)({
149
+ ...opts,
150
+ dir,
151
+ onEvent: (event) => {
152
+ opts.onEvent?.(event);
153
+ record.progress = event;
154
+ record.updatedAt = now();
155
+ if (fs.existsSync((0, exports.runDir)(dir)))
156
+ tryWrite(dir, record);
157
+ },
158
+ });
159
+ if (fs.existsSync((0, exports.runDir)(dir))) {
160
+ write(dir, { ...record, status: 'done', finishedAt: now(), updatedAt: now(), exitCode: report.exitCode, report });
161
+ }
162
+ return report;
163
+ }
164
+ catch (err) {
165
+ if (fs.existsSync((0, exports.runDir)(dir))) {
166
+ write(dir, { ...record, status: 'failed', finishedAt: now(), updatedAt: now(), exitCode: 2, error: err instanceof Error ? err.message : String(err) });
167
+ }
168
+ throw err;
169
+ }
170
+ }
171
+ /**
172
+ * Start a tour detached from the caller and return at once. The child is this package's own
173
+ * CLI with a fixed set of flags — never a command string from the caller.
174
+ */
175
+ function startBackground(dir, opts, entry = path.join(__dirname, 'cli', 'index.js')) {
176
+ const root = path.resolve(dir);
177
+ if (!fs.existsSync(path.join(root, '.ia-qa', 'config.json'))) {
178
+ return { started: false, reason: 'This project is not set up yet — there is no .ia-qa/config.json.' };
179
+ }
180
+ const running = activeRun(root);
181
+ if (running)
182
+ return { started: false, reason: new TourAlreadyRunning(running).message, run: running };
183
+ const args = [entry, 'tour', '--config', root, '--json'];
184
+ if (opts.more)
185
+ args.push('--more');
186
+ if (opts.suite)
187
+ args.push('--suite');
188
+ if (opts.strict)
189
+ args.push('--strict');
190
+ if (opts.batch)
191
+ args.push('--batch', String(opts.batch));
192
+ if (opts.session)
193
+ args.push('--session', opts.session);
194
+ fs.mkdirSync((0, exports.runDir)(root), { recursive: true });
195
+ const out = fs.openSync((0, exports.logFile)(root), 'w');
196
+ const child = (0, child_process_1.spawn)(process.execPath, args, { cwd: root, detached: true, stdio: ['ignore', out, out], windowsHide: true });
197
+ child.unref();
198
+ fs.closeSync(out);
199
+ write(root, {
200
+ id: newId(),
201
+ pid: child.pid ?? 0,
202
+ status: 'running',
203
+ startedAt: new Date().toISOString(),
204
+ updatedAt: new Date().toISOString(),
205
+ options: { more: !!opts.more, suite: !!opts.suite, ...(opts.batch ? { batch: opts.batch } : {}) },
206
+ });
207
+ return { started: true, pid: child.pid, log: (0, exports.logFile)(root) };
208
+ }
209
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
package/dist/setup.d.ts CHANGED
@@ -12,6 +12,10 @@ export interface SetupOptions {
12
12
  login?: PalLogin;
13
13
  /** Path of a Playwright storageState the suite already writes (login = session). */
14
14
  session?: string;
15
+ /** Folders holding the end-to-end suite, relative to the project. */
16
+ tests?: string[];
17
+ /** The command that runs that suite. Without one, a detected command is used. */
18
+ testCommand?: string;
15
19
  /** Write without asking for confirmation. */
16
20
  yes?: boolean;
17
21
  /** Ask for what is missing. Absent: nothing is asked, a missing answer is a refusal. */
@@ -25,10 +29,17 @@ export interface SetupOutcome {
25
29
  pages: PageTarget[];
26
30
  pagesFrom?: 'sitemap' | 'crawl' | 'home';
27
31
  login?: PalLogin;
32
+ tests?: string[];
33
+ testCommand?: string;
28
34
  /** What stops the file from being written, in words a person can act on. */
29
35
  problems: string[];
30
36
  /** The command to run next — a person's command when the login needs a browser. */
31
37
  next?: string;
32
38
  }
33
39
  export declare function configExists(dir: string): boolean;
40
+ /** Folders that look like an end-to-end suite. Proposed to a person, never assumed. */
41
+ export declare function detectTests(dir: string): {
42
+ paths: string[];
43
+ command?: string;
44
+ };
34
45
  export declare function runSetup(opts?: SetupOptions): Promise<SetupOutcome>;
package/dist/setup.js CHANGED
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.LOGIN_COMMAND = void 0;
37
37
  exports.configExists = configExists;
38
+ exports.detectTests = detectTests;
38
39
  exports.runSetup = runSetup;
39
40
  const fs = __importStar(require("fs"));
40
41
  const path = __importStar(require("path"));
@@ -59,9 +60,33 @@ function withHome(pages) {
59
60
  const name = pages.some((p) => p.name === 'home') ? 'home-page' : 'home';
60
61
  return [{ name, url: '/' }, ...pages];
61
62
  }
62
- function request(baseUrl, pages, login, session) {
63
+ function request(baseUrl, pages, login, session, tests, testCommand) {
63
64
  const mode = login === 'none' ? 'none' : 'session';
64
- return { baseUrl, pages, login: { mode, ...(login === 'session' && session ? { sessionFile: session } : {}) } };
65
+ return {
66
+ baseUrl,
67
+ pages,
68
+ login: { mode, ...(login === 'session' && session ? { sessionFile: session } : {}) },
69
+ ...(tests && tests.length > 0 ? { tests: { paths: tests, ...(testCommand ? { command: testCommand } : {}) } } : {}),
70
+ };
71
+ }
72
+ const TEST_DIRS = ['tests', 'e2e', 'test', 'cypress/e2e', 'specs'];
73
+ const SPEC_FILE = /\.(spec|test|cy)\.[cm]?[jt]sx?$/;
74
+ function hasSpecs(dir, depth = 0) {
75
+ if (depth > 3)
76
+ return false;
77
+ let entries;
78
+ try {
79
+ entries = fs.readdirSync(dir, { withFileTypes: true });
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ return entries.some((e) => e.isFile() ? SPEC_FILE.test(e.name) : e.isDirectory() && e.name !== 'node_modules' && hasSpecs(path.join(dir, e.name), depth + 1));
85
+ }
86
+ /** Folders that look like an end-to-end suite. Proposed to a person, never assumed. */
87
+ function detectTests(dir) {
88
+ const paths = TEST_DIRS.filter((d) => hasSpecs(path.join(dir, d)));
89
+ return { paths, command: paths.length > 0 ? (0, self_healing_1.detectTestCommand)(dir) : undefined };
65
90
  }
66
91
  async function runSetup(opts = {}) {
67
92
  const dir = path.resolve(opts.dir ?? process.cwd());
@@ -128,9 +153,31 @@ async function runSetup(opts = {}) {
128
153
  }
129
154
  }
130
155
  pages = withHome(pages);
131
- const body = request(url, pages, login, session);
156
+ let tests = opts.tests?.map((t) => t.trim()).filter(Boolean);
157
+ let testCommand = opts.testCommand?.trim();
158
+ if (!tests && opts.ask) {
159
+ const found = detectTests(dir);
160
+ if (found.paths.length > 0) {
161
+ const answer = (await opts.ask(`Found a test suite in ${found.paths.join(', ')}${found.command ? ` (run with: ${found.command})` : ''}. ` +
162
+ 'Read it too — repairs to its selectors, and which pages it never visits? [Y/n] ')).trim().toLowerCase();
163
+ if (answer === '' || answer === 'y' || answer === 'yes') {
164
+ tests = found.paths;
165
+ testCommand = testCommand || found.command;
166
+ }
167
+ }
168
+ }
169
+ const body = request(url, pages, login, session, tests, testCommand);
132
170
  const plan = (0, self_healing_1.planSetup)(body, dir);
133
- const outcome = { written: false, baseUrl: url, pages: plan.config.pages, pagesFrom, login, problems: plan.problems };
171
+ const outcome = {
172
+ written: false,
173
+ baseUrl: url,
174
+ pages: plan.config.pages,
175
+ pagesFrom,
176
+ login,
177
+ ...(plan.config.testPaths ? { tests: plan.config.testPaths } : {}),
178
+ ...(plan.config.testPaths && plan.config.testCommand ? { testCommand: plan.config.testCommand } : {}),
179
+ problems: plan.problems,
180
+ };
134
181
  if (plan.problems.length > 0)
135
182
  return outcome;
136
183
  const file = path.join(dir, '.ia-qa', 'config.json');
@@ -140,6 +187,7 @@ async function runSetup(opts = {}) {
140
187
  progress(` app ${url}`);
141
188
  progress(` pages ${names.length} from the ${pagesFrom === 'home' ? 'home page only' : pagesFrom}: ${names.slice(0, 8).join(', ')}${names.length > 8 ? `, +${names.length - 8} more` : ''}`);
142
189
  progress(` login ${login === 'none' ? 'none' : login === 'browser' ? `by hand — ${exports.LOGIN_COMMAND} saves .ia-qa/session.json` : `storageState ${session}`}`);
190
+ progress(` tests ${plan.config.testPaths ? `${plan.config.testPaths.join(', ')}${plan.config.testCommand ? ` · run with: ${plan.config.testCommand}` : ''}` : 'none'}`);
143
191
  progress(' Nothing else is written. No field holds a secret.');
144
192
  if (!opts.yes) {
145
193
  if (!opts.ask)
package/dist/setup.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
package/dist/state.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Pace } from './plan';
2
+ import type { SuiteRun } from './suite';
2
3
  /**
3
4
  * What a tour remembers between runs, and only what cannot be read back from the contracts:
4
5
  * which pages have explored depth is in each baseline file (`exploredDepth`), so it is never
@@ -14,6 +15,8 @@ export interface PalState {
14
15
  knownFindings: string[];
15
16
  /** Drift verdict of the latest regression tour — `--more` refuses to promote over a BLOCK. */
16
17
  lastVerdict?: 'PASS' | 'FIX' | 'BLOCK';
18
+ /** The latest `--suite` run: which pages the suite visited, and how it exited. */
19
+ suite?: SuiteRun;
17
20
  }
18
21
  export declare function statePath(): string;
19
22
  export declare function loadState(): PalState;
package/dist/state.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,8BAEC;AAED,8BAQC;AAED,8BAMC;AA1CD,uCAAyB;AACzB,2CAA6B;AAC7B,sDAAiD;AAoBjD,SAAgB,SAAS;IACvB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAA,yBAAU,GAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;AACpE,CAAC;AAED,SAAgB,SAAS;IACvB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAa,CAAC;QAC5E,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC;YAAE,OAAO,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;IACzI,CAAC;IAAC,MAAM,CAAC;QACP,mFAAmF;IACrF,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;AAC1D,CAAC;AAED,SAAgB,SAAS,CAAC,KAAe;IACvC,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,CAAC;IAC1B,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,8BAEC;AAED,8BAQC;AAED,8BAMC;AA7CD,uCAAyB;AACzB,2CAA6B;AAC7B,sDAAiD;AAuBjD,SAAgB,SAAS;IACvB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAA,yBAAU,GAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;AACpE,CAAC;AAED,SAAgB,SAAS;IACvB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAa,CAAC;QAC5E,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC;YAAE,OAAO,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;IACzI,CAAC;IAAC,MAAM,CAAC;QACP,mFAAmF;IACrF,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;AAC1D,CAAC;AAED,SAAgB,SAAS,CAAC,KAAe;IACvC,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC;IACzB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,CAAC;IAC1B,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,63 @@
1
+ import type { IaQaConfig } from '@ia-qa/self-healing';
2
+ /**
3
+ * Level 2: the test suite. Every answer here comes from `@ia-qa/self-healing` — the inventory
4
+ * `ingest` writes, the plan `fix --dry-run` computes, the names `audit` judges, the pages the
5
+ * capture hook records. This file only runs them in the right place and keeps what came back.
6
+ */
7
+ export declare const APPLY_COMMAND = "npx -p @ia-qa/self-healing ia-qa-heal fix";
8
+ export declare const CAPTURE_IMPORT = "import { test, expect } from '@ia-qa/self-healing/capture'";
9
+ export interface SuiteInventory {
10
+ paths: string[];
11
+ missingPaths: string[];
12
+ filesScanned: number;
13
+ selectors: number;
14
+ names: number;
15
+ }
16
+ export interface RepairPlan {
17
+ files: Array<{
18
+ file: string;
19
+ replacements: Array<{
20
+ from: string;
21
+ to: string;
22
+ count: number;
23
+ lines: number[];
24
+ }>;
25
+ }>;
26
+ total: number;
27
+ /** Occurrences found and deliberately left alone, with why — never silently dropped. */
28
+ leftAlone: number;
29
+ command: string;
30
+ }
31
+ export interface SuiteAudit {
32
+ deadNames: Array<{
33
+ name: string;
34
+ sites: Array<{
35
+ file: string;
36
+ line: number;
37
+ }>;
38
+ }>;
39
+ judged: number;
40
+ notJudged: number;
41
+ }
42
+ export interface SuiteRun {
43
+ command: string;
44
+ exitCode: number;
45
+ /** Pages the suite really visited, as the capture hook recorded them. Null: nothing was recorded. */
46
+ visited: string[] | null;
47
+ at: string;
48
+ }
49
+ /** `ingest`: what the suite writes as locators. Written to `usage.json`, where map, diff and fix read it. */
50
+ export declare function inventory(dir: string, config: IaQaConfig): SuiteInventory | null;
51
+ /** `fix --dry-run` over baseline/ → mapping/: the rewrites it would apply. Nothing is written. */
52
+ export declare function repairPlan(dir: string): Promise<RepairPlan | null>;
53
+ /** `audit`: locator names the suite writes that nothing on the mapped pages carries. Advisory. */
54
+ export declare function auditSuite(dir: string, config: IaQaConfig): SuiteAudit | null;
55
+ /**
56
+ * Run the suite with the capture hook armed, and learn which pages it visits.
57
+ *
58
+ * The capture lands in `.ia-qa/pal/suite-run/`, never in `mapping/`: a capture taken during a
59
+ * test run reads a page differently from `map`, and mixing the two in one directory is the
60
+ * phantom drift `ia-qa-heal run` warns about. Only the list of visited pages is kept.
61
+ * The command is the one in config.json — never a string from a caller.
62
+ */
63
+ export declare function runSuite(dir: string, config: IaQaConfig, onOutput: (chunk: string) => void): Promise<SuiteRun | null>;
package/dist/suite.js ADDED
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CAPTURE_IMPORT = exports.APPLY_COMMAND = void 0;
37
+ exports.inventory = inventory;
38
+ exports.repairPlan = repairPlan;
39
+ exports.auditSuite = auditSuite;
40
+ exports.runSuite = runSuite;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const child_process_1 = require("child_process");
44
+ const self_healing_1 = require("@ia-qa/self-healing");
45
+ /**
46
+ * Level 2: the test suite. Every answer here comes from `@ia-qa/self-healing` — the inventory
47
+ * `ingest` writes, the plan `fix --dry-run` computes, the names `audit` judges, the pages the
48
+ * capture hook records. This file only runs them in the right place and keeps what came back.
49
+ */
50
+ exports.APPLY_COMMAND = 'npx -p @ia-qa/self-healing ia-qa-heal fix';
51
+ exports.CAPTURE_IMPORT = "import { test, expect } from '@ia-qa/self-healing/capture'";
52
+ const rel = (dir, file) => path.relative(dir, file).replace(/\\/g, '/') || file;
53
+ function withExitCode(fn) {
54
+ const before = process.exitCode;
55
+ process.exitCode = undefined;
56
+ return fn().finally(() => {
57
+ process.exitCode = before;
58
+ });
59
+ }
60
+ /** `ingest`: what the suite writes as locators. Written to `usage.json`, where map, diff and fix read it. */
61
+ function inventory(dir, config) {
62
+ const declared = config.testPaths ?? [];
63
+ if (declared.length === 0)
64
+ return null;
65
+ const resolved = declared.map((p) => path.resolve(dir, p));
66
+ const missingPaths = declared.filter((_, i) => !fs.existsSync(resolved[i]));
67
+ const { usage } = (0, self_healing_1.ingestPaths)(resolved.filter((p) => fs.existsSync(p)), dir);
68
+ (0, self_healing_1.saveUsage)(usage, dir);
69
+ return {
70
+ paths: declared,
71
+ missingPaths,
72
+ filesScanned: usage.scanned,
73
+ selectors: Object.keys(usage.selectors).length,
74
+ names: Object.keys(usage.names ?? {}).length,
75
+ };
76
+ }
77
+ /** `fix --dry-run` over baseline/ → mapping/: the rewrites it would apply. Nothing is written. */
78
+ async function repairPlan(dir) {
79
+ const result = await withExitCode(() => (0, self_healing_1.runFix)(['--dry-run']));
80
+ if (!result || !result.dryRun)
81
+ return null;
82
+ const files = result.edits
83
+ .filter((e) => e.replacements.length > 0)
84
+ .map((e) => ({
85
+ file: rel(dir, e.file),
86
+ replacements: e.replacements.map((r) => ({ from: r.from, to: r.to, count: r.count, lines: r.lines ?? [] })),
87
+ }));
88
+ return {
89
+ files,
90
+ total: result.totalReplacements,
91
+ leftAlone: result.edits.reduce((s, e) => s + (e.skipped ?? []).reduce((t, k) => t + k.count, 0), 0),
92
+ command: exports.APPLY_COMMAND,
93
+ };
94
+ }
95
+ /** `audit`: locator names the suite writes that nothing on the mapped pages carries. Advisory. */
96
+ function auditSuite(dir, config) {
97
+ const outcome = (0, self_healing_1.auditProject)({ testPaths: (config.testPaths ?? []).map((p) => path.resolve(dir, p)) });
98
+ if (!outcome.ok)
99
+ return null;
100
+ return {
101
+ deadNames: outcome.report.deadLocators.map((d) => ({
102
+ name: d.name,
103
+ sites: d.sites.map((s) => ({ file: rel(dir, s.file), line: s.line })),
104
+ })),
105
+ judged: outcome.report.locatorsJudged,
106
+ notJudged: outcome.report.locatorsNotJudged,
107
+ };
108
+ }
109
+ /**
110
+ * Run the suite with the capture hook armed, and learn which pages it visits.
111
+ *
112
+ * The capture lands in `.ia-qa/pal/suite-run/`, never in `mapping/`: a capture taken during a
113
+ * test run reads a page differently from `map`, and mixing the two in one directory is the
114
+ * phantom drift `ia-qa-heal run` warns about. Only the list of visited pages is kept.
115
+ * The command is the one in config.json — never a string from a caller.
116
+ */
117
+ async function runSuite(dir, config, onOutput) {
118
+ const command = config.testCommand;
119
+ if (!command)
120
+ return null;
121
+ const isolated = path.join(dir, '.ia-qa', 'pal', 'suite-run');
122
+ fs.rmSync(isolated, { recursive: true, force: true });
123
+ fs.mkdirSync(path.join(isolated, '.ia-qa'), { recursive: true });
124
+ fs.writeFileSync(path.join(isolated, '.ia-qa', 'config.json'), JSON.stringify(config, null, 2));
125
+ const exitCode = await new Promise((resolve) => {
126
+ const child = (0, child_process_1.spawn)(command, {
127
+ cwd: dir,
128
+ shell: true,
129
+ env: { ...process.env, IAQA_CAPTURE: '1', IAQA_CONFIG_DIR: isolated },
130
+ });
131
+ child.stdout.on('data', (d) => onOutput(d.toString()));
132
+ child.stderr.on('data', (d) => onOutput(d.toString()));
133
+ child.on('error', () => resolve(127));
134
+ child.on('close', (code) => resolve(code ?? 1));
135
+ });
136
+ let visited = null;
137
+ try {
138
+ visited = (0, self_healing_1.mergeCaptures)(isolated)?.pages ?? null;
139
+ }
140
+ finally {
141
+ fs.rmSync(isolated, { recursive: true, force: true });
142
+ }
143
+ return { command, exitCode, visited: visited ? [...visited].sort() : null, at: new Date().toISOString() };
144
+ }
145
+ //# sourceMappingURL=suite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suite.js","sourceRoot":"","sources":["../src/suite.ts"],"names":[],"mappings":"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"}