@molecule/api-ai-tools 1.9.6 → 1.9.8
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 +178 -9
- package/dist/command-position.d.ts +36 -0
- package/dist/command-position.d.ts.map +1 -1
- package/dist/command-position.js +192 -19
- package/dist/cut-run.d.ts +8 -0
- package/dist/cut-run.d.ts.map +1 -1
- package/dist/cut-run.js +20 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/line-diff.d.ts +34 -0
- package/dist/line-diff.d.ts.map +1 -0
- package/dist/line-diff.js +150 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +70 -22
- package/dist/trace-artifacts.d.ts +57 -1
- package/dist/trace-artifacts.d.ts.map +1 -1
- package/dist/trace-artifacts.js +381 -43
- package/dist/utilities.d.ts +55 -5
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +150 -15
- package/package.json +1 -1
package/dist/utilities.d.ts
CHANGED
|
@@ -107,8 +107,19 @@ export declare function outputIsWithheldUntilExit(command: string): boolean;
|
|
|
107
107
|
* this leaves its task log empty, so the log is the wrong place to look and an empty
|
|
108
108
|
* log proves nothing (X1 flash-m29).
|
|
109
109
|
*
|
|
110
|
+
* Which redirect counts is decided by the command's own shell structure, from the same
|
|
111
|
+
* parse every other command reader uses: a redirect written in a BACKGROUNDED statement
|
|
112
|
+
* (`… &`) or inside a `( … )` / `{ … }` group writes that process's or group's output, not
|
|
113
|
+
* the command's. The platform's own preview launch is exactly that — the preview server is
|
|
114
|
+
* started with `>/tmp/mol-preview-4173.log 2>&1 &` inside the build/serve prelude, and the
|
|
115
|
+
* suite's foreground command follows it — so a reader that took the last `>` in the whole
|
|
116
|
+
* text told a run its output went to the PREVIEW's log (X1 flash-m136 +18:31).
|
|
117
|
+
*
|
|
118
|
+
* The target comes back without its shell quotes: `> '/tmp/x.log'` is `/tmp/x.log`, and
|
|
119
|
+
* the callers resolve a relative one against the command's cwd.
|
|
120
|
+
*
|
|
110
121
|
* @param command - The shell command.
|
|
111
|
-
* @returns The target
|
|
122
|
+
* @returns The target, or null (`/dev/null` and `&1`/`&2` are not files).
|
|
112
123
|
*/
|
|
113
124
|
export declare function outputRedirectTarget(command: string): string | null;
|
|
114
125
|
/**
|
|
@@ -182,6 +193,22 @@ export declare function streamingBackgroundCommand(command: string): {
|
|
|
182
193
|
* @returns True when the command starts one of those runners.
|
|
183
194
|
*/
|
|
184
195
|
export declare function isSuiteRunCommand(command: string): boolean;
|
|
196
|
+
/**
|
|
197
|
+
* The command with the `timeout <N>` wrapper lifted off the statement that runs the suite, and the
|
|
198
|
+
* bound that was lifted.
|
|
199
|
+
*
|
|
200
|
+
* Used where the platform moves a run to the background: the executor wrote the bound to fit this
|
|
201
|
+
* tool's foreground ceiling, and in the background that ceiling no longer applies — the task is
|
|
202
|
+
* bounded by `wait_for_task` and the turn's deadline — so the prefix only kills the walk
|
|
203
|
+
* ({@link withoutTimeoutWrapper}; X1 xr-molecule-flash-m143 +24:45).
|
|
204
|
+
*
|
|
205
|
+
* @param command - The shell command.
|
|
206
|
+
* @returns The rewritten command, and the largest lifted bound (null when nothing was lifted).
|
|
207
|
+
*/
|
|
208
|
+
export declare function withoutSuiteTimeout(command: string): {
|
|
209
|
+
command: string;
|
|
210
|
+
seconds: number | null;
|
|
211
|
+
};
|
|
185
212
|
/**
|
|
186
213
|
* Whether a command starts a Playwright run — a `playwright test` in command position, in a form
|
|
187
214
|
* that runs something.
|
|
@@ -825,7 +852,28 @@ export interface UniversalCause {
|
|
|
825
852
|
count: number;
|
|
826
853
|
/** The distinct spec files they live in, in the order the log named them. */
|
|
827
854
|
files: string[];
|
|
855
|
+
/**
|
|
856
|
+
* The cause is that the page rendered NOTHING: every failure so far is a wait for an element
|
|
857
|
+
* the page never painted, whatever the selector asked for ({@link emptyPageCause}). One cause
|
|
858
|
+
* is failing every test even though no two failures share an error signature, so the note says
|
|
859
|
+
* so in the page's terms instead of naming one locator as the signature.
|
|
860
|
+
*/
|
|
861
|
+
pageRendersNothing?: true;
|
|
862
|
+
/** The page's own uncaught error, when the run printed one. */
|
|
863
|
+
pageError?: string;
|
|
864
|
+
/**
|
|
865
|
+
* The distinct failures this cause covers, in log order — the rows a note lists for
|
|
866
|
+
* {@link pageRendersNothing}. Absent for a signature cause, whose rows are the repeating
|
|
867
|
+
* failure's own tests.
|
|
868
|
+
*/
|
|
869
|
+
tests?: FailedTest[];
|
|
828
870
|
}
|
|
871
|
+
/**
|
|
872
|
+
* How many tests a run must have walked — with nothing passing since its first failure — before
|
|
873
|
+
* "the page renders nothing" can be its one cause. A handful of failures is a handful of bugs;
|
|
874
|
+
* a page that never painted fails every spec that reaches it, and m141's walk had 36 by +20:30.
|
|
875
|
+
*/
|
|
876
|
+
export declare const EMPTY_PAGE_CAUSE_TESTS = 15;
|
|
829
877
|
/**
|
|
830
878
|
* How many tests a connection-class cause must cover before the run is stopped even when they
|
|
831
879
|
* are all in one file — see {@link universalCause}.
|
|
@@ -875,12 +923,14 @@ export declare function specFilesSelected(command: string): number | null;
|
|
|
875
923
|
* alongside the others.
|
|
876
924
|
*
|
|
877
925
|
* @param log - The log so far.
|
|
878
|
-
* @param found - The repeating cause {@link repeatingFailure} found in it
|
|
926
|
+
* @param found - The repeating cause {@link repeatingFailure} found in it, or null when no two
|
|
927
|
+
* failures share a signature (a page that renders nothing fails each spec at its own first
|
|
928
|
+
* locator — {@link emptyPageCause} still reads that run).
|
|
879
929
|
* @param command - How the run was started, when the caller knows it: its spec-file selection
|
|
880
930
|
* scales the file threshold ({@link specFilesSelected}).
|
|
881
931
|
* @returns The cause's count and files, or null when the run is not failing whole.
|
|
882
932
|
*/
|
|
883
|
-
export declare function universalCause(log: string, found: RepeatingFailure, command?: string | null): UniversalCause | null;
|
|
933
|
+
export declare function universalCause(log: string, found: RepeatingFailure | null, command?: string | null): UniversalCause | null;
|
|
884
934
|
/**
|
|
885
935
|
* The ONE finding that ends a wait early, and the only one a note may hand a stop command over
|
|
886
936
|
* for: a PROVEN cause that is failing the whole run.
|
|
@@ -909,12 +959,12 @@ export declare function universalCause(log: string, found: RepeatingFailure, com
|
|
|
909
959
|
* needs — is the run over as a measuring instrument — and it is THE one predicate behind both
|
|
910
960
|
* that decision and the note's wording, so the two cannot come to different verdicts.
|
|
911
961
|
*
|
|
912
|
-
* @param found - What {@link repeatingFailure} found mid-run.
|
|
962
|
+
* @param found - What {@link repeatingFailure} found mid-run, or null when no signature repeats.
|
|
913
963
|
* @param universal - What {@link universalCause} found for it, if anything.
|
|
914
964
|
* @returns The cause to stop the run over, or null — in which case nothing may be stopped, the
|
|
915
965
|
* wait keeps going, and the finding rides the run's result as a note.
|
|
916
966
|
*/
|
|
917
|
-
export declare function earlyReturnCause(found: RepeatingFailure, universal: UniversalCause | null | undefined): UniversalCause | null;
|
|
967
|
+
export declare function earlyReturnCause(found: RepeatingFailure | null, universal: UniversalCause | null | undefined): UniversalCause | null;
|
|
918
968
|
/**
|
|
919
969
|
* The titles a request excludes that a test's heading names — the ONE matcher for "is this
|
|
920
970
|
* failure one the request does not count?".
|
package/dist/utilities.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../src/utilities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAW3E;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAS5C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,GAAG,MAAM,KAAG,MAEE,CAAA;AAuGhD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsCzD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,MAAM,CAUpF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAElE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQnE;AAuDD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,8BAA8B,0CAA0C,CAAA;AAErF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG;IAC3D,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,CA2KA;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAK1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG;IACpD,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,CAEA;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAG/D;AAuJD,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,6FAA6F;IAC7F,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAkC3E;AAED,oFAAoF;AACpF,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAA;IACd;;;;;OAKG;IACH,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,yBAAyB,CAkBpF;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAalC;AA4BD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuBlE;AAID;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAQrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAOxE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQpD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU/D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGxD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,MAAM,CAKR;AAkCD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIvE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU1E;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI9E;AAID,yCAAyC;AACzC,eAAO,MAAM,aAAa,QAAkB,CAAA;AAC5C,8CAA8C;AAC9C,eAAO,MAAM,cAAc,QAAmB,CAAA;AAC9C,kDAAkD;AAClD,eAAO,MAAM,eAAe,QAAa,CAAA;AACzC;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAE1C;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA6BhG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAY5E;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAA;AAEtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB,QAAS,CAAA;AAEzC;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,OAAQ,CAAA;AAE/C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,QAAmD,CAAA;AAErF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,QAAwB,CAAA;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,QAAY,CAAA;AAE9C,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,MAAM,CAAA;AAKzC,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAa,GAAG,MAAM,GAAG,IAAI,CAyC3E;AAED,0BAA0B;AAC1B,eAAO,MAAM,kBAAkB,KAAK,CAAA;AACpC,wBAAwB;AACxB,eAAO,MAAM,gBAAgB,MAAM,CAAA;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,mHAW/B,CAAA;AAEV;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOnE;AAmFD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBjD;AAED,kEAAkE;AAClE,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAEvC,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,OAAO,CAAA;AAEtC;;;GAGG;AACH,eAAO,MAAM,uBAAuB,0KAC4G,CAAA;AAEhJ;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3E;AAED,gEAAgE;AAChE,eAAO,MAAM,0BAA0B,QAAS,CAAA;AAEhD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC,0DAA0D;AAC1D,MAAM,WAAW,UAAU;IACzB,gGAAgG;IAChG,KAAK,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,qFAAqF;IACrF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,0FAA0F;IAC1F,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,sFAAsF;IACtF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,sDAAsD;IACtD,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB;AA2SD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CA+CrE;AAED,2FAA2F;AAC3F,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,QAA2B,CAAA;AAE5D;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAKvC,oFAAoF;AACpF,eAAO,MAAM,0BAA0B,IAAI,CAAA;AA8D3C;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,KAAK,EAAE,MAAM,EAAE,CAAA;IACf;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,IAAI,CAAA;IACzB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,UAAU,EAAE,CAAA;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAA;AA4ExC;;;GAGG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAuCvC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2BhE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,cAAc,GAAG,IAAI,CAiCvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,SAAS,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,GAC3C,cAAc,GAAG,IAAI,CAOvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ7F;AAED,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,gGAAgG;IAChG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,yFAAyF;IACzF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,kEAAkE;IAClE,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,IAAI,EAAE,cAAc,CAAA;IACpB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,SAAS,MAAM,EAAO,GAAG,YAAY,EAAE,CAE7F;AA0OD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,SAAS,MAAM,EAAO,EAChC,GAAG,CAAC,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAC7E,UAAU,GAAE,SAAS,eAAe,EAAO,GAC1C,MAAM,GAAG,IAAI,CAqGf;AAuGD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAC9D,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,QAAQ,GAAE,SAAS,MAAM,EAAO,GAC/B,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,gBAAgB,EACvB,CAAC,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IACjC,GAAG,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACvC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,GACA,MAAM,CAuIR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAsCf;AAED,qEAAqE;AACrE,eAAO,MAAM,eAAe,QAA0C,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB7D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,MAAM,GAAG,IAAI,CAKhB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgBvC"}
|
package/dist/utilities.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
import { posix } from 'path';
|
|
8
|
-
import { commandSegments, locatedCommandSegments, statementArgumentEnd, } from './command-position.js';
|
|
8
|
+
import { commandSegments, locatedCommandSegments, statementArgumentEnd, withoutTimeoutWrapper, } from './command-position.js';
|
|
9
9
|
import { classifyRunFailure } from './failure-kind.js';
|
|
10
10
|
import { commandRunsNoTests } from './no-test-run.js';
|
|
11
11
|
import { isDiagnosisRun, scopedRerunCommand, suiteCommandTarget, suiteRunInTheWay, withoutHeredocs, withSuiteConfig, } from './suite-overlap.js';
|
|
@@ -272,20 +272,28 @@ export function outputIsWithheldUntilExit(command) {
|
|
|
272
272
|
* this leaves its task log empty, so the log is the wrong place to look and an empty
|
|
273
273
|
* log proves nothing (X1 flash-m29).
|
|
274
274
|
*
|
|
275
|
+
* Which redirect counts is decided by the command's own shell structure, from the same
|
|
276
|
+
* parse every other command reader uses: a redirect written in a BACKGROUNDED statement
|
|
277
|
+
* (`… &`) or inside a `( … )` / `{ … }` group writes that process's or group's output, not
|
|
278
|
+
* the command's. The platform's own preview launch is exactly that — the preview server is
|
|
279
|
+
* started with `>/tmp/mol-preview-4173.log 2>&1 &` inside the build/serve prelude, and the
|
|
280
|
+
* suite's foreground command follows it — so a reader that took the last `>` in the whole
|
|
281
|
+
* text told a run its output went to the PREVIEW's log (X1 flash-m136 +18:31).
|
|
282
|
+
*
|
|
283
|
+
* The target comes back without its shell quotes: `> '/tmp/x.log'` is `/tmp/x.log`, and
|
|
284
|
+
* the callers resolve a relative one against the command's cwd.
|
|
285
|
+
*
|
|
275
286
|
* @param command - The shell command.
|
|
276
|
-
* @returns The target
|
|
287
|
+
* @returns The target, or null (`/dev/null` and `&1`/`&2` are not files).
|
|
277
288
|
*/
|
|
278
289
|
export function outputRedirectTarget(command) {
|
|
279
|
-
// A heredoc that writes a file (`cat > cfg.ts <<'EOF' … EOF`) is not where the run's output
|
|
280
|
-
// goes: X1 flash-m44 was told its config file was the suite's log.
|
|
281
|
-
const text = command.replace(/[^\n;&|]*<<-?\s*(['"]?)(\w+)\1[\s\S]*?\n\s*\2\b/g, '');
|
|
282
|
-
const tee = /\|\s*tee\s+(?:-a\s+)?([^\s;&|]+)/.exec(text);
|
|
283
|
-
if (tee)
|
|
284
|
-
return tee[1];
|
|
285
290
|
let last = null;
|
|
286
|
-
for (const
|
|
287
|
-
|
|
288
|
-
|
|
291
|
+
for (const statement of locatedCommandSegments(command)) {
|
|
292
|
+
// A backgrounded statement's own redirect is that process's log, never the command's.
|
|
293
|
+
if (statement.terminator === '&')
|
|
294
|
+
continue;
|
|
295
|
+
if (statement.redirectTarget !== null)
|
|
296
|
+
last = statement.redirectTarget;
|
|
289
297
|
}
|
|
290
298
|
return last;
|
|
291
299
|
}
|
|
@@ -582,6 +590,21 @@ export function isSuiteRunCommand(command) {
|
|
|
582
590
|
return false;
|
|
583
591
|
return commandSegments(command).some((segment) => SUITE_RUN_COMMANDS.some((re) => re.test(segment.text)));
|
|
584
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* The command with the `timeout <N>` wrapper lifted off the statement that runs the suite, and the
|
|
595
|
+
* bound that was lifted.
|
|
596
|
+
*
|
|
597
|
+
* Used where the platform moves a run to the background: the executor wrote the bound to fit this
|
|
598
|
+
* tool's foreground ceiling, and in the background that ceiling no longer applies — the task is
|
|
599
|
+
* bounded by `wait_for_task` and the turn's deadline — so the prefix only kills the walk
|
|
600
|
+
* ({@link withoutTimeoutWrapper}; X1 xr-molecule-flash-m143 +24:45).
|
|
601
|
+
*
|
|
602
|
+
* @param command - The shell command.
|
|
603
|
+
* @returns The rewritten command, and the largest lifted bound (null when nothing was lifted).
|
|
604
|
+
*/
|
|
605
|
+
export function withoutSuiteTimeout(command) {
|
|
606
|
+
return withoutTimeoutWrapper(command, (segment) => isSuiteRunCommand(segment.text));
|
|
607
|
+
}
|
|
585
608
|
/**
|
|
586
609
|
* Whether a command starts a Playwright run — a `playwright test` in command position, in a form
|
|
587
610
|
* that runs something.
|
|
@@ -2123,6 +2146,82 @@ function failureBlockTests(text) {
|
|
|
2123
2146
|
* property of the run rather than of a page.
|
|
2124
2147
|
*/
|
|
2125
2148
|
export const UNIVERSAL_CAUSE_FILES = 3;
|
|
2149
|
+
/**
|
|
2150
|
+
* How many tests a run must have walked — with nothing passing since its first failure — before
|
|
2151
|
+
* "the page renders nothing" can be its one cause. A handful of failures is a handful of bugs;
|
|
2152
|
+
* a page that never painted fails every spec that reaches it, and m141's walk had 36 by +20:30.
|
|
2153
|
+
*/
|
|
2154
|
+
export const EMPTY_PAGE_CAUSE_TESTS = 15;
|
|
2155
|
+
/**
|
|
2156
|
+
* A failure body whose whole complaint is a wait for an element the page never rendered:
|
|
2157
|
+
* Playwright's `waiting for locator(…)` call log, its `element(s) not found` line, or the
|
|
2158
|
+
* assertion form's `toBeVisible() failed`. Anything else — a status code, a thrown error in the
|
|
2159
|
+
* test's own code — is a different failure and leaves this reading nothing.
|
|
2160
|
+
*/
|
|
2161
|
+
const LOCATOR_WAIT = /waiting for locator\(|element\(s\) not found|toBeVisible\(\) failed/;
|
|
2162
|
+
/** An uncaught page error, as a run that listens for `pageerror` prints it. */
|
|
2163
|
+
const PAGE_ERROR_LINE = /^\s*(?:\[pageerror\]|pageerror:)\s*(.+)$/m;
|
|
2164
|
+
/** An uncaught page error, in the browser's own `Uncaught …` wording. */
|
|
2165
|
+
const UNCAUGHT_PAGE_ERROR_LINE = /^\s*Uncaught(?:\s+Error)?:\s*(.+)$/m;
|
|
2166
|
+
/**
|
|
2167
|
+
* The page's own uncaught error, when the log printed one — the fact that names WHY a build
|
|
2168
|
+
* paints nothing (`No 'auth-client' provider bonded…`), rather than the locator it leaves behind.
|
|
2169
|
+
*
|
|
2170
|
+
* @param text - The log (ANSI already stripped).
|
|
2171
|
+
* @returns The error's message, or null.
|
|
2172
|
+
*/
|
|
2173
|
+
function pageErrorInLog(text) {
|
|
2174
|
+
const m = PAGE_ERROR_LINE.exec(text) ?? UNCAUGHT_PAGE_ERROR_LINE.exec(text);
|
|
2175
|
+
return m?.[1]?.trim() || null;
|
|
2176
|
+
}
|
|
2177
|
+
/**
|
|
2178
|
+
* The "nothing has passed and nothing renders" cause: every failure block the log has written is
|
|
2179
|
+
* a locator wait, the run has walked at least {@link EMPTY_PAGE_CAUSE_TESTS} tests across the
|
|
2180
|
+
* file threshold, and no test has passed since the first failure.
|
|
2181
|
+
*
|
|
2182
|
+
* This is ONE cause even though the signatures differ — each spec asks for its own first element
|
|
2183
|
+
* (`input[name="username"]`, `a.navbar-brand`, `h1`), so {@link repeatingFailure} cannot group
|
|
2184
|
+
* them and {@link universalCause}'s signature test cannot see the run is over. xr-molecule-flash-
|
|
2185
|
+
* m141 (+20:30) walked a built app that rendered nothing: 36 tests had failed, every one at its
|
|
2186
|
+
* first locator, and the note told the run to keep walking for another ~9 minutes.
|
|
2187
|
+
*
|
|
2188
|
+
* @param text - The log (ANSI already stripped).
|
|
2189
|
+
* @param threshold - The spec-file threshold this run is judged against ({@link universalCause}).
|
|
2190
|
+
* @param found - The repeating cause {@link repeatingFailure} found, when it found one.
|
|
2191
|
+
* @returns The cause, or null when the log is not this shape.
|
|
2192
|
+
*/
|
|
2193
|
+
function emptyPageCause(text, threshold, found) {
|
|
2194
|
+
const marks = resultMarks(text);
|
|
2195
|
+
const firstFailure = marks.indexOf('✘');
|
|
2196
|
+
if (firstFailure === -1 || marks.slice(firstFailure).includes('✓'))
|
|
2197
|
+
return null;
|
|
2198
|
+
const blocks = failureBlocks(text);
|
|
2199
|
+
if (blocks.length === 0 || !blocks.every((block) => LOCATOR_WAIT.test(block)))
|
|
2200
|
+
return null;
|
|
2201
|
+
// Both readings of the same failures: a `list` line carries the test and its duration, a
|
|
2202
|
+
// numbered block carries its body. The larger is the count — a failure that has a block but
|
|
2203
|
+
// whose result line the poll had not reached yet is still a failure.
|
|
2204
|
+
const byList = distinctTests(failedTests(text));
|
|
2205
|
+
const byBlock = distinctTests(failureBlockTests(text));
|
|
2206
|
+
const tests = byBlock.length >= byList.length ? byBlock : byList;
|
|
2207
|
+
// One signature already covers every failure: that is the signature cause, and its wording
|
|
2208
|
+
// (which names the repeated error) says more than "the page renders nothing" would.
|
|
2209
|
+
if (found !== null && found.message !== null && found.count >= tests.length)
|
|
2210
|
+
return null;
|
|
2211
|
+
if (tests.length < EMPTY_PAGE_CAUSE_TESTS)
|
|
2212
|
+
return null;
|
|
2213
|
+
const files = [...new Set(tests.map((t) => specFile(t.where)).filter(Boolean))];
|
|
2214
|
+
if (files.length < threshold)
|
|
2215
|
+
return null;
|
|
2216
|
+
const pageError = pageErrorInLog(text);
|
|
2217
|
+
return {
|
|
2218
|
+
count: tests.length,
|
|
2219
|
+
files,
|
|
2220
|
+
pageRendersNothing: true,
|
|
2221
|
+
...(pageError === null ? {} : { pageError }),
|
|
2222
|
+
tests,
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2126
2225
|
/**
|
|
2127
2226
|
* How many tests a connection-class cause must cover before the run is stopped even when they
|
|
2128
2227
|
* are all in one file — see {@link universalCause}.
|
|
@@ -2234,18 +2333,27 @@ export function specFilesSelected(command) {
|
|
|
2234
2333
|
* alongside the others.
|
|
2235
2334
|
*
|
|
2236
2335
|
* @param log - The log so far.
|
|
2237
|
-
* @param found - The repeating cause {@link repeatingFailure} found in it
|
|
2336
|
+
* @param found - The repeating cause {@link repeatingFailure} found in it, or null when no two
|
|
2337
|
+
* failures share a signature (a page that renders nothing fails each spec at its own first
|
|
2338
|
+
* locator — {@link emptyPageCause} still reads that run).
|
|
2238
2339
|
* @param command - How the run was started, when the caller knows it: its spec-file selection
|
|
2239
2340
|
* scales the file threshold ({@link specFilesSelected}).
|
|
2240
2341
|
* @returns The cause's count and files, or null when the run is not failing whole.
|
|
2241
2342
|
*/
|
|
2242
2343
|
export function universalCause(log, found, command) {
|
|
2243
2344
|
const text = log.replace(ANSI_SGR, '');
|
|
2244
|
-
const files = [...new Set(found.tests.map((t) => specFile(t.where)).filter(Boolean))];
|
|
2245
2345
|
// The threshold is what THIS run selects, not the suite's total: a run narrowed to one file
|
|
2246
2346
|
// can never span three of them, however whole its failure is.
|
|
2247
2347
|
const selected = command ? specFilesSelected(command) : null;
|
|
2248
2348
|
const threshold = selected === null ? UNIVERSAL_CAUSE_FILES : Math.min(UNIVERSAL_CAUSE_FILES, selected);
|
|
2349
|
+
// Nothing has passed and nothing renders: EVERY spec so far is waiting for its own first
|
|
2350
|
+
// element, so the signatures differ while the cause does not (xr-molecule-flash-m141).
|
|
2351
|
+
const emptyPage = emptyPageCause(text, threshold, found);
|
|
2352
|
+
if (emptyPage)
|
|
2353
|
+
return emptyPage;
|
|
2354
|
+
if (!found)
|
|
2355
|
+
return null;
|
|
2356
|
+
const files = [...new Set(found.tests.map((t) => specFile(t.where)).filter(Boolean))];
|
|
2249
2357
|
// The app never answered: three tests of that with nothing passing since is the whole of what
|
|
2250
2358
|
// a whole-suite run would have said, whatever the file count (xr-molecule-flash-m119).
|
|
2251
2359
|
const unreachable = found.message !== null &&
|
|
@@ -2294,13 +2402,18 @@ export function universalCause(log, found, command) {
|
|
|
2294
2402
|
* needs — is the run over as a measuring instrument — and it is THE one predicate behind both
|
|
2295
2403
|
* that decision and the note's wording, so the two cannot come to different verdicts.
|
|
2296
2404
|
*
|
|
2297
|
-
* @param found - What {@link repeatingFailure} found mid-run.
|
|
2405
|
+
* @param found - What {@link repeatingFailure} found mid-run, or null when no signature repeats.
|
|
2298
2406
|
* @param universal - What {@link universalCause} found for it, if anything.
|
|
2299
2407
|
* @returns The cause to stop the run over, or null — in which case nothing may be stopped, the
|
|
2300
2408
|
* wait keeps going, and the finding rides the run's result as a note.
|
|
2301
2409
|
*/
|
|
2302
2410
|
export function earlyReturnCause(found, universal) {
|
|
2303
|
-
|
|
2411
|
+
// "The page renders nothing" is a PROVEN cause without a repeated signature — the specs differ
|
|
2412
|
+
// in the locator they wait for, not in the reason (xr-molecule-flash-m141) — so the duration
|
|
2413
|
+
// guard below does not apply to it.
|
|
2414
|
+
if (universal?.pageRendersNothing)
|
|
2415
|
+
return universal;
|
|
2416
|
+
if (!found || found.message === null)
|
|
2304
2417
|
return null;
|
|
2305
2418
|
return universal ?? null;
|
|
2306
2419
|
}
|
|
@@ -2914,6 +3027,28 @@ export function repeatingFailureNote(found, o) {
|
|
|
2914
3027
|
const span = files.length === 0
|
|
2915
3028
|
? ''
|
|
2916
3029
|
: ` — across ${files.length} file${files.length === 1 ? '' : 's'} (${shown}${moreFiles})`;
|
|
3030
|
+
// The page renders NOTHING: the failures do not share an error signature — each spec is
|
|
3031
|
+
// waiting for its own first element — so naming one locator as "the way they failed" would be
|
|
3032
|
+
// wrong. The cause is the page, and the page's own error (when the run printed one) is what
|
|
3033
|
+
// names it (xr-molecule-flash-m141).
|
|
3034
|
+
if (stop.pageRendersNothing) {
|
|
3035
|
+
const pageTests = (stop.tests ?? found.tests).slice(0, REPEATING_FAILURE_LISTED);
|
|
3036
|
+
const pageRows = pageTests
|
|
3037
|
+
.map((t) => ` ✘ ${[t.where, t.title].filter(Boolean).join(' › ')}` +
|
|
3038
|
+
(t.seconds === null ? '' : ` (${t.seconds}s)`))
|
|
3039
|
+
.join('\n');
|
|
3040
|
+
const moreFailures = stop.count > pageTests.length ? `\n … and ${stop.count - pageTests.length} more` : '';
|
|
3041
|
+
const pageError = stop.pageError ? ` The page itself threw: \`${stop.pageError}\`.` : '';
|
|
3042
|
+
return (`Every test this run has walked so far has failed at its first locator — all ` +
|
|
3043
|
+
`${stop.count} of them${span}, with nothing passing since the first:\n` +
|
|
3044
|
+
`${pageRows}${moreFailures}\n` +
|
|
3045
|
+
`Each is waiting for an element the page never painted, so one cause explains all of ` +
|
|
3046
|
+
`them: the app is rendering NOTHING — its bundle throws while it loads, or it never ` +
|
|
3047
|
+
`mounts.${pageError} Every remaining test will fail the same way too, so walking the ` +
|
|
3048
|
+
`rest of this run only repeats this one cause. Stop it and fix that cause first: ` +
|
|
3049
|
+
`\`exec_command: ${o.stop}\`, then run the whole suite again. It is still going (${where}).` +
|
|
3050
|
+
`${reproduce}`);
|
|
3051
|
+
}
|
|
2917
3052
|
return (`Every test this run has walked so far has failed the same way — all ${found.count} of ` +
|
|
2918
3053
|
`them, ${signature}${span}, with nothing ` +
|
|
2919
3054
|
`passing since the first:\n${rows}${more}\n` +
|