@ia-qa/self-healing 1.25.0 → 1.26.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/README.md +10 -1
- package/TUTORIAL.md +17 -3
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/login.d.ts +86 -2
- package/dist/cli/login.js +213 -42
- package/dist/cli/login.js.map +1 -1
- package/dist/cli/session.d.ts +27 -0
- package/dist/cli/session.js +37 -27
- package/dist/cli/session.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/ia-qa-heal/SKILL.md +5 -1
package/README.md
CHANGED
|
@@ -152,7 +152,16 @@ npx ia-qa-heal login # opens a real browser; you log in however the app asks
|
|
|
152
152
|
npx ia-qa-heal map # reuses that session
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
-
**
|
|
155
|
+
**Nothing to confirm in the terminal.** `login` watches the window and finishes by itself the
|
|
156
|
+
moment the session it carries genuinely opens the app — "press Enter when you are done" was
|
|
157
|
+
the last place this verb took somebody's word for a fact about the world, and it mostly went
|
|
158
|
+
unanswered while the person got on with their day. What counts as done is a definition rather
|
|
159
|
+
than a guess: a clean browser carrying only the captured session has to reach somewhere the
|
|
160
|
+
logged-out one could not, so a magic-link login page with no password field on it is never
|
|
161
|
+
mistaken for success. `--wait 0` restores the press-Enter flow for an app whose login cannot
|
|
162
|
+
be observed from outside; `--wait <seconds>` changes how long to watch.
|
|
163
|
+
|
|
164
|
+
**The session is checked before it is saved.** `login` reopens
|
|
156
165
|
the same page in a clean browser carrying nothing but the captured session. Only a session that
|
|
157
166
|
lands on the app is saved and reported as good. A session that carries nothing is **not
|
|
158
167
|
written at all** — it could log nobody in, and writing it would replace a session that worked.
|
package/TUTORIAL.md
CHANGED
|
@@ -278,9 +278,23 @@ npx ia-qa-heal login # a real browser window opens at your first configured
|
|
|
278
278
|
npx ia-qa-heal map # reuses that session; no "auth" block needed
|
|
279
279
|
```
|
|
280
280
|
|
|
281
|
-
**
|
|
282
|
-
|
|
283
|
-
|
|
281
|
+
**You do not have to come back and confirm anything.** The window is watched: the moment the
|
|
282
|
+
session it carries genuinely opens the app, it is saved and the command finishes on its own.
|
|
283
|
+
That replaces "press Enter when you are done", which was the last place this verb took a
|
|
284
|
+
human's word for a fact about the world — and which failed in the most ordinary way there is,
|
|
285
|
+
by being left unanswered while the person went back to work.
|
|
286
|
+
|
|
287
|
+
What counts as done is a definition, not a guess: **a clean browser carrying only the captured
|
|
288
|
+
session has to reach somewhere the logged-out one could not.** Reading "no password field on
|
|
289
|
+
screen" as success instead would call a magic-link or passkey login page a finished login.
|
|
290
|
+
|
|
291
|
+
If your app's login cannot be seen from the outside at all, `--wait 0` restores the plain
|
|
292
|
+
press-Enter flow, and `--wait <seconds>` sets how long to watch (default 10 minutes). Running
|
|
293
|
+
out of time is **not** a refusal: whatever the browser holds is checked and reported anyway.
|
|
294
|
+
|
|
295
|
+
**It checks the session before saving it, and tells you which file now holds what.** The
|
|
296
|
+
session is replayed in a clean browser: same page, nothing but the captured cookies and local
|
|
297
|
+
storage.
|
|
284
298
|
|
|
285
299
|
| what the replay shows | what happens | exit |
|
|
286
300
|
|---|---|---|
|
package/dist/cli/args.js
CHANGED
|
@@ -17,7 +17,7 @@ exports.rejectUnknownFlags = rejectUnknownFlags;
|
|
|
17
17
|
exports.KNOWN_FLAGS = {
|
|
18
18
|
init: ['--yes', '--base-url', '--pages', '--discover', '--tests', '--test-command', '--bootstrap'],
|
|
19
19
|
discover: ['--sitemap', '--crawl', '--no-reveal', '--strict-host', '--apply', '--max', '--depth', '--session'],
|
|
20
|
-
login: ['--url', '--session'],
|
|
20
|
+
login: ['--url', '--session', '--wait'],
|
|
21
21
|
secret: ['--json'],
|
|
22
22
|
session: ['--check', '--offline', '--url', '--session', '--json'],
|
|
23
23
|
map: ['--screenshots', '--session', '--deep', '--depth', '--deep-budget', '--fix-redirects'],
|
package/dist/cli/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":";;;AAkCA,gDAeC;AAjDD;;;;;;;;;;;GAWG;AACU,QAAA,WAAW,GAAsC;IAC5D,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,CAAC;IAClG,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC;IAC9G,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":";;;AAkCA,gDAeC;AAjDD;;;;;;;;;;;GAWG;AACU,QAAA,WAAW,GAAsC;IAC5D,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,CAAC;IAClG,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC;IAC9G,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC;IACvC,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC;IACjE,GAAG,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,CAAC;IAC5F,QAAQ,EAAE,CAAC,WAAW,CAAC;IACvB,IAAI,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IACtE,GAAG,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC;IACnD,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC7B,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC;IACvD,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,CAAC;IAC3D,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;IAChD,GAAG,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACtF,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;IAC7D,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,YAAY,EAAE,CAAC,QAAQ,CAAC;IACxB,EAAE,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,CAAC;CACnF,CAAC;AAEF,SAAgB,kBAAkB,CAAC,OAAe,EAAE,IAAc;IAChE,MAAM,KAAK,GAAG,mBAAW,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO;IAChC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACjC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,eAAe,OAAO,0FAA0F;gBAC9G,4GAA4G;gBAC5G,8FAA8F,CACjG,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,qBAAqB,OAAO,8CAA8C,CAAC,CAAC;IAChH,CAAC;AACH,CAAC"}
|
package/dist/cli/login.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Browser } from 'playwright';
|
|
1
|
+
import type { Browser, BrowserContext, Page } from 'playwright';
|
|
2
2
|
/**
|
|
3
3
|
* `ia-qa-heal login` — open a browser, let a human log in, keep the session.
|
|
4
4
|
*
|
|
@@ -26,7 +26,19 @@ import type { Browser } from 'playwright';
|
|
|
26
26
|
* with your own suite's login) remain the two paths. A saved session is a local artefact
|
|
27
27
|
* with a shelf life — when it expires, `map` hits the wall again and says to re-run this.
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
/**
|
|
30
|
+
* What the verb achieved, for a caller that is not a shell.
|
|
31
|
+
*
|
|
32
|
+
* `ok` is the same thing the exit code says — a session that was **replayed** and opened the
|
|
33
|
+
* app — so an orchestrator cannot read success more loosely than the terminal does. The exit
|
|
34
|
+
* code is still set, because this is a CLI verb first.
|
|
35
|
+
*/
|
|
36
|
+
export interface LoginResult {
|
|
37
|
+
ok: boolean;
|
|
38
|
+
/** Where the session was written, when anything was written at all. */
|
|
39
|
+
file?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function runLogin(args: string[]): Promise<LoginResult>;
|
|
30
42
|
export interface SessionReplay {
|
|
31
43
|
landed: string;
|
|
32
44
|
wall: boolean;
|
|
@@ -58,6 +70,78 @@ export interface SessionReplay {
|
|
|
58
70
|
* says nothing when the browser is not even on the app any more.
|
|
59
71
|
*/
|
|
60
72
|
export declare function replaySession(browser: Browser, state: Awaited<ReturnType<Awaited<ReturnType<Browser['newContext']>>['storageState']>>, target: string, contextOptions?: Record<string, unknown>): Promise<SessionReplay>;
|
|
73
|
+
/** Why the watch stopped. Only `verified` means the session was proven from a clean context. */
|
|
74
|
+
export type LoginEnd = 'verified' | 'confirmed' | 'closed' | 'timeout';
|
|
75
|
+
export interface LoginWatch {
|
|
76
|
+
end: LoginEnd;
|
|
77
|
+
/** The verification that ended the watch, when one did. */
|
|
78
|
+
replay?: SessionReplay;
|
|
79
|
+
/**
|
|
80
|
+
* The state that `replay` was taken from — never a later one.
|
|
81
|
+
*
|
|
82
|
+
* They travel together because they must: verifying state S1 and then writing an S2 taken
|
|
83
|
+
* a moment later reports a proof about a file that was never the file. That is this
|
|
84
|
+
* verb's own bug in a new place, and the pair makes it unrepresentable.
|
|
85
|
+
*/
|
|
86
|
+
state?: Awaited<ReturnType<BrowserContext['storageState']>>;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Is this state, replayed in a clean context, evidence that somebody logged in?
|
|
90
|
+
*
|
|
91
|
+
* One rule, and it is the definition rather than a heuristic: **a login worked when a clean
|
|
92
|
+
* context reaches somewhere the unauthenticated browser could not.** `startedAt` is where
|
|
93
|
+
* the very first navigation landed — the wall — so a replay that lands back there gained
|
|
94
|
+
* nothing, whatever it shows.
|
|
95
|
+
*
|
|
96
|
+
* Reading "no password field" as success instead is the trap this avoids, and it is not
|
|
97
|
+
* theoretical: a magic-link or passkey login page has no password field at all, so the
|
|
98
|
+
* cheap signal says *logged in* from the first second, and the watch would save a state
|
|
99
|
+
* that opens nothing and call it ✅ — the exact false green this verb was rewritten to stop.
|
|
100
|
+
*/
|
|
101
|
+
export declare function loginProven(replay: SessionReplay, startedAt: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Watch a visible browser until the person is logged in — instead of asking them to say so.
|
|
104
|
+
*
|
|
105
|
+
* The prompt this replaces was the last place in the verb that trusted a human's word, and
|
|
106
|
+
* the verb's whole history is about not doing that: `storageState({ path })` wrote on that
|
|
107
|
+
* word and printed `✅ Session saved — 0 cookies` over a file that logged nobody in. Asking
|
|
108
|
+
* "are you done?" has the same shape — it is a question about the world answered by
|
|
109
|
+
* someone who is looking at a browser, not at the cookie jar. And it fails in the most
|
|
110
|
+
* ordinary way there is: the person logs in, goes back to what they were doing, and the
|
|
111
|
+
* terminal sits on an unanswered prompt. It was reported by the person who wrote it.
|
|
112
|
+
*
|
|
113
|
+
* So the watch asks the browser, on a loop, and the evidence it accepts is the one the rest
|
|
114
|
+
* of this file already accepts: a **clean context** carrying only the captured state,
|
|
115
|
+
* reaching somewhere the unauthenticated browser could not (`loginProven`).
|
|
116
|
+
*
|
|
117
|
+
* Three restraints:
|
|
118
|
+
*
|
|
119
|
+
* - **It never gives up early.** A verification that fails means *not yet* — a multi-step
|
|
120
|
+
* login, a consent screen still to come — never *this will not work*. After a few failed
|
|
121
|
+
* attempts it explains the one case that genuinely cannot succeed (a token in IndexedDB
|
|
122
|
+
* leaves a session file empty) and keeps watching, because the alternative is telling
|
|
123
|
+
* somebody their login failed while they are still typing.
|
|
124
|
+
* - **The keyboard still works.** `confirmed` is the escape hatch for every app whose
|
|
125
|
+
* login this cannot observe, and whichever finishes first wins. Nothing that worked
|
|
126
|
+
* before stops working.
|
|
127
|
+
* - **Replaying is not free**, so the cheap gate runs first: on the app's own site, no
|
|
128
|
+
* password field in any frame, and something in the cookie jar. A clean context is
|
|
129
|
+
* opened only once that holds, and then only when the live page has moved again or
|
|
130
|
+
* enough time has passed.
|
|
131
|
+
*/
|
|
132
|
+
export declare function watchForLogin(opts: {
|
|
133
|
+
browser: Browser;
|
|
134
|
+
context: BrowserContext;
|
|
135
|
+
page: Page;
|
|
136
|
+
target: string;
|
|
137
|
+
/** Where the FIRST navigation landed: the wall, and the thing a replay must beat. */
|
|
138
|
+
startedAt: string;
|
|
139
|
+
contextOptions?: Record<string, unknown>;
|
|
140
|
+
confirmed: Promise<void>;
|
|
141
|
+
timeoutMs?: number;
|
|
142
|
+
now?: () => number;
|
|
143
|
+
note?: (line: string) => void;
|
|
144
|
+
}): Promise<LoginWatch>;
|
|
61
145
|
export interface SessionDecision {
|
|
62
146
|
ok: boolean;
|
|
63
147
|
action: 'write' | 'quarantine' | 'none';
|
package/dist/cli/login.js
CHANGED
|
@@ -38,6 +38,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.runLogin = runLogin;
|
|
40
40
|
exports.replaySession = replaySession;
|
|
41
|
+
exports.loginProven = loginProven;
|
|
42
|
+
exports.watchForLogin = watchForLogin;
|
|
41
43
|
exports.sessionDecision = sessionDecision;
|
|
42
44
|
const fs = __importStar(require("fs"));
|
|
43
45
|
const path = __importStar(require("path"));
|
|
@@ -46,33 +48,7 @@ const launcher_1 = require("../launcher");
|
|
|
46
48
|
const map_1 = require("./map");
|
|
47
49
|
const sessionCheck_1 = require("../sessionCheck");
|
|
48
50
|
const config_1 = require("../config");
|
|
49
|
-
|
|
50
|
-
* `ia-qa-heal login` — open a browser, let a human log in, keep the session.
|
|
51
|
-
*
|
|
52
|
-
* `config.auth` fills a form: a username field, a password field, a submit button. That
|
|
53
|
-
* describes *one shape of login*, and every app whose login is not that shape is out of
|
|
54
|
-
* reach — federated SSO, MFA, a consent screen, a magic link, a device check, a captcha.
|
|
55
|
-
* No selector list gets through any of them, so "add an auth block" is the wrong answer
|
|
56
|
-
* to most walls, and `map` was left mapping a login form under the name `dashboard`.
|
|
57
|
-
*
|
|
58
|
-
* This verb models nothing at all, which is why it is the general one: the human performs
|
|
59
|
-
* whatever the app asks, and the resulting session is saved in Playwright's `storageState`
|
|
60
|
-
* shape and reused by `map`. It cannot know *how* your app authenticates, and never needs to.
|
|
61
|
-
*
|
|
62
|
-
* Deliberately not automatic, and never part of a gate:
|
|
63
|
-
* - It is the only caller that opens a **visible** browser (`headed`) — everything that
|
|
64
|
-
* produces a contract stays headless, because a window in CI is a hung build.
|
|
65
|
-
* - It refuses without a TTY and under CI: it waits for a person twice over (at the
|
|
66
|
-
* browser, then at the keyboard), and a pipeline that runs it just hangs.
|
|
67
|
-
* - What it writes is a **secret** — live cookies, i.e. whoever holds the file is logged
|
|
68
|
-
* in as that user. So it announces the path before opening anything, and writes
|
|
69
|
-
* `.ia-qa/.gitignore` so a commit cannot carry it. The file never leaves the machine:
|
|
70
|
-
* nothing in this package uploads it.
|
|
71
|
-
*
|
|
72
|
-
* For CI, `config.auth` (reproducible, no human) and capture-during-run (`IAQA_CAPTURE=1`
|
|
73
|
-
* with your own suite's login) remain the two paths. A saved session is a local artefact
|
|
74
|
-
* with a shelf life — when it expires, `map` hits the wall again and says to re-run this.
|
|
75
|
-
*/
|
|
51
|
+
const sessionCheck_2 = require("../sessionCheck");
|
|
76
52
|
async function runLogin(args) {
|
|
77
53
|
if (process.env.CI) {
|
|
78
54
|
console.error(`❌ Refusing to open a login browser under CI.\n\n` +
|
|
@@ -81,14 +57,14 @@ async function runLogin(args) {
|
|
|
81
57
|
` "auth" in .ia-qa/config.json fills a login form from env/SSM secrets\n` +
|
|
82
58
|
` IAQA_CAPTURE=1 + testCommand your own suite logs in; map rides along`);
|
|
83
59
|
process.exitCode = 2;
|
|
84
|
-
return;
|
|
60
|
+
return { ok: false };
|
|
85
61
|
}
|
|
86
62
|
if (!process.stdin.isTTY) {
|
|
87
63
|
console.error(`❌ \`ia-qa-heal login\` needs a terminal: it opens a browser, then waits for you to say\n` +
|
|
88
64
|
` you are logged in. With stdin closed it would wait forever.\n` +
|
|
89
65
|
` Run it in your own shell — an agent cannot do this step for you.`);
|
|
90
66
|
process.exitCode = 2;
|
|
91
|
-
return;
|
|
67
|
+
return { ok: false };
|
|
92
68
|
}
|
|
93
69
|
const config = (0, config_1.loadConfig)();
|
|
94
70
|
const urlIdx = args.indexOf('--url');
|
|
@@ -96,7 +72,7 @@ async function runLogin(args) {
|
|
|
96
72
|
if (urlIdx !== -1 && (!wanted || wanted.startsWith('-'))) {
|
|
97
73
|
console.error('❌ --url needs a URL or a path (e.g. --url /dashboard).');
|
|
98
74
|
process.exitCode = 2;
|
|
99
|
-
return;
|
|
75
|
+
return { ok: false };
|
|
100
76
|
}
|
|
101
77
|
const target = new URL(wanted || config.pages[0]?.url || '/', config.baseUrl).toString();
|
|
102
78
|
// Written where this project keeps its session, not always the default: someone who
|
|
@@ -107,9 +83,19 @@ async function runLogin(args) {
|
|
|
107
83
|
if (sessionIdx !== -1 && (!explicit || explicit.startsWith('-'))) {
|
|
108
84
|
console.error('❌ --session needs a file path.');
|
|
109
85
|
process.exitCode = 2;
|
|
110
|
-
return;
|
|
86
|
+
return { ok: false };
|
|
111
87
|
}
|
|
112
88
|
const file = (0, config_1.sessionTarget)(config, explicit).file;
|
|
89
|
+
// How long to watch the window before falling back to "tell me what is in there".
|
|
90
|
+
// `--wait 0` turns the watch off and restores the plain press-Enter flow, which is the
|
|
91
|
+
// escape hatch for an app whose login cannot be observed from the outside at all.
|
|
92
|
+
const waitIdx = args.indexOf('--wait');
|
|
93
|
+
const waitSeconds = waitIdx !== -1 ? Number(args[waitIdx + 1]) : 600;
|
|
94
|
+
if (waitIdx !== -1 && (!Number.isFinite(waitSeconds) || waitSeconds < 0)) {
|
|
95
|
+
console.error('❌ --wait needs a number of seconds (0 turns the watch off).');
|
|
96
|
+
process.exitCode = 2;
|
|
97
|
+
return { ok: false };
|
|
98
|
+
}
|
|
113
99
|
console.log(`\n🔑 ia-qa-heal login`);
|
|
114
100
|
console.log(` Opens a visible browser at ${target}.`);
|
|
115
101
|
console.log(` Log in there however your app asks — SSO, MFA, a consent screen, all of it.`);
|
|
@@ -123,7 +109,7 @@ async function runLogin(args) {
|
|
|
123
109
|
if (!go.ok) {
|
|
124
110
|
console.log('Nothing opened, nothing written.');
|
|
125
111
|
process.exitCode = 1;
|
|
126
|
-
return;
|
|
112
|
+
return { ok: false };
|
|
127
113
|
}
|
|
128
114
|
const { browser, using } = await (0, launcher_1.launchBrowser)({ headed: true });
|
|
129
115
|
console.log(`🌐 Using ${using} (visible window)`);
|
|
@@ -132,21 +118,69 @@ async function runLogin(args) {
|
|
|
132
118
|
const context = await browser.newContext(contextOptions);
|
|
133
119
|
const page = await context.newPage();
|
|
134
120
|
await page.goto(target, { waitUntil: 'domcontentloaded', timeout: 60000 });
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
121
|
+
// Where an UNauthenticated browser lands is the thing a real login has to beat, so it
|
|
122
|
+
// is read before anything else happens.
|
|
123
|
+
const startedAt = page.url();
|
|
124
|
+
console.log(waitSeconds > 0
|
|
125
|
+
? `\n👀 Log in in the browser window. I am watching it — when the session actually opens\n` +
|
|
126
|
+
` the app, I save it and carry on by myself. Nothing to come back and confirm here.\n` +
|
|
127
|
+
` (Press Enter if you would rather stop the wait now.)`
|
|
128
|
+
: `\n👀 Log in in the browser window, then press Enter here.`);
|
|
129
|
+
const enter = waitForEnter();
|
|
130
|
+
let watch;
|
|
131
|
+
try {
|
|
132
|
+
watch =
|
|
133
|
+
waitSeconds > 0
|
|
134
|
+
? await watchForLogin({
|
|
135
|
+
browser,
|
|
136
|
+
context,
|
|
137
|
+
page,
|
|
138
|
+
target,
|
|
139
|
+
startedAt,
|
|
140
|
+
contextOptions,
|
|
141
|
+
confirmed: enter.promise,
|
|
142
|
+
timeoutMs: waitSeconds * 1000,
|
|
143
|
+
})
|
|
144
|
+
: (await enter.promise, { end: 'confirmed' });
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
enter.cancel();
|
|
148
|
+
}
|
|
149
|
+
// A timeout is **not** a refusal. It only means nobody told us the login finished, so
|
|
150
|
+
// the question becomes the one this verb always answers: what does the browser actually
|
|
151
|
+
// hold right now? `sessionDecision` says it honestly — an empty state writes nothing and
|
|
152
|
+
// keeps the file that worked, a wall goes beside it, neither is ever a ✅. Returning
|
|
153
|
+
// early instead would throw away a session somebody really did obtain, just because the
|
|
154
|
+
// watch could not see the app from the outside.
|
|
155
|
+
if (watch.end === 'timeout') {
|
|
156
|
+
console.log(`\n⏳ Nothing that looks like a login happened in ${(0, sessionCheck_2.describeAge)(waitSeconds)}. Checking what the\n` +
|
|
157
|
+
` browser holds anyway — whatever it is, it is reported rather than assumed.`);
|
|
158
|
+
}
|
|
141
159
|
// Taken in memory, written only once it has been replayed. `storageState({ path })`
|
|
142
160
|
// wrote first and asked nothing, so an empty state — an app keeping its token in
|
|
143
161
|
// IndexedDB, or a login that never completed — printed a green "Session saved" *and*
|
|
144
162
|
// overwrote a session that worked. Two failures in one line: a false green, and the
|
|
145
163
|
// destruction of the good file it replaced.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const
|
|
164
|
+
//
|
|
165
|
+
// A closed window is not a special case: whatever the context held when it went is what
|
|
166
|
+
// gets judged, and `sessionDecision` says the honest thing about it.
|
|
167
|
+
const takenOn = page.isClosed() ? startedAt : page.url();
|
|
168
|
+
// The state and the proof about it travel together — writing a state taken *after* the
|
|
169
|
+
// verification would report a proof about a file that was never the file.
|
|
170
|
+
//
|
|
171
|
+
// Which pair, though, depends on how the watch ended. `verified` is the watch's own, by
|
|
172
|
+
// definition. A **closed** window leaves no way to take another, so the last attempt is
|
|
173
|
+
// all there is. But `confirmed` must be re-checked: pressing Enter means *look now*, and
|
|
174
|
+
// the person very often finishes the login and only then reaches for the keyboard — the
|
|
175
|
+
// last failed attempt would be a verdict about the moment before they succeeded.
|
|
176
|
+
const reusable = watch.end === 'verified' || (watch.end === 'closed' && watch.state);
|
|
177
|
+
let state = reusable ? watch.state : undefined;
|
|
178
|
+
let replay = reusable ? watch.replay : undefined;
|
|
179
|
+
if (!state || !replay) {
|
|
180
|
+
state = await context.storageState().catch(() => ({ cookies: [], origins: [] }));
|
|
181
|
+
console.log(`\n🔁 Checking the session actually holds — reopening ${target} with it, in a clean browser.`);
|
|
182
|
+
replay = await replaySession(browser, state, target, contextOptions);
|
|
183
|
+
}
|
|
150
184
|
const decision = sessionDecision({
|
|
151
185
|
cookies: state.cookies.length,
|
|
152
186
|
origins: state.origins?.length || 0,
|
|
@@ -167,11 +201,37 @@ async function runLogin(args) {
|
|
|
167
201
|
(decision.ok ? console.log : console.error)(line);
|
|
168
202
|
if (!decision.ok)
|
|
169
203
|
process.exitCode = 1;
|
|
204
|
+
return { ok: decision.ok, ...(decision.action !== 'none' ? { file: decision.target } : {}) };
|
|
170
205
|
}
|
|
171
206
|
finally {
|
|
172
207
|
await browser.close();
|
|
173
208
|
}
|
|
174
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* "Press Enter" as a *cancellable* promise, which `prompts` cannot be.
|
|
212
|
+
*
|
|
213
|
+
* The watch and the keyboard race each other, so the loser has to be taken back: a `prompts`
|
|
214
|
+
* question left open keeps stdin resumed and the process alive long after the browser has
|
|
215
|
+
* closed and the session has been written. Raw stdin gives back a `cancel` that removes the
|
|
216
|
+
* listener and pauses the stream, which is the whole reason for not reusing `prompts` here.
|
|
217
|
+
*/
|
|
218
|
+
function waitForEnter() {
|
|
219
|
+
let done = () => { };
|
|
220
|
+
const promise = new Promise((resolve) => {
|
|
221
|
+
done = resolve;
|
|
222
|
+
});
|
|
223
|
+
const onData = () => {
|
|
224
|
+
cancel();
|
|
225
|
+
done();
|
|
226
|
+
};
|
|
227
|
+
const cancel = () => {
|
|
228
|
+
process.stdin.off('data', onData);
|
|
229
|
+
process.stdin.pause();
|
|
230
|
+
};
|
|
231
|
+
process.stdin.resume();
|
|
232
|
+
process.stdin.on('data', onData);
|
|
233
|
+
return { promise, cancel };
|
|
234
|
+
}
|
|
175
235
|
/**
|
|
176
236
|
* `.ia-qa/.gitignore`, scoped to the one file in there that is a secret.
|
|
177
237
|
*
|
|
@@ -230,6 +290,117 @@ async function replaySession(browser, state, target, contextOptions = {}) {
|
|
|
230
290
|
await context.close();
|
|
231
291
|
}
|
|
232
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Is this state, replayed in a clean context, evidence that somebody logged in?
|
|
295
|
+
*
|
|
296
|
+
* One rule, and it is the definition rather than a heuristic: **a login worked when a clean
|
|
297
|
+
* context reaches somewhere the unauthenticated browser could not.** `startedAt` is where
|
|
298
|
+
* the very first navigation landed — the wall — so a replay that lands back there gained
|
|
299
|
+
* nothing, whatever it shows.
|
|
300
|
+
*
|
|
301
|
+
* Reading "no password field" as success instead is the trap this avoids, and it is not
|
|
302
|
+
* theoretical: a magic-link or passkey login page has no password field at all, so the
|
|
303
|
+
* cheap signal says *logged in* from the first second, and the watch would save a state
|
|
304
|
+
* that opens nothing and call it ✅ — the exact false green this verb was rewritten to stop.
|
|
305
|
+
*/
|
|
306
|
+
function loginProven(replay, startedAt) {
|
|
307
|
+
if (replay.error || replay.wall || replay.offSite)
|
|
308
|
+
return false;
|
|
309
|
+
if (!replay.landed)
|
|
310
|
+
return false;
|
|
311
|
+
return !(0, map_1.samePath)(replay.landed, startedAt);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Watch a visible browser until the person is logged in — instead of asking them to say so.
|
|
315
|
+
*
|
|
316
|
+
* The prompt this replaces was the last place in the verb that trusted a human's word, and
|
|
317
|
+
* the verb's whole history is about not doing that: `storageState({ path })` wrote on that
|
|
318
|
+
* word and printed `✅ Session saved — 0 cookies` over a file that logged nobody in. Asking
|
|
319
|
+
* "are you done?" has the same shape — it is a question about the world answered by
|
|
320
|
+
* someone who is looking at a browser, not at the cookie jar. And it fails in the most
|
|
321
|
+
* ordinary way there is: the person logs in, goes back to what they were doing, and the
|
|
322
|
+
* terminal sits on an unanswered prompt. It was reported by the person who wrote it.
|
|
323
|
+
*
|
|
324
|
+
* So the watch asks the browser, on a loop, and the evidence it accepts is the one the rest
|
|
325
|
+
* of this file already accepts: a **clean context** carrying only the captured state,
|
|
326
|
+
* reaching somewhere the unauthenticated browser could not (`loginProven`).
|
|
327
|
+
*
|
|
328
|
+
* Three restraints:
|
|
329
|
+
*
|
|
330
|
+
* - **It never gives up early.** A verification that fails means *not yet* — a multi-step
|
|
331
|
+
* login, a consent screen still to come — never *this will not work*. After a few failed
|
|
332
|
+
* attempts it explains the one case that genuinely cannot succeed (a token in IndexedDB
|
|
333
|
+
* leaves a session file empty) and keeps watching, because the alternative is telling
|
|
334
|
+
* somebody their login failed while they are still typing.
|
|
335
|
+
* - **The keyboard still works.** `confirmed` is the escape hatch for every app whose
|
|
336
|
+
* login this cannot observe, and whichever finishes first wins. Nothing that worked
|
|
337
|
+
* before stops working.
|
|
338
|
+
* - **Replaying is not free**, so the cheap gate runs first: on the app's own site, no
|
|
339
|
+
* password field in any frame, and something in the cookie jar. A clean context is
|
|
340
|
+
* opened only once that holds, and then only when the live page has moved again or
|
|
341
|
+
* enough time has passed.
|
|
342
|
+
*/
|
|
343
|
+
async function watchForLogin(opts) {
|
|
344
|
+
const note = opts.note ?? ((line) => console.log(line));
|
|
345
|
+
const now = opts.now ?? Date.now;
|
|
346
|
+
const deadline = now() + (opts.timeoutMs ?? 10 * 60 * 1000);
|
|
347
|
+
let confirmed = false;
|
|
348
|
+
void opts.confirmed.then(() => {
|
|
349
|
+
confirmed = true;
|
|
350
|
+
});
|
|
351
|
+
let lastVerifiedUrl = '';
|
|
352
|
+
let lastVerifiedAt = 0;
|
|
353
|
+
let attempts = 0;
|
|
354
|
+
// The last attempt, kept as a pair. It is offered on a `confirmed`/`closed` ending only
|
|
355
|
+
// because it is a true statement about a state we still hold; it is never a success.
|
|
356
|
+
let last;
|
|
357
|
+
for (;;) {
|
|
358
|
+
if (confirmed)
|
|
359
|
+
return { end: 'confirmed', ...last };
|
|
360
|
+
if (opts.page.isClosed())
|
|
361
|
+
return { end: 'closed', ...last };
|
|
362
|
+
if (now() >= deadline)
|
|
363
|
+
return { end: 'timeout', ...last };
|
|
364
|
+
let url = '';
|
|
365
|
+
let cookies = 0;
|
|
366
|
+
try {
|
|
367
|
+
url = opts.page.url();
|
|
368
|
+
cookies = (await opts.context.cookies()).length;
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
// The context went away under us — the person closed the window.
|
|
372
|
+
return { end: 'closed', ...last };
|
|
373
|
+
}
|
|
374
|
+
const worthVerifying = cookies > 0 &&
|
|
375
|
+
(0, sessionCheck_1.sameSite)(url, opts.target) &&
|
|
376
|
+
!(0, map_1.samePath)(url, opts.startedAt) &&
|
|
377
|
+
!(await (0, map_1.hasPasswordField)(opts.page, 0)) &&
|
|
378
|
+
(url !== lastVerifiedUrl || now() - lastVerifiedAt > 8000);
|
|
379
|
+
if (worthVerifying) {
|
|
380
|
+
lastVerifiedUrl = url;
|
|
381
|
+
lastVerifiedAt = now();
|
|
382
|
+
attempts++;
|
|
383
|
+
let state;
|
|
384
|
+
try {
|
|
385
|
+
state = await opts.context.storageState();
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
return { end: 'closed', ...last };
|
|
389
|
+
}
|
|
390
|
+
const replay = await replaySession(opts.browser, state, opts.target, opts.contextOptions ?? {});
|
|
391
|
+
last = { replay, state };
|
|
392
|
+
if (loginProven(replay, opts.startedAt))
|
|
393
|
+
return { end: 'verified', replay, state };
|
|
394
|
+
if (attempts === 3) {
|
|
395
|
+
note(`\n ⏳ You look logged in, but the session I can carry does not open the app on its own yet.\n` +
|
|
396
|
+
` Still watching — a multi-step login is normal here. If your app keeps its token in\n` +
|
|
397
|
+
` IndexedDB, in memory or in a service worker, a session file can never hold it:\n` +
|
|
398
|
+
` press Enter and I will tell you exactly that instead of waiting.`);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
await new Promise((r) => setTimeout(r, 1200));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
233
404
|
/**
|
|
234
405
|
* What to do with a session that has just been replayed — and above all, what never to do.
|
|
235
406
|
*
|
package/dist/cli/login.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/cli/login.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/cli/login.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/session.d.ts
CHANGED
|
@@ -21,4 +21,31 @@ export interface SessionCheck {
|
|
|
21
21
|
facts: SessionFacts;
|
|
22
22
|
verdict: SessionVerdict;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* The same check, for a caller that is not a terminal.
|
|
26
|
+
*
|
|
27
|
+
* Exported because an orchestrator has a reason to ask this *before* it spends minutes on a
|
|
28
|
+
* SUT — a session is one credential for the whole app, so a dead one makes every page of a
|
|
29
|
+
* tour fail in turn, and the field has watched exactly that happen for eighteen minutes.
|
|
30
|
+
* It is the verdict `session --check` prints, not a second opinion: rebuilding it from
|
|
31
|
+
* `readFacts` and a navigation is the CLI/MCP dispatch split in another costume.
|
|
32
|
+
*
|
|
33
|
+
* `present: false` is not a failure — a project with no session file is the ordinary case
|
|
34
|
+
* for a public app or one using `config.auth`, and calling that "broken" would be a wrong
|
|
35
|
+
* verdict on a healthy project.
|
|
36
|
+
*/
|
|
37
|
+
export interface SessionProbe {
|
|
38
|
+
present: boolean;
|
|
39
|
+
file?: string;
|
|
40
|
+
source?: string;
|
|
41
|
+
facts?: SessionFacts;
|
|
42
|
+
verdict?: SessionVerdict;
|
|
43
|
+
/** The file exists but could not be read or parsed. */
|
|
44
|
+
unreadable?: string;
|
|
45
|
+
}
|
|
46
|
+
export declare function probeSession(opts?: {
|
|
47
|
+
url?: string;
|
|
48
|
+
session?: string;
|
|
49
|
+
offline?: boolean;
|
|
50
|
+
}): Promise<SessionProbe>;
|
|
24
51
|
export declare function runSessionCheck(args: string[]): Promise<void>;
|
package/dist/cli/session.js
CHANGED
|
@@ -33,12 +33,40 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.probeSession = probeSession;
|
|
36
37
|
exports.runSessionCheck = runSessionCheck;
|
|
37
38
|
const fs = __importStar(require("fs"));
|
|
38
39
|
const config_1 = require("../config");
|
|
39
40
|
const launcher_1 = require("../launcher");
|
|
40
41
|
const login_1 = require("./login");
|
|
41
42
|
const sessionCheck_1 = require("../sessionCheck");
|
|
43
|
+
async function probeSession(opts = {}) {
|
|
44
|
+
const config = (0, config_1.loadConfig)();
|
|
45
|
+
const choice = (0, config_1.resolveSession)(config, opts.session);
|
|
46
|
+
if (!choice)
|
|
47
|
+
return { present: false };
|
|
48
|
+
let state;
|
|
49
|
+
try {
|
|
50
|
+
state = JSON.parse(fs.readFileSync(choice.file, 'utf8'));
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
return { present: true, file: choice.file, source: choice.source, unreadable: err instanceof Error ? err.message : String(err) };
|
|
54
|
+
}
|
|
55
|
+
const target = opts.url ?? config.baseUrl;
|
|
56
|
+
const facts = (0, sessionCheck_1.readFacts)(state, target);
|
|
57
|
+
const offlineVerdict = (0, sessionCheck_1.judgeSession)(facts);
|
|
58
|
+
if (offlineVerdict.cause !== 'unknown' || opts.offline) {
|
|
59
|
+
return { present: true, file: choice.file, source: choice.source, facts, verdict: offlineVerdict };
|
|
60
|
+
}
|
|
61
|
+
const { browser } = await (0, launcher_1.launchBrowser)();
|
|
62
|
+
try {
|
|
63
|
+
const replay = await (0, login_1.replaySession)(browser, state, target);
|
|
64
|
+
return { present: true, file: choice.file, source: choice.source, facts, verdict: (0, sessionCheck_1.judgeSession)(facts, replay) };
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
await browser.close();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
42
70
|
/**
|
|
43
71
|
* The causes that mean *could not tell*, as opposed to *does not hold*.
|
|
44
72
|
*
|
|
@@ -74,9 +102,11 @@ async function runSessionCheck(args) {
|
|
|
74
102
|
const wantedUrl = urlIdx !== -1 ? args[urlIdx + 1] : undefined;
|
|
75
103
|
const sessionIdx = args.indexOf('--session');
|
|
76
104
|
const wantedSession = sessionIdx !== -1 ? args[sessionIdx + 1] : undefined;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
105
|
+
// Every fact and every verdict comes from `probeSession`; this function only renders and
|
|
106
|
+
// picks the exit code. An orchestrator asking the same question in process therefore gets
|
|
107
|
+
// the identical answer, which is the point of having extracted it.
|
|
108
|
+
const probe = await probeSession({ url: wantedUrl, session: wantedSession, offline });
|
|
109
|
+
if (!probe.present) {
|
|
80
110
|
// Not a failure: a project with no session is the ordinary case for a public app or one
|
|
81
111
|
// using `config.auth`. Saying "no session is broken" would be a wrong verdict.
|
|
82
112
|
const message = `No session file to check.\n` +
|
|
@@ -88,33 +118,13 @@ async function runSessionCheck(args) {
|
|
|
88
118
|
console.log(`\nℹ️ ${message}`);
|
|
89
119
|
return;
|
|
90
120
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
state = JSON.parse(fs.readFileSync(choice.file, 'utf8'));
|
|
94
|
-
}
|
|
95
|
-
catch (err) {
|
|
96
|
-
console.error(`❌ ${choice.file} could not be read: ${err instanceof Error ? err.message : String(err)}`);
|
|
121
|
+
if (probe.unreadable || !probe.facts || !probe.verdict) {
|
|
122
|
+
console.error(`❌ ${probe.file} could not be read: ${probe.unreadable ?? 'no verdict'}`);
|
|
97
123
|
process.exitCode = 2;
|
|
98
124
|
return;
|
|
99
125
|
}
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
// The offline causes are conclusive, so the browser is not opened to re-confirm an expiry
|
|
103
|
-
// date — the cheapest honest answer, not a degraded one.
|
|
104
|
-
const offlineVerdict = (0, sessionCheck_1.judgeSession)(facts);
|
|
105
|
-
const decidedOffline = offlineVerdict.cause !== 'unknown';
|
|
106
|
-
let verdict = offlineVerdict;
|
|
107
|
-
if (!decidedOffline && !offline) {
|
|
108
|
-
const { browser } = await (0, launcher_1.launchBrowser)();
|
|
109
|
-
try {
|
|
110
|
-
const replay = await (0, login_1.replaySession)(browser, state, target);
|
|
111
|
-
verdict = (0, sessionCheck_1.judgeSession)(facts, replay);
|
|
112
|
-
}
|
|
113
|
-
finally {
|
|
114
|
-
await browser.close();
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
const check = { file: choice.file, source: choice.source, facts, verdict };
|
|
126
|
+
const check = { file: probe.file, source: probe.source, facts: probe.facts, verdict: probe.verdict };
|
|
127
|
+
const verdict = probe.verdict;
|
|
118
128
|
if (json) {
|
|
119
129
|
console.log(JSON.stringify({ schema: 'ia-qa-heal/session@1', present: true, ...check }, null, 2));
|
|
120
130
|
}
|
package/dist/cli/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/cli/session.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/cli/session.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,10 @@ export { configuredTestPaths } from './config';
|
|
|
36
36
|
export { runMap, LoginWallError } from './cli/map';
|
|
37
37
|
export type { MapResult, MapFailure, MapPageStat } from './cli/map';
|
|
38
38
|
export { runBaseline } from './cli/baseline';
|
|
39
|
+
export { probeSession } from './cli/session';
|
|
40
|
+
export type { SessionProbe } from './cli/session';
|
|
41
|
+
export { runLogin } from './cli/login';
|
|
42
|
+
export type { LoginResult } from './cli/login';
|
|
39
43
|
export { dirDiffAggregate } from './cli/diff';
|
|
40
44
|
export type { DirReport, DirDiffCollection } from './cli/diff';
|
|
41
45
|
export type { RouteChange } from './routeDrift';
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.globToRegex = exports.readTestDepth = exports.collectUnattributable = exports.computePageDepth = exports.computeTestDepth = exports.saveExercised = exports.EXERCISED_FILENAME = exports.contractPageNames = exports.exercisedPath = exports.loadExercised = exports.usagePath = exports.usageFiles = exports.loadUsage = exports.saveUsage = exports.ingestPaths = exports.scanText = exports.crawlApp = exports.sitemapsFromRobots = exports.isSitemapIndex = exports.extractLocs = exports.discoverFromSitemap = exports.UNSAFE_URL_RE = exports.mergePages = exports.toCandidate = exports.normalizedPath = exports.isSafeCandidateUrl = exports.resolvePageName = exports.pageNameFromUrl = exports.mapUrl = exports.markdownPath = exports.saveMarkdown = exports.renderPageContract = exports.saveMapping = exports.loadMapping = exports.extractInteractiveElements = exports.COMPATIBLE_EXAMPLES = exports.renderModelList = exports.defaultKeyEnv = exports.findProvider = exports.AI_PROVIDERS = exports.parseModelJson = exports.buildPrompt = exports.prefilter = exports.aiResolve = exports.PROVIDER_HOST = exports.egressHost = exports.createAiResolver = exports.llmResolverStub = exports.aiFill = exports.aiClick = void 0;
|
|
4
|
-
exports.
|
|
5
|
-
exports.createSkillVerb = exports.NAVIGATION_SVG_FILENAME = exports.NAVIGATION_FILENAME = exports.OVERVIEW_FILENAME = exports.navigationSvgPath = exports.navigationPath = exports.overviewPath = exports.writeOverview = exports.navigationGraph = exports.layoutGraph = exports.renderNavigationSvg = void 0;
|
|
4
|
+
exports.buildOverview = exports.minPagesForLayout = exports.stripLayoutFromPages = exports.extractLayout = exports.isWebAddress = exports.readSitemap = exports.writeSetup = exports.planSetup = exports.listShape = exports.groupListChurn = exports.maskDigits = exports.groupNumericLabelDrift = exports.detectTestCommand = exports.auditProject = exports.runFix = exports.HISTORY_FILENAME = exports.historyPath = exports.WIDE_RUN_SHARE = exports.pageChurn = exports.readHistory = exports.checkCounts = exports.checkHeadline = exports.checkVerdict = exports.checkProject = exports.dirDiffAggregate = exports.runLogin = exports.probeSession = exports.runBaseline = exports.LoginWallError = exports.runMap = exports.configuredTestPaths = exports.baselineDir = exports.mappingDir = exports.setBaseDir = exports.LAYOUT_DIRNAME = exports.layoutPath = exports.layoutDir = exports.maskSecret = exports.looksLikeSecret = exports.resolveSecret = exports.loadConfig = exports.replaceQuoted = exports.collectFiles = exports.applyRewrites = exports.computeRewrites = exports.launchBrowser = exports.CAPTURE_DIRNAME = exports.captureDir = exports.unionElements = exports.mergeCaptures = void 0;
|
|
5
|
+
exports.createSkillVerb = exports.NAVIGATION_SVG_FILENAME = exports.NAVIGATION_FILENAME = exports.OVERVIEW_FILENAME = exports.navigationSvgPath = exports.navigationPath = exports.overviewPath = exports.writeOverview = exports.navigationGraph = exports.layoutGraph = exports.renderNavigationSvg = exports.renderNavigation = exports.renderOverview = void 0;
|
|
6
6
|
var healer_1 = require("./playwright/healer");
|
|
7
7
|
Object.defineProperty(exports, "aiClick", { enumerable: true, get: function () { return healer_1.aiClick; } });
|
|
8
8
|
Object.defineProperty(exports, "aiFill", { enumerable: true, get: function () { return healer_1.aiFill; } });
|
|
@@ -112,6 +112,16 @@ Object.defineProperty(exports, "runMap", { enumerable: true, get: function () {
|
|
|
112
112
|
Object.defineProperty(exports, "LoginWallError", { enumerable: true, get: function () { return map_1.LoginWallError; } });
|
|
113
113
|
var baseline_1 = require("./cli/baseline");
|
|
114
114
|
Object.defineProperty(exports, "runBaseline", { enumerable: true, get: function () { return baseline_1.runBaseline; } });
|
|
115
|
+
// The session half an orchestrator needs BEFORE it spends minutes on a SUT. A session is one
|
|
116
|
+
// credential for the whole app, so a dead one makes every page fail in turn — the field has
|
|
117
|
+
// watched that run for eighteen minutes. `probeSession` is the verdict `session --check`
|
|
118
|
+
// prints, not a second opinion; `runLogin` is the one step that needs a person, exported so
|
|
119
|
+
// an orchestrator can hand the browser over instead of printing a command to copy. It still
|
|
120
|
+
// refuses without a TTY and under CI, which is what keeps it out of an agent's reach.
|
|
121
|
+
var session_1 = require("./cli/session");
|
|
122
|
+
Object.defineProperty(exports, "probeSession", { enumerable: true, get: function () { return session_1.probeSession; } });
|
|
123
|
+
var login_1 = require("./cli/login");
|
|
124
|
+
Object.defineProperty(exports, "runLogin", { enumerable: true, get: function () { return login_1.runLogin; } });
|
|
115
125
|
var diff_1 = require("./cli/diff");
|
|
116
126
|
Object.defineProperty(exports, "dirDiffAggregate", { enumerable: true, get: function () { return diff_1.dirDiffAggregate; } });
|
|
117
127
|
var check_1 = require("./cli/check");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ia-qa/self-healing",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.0",
|
|
4
4
|
"description": "Your Playwright, Cypress or Selenium tests break when a selector moves — this finds the element again and rewrites the test. Deterministic: no LLM decides whether your build passes. Runs entirely on your machine, with a local MCP server for agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"self-healing",
|
|
@@ -174,7 +174,11 @@ established which element the test meant.
|
|
|
174
174
|
report those as pages that failed. For everything a form cannot answer there is exactly one step, and it
|
|
175
175
|
belongs to the human: `ia-qa-heal login` opens a visible browser, they log in once, and the
|
|
176
176
|
session is reused by `map`. It refuses without a TTY and under CI — that refusal is aimed at
|
|
177
|
-
you.
|
|
177
|
+
you. Tell them there is **nothing to confirm afterwards**: the verb watches the window and
|
|
178
|
+
saves the session the moment it genuinely opens the app, so the old "press Enter when done"
|
|
179
|
+
step is gone. Do not tell them to run it with `--wait 0` unless their login cannot be
|
|
180
|
+
observed from outside at all — that flag restores the manual step you would be asking them
|
|
181
|
+
to remember. Never ask for their password, never put a credential in `config.json` (it holds `secrets`
|
|
178
182
|
*references* to env/SSM, never values), and never commit `.ia-qa/session.json` — it is a live
|
|
179
183
|
session, gitignored on creation. For CI, the reproducible paths are `auth` and capture-during-
|
|
180
184
|
run (`IAQA_CAPTURE=1` + `testCommand`), never a saved session.
|