@reportforge/playwright-pdf 0.19.1 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +3 -2
- package/dist/cli/index.js +1005 -176
- package/dist/index.d.mts +38 -2
- package/dist/index.d.ts +38 -2
- package/dist/index.js +327 -151
- package/dist/index.mjs +402 -226
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1229,13 +1229,13 @@ var require_ast = __commonJS({
|
|
|
1229
1229
|
helperExpression: function helperExpression(node) {
|
|
1230
1230
|
return node.type === "SubExpression" || (node.type === "MustacheStatement" || node.type === "BlockStatement") && !!(node.params && node.params.length || node.hash);
|
|
1231
1231
|
},
|
|
1232
|
-
scopedId: function scopedId(
|
|
1233
|
-
return /^\.|this\b/.test(
|
|
1232
|
+
scopedId: function scopedId(path17) {
|
|
1233
|
+
return /^\.|this\b/.test(path17.original);
|
|
1234
1234
|
},
|
|
1235
1235
|
// an ID is simple if it only has one part, and that part is not
|
|
1236
1236
|
// `..` or `this`.
|
|
1237
|
-
simpleId: function simpleId(
|
|
1238
|
-
return
|
|
1237
|
+
simpleId: function simpleId(path17) {
|
|
1238
|
+
return path17.parts.length === 1 && !AST.helpers.scopedId(path17) && !path17.depth;
|
|
1239
1239
|
}
|
|
1240
1240
|
}
|
|
1241
1241
|
};
|
|
@@ -2309,12 +2309,12 @@ var require_helpers2 = __commonJS({
|
|
|
2309
2309
|
loc
|
|
2310
2310
|
};
|
|
2311
2311
|
}
|
|
2312
|
-
function prepareMustache(
|
|
2312
|
+
function prepareMustache(path17, params, hash, open, strip, locInfo) {
|
|
2313
2313
|
var escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== "{" && escapeFlag !== "&";
|
|
2314
2314
|
var decorator = /\*/.test(open);
|
|
2315
2315
|
return {
|
|
2316
2316
|
type: decorator ? "Decorator" : "MustacheStatement",
|
|
2317
|
-
path:
|
|
2317
|
+
path: path17,
|
|
2318
2318
|
params,
|
|
2319
2319
|
hash,
|
|
2320
2320
|
escaped,
|
|
@@ -2634,9 +2634,9 @@ var require_compiler = __commonJS({
|
|
|
2634
2634
|
},
|
|
2635
2635
|
DecoratorBlock: function DecoratorBlock(decorator) {
|
|
2636
2636
|
var program = decorator.program && this.compileProgram(decorator.program);
|
|
2637
|
-
var params = this.setupFullMustacheParams(decorator, program, void 0),
|
|
2637
|
+
var params = this.setupFullMustacheParams(decorator, program, void 0), path17 = decorator.path;
|
|
2638
2638
|
this.useDecorators = true;
|
|
2639
|
-
this.opcode("registerDecorator", params.length,
|
|
2639
|
+
this.opcode("registerDecorator", params.length, path17.original);
|
|
2640
2640
|
},
|
|
2641
2641
|
PartialStatement: function PartialStatement(partial) {
|
|
2642
2642
|
this.usePartial = true;
|
|
@@ -2700,46 +2700,46 @@ var require_compiler = __commonJS({
|
|
|
2700
2700
|
}
|
|
2701
2701
|
},
|
|
2702
2702
|
ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
|
|
2703
|
-
var
|
|
2704
|
-
this.opcode("getContext",
|
|
2703
|
+
var path17 = sexpr.path, name = path17.parts[0], isBlock = program != null || inverse != null;
|
|
2704
|
+
this.opcode("getContext", path17.depth);
|
|
2705
2705
|
this.opcode("pushProgram", program);
|
|
2706
2706
|
this.opcode("pushProgram", inverse);
|
|
2707
|
-
|
|
2708
|
-
this.accept(
|
|
2707
|
+
path17.strict = true;
|
|
2708
|
+
this.accept(path17);
|
|
2709
2709
|
this.opcode("invokeAmbiguous", name, isBlock);
|
|
2710
2710
|
},
|
|
2711
2711
|
simpleSexpr: function simpleSexpr(sexpr) {
|
|
2712
|
-
var
|
|
2713
|
-
|
|
2714
|
-
this.accept(
|
|
2712
|
+
var path17 = sexpr.path;
|
|
2713
|
+
path17.strict = true;
|
|
2714
|
+
this.accept(path17);
|
|
2715
2715
|
this.opcode("resolvePossibleLambda");
|
|
2716
2716
|
},
|
|
2717
2717
|
helperSexpr: function helperSexpr(sexpr, program, inverse) {
|
|
2718
|
-
var params = this.setupFullMustacheParams(sexpr, program, inverse),
|
|
2718
|
+
var params = this.setupFullMustacheParams(sexpr, program, inverse), path17 = sexpr.path, name = path17.parts[0];
|
|
2719
2719
|
if (this.options.knownHelpers[name]) {
|
|
2720
2720
|
this.opcode("invokeKnownHelper", params.length, name);
|
|
2721
2721
|
} else if (this.options.knownHelpersOnly) {
|
|
2722
2722
|
throw new _exception2["default"]("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
|
2723
2723
|
} else {
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
this.accept(
|
|
2727
|
-
this.opcode("invokeHelper", params.length,
|
|
2724
|
+
path17.strict = true;
|
|
2725
|
+
path17.falsy = true;
|
|
2726
|
+
this.accept(path17);
|
|
2727
|
+
this.opcode("invokeHelper", params.length, path17.original, _ast2["default"].helpers.simpleId(path17));
|
|
2728
2728
|
}
|
|
2729
2729
|
},
|
|
2730
|
-
PathExpression: function PathExpression(
|
|
2731
|
-
this.addDepth(
|
|
2732
|
-
this.opcode("getContext",
|
|
2733
|
-
var name =
|
|
2730
|
+
PathExpression: function PathExpression(path17) {
|
|
2731
|
+
this.addDepth(path17.depth);
|
|
2732
|
+
this.opcode("getContext", path17.depth);
|
|
2733
|
+
var name = path17.parts[0], scoped = _ast2["default"].helpers.scopedId(path17), blockParamId = !path17.depth && !scoped && this.blockParamIndex(name);
|
|
2734
2734
|
if (blockParamId) {
|
|
2735
|
-
this.opcode("lookupBlockParam", blockParamId,
|
|
2735
|
+
this.opcode("lookupBlockParam", blockParamId, path17.parts);
|
|
2736
2736
|
} else if (!name) {
|
|
2737
2737
|
this.opcode("pushContext");
|
|
2738
|
-
} else if (
|
|
2738
|
+
} else if (path17.data) {
|
|
2739
2739
|
this.options.data = true;
|
|
2740
|
-
this.opcode("lookupData",
|
|
2740
|
+
this.opcode("lookupData", path17.depth, path17.parts, path17.strict);
|
|
2741
2741
|
} else {
|
|
2742
|
-
this.opcode("lookupOnContext",
|
|
2742
|
+
this.opcode("lookupOnContext", path17.parts, path17.falsy, path17.strict, scoped);
|
|
2743
2743
|
}
|
|
2744
2744
|
},
|
|
2745
2745
|
StringLiteral: function StringLiteral(string) {
|
|
@@ -3095,16 +3095,16 @@ var require_util = __commonJS({
|
|
|
3095
3095
|
}
|
|
3096
3096
|
exports.urlGenerate = urlGenerate;
|
|
3097
3097
|
function normalize(aPath) {
|
|
3098
|
-
var
|
|
3098
|
+
var path17 = aPath;
|
|
3099
3099
|
var url = urlParse(aPath);
|
|
3100
3100
|
if (url) {
|
|
3101
3101
|
if (!url.path) {
|
|
3102
3102
|
return aPath;
|
|
3103
3103
|
}
|
|
3104
|
-
|
|
3104
|
+
path17 = url.path;
|
|
3105
3105
|
}
|
|
3106
|
-
var isAbsolute = exports.isAbsolute(
|
|
3107
|
-
var parts =
|
|
3106
|
+
var isAbsolute = exports.isAbsolute(path17);
|
|
3107
|
+
var parts = path17.split(/\/+/);
|
|
3108
3108
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
|
3109
3109
|
part = parts[i];
|
|
3110
3110
|
if (part === ".") {
|
|
@@ -3121,15 +3121,15 @@ var require_util = __commonJS({
|
|
|
3121
3121
|
}
|
|
3122
3122
|
}
|
|
3123
3123
|
}
|
|
3124
|
-
|
|
3125
|
-
if (
|
|
3126
|
-
|
|
3124
|
+
path17 = parts.join("/");
|
|
3125
|
+
if (path17 === "") {
|
|
3126
|
+
path17 = isAbsolute ? "/" : ".";
|
|
3127
3127
|
}
|
|
3128
3128
|
if (url) {
|
|
3129
|
-
url.path =
|
|
3129
|
+
url.path = path17;
|
|
3130
3130
|
return urlGenerate(url);
|
|
3131
3131
|
}
|
|
3132
|
-
return
|
|
3132
|
+
return path17;
|
|
3133
3133
|
}
|
|
3134
3134
|
exports.normalize = normalize;
|
|
3135
3135
|
function join(aRoot, aPath) {
|
|
@@ -5932,8 +5932,8 @@ var require_printer = __commonJS({
|
|
|
5932
5932
|
return this.accept(sexpr.path) + " " + params + hash;
|
|
5933
5933
|
};
|
|
5934
5934
|
PrintVisitor.prototype.PathExpression = function(id) {
|
|
5935
|
-
var
|
|
5936
|
-
return (id.data ? "@" : "") + "PATH:" +
|
|
5935
|
+
var path17 = id.parts.join("/");
|
|
5936
|
+
return (id.data ? "@" : "") + "PATH:" + path17;
|
|
5937
5937
|
};
|
|
5938
5938
|
PrintVisitor.prototype.StringLiteral = function(string) {
|
|
5939
5939
|
return '"' + string.value + '"';
|
|
@@ -5974,8 +5974,8 @@ var require_lib = __commonJS({
|
|
|
5974
5974
|
handlebars.print = printer.print;
|
|
5975
5975
|
module.exports = handlebars;
|
|
5976
5976
|
function extension(module2, filename) {
|
|
5977
|
-
var
|
|
5978
|
-
var templateString =
|
|
5977
|
+
var fs16 = __require("fs");
|
|
5978
|
+
var templateString = fs16.readFileSync(filename, "utf8");
|
|
5979
5979
|
module2.exports = handlebars.compile(templateString);
|
|
5980
5980
|
}
|
|
5981
5981
|
if (typeof __require !== "undefined" && __require.extensions) {
|
|
@@ -6004,7 +6004,7 @@ var require_util2 = __commonJS({
|
|
|
6004
6004
|
"node_modules/chrome-finder/lib/util.js"(exports, module) {
|
|
6005
6005
|
"use strict";
|
|
6006
6006
|
init_esm_shims();
|
|
6007
|
-
var
|
|
6007
|
+
var fs16 = __require("fs");
|
|
6008
6008
|
var newLineRegex = /\r?\n/;
|
|
6009
6009
|
function sort(installations, priorities) {
|
|
6010
6010
|
const defaultPriority = 10;
|
|
@@ -6022,7 +6022,7 @@ var require_util2 = __commonJS({
|
|
|
6022
6022
|
return false;
|
|
6023
6023
|
}
|
|
6024
6024
|
try {
|
|
6025
|
-
|
|
6025
|
+
fs16.accessSync(file);
|
|
6026
6026
|
return true;
|
|
6027
6027
|
} catch (e) {
|
|
6028
6028
|
return false;
|
|
@@ -6033,7 +6033,7 @@ var require_util2 = __commonJS({
|
|
|
6033
6033
|
return false;
|
|
6034
6034
|
}
|
|
6035
6035
|
try {
|
|
6036
|
-
var stat =
|
|
6036
|
+
var stat = fs16.statSync(file);
|
|
6037
6037
|
return stat && typeof stat.isFile === "function" && stat.isFile();
|
|
6038
6038
|
} catch (e) {
|
|
6039
6039
|
return false;
|
|
@@ -6053,7 +6053,7 @@ var require_win32 = __commonJS({
|
|
|
6053
6053
|
"node_modules/chrome-finder/lib/win32.js"(exports, module) {
|
|
6054
6054
|
"use strict";
|
|
6055
6055
|
init_esm_shims();
|
|
6056
|
-
var
|
|
6056
|
+
var path17 = __require("path");
|
|
6057
6057
|
var { canAccess } = require_util2();
|
|
6058
6058
|
function win32() {
|
|
6059
6059
|
const installations = [];
|
|
@@ -6067,7 +6067,7 @@ var require_win32 = __commonJS({
|
|
|
6067
6067
|
const prefixes = [process.env.LOCALAPPDATA, process.env.PROGRAMFILES, process.env["PROGRAMFILES(X86)"]];
|
|
6068
6068
|
prefixes.forEach((prefix) => suffixes.forEach((suffix) => {
|
|
6069
6069
|
if (prefix) {
|
|
6070
|
-
const chromePath =
|
|
6070
|
+
const chromePath = path17.join(prefix, suffix);
|
|
6071
6071
|
if (canAccess(chromePath)) {
|
|
6072
6072
|
installations.push(chromePath);
|
|
6073
6073
|
}
|
|
@@ -6085,7 +6085,7 @@ var require_darwin = __commonJS({
|
|
|
6085
6085
|
"use strict";
|
|
6086
6086
|
init_esm_shims();
|
|
6087
6087
|
var { execSync: execSync3 } = __require("child_process");
|
|
6088
|
-
var
|
|
6088
|
+
var path17 = __require("path");
|
|
6089
6089
|
var { canAccess, newLineRegex, sort } = require_util2();
|
|
6090
6090
|
function darwin() {
|
|
6091
6091
|
const suffixes = ["/Contents/MacOS/Google Chrome Canary", "/Contents/MacOS/Google Chrome", "/Contents/MacOS/Chromium"];
|
|
@@ -6095,7 +6095,7 @@ var require_darwin = __commonJS({
|
|
|
6095
6095
|
${LSREGISTER} -dump | grep -E -i -o '/.+(google chrome( canary)?|chromium)\\.app(\\s|$)' | grep -E -v 'Caches|TimeMachine|Temporary|/Volumes|\\.Trash'
|
|
6096
6096
|
`).toString().split(newLineRegex).forEach((inst) => {
|
|
6097
6097
|
suffixes.forEach((suffix) => {
|
|
6098
|
-
const execPath =
|
|
6098
|
+
const execPath = path17.join(inst.trim(), suffix);
|
|
6099
6099
|
if (canAccess(execPath)) {
|
|
6100
6100
|
installations.push(execPath);
|
|
6101
6101
|
}
|
|
@@ -6124,8 +6124,8 @@ var require_linux = __commonJS({
|
|
|
6124
6124
|
"use strict";
|
|
6125
6125
|
init_esm_shims();
|
|
6126
6126
|
var { execSync: execSync3, execFileSync: execFileSync2 } = __require("child_process");
|
|
6127
|
-
var
|
|
6128
|
-
var
|
|
6127
|
+
var path17 = __require("path");
|
|
6128
|
+
var fs16 = __require("fs");
|
|
6129
6129
|
var { canAccess, sort, isExecutable, newLineRegex } = require_util2();
|
|
6130
6130
|
function findChromeExecutablesForLinuxDesktop(folder) {
|
|
6131
6131
|
const argumentsRegex = /(^[^ ]+).*/;
|
|
@@ -6142,7 +6142,7 @@ var require_linux = __commonJS({
|
|
|
6142
6142
|
function linux() {
|
|
6143
6143
|
let installations = [];
|
|
6144
6144
|
const desktopInstallationFolders = [
|
|
6145
|
-
|
|
6145
|
+
path17.join(__require("os").homedir(), ".local/share/applications/"),
|
|
6146
6146
|
"/usr/share/applications/"
|
|
6147
6147
|
];
|
|
6148
6148
|
desktopInstallationFolders.forEach((folder) => {
|
|
@@ -6168,7 +6168,7 @@ var require_linux = __commonJS({
|
|
|
6168
6168
|
].map((possiblePath) => {
|
|
6169
6169
|
try {
|
|
6170
6170
|
const chromePathToTest = possiblePath + "/" + executable;
|
|
6171
|
-
if (
|
|
6171
|
+
if (fs16.existsSync(chromePathToTest) && canAccess(chromePathToTest) && isExecutable(chromePathToTest)) {
|
|
6172
6172
|
installations.push(chromePathToTest);
|
|
6173
6173
|
return chromePathToTest;
|
|
6174
6174
|
}
|
|
@@ -6750,8 +6750,8 @@ function getErrorMap() {
|
|
|
6750
6750
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
6751
6751
|
init_esm_shims();
|
|
6752
6752
|
var makeIssue = (params) => {
|
|
6753
|
-
const { data, path:
|
|
6754
|
-
const fullPath = [...
|
|
6753
|
+
const { data, path: path17, errorMaps, issueData } = params;
|
|
6754
|
+
const fullPath = [...path17, ...issueData.path || []];
|
|
6755
6755
|
const fullIssue = {
|
|
6756
6756
|
...issueData,
|
|
6757
6757
|
path: fullPath
|
|
@@ -6871,11 +6871,11 @@ var errorUtil;
|
|
|
6871
6871
|
|
|
6872
6872
|
// node_modules/zod/v3/types.js
|
|
6873
6873
|
var ParseInputLazyPath = class {
|
|
6874
|
-
constructor(parent, value,
|
|
6874
|
+
constructor(parent, value, path17, key) {
|
|
6875
6875
|
this._cachedPath = [];
|
|
6876
6876
|
this.parent = parent;
|
|
6877
6877
|
this.data = value;
|
|
6878
|
-
this._path =
|
|
6878
|
+
this._path = path17;
|
|
6879
6879
|
this._key = key;
|
|
6880
6880
|
}
|
|
6881
6881
|
get path() {
|
|
@@ -10482,9 +10482,17 @@ var failureAnalysisConfigSchema = external_exports.object({
|
|
|
10482
10482
|
// Qualitative floor (not a numeric % — consistent with the match-strength design).
|
|
10483
10483
|
minStrength: external_exports.enum(["weak", "moderate", "strong"]).default("weak"),
|
|
10484
10484
|
maxFailuresToAnalyse: external_exports.number().int().min(1).default(500),
|
|
10485
|
-
// Consumed by the Plan 3 feedback collector; inert until then.
|
|
10486
10485
|
collectUnclassified: external_exports.boolean().default(true),
|
|
10487
|
-
|
|
10486
|
+
// What the feedback collector stores (while collectUnclassified is on):
|
|
10487
|
+
// 'blind-spots' = unknown/low-confidence only; 'all' = every model-scored
|
|
10488
|
+
// failure, so wrong-but-confident verdicts can be corrected by labeling.
|
|
10489
|
+
collectScope: external_exports.enum(["blind-spots", "all"]).default("blind-spots"),
|
|
10490
|
+
autoUpdateModel: external_exports.boolean().default(true),
|
|
10491
|
+
// Use the on-device trained model (when present and its evaluation gate passed).
|
|
10492
|
+
localModel: external_exports.boolean().default(true),
|
|
10493
|
+
// Override the local model file location (default ~/.reportforge/model-local.json).
|
|
10494
|
+
// Point at a repo-committed file to share a team-trained model with ephemeral CI.
|
|
10495
|
+
localModelPath: external_exports.string().optional()
|
|
10488
10496
|
}).default({});
|
|
10489
10497
|
var captureConfigSchema = external_exports.object({
|
|
10490
10498
|
steps: external_exports.boolean().default(false),
|
|
@@ -10850,7 +10858,48 @@ import { createPublicKey as createPublicKey2, verify as verify2 } from "crypto";
|
|
|
10850
10858
|
|
|
10851
10859
|
// src/analysis/model-bundle.ts
|
|
10852
10860
|
init_esm_shims();
|
|
10853
|
-
var MODEL = { "alpha": 1, "labels": ["assertion", "env-config", "flaky-by-retry", "locator-not-found", "navigation", "network", "timeout"], "logLikelihoods": { "assertion": { "NUM": -4.574710978503383, "assertionerror": -4.980176086611547, "be": -4.980176086611547, "cart": -4.980176086611547, "checkout": -4.980176086611547, "com": -4.980176086611547, "dashboard": -4.980176086611547, "deep": -4.980176086611547, "equal": -4.980176086611547, "equality": -4.980176086611547, "error": -4.980176086611547, "expect": -3.5938817254916566, "expected": -3.1083739097099556, "failed": -4.980176086611547, "false": -4.980176086611547, "got": -4.980176086611547, "id": -4.574710978503383, "john": -4.980176086611547, "locator": -4.574710978503383, "login": -4.980176086611547, "must": -4.980176086611547, "page": -4.980176086611547, "pattern": -4.980176086611547, "received": -3.275427994373122, "string": -4.980176086611547, "to": -4.980176086611547, "tobe": -4.980176086611547, "tobetruthy": -4.980176086611547, "toequal": -4.980176086611547, "tohavecount": -4.980176086611547, "tohavetext": -4.980176086611547, "tohavetitle": -4.980176086611547, "tohavevalue": -4.980176086611547, "truthy": -4.980176086611547, "value": -4.980176086611547 }, "env-config": { "NUM": -4.997212273764115, "api": -4.997212273764115, "at": -4.997212273764115, "back": -4.997212273764115, "base": -4.997212273764115, "baseurl": -4.997212273764115, "browsers": -4.997212273764115, "cannot": -4.997212273764115, "ci": -4.997212273764115, "config": -4.304065093204169, "directory": -4.591747165655951, "dotenv": -4.997212273764115, "enoent": -4.997212273764115, "env": -4.591747165655951, "environment": -4.591747165655951, "error": -4.08092154188996, "existent": -4.997212273764115, "failed": -4.997212273764115, "falling": -4.997212273764115, "file": -4.997212273764115, "find": -4.997212273764115, "from": -4.997212273764115, "in": -4.591747165655951, "invalid": -4.997212273764115, "is": -4.997212273764115, "json": -4.591747165655951, "key": -4.997212273764115, "load": -4.997212273764115, "missing": -4.997212273764115, "module": -4.997212273764115, "no": -4.997212273764115, "non": -4.997212273764115, "not": -4.997212273764115, "open": -4.997212273764115, "or": -4.997212273764115, "path": -4.997212273764115, "playwright": -4.591747165655951, "points": -4.997212273764115, "position": -4.997212273764115, "required": -4.997212273764115, "set": -4.997212273764115, "spec": -4.997212273764115, "such": -4.997212273764115, "syntaxerror": -4.997212273764115, "test": -4.997212273764115, "to": -4.304065093204169, "token": -4.997212273764115, "ts": -4.997212273764115, "tsconfig": -4.997212273764115, "undefined": -4.591747165655951, "unexpected": -4.997212273764115, "url": -4.997212273764115, "values": -4.997212273764115, "variable": -4.591747165655951 }, "flaky-by-retry": { "after": -4.58836306767171, "and": -4.993828175779875, "animation": -4.993828175779875, "attempt": -4.07753744390572, "between": -4.993828175779875, "blip": -4.993828175779875, "cause": -4.993828175779875, "change": -4.993828175779875, "click": -4.993828175779875, "code": -4.993828175779875, "commit": -4.993828175779875, "condition": -4.993828175779875, "dependency": -4.993828175779875, "detached": -4.993828175779875, "deterministic": -4.993828175779875, "element": -4.993828175779875, "failed": -4.300680995219929, "fails": -4.993828175779875, "flaky": -4.07753744390572, "green": -4.993828175779875, "in": -4.993828175779875, "intermittent": -4.993828175779875, "locator": -4.993828175779875, "marked": -4.993828175779875, "network": -4.993828175779875, "no": -4.993828175779875, "non": -4.993828175779875, "on": -3.895215887111765, "order": -4.993828175779875, "passed": -3.895215887111765, "quarantined": -4.993828175779875, "race": -4.993828175779875, "reproducible": -4.993828175779875, "rerun": -4.993828175779875, "retry": -4.07753744390572, "runs": -4.993828175779875, "same": -4.993828175779875, "second": -4.993828175779875, "stale": -4.993828175779875, "succeeded": -4.993828175779875, "test": -4.58836306767171, "the": -4.993828175779875, "then": -4.993828175779875, "timeout": -4.993828175779875, "unstable": -4.993828175779875, "with": -4.993828175779875, "without": -4.993828175779875 }, "locator-not-found": { "an": -4.993828175779875, "attached": -4.993828175779875, "btn": -4.993828175779875, "button": -4.58836306767171, "cart": -4.993828175779875, "checkout": -4.993828175779875, "click": -4.993828175779875, "data": -4.993828175779875, "div": -4.993828175779875, "dom": -4.993828175779875, "element": -4.07753744390572, "elements": -4.300680995219929, "error": -4.58836306767171, "find": -4.993828175779875, "for": -4.58836306767171, "found": -4.58836306767171, "getbyrole": -4.993828175779875, "getbytext": -4.993828175779875, "icon": -4.993828175779875, "id": -4.993828175779875, "is": -4.993828175779875, "locator": -4.07753744390572, "matched": -4.993828175779875, "matches": -4.993828175779875, "missing": -4.993828175779875, "mode": -4.58836306767171, "name": -4.993828175779875, "no": -4.58836306767171, "node": -4.993828175779875, "not": -4.58836306767171, "resolved": -4.58836306767171, "save": -4.993828175779875, "selector": -4.58836306767171, "strict": -4.58836306767171, "submit": -4.993828175779875, "testid": -4.993828175779875, "textcontent": -4.993828175779875, "the": -4.58836306767171, "to": -4.07753744390572, "total": -4.993828175779875, "unable": -4.993828175779875, "violation": -4.58836306767171, "waiting": -4.993828175779875, "with": -4.993828175779875, "xpath": -4.993828175779875 }, "navigation": { "NUM": -4.983606621708336, "aborted": -4.983606621708336, "another": -4.983606621708336, "back": -4.983606621708336, "because": -4.578141513600172, "by": -4.578141513600172, "checkout": -4.983606621708336, "context": -4.983606621708336, "crashed": -4.983606621708336, "dashboard": -4.983606621708336, "destroyed": -4.983606621708336, "detached": -4.983606621708336, "entry": -4.983606621708336, "err": -4.578141513600172, "exceeded": -4.983606621708336, "execution": -4.983606621708336, "failed": -4.983606621708336, "frame": -4.578141513600172, "goback": -4.983606621708336, "goto": -4.290459441148391, "history": -4.983606621708336, "home": -4.983606621708336, "interrupted": -4.578141513600172, "is": -4.983606621708336, "likely": -4.983606621708336, "login": -4.983606621708336, "many": -4.983606621708336, "maybe": -4.983606621708336, "most": -4.983606621708336, "navigate": -4.983606621708336, "navigating": -4.983606621708336, "navigation": -3.7308436532129683, "net": -4.578141513600172, "no": -4.983606621708336, "of": -4.983606621708336, "page": -3.884994333040227, "redirects": -4.983606621708336, "timeout": -4.983606621708336, "to": -3.7308436532129683, "too": -4.983606621708336, "waitforurl": -4.983606621708336, "was": -4.578141513600172 }, "network": { "NUM": -4.57126863431241, "URL": -4.283586561860629, "again": -4.976733742420574, "api": -4.976733742420574, "apirequestcontext": -4.976733742420574, "at": -4.976733742420574, "body": -4.976733742420574, "connect": -4.976733742420574, "connection": -4.57126863431241, "disconnected": -4.976733742420574, "eai": -4.976733742420574, "econnrefused": -4.976733742420574, "err": -3.8781214537524646, "error": -4.976733742420574, "failed": -4.283586561860629, "fetch": -4.976733742420574, "fetching": -4.976733742420574, "from": -4.976733742420574, "get": -4.976733742420574, "getaddrinfo": -4.976733742420574, "goto": -4.976733742420574, "hang": -4.976733742420574, "internet": -4.976733742420574, "loading": -4.976733742420574, "name": -4.976733742420574, "net": -3.8781214537524646, "not": -4.976733742420574, "on": -4.976733742420574, "out": -4.976733742420574, "page": -4.57126863431241, "products": -4.976733742420574, "protocol": -4.976733742420574, "reading": -4.976733742420574, "reason": -4.976733742420574, "refused": -4.976733742420574, "request": -4.57126863431241, "resolved": -4.976733742420574, "resource": -4.976733742420574, "response": -4.976733742420574, "route": -4.976733742420574, "socket": -4.976733742420574, "ssl": -4.976733742420574, "timed": -4.976733742420574, "to": -4.976733742420574, "up": -4.976733742420574, "upstream": -4.976733742420574, "while": -4.976733742420574 }, "timeout": { "NUM": -3.4965075614664802, "after": -5.000584958242754, "be": -4.59511985013459, "cart": -5.000584958242754, "click": -5.000584958242754, "element": -5.000584958242754, "event": -5.000584958242754, "exceeded": -3.6142905971228636, "expect": -5.000584958242754, "fill": -5.000584958242754, "for": -3.7478219897473863, "function": -5.000584958242754, "load": -5.000584958242754, "locator": -4.084294226368599, "navigation": -5.000584958242754, "of": -5.000584958242754, "out": -5.000584958242754, "page": -4.59511985013459, "running": -5.000584958242754, "selector": -5.000584958242754, "submit": -5.000584958242754, "test": -4.59511985013459, "timed": -5.000584958242754, "timeout": -3.6142905971228636, "timeouterror": -4.59511985013459, "to": -4.59511985013459, "tobevisible": -5.000584958242754, "visible": -4.59511985013459, "waitforloadstate": -5.000584958242754, "waitforselector": -5.000584958242754, "waiting": -3.7478219897473863, "while": -5.000584958242754 } }, "playwrightVersion": "1.59.1", "priors": { "assertion": -1.9636097261547143, "env-config": -1.9636097261547143, "flaky-by-retry": -1.9636097261547143, "locator-not-found": -1.9636097261547143, "navigation": -1.9636097261547143, "network": -1.9636097261547143, "timeout": -1.845826690498331 }, "totals": { "assertion": 64, "env-config": 69, "flaky-by-retry": 68, "locator-not-found": 68, "navigation": 65, "network": 63, "timeout": 70 }, "version": 1, "vocabSize": 227 };
|
|
10861
|
+
var MODEL = { "alpha": 1, "labels": ["assertion", "env-config", "flaky-by-retry", "locator-not-found", "navigation", "network", "timeout"], "logLikelihoods": { "assertion": { "13": -6.424058322604399, "16": -6.424058322604399, "17": -6.424058322604399, "20": -6.424058322604399, "21": -6.018593214496234, "22": -6.424058322604399, "23": -6.424058322604399, "25": -6.424058322604399, "30": -6.424058322604399, "41": -6.424058322604399, "43": -6.424058322604399, "61": -6.424058322604399, "00": -6.018593214496234, "03": -6.424058322604399, "12t07": -6.424058322604399, "6s": -6.424058322604399, "NUM": -4.283992159108128, "URL": -6.424058322604399, "actual": -6.018593214496234, "am": -6.424058322604399, "assertionerror": -6.424058322604399, "assertionname": -6.424058322604399, "async": -6.424058322604399, "at": -5.507767590730244, "await": -5.32544603393629, "basic": -5.507767590730244, "be": -5.730911142044453, "below": -6.424058322604399, "button": -6.424058322604399, "call": -5.507767590730244, "cart": -6.424058322604399, "checkout": -6.424058322604399, "com": -6.424058322604399, "const": -6.424058322604399, "count": -5.730911142044453, "dashboard": -6.424058322604399, "deep": -6.424058322604399, "downloads": -6.018593214496234, "equal": -6.424058322604399, "equality": -6.424058322604399, "error": -5.32544603393629, "example": -5.171295354109031, "expect": -4.283992159108128, "expected": -3.9817112872351945, "failed": -6.018593214496234, "false": -6.424058322604399, "field": -6.424058322604399, "for": -5.507767590730244, "getbytext": -6.018593214496234, "getting": -6.424058322604399, "ggorlen": -6.424058322604399, "got": -6.424058322604399, "goto": -6.424058322604399, "id": -6.018593214496234, "in": -6.018593214496234, "inner": -6.018593214496234, "internal": -6.018593214496234, "isnot": -6.018593214496234, "john": -6.424058322604399, "js": -5.32544603393629, "lib": -6.424058322604399, "locator": -4.478148173549085, "log": -5.507767590730244, "logged": -6.018593214496234, "login": -6.424058322604399, "matcherhint": -6.424058322604399, "matcherresult": -5.507767590730244, "modules": -6.424058322604399, "must": -6.424058322604399, "my": -6.424058322604399, "name": -6.018593214496234, "navbar": -5.507767590730244, "node": -5.507767590730244, "not": -6.424058322604399, "npx": -6.424058322604399, "page": -5.171295354109031, "pattern": -6.424058322604399, "playwright": -5.32544603393629, "printexpected": -6.018593214496234, "printreceived": -6.018593214496234, "process": -6.424058322604399, "processimmediate": -6.424058322604399, "queues": -6.424058322604399, "received": -4.22683374526818, "reply": -6.424058322604399, "return": -6.424058322604399, "runnextticks": -6.424058322604399, "running": -6.424058322604399, "runtestwithbeforehooks": -6.424058322604399, "selector": -6.424058322604399, "should": -6.018593214496234, "spec": -5.32544603393629, "string": -5.037763961484508, "task": -6.424058322604399, "test": -4.814620410170298, "tests": -5.507767590730244, "text": -6.424058322604399, "this": -5.171295354109031, "timeout": -5.730911142044453, "timers": -6.424058322604399, "title": -5.507767590730244, "to": -6.424058322604399, "tobe": -6.424058322604399, "tobetruthy": -6.424058322604399, "tobevisible": -6.018593214496234, "toequal": -6.424058322604399, "tohavecount": -6.424058322604399, "tohavetext": -4.919980925828125, "tohavetitle": -6.424058322604399, "tohavevalue": -6.424058322604399, "truthy": -6.424058322604399, "ts": -6.424058322604399, "undefined": -6.018593214496234, "users": -6.018593214496234, "using": -6.424058322604399, "utils": -5.32544603393629, "value": -6.424058322604399, "vu": -6.018593214496234, "waiting": -5.507767590730244, "with": -5.730911142044453, "worker": -6.424058322604399, "workerrunner": -6.018593214496234 }, "env-config": { "16": -6.687108607866515, "44": -6.687108607866515, "64": -6.687108607866515, "66": -6.687108607866515, "70": -5.77081787599236, "00": -6.28164349975835, "05": -6.687108607866515, "16t15": -6.687108607866515, "51z": -6.687108607866515, "8hauptrolle": -6.687108607866515, "NUM": -5.18303121109024, "activity": -6.687108607866515, "add": -6.687108607866515, "additional": -6.687108607866515, "aimed": -6.687108607866515, "alderoberge": -6.687108607866515, "alejo": -6.687108607866515, "also": -5.588496319198405, "and": -5.588496319198405, "any": -6.28164349975835, "anyone": -6.28164349975835, "api": -6.687108607866515, "assist": -6.687108607866515, "at": -5.434345639371147, "available": -6.28164349975835, "awb": -6.28164349975835, "back": -6.687108607866515, "base": -6.687108607866515, "baseurl": -6.687108607866515, "be": -6.28164349975835, "believe": -6.687108607866515, "binary": -6.687108607866515, "box": -6.28164349975835, "bridge": -6.687108607866515, "browser": -6.687108607866515, "browsername": -5.588496319198405, "browsers": -5.18303121109024, "browsertype": -4.9823605156280895, "but": -6.28164349975835, "by": -6.687108607866515, "cache": -5.77081787599236, "can": -6.28164349975835, "cannot": -6.687108607866515, "channel": -5.077670695432414, "cheron": -6.687108607866515, "chrome": -5.18303121109024, "chromium": -4.9823605156280895, "ci": -6.687108607866515, "cmu": -4.9823605156280895, "cmulex": -6.687108607866515, "command": -5.993961427306569, "commented": -6.687108607866515, "config": -5.993961427306569, "default": -6.687108607866515, "dependencies": -5.588496319198405, "deps": -5.993961427306569, "despite": -6.687108607866515, "difference": -6.687108607866515, "different": -6.687108607866515, "directory": -6.28164349975835, "displays": -6.687108607866515, "distros": -5.993961427306569, "do": -6.28164349975835, "docker": -6.687108607866515, "doesn": -5.434345639371147, "dotenv": -6.687108607866515, "download": -6.28164349975835, "edit": -6.687108607866515, "effort": -6.687108607866515, "elementary": -6.687108607866515, "enoent": -6.687108607866515, "env": -6.28164349975835, "environment": -6.28164349975835, "error": -4.741198458811201, "example": -6.687108607866515, "exec": -6.687108607866515, "executable": -5.77081787599236, "exist": -5.77081787599236, "existent": -6.687108607866515, "explain": -6.28164349975835, "eyes": -6.687108607866515, "failed": -6.687108607866515, "fak3": -6.687108607866515, "falling": -6.687108607866515, "file": -6.28164349975835, "files": -6.687108607866515, "find": -6.687108607866515, "firefox": -6.28164349975835, "fix": -6.687108607866515, "fixing": -6.687108607866515, "following": -6.28164349975835, "for": -5.588496319198405, "from": -6.687108607866515, "gnu": -6.687108607866515, "goes": -6.687108607866515, "goto": -6.687108607866515, "grapheme": -6.28164349975835, "guess": -6.28164349975835, "has": -6.28164349975835, "have": -6.28164349975835, "having": -6.28164349975835, "home": -6.687108607866515, "hopefully": -6.687108607866515, "host": -5.77081787599236, "if": -6.28164349975835, "image": -6.687108607866515, "in": -6.28164349975835, "incompatible": -6.687108607866515, "indic": -6.28164349975835, "information": -6.687108607866515, "insights": -6.687108607866515, "install": -5.588496319198405, "installed": -5.993961427306569, "instead": -6.687108607866515, "into": -6.687108607866515, "invalid": -6.687108607866515, "is": -5.077670695432414, "isn": -6.687108607866515, "issue": -5.588496319198405, "it": -4.9823605156280895, "js": -6.687108607866515, "json": -6.28164349975835, "just": -5.588496319198405, "kal": -6.687108607866515, "kal16": -6.687108607866515, "keep": -6.687108607866515, "key": -6.687108607866515, "kunukn": -6.687108607866515, "lang": -6.28164349975835, "launch": -4.9823605156280895, "leo": -6.687108607866515, "lex": -6.28164349975835, "lib": -6.687108607866515, "libatk": -6.28164349975835, "libatspi": -6.687108607866515, "libcups": -6.687108607866515, "libdbus": -6.687108607866515, "libdrm": -6.687108607866515, "libexpat": -6.687108607866515, "libflite": -4.741198458811201, "libgio": -6.687108607866515, "libglib": -6.687108607866515, "libgobject": -6.687108607866515, "libgstcodecparsers": -6.687108607866515, "libicu70": -6.687108607866515, "libicudata": -6.687108607866515, "libicui18n": -6.687108607866515, "libicuio": -6.687108607866515, "libicuuc": -6.687108607866515, "libnspr4": -6.687108607866515, "libnss3": -6.687108607866515, "libnssutil3": -6.687108607866515, "libpthread": -6.687108607866515, "libraries": -5.77081787599236, "libsmime3": -6.687108607866515, "libx264": -6.687108607866515, "libxcb": -6.687108607866515, "libxkbcommon": -6.687108607866515, "like": -5.77081787599236, "linux": -4.895349138638459, "load": -6.687108607866515, "looks": -5.993961427306569, "lookup": -6.687108607866515, "lot": -6.687108607866515, "make": -6.687108607866515, "malaver": -6.687108607866515, "matching": -6.687108607866515, "may": -6.28164349975835, "meant": -6.687108607866515, "message": -6.687108607866515, "minibrowser": -6.687108607866515, "mint": -5.77081787599236, "missing": -5.077670695432414, "module": -6.687108607866515, "more": -6.687108607866515, "most": -6.28164349975835, "ms": -5.77081787599236, "must": -6.687108607866515, "my": -6.687108607866515, "name": -6.687108607866515, "need": -6.687108607866515, "new": -6.28164349975835, "newer": -6.687108607866515, "no": -6.687108607866515, "non": -6.687108607866515, "not": -5.993961427306569, "npx": -6.28164349975835, "of": -5.434345639371147, "old": -6.687108607866515, "on": -5.18303121109024, "one": -6.28164349975835, "open": -6.687108607866515, "or": -5.77081787599236, "other": -6.687108607866515, "out": -5.77081787599236, "package": -6.687108607866515, "page": -6.687108607866515, "parameter": -6.687108607866515, "path": -6.687108607866515, "platforms": -6.687108607866515, "playwright": -4.435816809260019, "please": -6.28164349975835, "pnpm": -6.687108607866515, "points": -6.687108607866515, "popular": -6.28164349975835, "position": -6.687108607866515, "prompt": -6.687108607866515, "provided": -6.687108607866515, "quick": -6.687108607866515, "react": -6.687108607866515, "related": -6.687108607866515, "replace": -6.687108607866515, "reply": -6.687108607866515, "repositories": -6.28164349975835, "required": -6.687108607866515, "rms": -6.687108607866515, "root": -5.993961427306569, "run": -5.300814246746624, "running": -5.993961427306569, "safari": -6.28164349975835, "same": -5.77081787599236, "seems": -6.687108607866515, "set": -6.687108607866515, "should": -6.28164349975835, "simensbat": -6.687108607866515, "simply": -6.687108607866515, "slt": -6.687108607866515, "so": -3.742669628700074, "some": -6.28164349975835, "spec": -6.28164349975835, "such": -6.687108607866515, "super": -6.687108607866515, "support": -6.687108607866515, "symbol": -6.28164349975835, "syntaxerror": -6.687108607866515, "system": -5.588496319198405, "team": -6.687108607866515, "test": -6.28164349975835, "tests": -6.687108607866515, "the": -4.547042444370244, "there": -5.77081787599236, "this": -5.77081787599236, "time": -6.687108607866515, "title": -6.687108607866515, "tls": -6.687108607866515, "to": -4.489884030530295, "token": -6.687108607866515, "tried": -6.28164349975835, "troubleshooting": -6.687108607866515, "ts": -6.687108607866515, "tsconfig": -6.687108607866515, "ubuntu": -5.588496319198405, "undefined": -5.993961427306569, "unexpected": -6.687108607866515, "unsupported": -5.588496319198405, "updated": -6.28164349975835, "url": -6.687108607866515, "us": -5.588496319198405, "use": -6.687108607866515, "usenglish": -6.687108607866515, "uses": -6.28164349975835, "using": -6.28164349975835, "usr": -6.687108607866515, "value": -6.687108607866515, "values": -6.687108607866515, "variable": -6.28164349975835, "version": -6.28164349975835, "vsts": -6.687108607866515, "was": -5.993961427306569, "way": -6.687108607866515, "webkit": -5.77081787599236, "which": -6.28164349975835, "why": -6.28164349975835, "with": -5.300814246746624, "work": -5.77081787599236, "worker": -6.687108607866515, "works": -6.28164349975835, "would": -6.687108607866515, "x86": -6.687108607866515, "you": -6.28164349975835 }, "flaky-by-retry": { "after": -5.786897381366708, "and": -6.192362489474872, "animation": -6.192362489474872, "attempt": -5.276071757600717, "between": -6.192362489474872, "blip": -6.192362489474872, "cause": -6.192362489474872, "change": -6.192362489474872, "click": -6.192362489474872, "code": -6.192362489474872, "commit": -6.192362489474872, "condition": -6.192362489474872, "dependency": -6.192362489474872, "detached": -6.192362489474872, "deterministic": -6.192362489474872, "element": -6.192362489474872, "failed": -5.499215308914927, "fails": -6.192362489474872, "flaky": -5.276071757600717, "green": -6.192362489474872, "in": -6.192362489474872, "intermittent": -6.192362489474872, "locator": -6.192362489474872, "marked": -6.192362489474872, "network": -6.192362489474872, "no": -6.192362489474872, "non": -6.192362489474872, "on": -5.093750200806762, "order": -6.192362489474872, "passed": -5.093750200806762, "quarantined": -6.192362489474872, "race": -6.192362489474872, "reproducible": -6.192362489474872, "rerun": -6.192362489474872, "retry": -5.276071757600717, "runs": -6.192362489474872, "same": -6.192362489474872, "second": -6.192362489474872, "stale": -6.192362489474872, "succeeded": -6.192362489474872, "test": -5.786897381366708, "the": -6.192362489474872, "then": -6.192362489474872, "timeout": -6.192362489474872, "unstable": -6.192362489474872, "with": -6.192362489474872, "without": -6.192362489474872 }, "locator-not-found": { "25": -6.459904454377535, "30": -5.3612921657094255, "46": -6.459904454377535, "06": -6.459904454377535, "NUM": -5.5436137225033795, "aka": -4.588102277475944, "alert": -6.459904454377535, "all": -6.459904454377535, "an": -6.459904454377535, "api": -6.459904454377535, "aria": -6.05443934626937, "async": -6.459904454377535, "attached": -6.459904454377535, "based": -6.459904454377535, "being": -6.459904454377535, "birth": -6.459904454377535, "btn": -6.459904454377535, "button": -4.588102277475944, "by": -6.459904454377535, "captura": -6.459904454377535, "cart": -6.459904454377535, "carteiras": -6.05443934626937, "cell": -6.05443934626937, "checkout": -6.459904454377535, "checks": -6.459904454377535, "click": -5.5436137225033795, "cns": -5.766757273817589, "columns": -6.459904454377535, "const": -6.459904454377535, "contains": -6.459904454377535, "copy": -6.05443934626937, "count": -6.459904454377535, "cpf": -5.766757273817589, "da": -6.05443934626937, "data": -6.05443934626937, "de": -6.459904454377535, "div": -5.2071414858821665, "does": -6.459904454377535, "dom": -6.459904454377535, "easiest": -6.459904454377535, "element": -5.5436137225033795, "elements": -4.755156362139109, "error": -4.513994305322221, "even": -6.459904454377535, "exact": -5.766757273817589, "expected": -6.459904454377535, "fail": -6.459904454377535, "field": -6.459904454377535, "filtering": -6.459904454377535, "find": -6.459904454377535, "first": -5.766757273817589, "for": -6.05443934626937, "found": -6.05443934626937, "frame": -6.459904454377535, "from": -6.459904454377535, "getbyrole": -5.3612921657094255, "getbytext": -5.073610093257644, "icon": -6.459904454377535, "id": -5.766757273817589, "if": -6.459904454377535, "iframe": -6.459904454377535, "in": -5.766757273817589, "into": -6.459904454377535, "is": -5.5436137225033795, "issue": -6.05443934626937, "it": -5.766757273817589, "javascript": -6.459904454377535, "just": -6.459904454377535, "kb": -6.459904454377535, "label": -6.05443934626937, "licenses": -6.459904454377535, "link": -6.459904454377535, "list": -6.459904454377535, "locator": -4.2626798770413155, "match": -6.459904454377535, "matched": -6.459904454377535, "matches": -6.459904454377535, "mean": -6.459904454377535, "method": -6.459904454377535, "missing": -6.459904454377535, "mode": -4.66814498514948, "mother": -6.459904454377535, "munic": -6.05443934626937, "municipality": -6.459904454377535, "my": -6.459904454377535, "name": -5.2071414858821665, "nascimento": -6.05443934626937, "new": -6.05443934626937, "no": -6.05443934626937, "node": -6.459904454377535, "nome": -5.5436137225033795, "not": -6.05443934626937, "note": -6.459904454377535, "nov": -6.05443934626937, "novalistagem": -6.459904454377535, "nth": -6.459904454377535, "of": -6.459904454377535, "or": -5.766757273817589, "page": -6.459904454377535, "passes": -6.459904454377535, "pio": -6.05443934626937, "playwright": -6.05443934626937, "position": -5.766757273817589, "question": -6.459904454377535, "resolve": -6.459904454377535, "resolved": -4.955827057601261, "response": -6.459904454377535, "rest": -6.459904454377535, "result": -5.766757273817589, "results": -6.459904454377535, "role": -6.459904454377535, "run": -6.459904454377535, "save": -6.459904454377535, "selection": -6.459904454377535, "selector": -6.05443934626937, "simplest": -6.459904454377535, "solution": -6.459904454377535, "span": -5.766757273817589, "specify": -6.459904454377535, "specifying": -6.459904454377535, "state": -6.459904454377535, "strict": -4.66814498514948, "submit": -6.459904454377535, "tabindex": -6.05443934626937, "table": -6.459904454377535, "take": -6.459904454377535, "td": -6.459904454377535, "tela": -6.459904454377535, "test": -6.05443934626937, "testid": -6.459904454377535, "text": -5.766757273817589, "textcontent": -6.459904454377535, "that": -6.05443934626937, "the": -4.513994305322221, "thead": -6.459904454377535, "this": -5.5436137225033795, "title": -6.459904454377535, "to": -4.513994305322221, "total": -6.459904454377535, "tr": -6.459904454377535, "true": -5.766757273817589, "type": -6.05443934626937, "uf": -6.05443934626937, "unable": -6.459904454377535, "validate": -6.459904454377535, "validatefieldvalue": -6.459904454377535, "validation": -6.459904454377535, "violation": -4.755156362139109, "waitfor": -6.459904454377535, "waiting": -6.459904454377535, "we": -6.459904454377535, "what": -6.459904454377535, "when": -6.459904454377535, "whether": -6.459904454377535, "will": -6.459904454377535, "with": -6.459904454377535, "xpath": -6.459904454377535 }, "navigation": { "14": -6.304448802421981, "19": -6.709913910530146, "25": -6.709913910530146, "27": -6.304448802421981, "39": -6.709913910530146, "49": -6.709913910530146, "66": -6.709913910530146, "0ms": -6.304448802421981, "6ms": -6.709913910530146, "NUM": -4.569847747033875, "URL": -5.793623178655991, "abort": -6.0167667299702, "aborted": -4.91815444130209, "acting": -6.709913910530146, "additional": -6.709913910530146, "adjusting": -6.709913910530146, "after": -6.0167667299702, "an": -6.304448802421981, "and": -6.304448802421981, "another": -6.709913910530146, "api": -5.611301621862036, "appends": -6.709913910530146, "are": -6.709913910530146, "argument": -6.709913910530146, "as": -6.709913910530146, "async": -6.0167667299702, "at": -5.457150942034778, "avoid": -6.709913910530146, "await": -4.91815444130209, "back": -6.709913910530146, "base": -6.709913910530146, "be": -6.709913910530146, "because": -5.457150942034778, "before": -6.304448802421981, "behavior": -6.709913910530146, "being": -6.709913910530146, "both": -6.709913910530146, "browser": -6.0167667299702, "bug": -6.304448802421981, "but": -6.304448802421981, "by": -6.0167667299702, "call": -5.457150942034778, "callback": -6.709913910530146, "called": -6.709913910530146, "calling": -6.709913910530146, "cancelled": -6.709913910530146, "cannot": -6.709913910530146, "caused": -6.709913910530146, "causes": -6.709913910530146, "certain": -6.709913910530146, "chain": -6.304448802421981, "channel": -6.709913910530146, "checkout": -6.709913910530146, "chrome": -6.709913910530146, "click": -6.709913910530146, "close": -6.709913910530146, "closed": -6.709913910530146, "code": -6.709913910530146, "comment": -6.709913910530146, "commented": -6.709913910530146, "common": -6.304448802421981, "complicated": -6.709913910530146, "connection": -6.709913910530146, "const": -6.709913910530146, "context": -6.304448802421981, "copy": -6.0167667299702, "crashed": -5.793623178655991, "create": -6.709913910530146, "dashboard": -6.0167667299702, "debugging": -6.709913910530146, "describe": -6.709913910530146, "destroyed": -6.0167667299702, "detached": -5.100475998096045, "developer": -6.709913910530146, "didn": -6.709913910530146, "different": -6.709913910530146, "directly": -6.709913910530146, "document": -6.709913910530146, "does": -6.709913910530146, "domcontentloaded": -6.304448802421981, "dowrite": -6.709913910530146, "during": -6.304448802421981, "en": -6.709913910530146, "entry": -6.709913910530146, "err": -4.695010889987881, "error": -4.838111733628554, "event": -6.304448802421981, "example": -6.709913910530146, "exceeded": -6.304448802421981, "execution": -6.709913910530146, "expect": -6.709913910530146, "expected": -6.709913910530146, "facing": -6.709913910530146, "failed": -5.611301621862036, "file": -5.323619549410255, "fine": -6.304448802421981, "fired": -6.304448802421981, "firefox": -6.709913910530146, "for": -5.793623178655991, "frame": -4.6304723688503096, "frames": -6.709913910530146, "frequent": -6.709913910530146, "from": -6.709913910530146, "frompromise": -6.709913910530146, "full": -6.709913910530146, "future": -6.709913910530146, "getbyrole": -6.709913910530146, "getting": -6.709913910530146, "given": -6.709913910530146, "goback": -6.709913910530146, "going": -6.709913910530146, "goto": -4.312018637731775, "handler": -6.709913910530146, "happens": -6.709913910530146, "have": -6.709913910530146, "headless": -6.709913910530146, "helper": -6.0167667299702, "hint": -6.709913910530146, "history": -6.709913910530146, "home": -5.323619549410255, "html": -6.0167667299702, "impl": -6.709913910530146, "in": -5.457150942034778, "include": -6.709913910530146, "info": -6.709913910530146, "initial": -6.709913910530146, "innerhtml": -6.709913910530146, "inside": -6.709913910530146, "instead": -6.709913910530146, "internal": -6.709913910530146, "interrupted": -6.304448802421981, "is": -6.304448802421981, "issue": -5.457150942034778, "it": -6.304448802421981, "its": -6.709913910530146, "js": -5.611301621862036, "jul": -6.304448802421981, "lang": -6.709913910530146, "last": -6.304448802421981, "lib": -5.793623178655991, "likely": -6.709913910530146, "line": -5.457150942034778, "link": -5.793623178655991, "load": -5.793623178655991, "loads": -6.304448802421981, "locals": -5.793623178655991, "log": -6.0167667299702, "login": -6.0167667299702, "logs": -6.304448802421981, "main": -6.709913910530146, "many": -6.304448802421981, "maxschmitt": -6.709913910530146, "may": -6.709913910530146, "maybe": -5.100475998096045, "means": -6.709913910530146, "message": -6.709913910530146, "method": -6.709913910530146, "mistake": -6.709913910530146, "mjs": -6.709913910530146, "mobile": -6.709913910530146, "mode": -6.709913910530146, "more": -6.709913910530146, "most": -6.0167667299702, "my": -6.709913910530146, "name": -6.304448802421981, "navigate": -6.709913910530146, "navigates": -6.709913910530146, "navigatetojobs": -6.709913910530146, "navigating": -5.323619549410255, "navigation": -4.695010889987881, "net": -4.838111733628554, "new": -5.205836513753871, "next": -6.709913910530146, "no": -6.304448802421981, "node": -6.0167667299702, "non": -6.709913910530146, "none": -6.709913910530146, "oauth": -6.709913910530146, "obj": -6.709913910530146, "of": -5.457150942034778, "on": -6.0167667299702, "open": -6.304448802421981, "options": -6.709913910530146, "or": -6.304448802421981, "other": -6.709913910530146, "out": -6.709913910530146, "packages": -5.793623178655991, "page": -3.9065535296236105, "pages": -6.0167667299702, "params": -6.304448802421981, "per": -6.709913910530146, "playwright": -4.91815444130209, "pretty": -6.709913910530146, "process": -6.709913910530146, "promises": -6.709913910530146, "pw": -5.793623178655991, "py": -5.457150942034778, "python3": -5.793623178655991, "randomly": -6.709913910530146, "rebuilds": -6.709913910530146, "received": -6.709913910530146, "recent": -6.304448802421981, "redirect": -6.0167667299702, "redirects": -6.709913910530146, "reload": -6.304448802421981, "removed": -6.304448802421981, "removes": -6.709913910530146, "replaced": -6.709913910530146, "replaces": -6.709913910530146, "replicate": -6.709913910530146, "request": -6.709913910530146, "resolved": -6.709913910530146, "response": -6.709913910530146, "result": -6.709913910530146, "retrieving": -6.709913910530146, "return": -6.709913910530146, "returns": -6.709913910530146, "root": -6.709913910530146, "route": -6.0167667299702, "run": -6.709913910530146, "same": -6.709913910530146, "script": -6.304448802421981, "selector": -6.709913910530146, "self": -5.611301621862036, "send": -6.304448802421981, "sends": -6.709913910530146, "settings": -6.304448802421981, "site": -5.793623178655991, "skip": -6.709913910530146, "socket": -6.709913910530146, "some": -6.304448802421981, "somepage": -6.709913910530146, "spa": -6.304448802421981, "started": -6.709913910530146, "states": -6.709913910530146, "stcpage": -6.304448802421981, "stcunregisteredpage": -6.709913910530146, "stephen100mwangi": -6.709913910530146, "stream": -5.793623178655991, "suddenly": -6.709913910530146, "suspects": -6.709913910530146, "test": -5.457150942034778, "tests": -6.709913910530146, "than": -6.709913910530146, "that": -5.793623178655991, "the": -4.695010889987881, "then": -6.709913910530146, "there": -6.709913910530146, "thing": -6.709913910530146, "this": -6.709913910530146, "through": -6.709913910530146, "timeout": -6.304448802421981, "to": -4.4073288175361, "too": -6.709913910530146, "totally": -6.709913910530146, "traceback": -6.0167667299702, "tried": -6.709913910530146, "triggers": -6.709913910530146, "triggeruncaughtexception": -6.709913910530146, "true": -6.709913910530146, "trying": -6.709913910530146, "uid": -6.709913910530146, "unhandledpromiserejectionwarning": -6.709913910530146, "until": -5.793623178655991, "url": -5.611301621862036, "users": -6.709913910530146, "v18": -6.709913910530146, "variant": -6.304448802421981, "venv": -5.793623178655991, "wait": -6.709913910530146, "waitforurl": -6.304448802421981, "waiting": -6.0167667299702, "waituntil": -6.709913910530146, "was": -4.6304723688503096, "way": -6.709913910530146, "website": -6.709913910530146, "were": -6.709913910530146, "when": -6.0167667299702, "which": -6.709913910530146, "while": -6.304448802421981, "with": -6.0167667299702, "worked": -6.709913910530146, "works": -6.709913910530146, "writable": -6.0167667299702, "write": -6.304448802421981, "writeorbuffer": -6.709913910530146, "your": -6.709913910530146 }, "network": { "10": -5.903316160331277, "11": -5.680172609017068, "12": -4.804703871663167, "13": -6.190998232783058, "14": -4.345171542284727, "15": -4.345171542284727, "16": -5.343700372395855, "17": -4.345171542284727, "19": -6.596463340891223, "20": -6.596463340891223, "21": -6.190998232783058, "23": -6.596463340891223, "31": -5.210168979771332, "34": -6.596463340891223, "48": -6.596463340891223, "51": -6.596463340891223, "61": -6.596463340891223, "64": -6.596463340891223, "65": -6.596463340891223, "69": -6.596463340891223, "77": -6.596463340891223, "95": -6.596463340891223, "98": -6.596463340891223, "NUM": -5.210168979771332, "URL": -4.345171542284727, "access": -6.190998232783058, "again": -6.596463340891223, "am": -6.596463340891223, "and": -6.190998232783058, "anonymous": -6.596463340891223, "api": -6.190998232783058, "apirequestcontext": -6.596463340891223, "applicationurl": -6.596463340891223, "async": -6.190998232783058, "at": -4.070734696582967, "await": -5.903316160331277, "basepage": -6.596463340891223, "before": -6.190998232783058, "beforeeach": -6.596463340891223, "body": -6.596463340891223, "bundle": -6.190998232783058, "capture": -6.596463340891223, "capturestacktrace": -6.596463340891223, "channelowner": -6.190998232783058, "check": -5.680172609017068, "checkout": -6.596463340891223, "chromium": -6.596463340891223, "client": -5.497851052223113, "clientrequest": -6.190998232783058, "close": -6.596463340891223, "code": -6.190998232783058, "common": -6.596463340891223, "connect": -6.596463340891223, "connection": -4.8917152486527975, "const": -6.596463340891223, "dashboardpage": -5.343700372395855, "day": -6.596463340891223, "debug": -6.596463340891223, "deliver": -6.596463340891223, "disconnected": -6.596463340891223, "domcontentloaded": -6.190998232783058, "each": -6.596463340891223, "eai": -6.596463340891223, "econnrefused": -6.596463340891223, "econnreset": -6.596463340891223, "emit": -6.190998232783058, "environment": -6.596463340891223, "err": -4.650553191835909, "error": -4.581560320348958, "events": -6.190998232783058, "failed": -5.903316160331277, "fetch": -6.596463340891223, "fetching": -6.596463340891223, "for": -6.596463340891223, "frame": -5.680172609017068, "from": -6.596463340891223, "get": -6.596463340891223, "getaddrinfo": -6.596463340891223, "git": -6.190998232783058, "goto": -4.650553191835909, "gotosearchproduct": -6.596463340891223, "handler": -6.596463340891223, "hang": -6.190998232783058, "hook": -6.596463340891223, "http": -6.596463340891223, "internet": -6.596463340891223, "js": -4.581560320348958, "lib": -5.343700372395855, "load": -6.190998232783058, "loadapplication": -6.596463340891223, "loading": -6.596463340891223, "login": -5.680172609017068, "logs": -5.092385944114948, "modules": -4.724661163989631, "name": -5.497851052223113, "navigating": -5.210168979771332, "net": -4.517021799211387, "networkidle": -5.680172609017068, "new": -5.903316160331277, "node": -4.724661163989631, "not": -5.903316160331277, "note": -6.596463340891223, "object": -6.596463340891223, "on": -6.190998232783058, "out": -6.190998232783058, "page": -4.456397177394951, "pages": -6.596463340891223, "personal": -6.190998232783058, "playwright": -4.154116305522018, "pnpm": -5.343700372395855, "product": -6.596463340891223, "producteditpage": -6.190998232783058, "products": -6.596463340891223, "productsearchpage": -6.190998232783058, "project": -6.190998232783058, "promises": -6.596463340891223, "protocol": -6.596463340891223, "proxy": -6.596463340891223, "proxyerror": -6.596463340891223, "public": -6.596463340891223, "pw": -6.596463340891223, "reading": -6.596463340891223, "reason": -6.596463340891223, "recording": -6.596463340891223, "refused": -5.343700372395855, "request": -6.190998232783058, "resolved": -5.903316160331277, "resource": -6.596463340891223, "response": -6.596463340891223, "route": -6.596463340891223, "runner": -6.190998232783058, "same": -6.596463340891223, "sauce": -6.190998232783058, "saucelabintegration": -6.596463340891223, "scheduleedit": -6.596463340891223, "sendmessagetoserver": -6.596463340891223, "server": -6.596463340891223, "settings": -6.596463340891223, "single": -6.596463340891223, "socket": -5.680172609017068, "socketcloselistener": -6.596463340891223, "spec": -6.190998232783058, "ssl": -6.596463340891223, "stacktrace": -6.596463340891223, "started": -6.596463340891223, "starting": -6.596463340891223, "tcp": -6.596463340891223, "test": -6.596463340891223, "tests": -5.680172609017068, "this": -6.596463340891223, "timed": -6.190998232783058, "timeouts": -6.596463340891223, "to": -4.987025428457122, "token": -6.190998232783058, "trace": -6.596463340891223, "ts": -6.596463340891223, "until": -5.210168979771332, "up": -6.190998232783058, "update": -6.190998232783058, "upstream": -6.596463340891223, "url": -6.190998232783058, "use": -6.596463340891223, "user": -5.903316160331277, "utils": -6.596463340891223, "valueof": -6.596463340891223, "variable": -6.596463340891223, "waiting": -5.210168979771332, "waituntil": -6.596463340891223, "while": -6.596463340891223, "wo": -6.596463340891223, "work": -5.343700372395855, "wrapapicall": -6.596463340891223, "your": -6.596463340891223 }, "timeout": { "10": -6.434546518787453, "15": -6.840011626895618, "16": -6.840011626895618, "17": -6.840011626895618, "18": -6.840011626895618, "19": -6.840011626895618, "20": -6.434546518787453, "21": -6.434546518787453, "22": -6.840011626895618, "23": -6.840011626895618, "30": -5.741399338227508, "31": -6.840011626895618, "54": -6.840011626895618, "58": -6.840011626895618, "59": -6.840011626895618, "60": -6.146864446335672, "61": -6.434546518787453, "62": -6.840011626895618, "63": -6.840011626895618, "64": -6.840011626895618, "73": -6.840011626895618, "79": -6.840011626895618, "83": -6.840011626895618, "00": -6.434546518787453, "NUM": -3.7719586917620003, "URL": -6.434546518787453, "action": -5.453717265775727, "actiontimeout": -6.840011626895618, "actual": -6.146864446335672, "after": -6.840011626895618, "afterall": -6.840011626895618, "all": -6.840011626895618, "amount": -6.840011626895618, "an": -5.741399338227508, "and": -5.135263534657192, "angle": -6.840011626895618, "anush": -6.434546518787453, "anzeigen": -6.840011626895618, "api": -5.923720895021463, "app": -6.840011626895618, "appeared": -6.840011626895618, "apply": -6.840011626895618, "are": -6.840011626895618, "areas": -6.840011626895618, "aren": -6.840011626895618, "as": -6.840011626895618, "assertions": -6.840011626895618, "async": -6.840011626895618, "at": -4.968209449994026, "attempt": -6.840011626895618, "attempting": -6.434546518787453, "attributetopage": -6.840011626895618, "auth": -6.146864446335672, "av": -6.434546518787453, "available": -6.840011626895618, "await": -5.453717265775727, "baseurl": -6.434546518787453, "basic": -6.146864446335672, "be": -5.741399338227508, "been": -5.923720895021463, "beforeall": -6.840011626895618, "beforeeach": -6.434546518787453, "between": -6.840011626895618, "bin": -6.840011626895618, "binding": -6.840011626895618, "br": -4.825108606353353, "browser": -5.58724865840025, "browsertype": -6.840011626895618, "btn": -6.840011626895618, "but": -6.840011626895618, "button": -5.923720895021463, "by": -6.434546518787453, "cache": -6.434546518787453, "call": -6.434546518787453, "can": -6.840011626895618, "capture": -6.840011626895618, "cart": -6.840011626895618, "case": -6.434546518787453, "certificates": -6.840011626895618, "chromium": -5.335934230119343, "class": -6.840011626895618, "click": -5.135263534657192, "closed": -5.230573714461517, "config": -5.58724865840025, "configured": -6.840011626895618, "const": -5.923720895021463, "consume": -6.840011626895618, "context": -5.923720895021463, "copy": -6.840011626895618, "core20": -6.840011626895618, "correlation": -6.840011626895618, "could": -6.146864446335672, "ctaheader": -6.840011626895618, "current": -6.840011626895618, "data": -6.146864446335672, "debug": -6.840011626895618, "default": -6.434546518787453, "defer": -6.840011626895618, "describe": -6.840011626895618, "deutschland": -6.434546518787453, "div": -6.146864446335672, "domcontentloaded": -6.434546518787453, "done": -6.840011626895618, "down": -6.840011626895618, "dropdown": -6.840011626895618, "during": -6.434546518787453, "each": -6.434546518787453, "element": -5.741399338227508, "enabled": -5.58724865840025, "entire": -6.840011626895618, "environment": -6.434546518787453, "err": -6.840011626895618, "error": -4.825108606353353, "event": -6.146864446335672, "exceeded": -4.699945463399347, "expect": -6.146864446335672, "fail": -6.840011626895618, "fill": -6.840011626895618, "filter": -6.840011626895618, "fired": -6.840011626895618, "first": -6.840011626895618, "fixture": -6.146864446335672, "for": -4.588719828289123, "force": -6.840011626895618, "form": -5.741399338227508, "frame": -6.434546518787453, "frames": -6.434546518787453, "from": -6.146864446335672, "function": -6.840011626895618, "glibc": -6.840011626895618, "global": -6.434546518787453, "globaltimeout": -6.840011626895618, "gnu": -6.840011626895618, "goto": -5.230573714461517, "gtk": -6.840011626895618, "has": -5.741399338227508, "hastext": -6.434546518787453, "have": -6.434546518787453, "helper": -6.840011626895618, "hold": -6.434546518787453, "home": -6.146864446335672, "hook": -6.146864446335672, "httpcredentials": -6.434546518787453, "icon": -6.840011626895618, "id": -6.840011626895618, "if": -6.146864446335672, "in": -4.825108606353353, "inaccurate": -6.146864446335672, "indexof": -6.840011626895618, "individual": -6.840011626895618, "init": -6.840011626895618, "insert": -6.840011626895618, "inspector": -6.840011626895618, "into": -6.434546518787453, "invalid": -6.840011626895618, "is": -5.048252157667562, "isn": -6.840011626895618, "issues": -6.840011626895618, "it": -6.434546518787453, "javascript": -6.840011626895618, "js": -5.230573714461517, "just": -5.923720895021463, "label": -6.840011626895618, "launch": -6.840011626895618, "league": -6.840011626895618, "leagues": -6.840011626895618, "lib": -5.335934230119343, "libc": -6.840011626895618, "libpthread": -6.840011626895618, "likely": -6.840011626895618, "link": -6.840011626895618, "linux": -6.840011626895618, "load": -6.434546518787453, "loading": -6.840011626895618, "locator": -4.699945463399347, "log": -6.434546518787453, "logs": -5.923720895021463, "lookup": -6.840011626895618, "may": -6.840011626895618, "message": -6.840011626895618, "minibrowser": -6.434546518787453, "minutes": -6.840011626895618, "module": -6.840011626895618, "modules": -5.453717265775727, "more": -6.840011626895618, "ms": -5.923720895021463, "my": -6.840011626895618, "navigated": -6.840011626895618, "navigating": -6.840011626895618, "navigation": -5.335934230119343, "navigationtimeout": -6.840011626895618, "needed": -6.840011626895618, "network": -6.840011626895618, "new": -6.840011626895618, "newcontext": -6.840011626895618, "news": -6.840011626895618, "ng": -6.434546518787453, "no": -5.453717265775727, "node": -5.335934230119343, "not": -5.923720895021463, "note": -6.840011626895618, "nth": -6.840011626895618, "occur": -6.840011626895618, "of": -5.230573714461517, "on": -6.434546518787453, "open": -6.146864446335672, "option": -6.840011626895618, "options": -5.923720895021463, "or": -5.741399338227508, "out": -6.840011626895618, "override": -6.434546518787453, "page": -4.1658629774690885, "pages": -6.840011626895618, "password": -5.923720895021463, "pbutton": -6.840011626895618, "pid": -6.434546518787453, "pipe": -6.840011626895618, "playwright": -4.642787049559399, "private": -6.840011626895618, "problematic": -6.840011626895618, "progress": -6.840011626895618, "progresscontroller": -6.840011626895618, "protocol": -6.840011626895618, "pthread": -6.840011626895618, "pw": -6.434546518787453, "question": -6.840011626895618, "rather": -6.840011626895618, "reason": -6.146864446335672, "regexp": -6.840011626895618, "release": -6.434546518787453, "rerun": -6.840011626895618, "resolved": -6.434546518787453, "retrieve": -6.840011626895618, "retry": -6.840011626895618, "run": -6.146864446335672, "runnavigationtask": -6.840011626895618, "running": -6.434546518787453, "say": -6.840011626895618, "scope": -6.840011626895618, "scrolling": -6.434546518787453, "seconds": -6.840011626895618, "select": -6.146864446335672, "selector": -5.923720895021463, "self": -6.840011626895618, "session": -6.840011626895618, "set": -5.58724865840025, "sets": -6.840011626895618, "settimeout": -6.840011626895618, "sh": -6.840011626895618, "share": -6.434546518787453, "show": -6.840011626895618, "sidebar": -6.434546518787453, "signed": -6.840011626895618, "similar": -6.840011626895618, "single": -6.840011626895618, "site": -6.146864446335672, "slow": -6.840011626895618, "snap": -6.840011626895618, "so": -6.840011626895618, "sometimes": -6.840011626895618, "span": -6.840011626895618, "spec": -6.434546518787453, "specific": -6.434546518787453, "src": -6.840011626895618, "ssl": -6.840011626895618, "stable": -6.146864446335672, "startup": -6.840011626895618, "statement": -6.840011626895618, "status": -6.840011626895618, "stuck": -6.146864446335672, "submit": -6.840011626895618, "symbol": -6.434546518787453, "target": -4.825108606353353, "teaser": -6.840011626895618, "test": -4.642787049559399, "tests": -6.146864446335672, "text": -6.434546518787453, "that": -5.923720895021463, "the": -4.314282982587362, "there": -5.923720895021463, "this": -5.923720895021463, "throw": -6.840011626895618, "throws": -6.840011626895618, "time": -6.840011626895618, "timed": -6.840011626895618, "timeout": -3.9222408948113383, "timeouterror": -5.923720895021463, "timeouts": -5.923720895021463, "to": -4.588719828289123, "tobevisible": -6.840011626895618, "tried": -6.840011626895618, "ts": -6.434546518787453, "undefined": -6.840011626895618, "unhandledpromiserejectionwarning": -6.840011626895618, "until": -6.840011626895618, "url": -5.923720895021463, "use": -5.923720895021463, "user": -6.434546518787453, "username": -6.434546518787453, "using": -6.840011626895618, "usr": -6.840011626895618, "variable": -6.840011626895618, "version": -6.840011626895618, "view": -6.840011626895618, "visible": -5.453717265775727, "wait": -6.840011626895618, "waitforloadstate": -6.840011626895618, "waitforselector": -6.434546518787453, "waitfortimeout": -6.434546518787453, "waiting": -4.894101477840304, "waituntil": -6.840011626895618, "wamdata": -6.840011626895618, "was": -5.58724865840025, "way": -6.840011626895618, "we": -6.840011626895618, "webkit": -6.434546518787453, "when": -6.840011626895618, "while": -6.146864446335672, "whole": -6.840011626895618, "will": -6.840011626895618, "window": -6.840011626895618, "with": -6.146864446335672, "wrapper": -5.923720895021463, "x86": -6.840011626895618, "yet": -6.840011626895618, "your": -6.434546518787453 } }, "playwrightVersion": "1.61.1", "priors": { "assertion": -2.2472349979108808, "env-config": -1.6766901394432678, "flaky-by-retry": -2.7327428136925813, "locator-not-found": -2.0395956331326364, "navigation": -1.7211419020141017, "network": -2.1041341542702074, "timeout": -1.5540878173509354 }, "totals": { "assertion": 323, "env-config": 694, "flaky-by-retry": 68, "locator-not-found": 368, "navigation": 731, "network": 555, "timeout": 959 }, "version": 3, "vocabSize": 910 };
|
|
10862
|
+
|
|
10863
|
+
// src/analysis/NaiveBayesClassifier.ts
|
|
10864
|
+
init_esm_shims();
|
|
10865
|
+
|
|
10866
|
+
// src/analysis/tokenize.ts
|
|
10867
|
+
init_esm_shims();
|
|
10868
|
+
function tokenize(text) {
|
|
10869
|
+
return text.toLowerCase().replace(/https?:\/\/\S+/gi, " URL ").replace(/[^a-zA-Z0-9\s]/g, " ").replace(/\b\d{3,}[a-z]*\b/g, " NUM ").split(/\s+/).filter((t) => t.length > 1);
|
|
10870
|
+
}
|
|
10871
|
+
|
|
10872
|
+
// src/analysis/NaiveBayesClassifier.ts
|
|
10873
|
+
function classify(model, text) {
|
|
10874
|
+
return classifyTokens(model, tokenize(text));
|
|
10875
|
+
}
|
|
10876
|
+
function classifyTokens(model, tokens) {
|
|
10877
|
+
const vocabTokens = tokens.filter(
|
|
10878
|
+
(tok) => tok.length > 0 && model.labels.some((l) => model.logLikelihoods[l]?.[tok] !== void 0)
|
|
10879
|
+
);
|
|
10880
|
+
if (vocabTokens.length === 0) {
|
|
10881
|
+
return { label: "unknown", margin: 0 };
|
|
10882
|
+
}
|
|
10883
|
+
const scores = {};
|
|
10884
|
+
for (const label of model.labels) {
|
|
10885
|
+
let s = model.priors[label];
|
|
10886
|
+
const oov = Math.log(model.alpha / (model.totals[label] + model.alpha * model.vocabSize));
|
|
10887
|
+
const ll = model.logLikelihoods[label];
|
|
10888
|
+
for (const tok of vocabTokens) {
|
|
10889
|
+
s += ll[tok] ?? oov;
|
|
10890
|
+
}
|
|
10891
|
+
scores[label] = s;
|
|
10892
|
+
}
|
|
10893
|
+
const ranked = Object.entries(scores).sort((a, b) => b[1] - a[1]);
|
|
10894
|
+
const topLog = ranked[0][1];
|
|
10895
|
+
const secondLog = ranked[1]?.[1] ?? topLog;
|
|
10896
|
+
const margin = (topLog - secondLog) / vocabTokens.length;
|
|
10897
|
+
return { label: ranked[0][0], margin };
|
|
10898
|
+
}
|
|
10899
|
+
function isValidNaiveBayesModel(m) {
|
|
10900
|
+
const x = m;
|
|
10901
|
+
return !!x && Array.isArray(x.labels) && x.labels.length > 0 && typeof x.version === "number" && !!x.priors && !!x.totals && !!x.logLikelihoods && typeof x.vocabSize === "number" && typeof x.alpha === "number";
|
|
10902
|
+
}
|
|
10854
10903
|
|
|
10855
10904
|
// src/analysis/ModelStore.ts
|
|
10856
10905
|
var MODEL_SIG_DOMAIN = "reportforge-model-sig:v1\n";
|
|
@@ -10875,10 +10924,7 @@ function verifyModelSignature(modelJson, signatureB64url) {
|
|
|
10875
10924
|
return false;
|
|
10876
10925
|
}
|
|
10877
10926
|
}
|
|
10878
|
-
|
|
10879
|
-
const x = m;
|
|
10880
|
-
return !!x && Array.isArray(x.labels) && x.labels.length > 0 && typeof x.version === "number" && !!x.priors && !!x.totals && !!x.logLikelihoods && typeof x.vocabSize === "number" && typeof x.alpha === "number";
|
|
10881
|
-
}
|
|
10927
|
+
var schemaValid = isValidNaiveBayesModel;
|
|
10882
10928
|
function readCache2() {
|
|
10883
10929
|
try {
|
|
10884
10930
|
const raw = fs3.readFileSync(cacheFile(), "utf8");
|
|
@@ -11195,42 +11241,61 @@ function maybePrintUpdateNotice(licenseInfo, currentVersion) {
|
|
|
11195
11241
|
// src/analysis/index.ts
|
|
11196
11242
|
init_esm_shims();
|
|
11197
11243
|
|
|
11198
|
-
// src/analysis/
|
|
11244
|
+
// src/analysis/LocalModelStore.ts
|
|
11199
11245
|
init_esm_shims();
|
|
11246
|
+
import fs4 from "fs";
|
|
11247
|
+
import os5 from "os";
|
|
11248
|
+
import path5 from "path";
|
|
11249
|
+
var testDeps2 = null;
|
|
11250
|
+
function defaultLocalModelPath() {
|
|
11251
|
+
return testDeps2?.file ?? path5.join(os5.homedir(), ".reportforge", "model-local.json");
|
|
11252
|
+
}
|
|
11253
|
+
function loadLocalModel(overridePath) {
|
|
11254
|
+
const file = overridePath ?? defaultLocalModelPath();
|
|
11255
|
+
const explicit = overridePath !== void 0;
|
|
11256
|
+
const reject = (why) => {
|
|
11257
|
+
const msg = `local model at ${file} not used: ${why}`;
|
|
11258
|
+
if (explicit) logger.warn(msg);
|
|
11259
|
+
else logger.debug(msg);
|
|
11260
|
+
return null;
|
|
11261
|
+
};
|
|
11262
|
+
let parsed;
|
|
11263
|
+
try {
|
|
11264
|
+
parsed = JSON.parse(fs4.readFileSync(file, "utf8"));
|
|
11265
|
+
} catch (e) {
|
|
11266
|
+
return explicit ? reject(`unreadable (${e.message})`) : null;
|
|
11267
|
+
}
|
|
11268
|
+
if (parsed.formatVersion !== 1) return reject(`unsupported formatVersion ${String(parsed.formatVersion)}`);
|
|
11269
|
+
if (!isValidNaiveBayesModel(parsed.model)) return reject("embedded model failed schema validation");
|
|
11270
|
+
const meta = parsed.meta;
|
|
11271
|
+
if (!meta || typeof meta.gatePassed !== "boolean") return reject("missing meta");
|
|
11272
|
+
if (!meta.gatePassed) return reject("its evaluation gate did not pass - run train-model after labeling more feedback");
|
|
11273
|
+
if (typeof meta.acceptThreshold !== "number") return reject("gate passed but no calibrated threshold (corrupt meta)");
|
|
11274
|
+
return {
|
|
11275
|
+
model: parsed.model,
|
|
11276
|
+
acceptThreshold: meta.acceptThreshold,
|
|
11277
|
+
strongThreshold: typeof meta.strongThreshold === "number" ? meta.strongThreshold : null,
|
|
11278
|
+
meta
|
|
11279
|
+
};
|
|
11280
|
+
}
|
|
11200
11281
|
|
|
11201
|
-
// src/analysis/
|
|
11282
|
+
// src/analysis/FailureClusterer.ts
|
|
11202
11283
|
init_esm_shims();
|
|
11203
11284
|
|
|
11204
|
-
// src/analysis/
|
|
11285
|
+
// src/analysis/redact.ts
|
|
11205
11286
|
init_esm_shims();
|
|
11206
|
-
|
|
11207
|
-
|
|
11287
|
+
var URI_RE = /[a-z][\w+.-]*:\/\/\S+/gi;
|
|
11288
|
+
var EMAIL_RE = /\b[\w.+-]+@[\w.-]+\.\w+\b/g;
|
|
11289
|
+
var SECRET_RE = /\b(?=[A-Za-z0-9_+/=-]*[0-9])(?=[A-Za-z0-9_+/=-]*[A-Za-z])[A-Za-z0-9_+/=-]{16,}\b/g;
|
|
11290
|
+
var IP_RE = /\b\d{1,3}(?:\.\d{1,3}){3}\b/g;
|
|
11291
|
+
var WIN_PATH_RE = /[A-Za-z]:\\[^\s'"]+/g;
|
|
11292
|
+
var UNIX_PATH_RE = /(?:\/[\w.-]+){2,}/g;
|
|
11293
|
+
function redactForStorage(raw) {
|
|
11294
|
+
const redacted = raw.replace(URI_RE, " URL ").replace(EMAIL_RE, " EMAIL ").replace(SECRET_RE, " SECRET ").replace(IP_RE, " IP ").replace(WIN_PATH_RE, " PATH ").replace(UNIX_PATH_RE, " PATH ");
|
|
11295
|
+
return tokenize(redacted).join(" ");
|
|
11208
11296
|
}
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
function classify(model, text) {
|
|
11212
|
-
const tokens = tokenize(text);
|
|
11213
|
-
const vocabTokens = tokens.filter(
|
|
11214
|
-
(tok) => model.labels.some((l) => model.logLikelihoods[l]?.[tok] !== void 0)
|
|
11215
|
-
);
|
|
11216
|
-
if (vocabTokens.length === 0) {
|
|
11217
|
-
return { label: "unknown", margin: 0 };
|
|
11218
|
-
}
|
|
11219
|
-
const scores = {};
|
|
11220
|
-
for (const label of model.labels) {
|
|
11221
|
-
let s = model.priors[label];
|
|
11222
|
-
const oov = Math.log(model.alpha / (model.totals[label] + model.alpha * model.vocabSize));
|
|
11223
|
-
const ll = model.logLikelihoods[label];
|
|
11224
|
-
for (const tok of vocabTokens) {
|
|
11225
|
-
s += ll[tok] ?? oov;
|
|
11226
|
-
}
|
|
11227
|
-
scores[label] = s;
|
|
11228
|
-
}
|
|
11229
|
-
const ranked = Object.entries(scores).sort((a, b) => b[1] - a[1]);
|
|
11230
|
-
const topLog = ranked[0][1];
|
|
11231
|
-
const secondLog = ranked[1]?.[1] ?? topLog;
|
|
11232
|
-
const margin = (topLog - secondLog) / vocabTokens.length;
|
|
11233
|
-
return { label: ranked[0][0], margin };
|
|
11297
|
+
function localInferenceTokens(message) {
|
|
11298
|
+
return redactForStorage(message).split(" ").filter(Boolean);
|
|
11234
11299
|
}
|
|
11235
11300
|
|
|
11236
11301
|
// src/analysis/constants.ts
|
|
@@ -11259,7 +11324,7 @@ function errorHeader(message) {
|
|
|
11259
11324
|
return beforeCallLog.split("\n").filter((line) => !/^\s*[-+]?\s*(?:Expected|Received)\b/i.test(line)).join("\n");
|
|
11260
11325
|
}
|
|
11261
11326
|
function isAssertionTimeout(message) {
|
|
11262
|
-
return /Expect "[^"]+" with timeout/.test(message) && /resolved to [1-9]\d* element/.test(message);
|
|
11327
|
+
return /(?:Expect "[^"]+"|expect\.\w+) with timeout/.test(message) && /resolved to [1-9]\d* element/.test(message);
|
|
11263
11328
|
}
|
|
11264
11329
|
function isNetwork(message) {
|
|
11265
11330
|
return /net::ERR_(CONNECTION|NAME_NOT_RESOLVED|INTERNET_DISCONNECTED|SSL|TIMED_OUT|ADDRESS|NETWORK_CHANGED|EMPTY_RESPONSE)|\bECONN(?:REFUSED|RESET)\b|\bENOTFOUND\b|\bEAI_AGAIN\b|getaddrinfo|socket hang up|fetch failed/.test(errorHeader(message));
|
|
@@ -11296,26 +11361,37 @@ function topFrame(stack) {
|
|
|
11296
11361
|
function representativeMessage(message) {
|
|
11297
11362
|
return clampWithEllipsis(message.split("\n")[0], MAX_MESSAGE_CHARS);
|
|
11298
11363
|
}
|
|
11299
|
-
function classifyOne(f,
|
|
11364
|
+
function classifyOne(f, chain) {
|
|
11300
11365
|
const frame = topFrame(f.error.stack);
|
|
11301
11366
|
if (f.retryHistory.some((r) => r.status === "passed")) {
|
|
11302
|
-
return { category: "flaky-by-retry", margin: OVERRIDE_MARGIN, failure: f, frame };
|
|
11367
|
+
return { category: "flaky-by-retry", margin: OVERRIDE_MARGIN, strength: "strong", source: "retry", failure: f, frame };
|
|
11303
11368
|
}
|
|
11304
11369
|
for (const [match, category] of MESSAGE_RULES) {
|
|
11305
|
-
if (match(f.error.message))
|
|
11370
|
+
if (match(f.error.message)) {
|
|
11371
|
+
return { category, margin: OVERRIDE_MARGIN, strength: "strong", source: "rule", failure: f, frame };
|
|
11372
|
+
}
|
|
11373
|
+
}
|
|
11374
|
+
if (chain.local) {
|
|
11375
|
+
const { model, acceptThreshold, strongThreshold } = chain.local;
|
|
11376
|
+
const r = classifyTokens(model, localInferenceTokens(f.error.message));
|
|
11377
|
+
if (r.label !== "unknown" && r.margin >= acceptThreshold) {
|
|
11378
|
+
const strength = strongThreshold !== null && r.margin >= strongThreshold ? "strong" : "moderate";
|
|
11379
|
+
return { category: r.label, margin: r.margin, strength, source: "local", failure: f, frame };
|
|
11380
|
+
}
|
|
11306
11381
|
}
|
|
11307
|
-
const { label, margin } = classify(
|
|
11308
|
-
return { category: label, margin, failure: f, frame };
|
|
11382
|
+
const { label, margin } = classify(chain.base, classifyInput(f));
|
|
11383
|
+
return { category: label, margin, strength: strengthOf(margin), source: "base", failure: f, frame };
|
|
11309
11384
|
}
|
|
11310
|
-
function classifyAll(failures,
|
|
11311
|
-
return failures.map((f) => classifyOne(f,
|
|
11385
|
+
function classifyAll(failures, chain) {
|
|
11386
|
+
return failures.map((f) => classifyOne(f, chain));
|
|
11312
11387
|
}
|
|
11313
11388
|
function perTestClassifications(classified) {
|
|
11314
11389
|
return classified.map((c) => ({
|
|
11315
11390
|
testId: c.failure.testId,
|
|
11316
11391
|
category: c.category,
|
|
11317
11392
|
message: representativeMessage(c.failure.error.message),
|
|
11318
|
-
strength:
|
|
11393
|
+
strength: c.strength
|
|
11394
|
+
// resolved at classification time, per producing source
|
|
11319
11395
|
}));
|
|
11320
11396
|
}
|
|
11321
11397
|
function clusterClassified(classified) {
|
|
@@ -11326,13 +11402,16 @@ function clusterClassified(classified) {
|
|
|
11326
11402
|
if (bucket) bucket.push(c);
|
|
11327
11403
|
else groups.set(key, [c]);
|
|
11328
11404
|
}
|
|
11405
|
+
const rank = Object.fromEntries(
|
|
11406
|
+
STRENGTH_LEVELS.map((level, i) => [level, i])
|
|
11407
|
+
);
|
|
11329
11408
|
const clusters = [];
|
|
11330
11409
|
for (const members of groups.values()) {
|
|
11331
|
-
const
|
|
11410
|
+
const strongest = members.reduce((a, b) => rank[b.strength] > rank[a.strength] ? b : a);
|
|
11332
11411
|
clusters.push({
|
|
11333
11412
|
category: members[0].category,
|
|
11334
|
-
strength:
|
|
11335
|
-
margin,
|
|
11413
|
+
strength: strongest.strength,
|
|
11414
|
+
margin: Math.max(...members.map((m) => m.margin)),
|
|
11336
11415
|
count: members.length,
|
|
11337
11416
|
tests: members.slice(0, MAX_TESTS_PER_CLUSTER).map((m) => m.failure.testTitle),
|
|
11338
11417
|
testsTotal: members.length,
|
|
@@ -11408,82 +11487,133 @@ function buildBriefSentence(stats, analysis, trend) {
|
|
|
11408
11487
|
|
|
11409
11488
|
// src/analysis/UnclassifiedCollector.ts
|
|
11410
11489
|
init_esm_shims();
|
|
11411
|
-
import
|
|
11412
|
-
import
|
|
11413
|
-
import
|
|
11490
|
+
import fs6 from "fs";
|
|
11491
|
+
import os7 from "os";
|
|
11492
|
+
import path7 from "path";
|
|
11414
11493
|
|
|
11415
11494
|
// src/analysis/feedback-csv.ts
|
|
11416
11495
|
init_esm_shims();
|
|
11417
|
-
var FEEDBACK_HEADER = "category,margin,text";
|
|
11496
|
+
var FEEDBACK_HEADER = "category,margin,label,text";
|
|
11497
|
+
var LEGACY_FEEDBACK_HEADER = "category,margin,text";
|
|
11418
11498
|
function parseFeedbackRows(content) {
|
|
11419
|
-
|
|
11499
|
+
const lines = content.trim().split("\n").filter(Boolean);
|
|
11500
|
+
if (lines.length === 0) return [];
|
|
11501
|
+
const header = lines[0].trim();
|
|
11502
|
+
const isV2 = header === FEEDBACK_HEADER;
|
|
11503
|
+
if (!isV2 && header !== LEGACY_FEEDBACK_HEADER) return [];
|
|
11504
|
+
const minParts = isV2 ? 4 : 3;
|
|
11505
|
+
const rows = [];
|
|
11506
|
+
for (const line of lines.slice(1)) {
|
|
11420
11507
|
const parts = line.split(",");
|
|
11421
|
-
|
|
11422
|
-
|
|
11508
|
+
if (parts.length < minParts) continue;
|
|
11509
|
+
const row = isV2 ? { category: parts[0], margin: parts[1], label: parts[2], text: parts.slice(3).join(",") } : { category: parts[0], margin: parts[1], label: "", text: parts.slice(2).join(",") };
|
|
11510
|
+
if (row.text.trim().length === 0) continue;
|
|
11511
|
+
rows.push(row);
|
|
11512
|
+
}
|
|
11513
|
+
return rows;
|
|
11514
|
+
}
|
|
11515
|
+
function serializeFeedbackRow(r) {
|
|
11516
|
+
const label = r.label.replace(/[,\r\n]/g, "").trim();
|
|
11517
|
+
return `${r.category},${r.margin},${label},${r.text}`;
|
|
11423
11518
|
}
|
|
11424
11519
|
function feedbackIdentity(category, text) {
|
|
11425
11520
|
return `${category} ${text}`;
|
|
11426
11521
|
}
|
|
11427
11522
|
|
|
11523
|
+
// src/analysis/FeedbackStore.ts
|
|
11524
|
+
init_esm_shims();
|
|
11525
|
+
import fs5 from "fs";
|
|
11526
|
+
import os6 from "os";
|
|
11527
|
+
import path6 from "path";
|
|
11528
|
+
var MARKER_FILENAME = "project.json";
|
|
11529
|
+
function writeProjectMarker(projectDir, marker) {
|
|
11530
|
+
try {
|
|
11531
|
+
atomicWrite(path6.join(projectDir, MARKER_FILENAME), JSON.stringify(marker));
|
|
11532
|
+
} catch {
|
|
11533
|
+
}
|
|
11534
|
+
}
|
|
11535
|
+
function rewriteFeedbackFile(file, rows) {
|
|
11536
|
+
const body = rows.map(serializeFeedbackRow).join("\n");
|
|
11537
|
+
atomicWrite(file, `${FEEDBACK_HEADER}
|
|
11538
|
+
${body}${body ? "\n" : ""}`);
|
|
11539
|
+
}
|
|
11540
|
+
function atomicWrite(file, content) {
|
|
11541
|
+
fs5.mkdirSync(path6.dirname(file), { recursive: true });
|
|
11542
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
11543
|
+
fs5.writeFileSync(tmp, content, "utf8");
|
|
11544
|
+
fs5.renameSync(tmp, file);
|
|
11545
|
+
}
|
|
11546
|
+
|
|
11428
11547
|
// src/analysis/UnclassifiedCollector.ts
|
|
11429
11548
|
var MAX_ROWS = 500;
|
|
11430
11549
|
var FILENAME = "unclassified.csv";
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
var WIN_PATH_RE = /[A-Za-z]:\\[^\s'"]+/g;
|
|
11436
|
-
var UNIX_PATH_RE = /(?:\/[\w.-]+){2,}/g;
|
|
11437
|
-
function redactForStorage(raw) {
|
|
11438
|
-
const redacted = raw.replace(URI_RE, " URL ").replace(EMAIL_RE, " EMAIL ").replace(SECRET_RE, " SECRET ").replace(IP_RE, " IP ").replace(WIN_PATH_RE, " PATH ").replace(UNIX_PATH_RE, " PATH ");
|
|
11439
|
-
return tokenize(redacted).join(" ");
|
|
11440
|
-
}
|
|
11441
|
-
function shouldCollect(c) {
|
|
11442
|
-
return c.category === "unknown" || c.margin <= STRENGTH.collectMaxMargin;
|
|
11550
|
+
function shouldCollect(c, scope) {
|
|
11551
|
+
if (c.source !== "base") return false;
|
|
11552
|
+
if (c.category === "unknown" || c.margin <= STRENGTH.collectMaxMargin) return true;
|
|
11553
|
+
return scope === "all";
|
|
11443
11554
|
}
|
|
11444
11555
|
function tildeify(p) {
|
|
11445
|
-
const home =
|
|
11556
|
+
const home = os7.homedir();
|
|
11446
11557
|
return p.startsWith(home) ? `~${p.slice(home.length)}` : p;
|
|
11447
11558
|
}
|
|
11448
|
-
function collectUnclassified(classified, projectDir) {
|
|
11449
|
-
const
|
|
11559
|
+
function collectUnclassified(classified, projectDir, opts = {}) {
|
|
11560
|
+
const scope = opts.scope ?? "blind-spots";
|
|
11561
|
+
const rows = classified.filter((c) => shouldCollect(c, scope)).map((c) => ({ text: redactForStorage(c.failure.error.message), category: c.category, margin: c.margin })).filter((r) => r.text.length > 0);
|
|
11450
11562
|
if (rows.length === 0) return;
|
|
11451
|
-
const file =
|
|
11452
|
-
const firstTime = !
|
|
11563
|
+
const file = path7.join(projectDir, FILENAME);
|
|
11564
|
+
const firstTime = !fs6.existsSync(file);
|
|
11453
11565
|
const byIdentity = /* @__PURE__ */ new Map();
|
|
11454
11566
|
if (!firstTime) {
|
|
11455
|
-
for (const r of parseFeedbackRows(
|
|
11456
|
-
byIdentity.set(feedbackIdentity(r.category, r.text), r
|
|
11567
|
+
for (const r of parseFeedbackRows(fs6.readFileSync(file, "utf8"))) {
|
|
11568
|
+
byIdentity.set(feedbackIdentity(r.category, r.text), r);
|
|
11457
11569
|
}
|
|
11458
11570
|
}
|
|
11459
|
-
let added = false;
|
|
11460
11571
|
for (const r of rows) {
|
|
11461
11572
|
const id = feedbackIdentity(r.category, r.text);
|
|
11573
|
+
const label = byIdentity.get(id)?.label ?? "";
|
|
11462
11574
|
byIdentity.delete(id);
|
|
11463
|
-
byIdentity.set(id,
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
`, "utf8");
|
|
11575
|
+
byIdentity.set(id, { category: r.category, margin: String(r.margin), label, text: r.text });
|
|
11576
|
+
}
|
|
11577
|
+
const all = evictOldestUnlabeledFirst([...byIdentity.values()], MAX_ROWS);
|
|
11578
|
+
fs6.mkdirSync(projectDir, { recursive: true });
|
|
11579
|
+
rewriteFeedbackFile(file, all);
|
|
11580
|
+
if (opts.project) {
|
|
11581
|
+
writeProjectMarker(projectDir, { cwd: opts.project.cwd, outputFile: opts.project.outputFile, updatedAt: Date.now() });
|
|
11582
|
+
}
|
|
11472
11583
|
if (firstTime) {
|
|
11473
11584
|
logger.info(
|
|
11474
11585
|
`Unrecognized failures collected locally at ${tildeify(file)} to improve offline classification. Local only - never sent anywhere. Disable: failureAnalysis.collectUnclassified=false`
|
|
11475
11586
|
);
|
|
11476
11587
|
}
|
|
11477
11588
|
}
|
|
11589
|
+
function evictOldestUnlabeledFirst(rows, max) {
|
|
11590
|
+
const excess = rows.length - max;
|
|
11591
|
+
if (excess <= 0) return rows;
|
|
11592
|
+
let unlabeledToDrop = Math.min(excess, rows.filter((r) => r.label === "").length);
|
|
11593
|
+
let labeledToDrop = excess - unlabeledToDrop;
|
|
11594
|
+
const out = [];
|
|
11595
|
+
for (const r of rows) {
|
|
11596
|
+
if (r.label === "" && unlabeledToDrop > 0) {
|
|
11597
|
+
unlabeledToDrop--;
|
|
11598
|
+
continue;
|
|
11599
|
+
}
|
|
11600
|
+
if (r.label !== "" && labeledToDrop > 0) {
|
|
11601
|
+
labeledToDrop--;
|
|
11602
|
+
continue;
|
|
11603
|
+
}
|
|
11604
|
+
out.push(r);
|
|
11605
|
+
}
|
|
11606
|
+
return out;
|
|
11607
|
+
}
|
|
11478
11608
|
|
|
11479
11609
|
// src/utils/paths.ts
|
|
11480
11610
|
init_esm_shims();
|
|
11481
|
-
import
|
|
11482
|
-
import
|
|
11611
|
+
import os8 from "os";
|
|
11612
|
+
import path8 from "path";
|
|
11483
11613
|
import crypto from "crypto";
|
|
11484
11614
|
function resolveProjectDir(options, cwd) {
|
|
11485
11615
|
const projectKey = crypto.createHash("sha256").update(cwd + (options.outputFile ?? "")).digest("hex").slice(0, 8);
|
|
11486
|
-
return
|
|
11616
|
+
return path8.join(os8.homedir(), ".reportforge", projectKey);
|
|
11487
11617
|
}
|
|
11488
11618
|
|
|
11489
11619
|
// src/analysis/index.ts
|
|
@@ -11518,16 +11648,36 @@ function runFailureAnalysis(reportData, options, cwd) {
|
|
|
11518
11648
|
if (reportData.stats.failed === 0 || !fa.enabled) return;
|
|
11519
11649
|
const cap = fa.maxFailuresToAnalyse;
|
|
11520
11650
|
const analysed = reportData.failures.slice(0, cap);
|
|
11521
|
-
const
|
|
11522
|
-
const
|
|
11651
|
+
const base = loadModel(fa.autoUpdateModel);
|
|
11652
|
+
const local = fa.localModel ? loadLocalModel(fa.localModelPath) ?? void 0 : void 0;
|
|
11653
|
+
if (local) {
|
|
11654
|
+
logger.debug(
|
|
11655
|
+
`local model active (trained ${local.meta.trainedAt}, ${local.meta.labeledCount} labeled rows, accept margin >= ${local.acceptThreshold})`
|
|
11656
|
+
);
|
|
11657
|
+
if (local.meta.baseVersionAtEval !== base.version) {
|
|
11658
|
+
logger.debug(
|
|
11659
|
+
`local model was gate-checked against base v${local.meta.baseVersionAtEval} but base v${base.version} is active - re-run train-model to re-validate against the current base`
|
|
11660
|
+
);
|
|
11661
|
+
}
|
|
11662
|
+
}
|
|
11663
|
+
const classified = classifyAll(analysed, { base, local });
|
|
11664
|
+
logger.debug(`failure analysis: ${classified.length} classified - ${sourceTally(classified)}`);
|
|
11523
11665
|
reportData.classifications = perTestClassifications(classified);
|
|
11524
11666
|
if (templatesConsumeAnalysis(options)) {
|
|
11525
11667
|
reportData.analysis = analyseClassified(classified, reportData.failures.length, fa);
|
|
11526
11668
|
}
|
|
11527
11669
|
if (fa.collectUnclassified) {
|
|
11528
|
-
collectUnclassified(classified, resolveProjectDir(options, cwd)
|
|
11670
|
+
collectUnclassified(classified, resolveProjectDir(options, cwd), {
|
|
11671
|
+
scope: fa.collectScope,
|
|
11672
|
+
project: { cwd, outputFile: options.outputFile }
|
|
11673
|
+
});
|
|
11529
11674
|
}
|
|
11530
11675
|
}
|
|
11676
|
+
function sourceTally(classified) {
|
|
11677
|
+
const counts = /* @__PURE__ */ new Map();
|
|
11678
|
+
for (const c of classified) counts.set(c.source, (counts.get(c.source) ?? 0) + 1);
|
|
11679
|
+
return ["rule", "retry", "local", "base"].filter((s) => counts.has(s)).map((s) => `${counts.get(s)} ${s}`).join(" / ");
|
|
11680
|
+
}
|
|
11531
11681
|
|
|
11532
11682
|
// src/collector/DataCollector.ts
|
|
11533
11683
|
init_esm_shims();
|
|
@@ -11803,8 +11953,8 @@ function buildSuiteResults(projects, limit) {
|
|
|
11803
11953
|
const top = projects.flatMap((p) => p.suites);
|
|
11804
11954
|
if (top.length <= 1 && top[0] && top[0].suites.length > 0) {
|
|
11805
11955
|
const file = top[0];
|
|
11806
|
-
const
|
|
11807
|
-
const rootRow = file.tests.length > 0 ? [{ label: file.title, passed:
|
|
11956
|
+
const fs16 = statsFromTests(file.tests);
|
|
11957
|
+
const rootRow = file.tests.length > 0 ? [{ label: file.title, passed: fs16.passed, failed: fs16.failed, timedOut: fs16.timedOut, skipped: fs16.skipped }] : [];
|
|
11808
11958
|
return capRows([...rootRow, ...file.suites.map(toRow)], limit);
|
|
11809
11959
|
}
|
|
11810
11960
|
return capRows(top.map(toRow), limit);
|
|
@@ -12450,14 +12600,14 @@ var ShardMerger = class {
|
|
|
12450
12600
|
|
|
12451
12601
|
// src/pdf/PdfGenerator.ts
|
|
12452
12602
|
init_esm_shims();
|
|
12453
|
-
import
|
|
12454
|
-
import
|
|
12603
|
+
import fs14 from "fs";
|
|
12604
|
+
import path14 from "path";
|
|
12455
12605
|
|
|
12456
12606
|
// src/templates/engine.ts
|
|
12457
12607
|
init_esm_shims();
|
|
12458
12608
|
var import_handlebars = __toESM(require_lib());
|
|
12459
|
-
import
|
|
12460
|
-
import
|
|
12609
|
+
import fs7 from "fs";
|
|
12610
|
+
import path9 from "path";
|
|
12461
12611
|
|
|
12462
12612
|
// src/utils/duration.ts
|
|
12463
12613
|
init_esm_shims();
|
|
@@ -12516,9 +12666,9 @@ var TemplateEngine = class {
|
|
|
12516
12666
|
this.customTemplateCache = /* @__PURE__ */ new Map();
|
|
12517
12667
|
this.styleCache = /* @__PURE__ */ new Map();
|
|
12518
12668
|
this.handlebars = import_handlebars.default.create();
|
|
12519
|
-
this.templatesDir =
|
|
12520
|
-
if (!
|
|
12521
|
-
this.templatesDir =
|
|
12669
|
+
this.templatesDir = path9.resolve(__dirname, "templates");
|
|
12670
|
+
if (!fs7.existsSync(this.templatesDir)) {
|
|
12671
|
+
this.templatesDir = path9.resolve(__dirname, "../templates");
|
|
12522
12672
|
}
|
|
12523
12673
|
this.registerHelpers();
|
|
12524
12674
|
this.registerPartials();
|
|
@@ -12535,21 +12685,21 @@ var TemplateEngine = class {
|
|
|
12535
12685
|
this.chartjsInline = inline;
|
|
12536
12686
|
}
|
|
12537
12687
|
render(data, template, userSections, slowTestThreshold) {
|
|
12538
|
-
const layoutPath =
|
|
12539
|
-
if (!
|
|
12688
|
+
const layoutPath = path9.join(this.templatesDir, "layouts", `${template}.hbs`);
|
|
12689
|
+
if (!fs7.existsSync(layoutPath)) {
|
|
12540
12690
|
throw new Error(`[reportforge] Template layout not found: ${layoutPath}`);
|
|
12541
12691
|
}
|
|
12542
|
-
const layoutSource =
|
|
12692
|
+
const layoutSource = fs7.readFileSync(layoutPath, "utf8");
|
|
12543
12693
|
const compiledLayout = this.handlebars.compile(layoutSource);
|
|
12544
12694
|
const ctx = this.buildContext(data, template, userSections, slowTestThreshold);
|
|
12545
12695
|
return compiledLayout(ctx);
|
|
12546
12696
|
}
|
|
12547
12697
|
renderFromPath(data, filePath, slowTestThreshold) {
|
|
12548
12698
|
if (!this.customTemplateCache.has(filePath)) {
|
|
12549
|
-
if (!
|
|
12699
|
+
if (!fs7.existsSync(filePath)) {
|
|
12550
12700
|
throw new Error(`[reportforge] Custom template not found: ${filePath}`);
|
|
12551
12701
|
}
|
|
12552
|
-
const source =
|
|
12702
|
+
const source = fs7.readFileSync(filePath, "utf8");
|
|
12553
12703
|
this.customTemplateCache.set(filePath, this.handlebars.compile(source));
|
|
12554
12704
|
}
|
|
12555
12705
|
const compiledFn = this.customTemplateCache.get(filePath);
|
|
@@ -12681,18 +12831,18 @@ var TemplateEngine = class {
|
|
|
12681
12831
|
readStyle(filename) {
|
|
12682
12832
|
const cached = this.styleCache.get(filename);
|
|
12683
12833
|
if (cached !== void 0) return cached;
|
|
12684
|
-
const stylePath =
|
|
12685
|
-
const css =
|
|
12834
|
+
const stylePath = path9.join(this.templatesDir, "styles", filename);
|
|
12835
|
+
const css = fs7.existsSync(stylePath) ? fs7.readFileSync(stylePath, "utf8") : "";
|
|
12686
12836
|
this.styleCache.set(filename, css);
|
|
12687
12837
|
return css;
|
|
12688
12838
|
}
|
|
12689
12839
|
registerPartials() {
|
|
12690
|
-
const partialsDir =
|
|
12691
|
-
if (!
|
|
12692
|
-
for (const file of
|
|
12840
|
+
const partialsDir = path9.join(this.templatesDir, "partials");
|
|
12841
|
+
if (!fs7.existsSync(partialsDir)) return;
|
|
12842
|
+
for (const file of fs7.readdirSync(partialsDir)) {
|
|
12693
12843
|
if (!file.endsWith(".hbs")) continue;
|
|
12694
|
-
const name =
|
|
12695
|
-
const src =
|
|
12844
|
+
const name = path9.basename(file, ".hbs");
|
|
12845
|
+
const src = fs7.readFileSync(path9.join(partialsDir, file), "utf8");
|
|
12696
12846
|
this.handlebars.registerPartial(name, src);
|
|
12697
12847
|
}
|
|
12698
12848
|
}
|
|
@@ -12797,7 +12947,7 @@ var TemplateEngine = class {
|
|
|
12797
12947
|
|
|
12798
12948
|
// src/screenshots/ScreenshotEmbedder.ts
|
|
12799
12949
|
init_esm_shims();
|
|
12800
|
-
import
|
|
12950
|
+
import fs8 from "fs";
|
|
12801
12951
|
import sharp from "sharp";
|
|
12802
12952
|
var ScreenshotEmbedder = class {
|
|
12803
12953
|
async embedAll(failures, opts) {
|
|
@@ -12806,7 +12956,7 @@ var ScreenshotEmbedder = class {
|
|
|
12806
12956
|
async embed(failure, opts) {
|
|
12807
12957
|
if (!failure.screenshotPath && !failure.screenshotBuffer) return;
|
|
12808
12958
|
try {
|
|
12809
|
-
const raw = failure.screenshotBuffer ?? await
|
|
12959
|
+
const raw = failure.screenshotBuffer ?? await fs8.promises.readFile(failure.screenshotPath);
|
|
12810
12960
|
const { buffer, mime } = opts.reencode ? await this.recompress(raw, opts) : { buffer: raw, mime: this.detectMimeType(raw) };
|
|
12811
12961
|
failure.screenshotBase64 = `data:${mime};base64,${buffer.toString("base64")}`;
|
|
12812
12962
|
} catch (e) {
|
|
@@ -12818,7 +12968,7 @@ var ScreenshotEmbedder = class {
|
|
|
12818
12968
|
}
|
|
12819
12969
|
async embedLogoFile(logoPath) {
|
|
12820
12970
|
try {
|
|
12821
|
-
const buffer = await
|
|
12971
|
+
const buffer = await fs8.promises.readFile(logoPath);
|
|
12822
12972
|
const ext = logoPath.split(".").pop()?.toLowerCase();
|
|
12823
12973
|
let mime = "image/png";
|
|
12824
12974
|
if (ext === "jpg" || ext === "jpeg") mime = "image/jpeg";
|
|
@@ -12863,7 +13013,7 @@ var ScreenshotEmbedder = class {
|
|
|
12863
13013
|
// src/pdf/BrowserManager.ts
|
|
12864
13014
|
init_esm_shims();
|
|
12865
13015
|
import { execSync as execSync2 } from "child_process";
|
|
12866
|
-
import
|
|
13016
|
+
import fs9 from "fs";
|
|
12867
13017
|
var LAUNCH_ARGS = [
|
|
12868
13018
|
"--no-sandbox",
|
|
12869
13019
|
"--disable-setuid-sandbox",
|
|
@@ -12895,13 +13045,13 @@ var BrowserManager = class {
|
|
|
12895
13045
|
}
|
|
12896
13046
|
}
|
|
12897
13047
|
resolveChromePath(explicit, puppeteer) {
|
|
12898
|
-
if (explicit &&
|
|
13048
|
+
if (explicit && fs9.existsSync(explicit)) return explicit;
|
|
12899
13049
|
const envPath = process.env.PUPPETEER_EXECUTABLE_PATH;
|
|
12900
|
-
if (envPath &&
|
|
13050
|
+
if (envPath && fs9.existsSync(envPath)) return envPath;
|
|
12901
13051
|
try {
|
|
12902
13052
|
const chromeFinder = require_lib2();
|
|
12903
13053
|
const found = chromeFinder();
|
|
12904
|
-
if (found &&
|
|
13054
|
+
if (found && fs9.existsSync(found)) return found;
|
|
12905
13055
|
} catch (err) {
|
|
12906
13056
|
logger.debug("chrome discovery: chrome-finder failed", { error: err.message });
|
|
12907
13057
|
}
|
|
@@ -12913,20 +13063,20 @@ var BrowserManager = class {
|
|
|
12913
13063
|
"/snap/bin/chromium"
|
|
12914
13064
|
];
|
|
12915
13065
|
for (const p of linuxPaths) {
|
|
12916
|
-
if (
|
|
13066
|
+
if (fs9.existsSync(p)) return p;
|
|
12917
13067
|
}
|
|
12918
13068
|
try {
|
|
12919
13069
|
const found = execSync2("which google-chrome chromium chromium-browser 2>/dev/null", {
|
|
12920
13070
|
stdio: "pipe"
|
|
12921
13071
|
}).toString().trim().split("\n")[0];
|
|
12922
|
-
if (found &&
|
|
13072
|
+
if (found && fs9.existsSync(found)) return found;
|
|
12923
13073
|
} catch {
|
|
12924
13074
|
logger.debug("chrome discovery: which lookup found nothing");
|
|
12925
13075
|
}
|
|
12926
13076
|
if (puppeteer.executablePath) {
|
|
12927
13077
|
try {
|
|
12928
13078
|
const bundled = puppeteer.executablePath();
|
|
12929
|
-
if (bundled &&
|
|
13079
|
+
if (bundled && fs9.existsSync(bundled)) return bundled;
|
|
12930
13080
|
} catch (err) {
|
|
12931
13081
|
logger.debug("chrome discovery: no puppeteer bundled executable", { error: err.message });
|
|
12932
13082
|
}
|
|
@@ -12940,22 +13090,22 @@ var BrowserManager = class {
|
|
|
12940
13090
|
|
|
12941
13091
|
// src/pdf/HtmlWriter.ts
|
|
12942
13092
|
init_esm_shims();
|
|
12943
|
-
import
|
|
12944
|
-
import
|
|
12945
|
-
import
|
|
13093
|
+
import fs10 from "fs";
|
|
13094
|
+
import os9 from "os";
|
|
13095
|
+
import path10 from "path";
|
|
12946
13096
|
import crypto2 from "crypto";
|
|
12947
13097
|
var HtmlWriter = class {
|
|
12948
13098
|
async write(html) {
|
|
12949
|
-
const tmpDir =
|
|
13099
|
+
const tmpDir = os9.tmpdir();
|
|
12950
13100
|
const filename = `rf-report-${crypto2.randomBytes(8).toString("hex")}.html`;
|
|
12951
|
-
this.tempPath =
|
|
12952
|
-
await
|
|
13101
|
+
this.tempPath = path10.join(tmpDir, filename);
|
|
13102
|
+
await fs10.promises.writeFile(this.tempPath, html, "utf8");
|
|
12953
13103
|
return this.tempPath;
|
|
12954
13104
|
}
|
|
12955
13105
|
async cleanup() {
|
|
12956
13106
|
if (this.tempPath) {
|
|
12957
13107
|
const tempPath = this.tempPath;
|
|
12958
|
-
await
|
|
13108
|
+
await fs10.promises.unlink(tempPath).catch(
|
|
12959
13109
|
(err) => logger.debug("temp HTML cleanup failed (ignored)", { path: tempPath, error: err.message })
|
|
12960
13110
|
);
|
|
12961
13111
|
this.tempPath = void 0;
|
|
@@ -12990,9 +13140,9 @@ var ChartRenderer = class {
|
|
|
12990
13140
|
// src/pdf/PdfEncryptor.ts
|
|
12991
13141
|
init_esm_shims();
|
|
12992
13142
|
import { execFileSync } from "child_process";
|
|
12993
|
-
import
|
|
12994
|
-
import
|
|
12995
|
-
import
|
|
13143
|
+
import fs11 from "fs";
|
|
13144
|
+
import path11 from "path";
|
|
13145
|
+
import os10 from "os";
|
|
12996
13146
|
import crypto3 from "crypto";
|
|
12997
13147
|
var PdfEncryptor = class {
|
|
12998
13148
|
async encrypt(pdfPath, password) {
|
|
@@ -13003,19 +13153,19 @@ var PdfEncryptor = class {
|
|
|
13003
13153
|
);
|
|
13004
13154
|
return;
|
|
13005
13155
|
}
|
|
13006
|
-
const tmpPath =
|
|
13007
|
-
const argFile =
|
|
13156
|
+
const tmpPath = path11.join(os10.tmpdir(), `rf-encrypted-${Date.now()}.pdf`);
|
|
13157
|
+
const argFile = path11.join(os10.tmpdir(), `rf-qpdf-args-${crypto3.randomBytes(8).toString("hex")}`);
|
|
13008
13158
|
try {
|
|
13009
13159
|
const args = ["--encrypt", password, password, "256", "--", pdfPath, tmpPath];
|
|
13010
|
-
|
|
13160
|
+
fs11.writeFileSync(argFile, args.join("\n"), { mode: 384 });
|
|
13011
13161
|
execFileSync("qpdf", [`@${argFile}`], { stdio: "pipe" });
|
|
13012
|
-
|
|
13162
|
+
fs11.renameSync(tmpPath, pdfPath);
|
|
13013
13163
|
logger.info(`PDF encrypted with password.`);
|
|
13014
13164
|
} catch (e) {
|
|
13015
13165
|
throw new Error(`qpdf encryption failed: ${e.message}`);
|
|
13016
13166
|
} finally {
|
|
13017
|
-
if (
|
|
13018
|
-
|
|
13167
|
+
if (fs11.existsSync(tmpPath)) fs11.unlinkSync(tmpPath);
|
|
13168
|
+
fs11.rmSync(argFile, { force: true });
|
|
13019
13169
|
}
|
|
13020
13170
|
}
|
|
13021
13171
|
isQpdfAvailable() {
|
|
@@ -13031,8 +13181,8 @@ var PdfEncryptor = class {
|
|
|
13031
13181
|
|
|
13032
13182
|
// src/filename/FilenameResolver.ts
|
|
13033
13183
|
init_esm_shims();
|
|
13034
|
-
import
|
|
13035
|
-
import
|
|
13184
|
+
import path12 from "path";
|
|
13185
|
+
import fs12 from "fs";
|
|
13036
13186
|
var MAX_BRANCH_LENGTH = 50;
|
|
13037
13187
|
var FilenameResolver = class {
|
|
13038
13188
|
/**
|
|
@@ -13049,8 +13199,8 @@ var FilenameResolver = class {
|
|
|
13049
13199
|
const branch = this.sanitiseBranch(ctx.branch);
|
|
13050
13200
|
const status = ctx.status;
|
|
13051
13201
|
const resolved = template.replace(/\{date\}/g, date).replace(/\{branch\}/g, branch).replace(/\{status\}/g, status);
|
|
13052
|
-
const absolute =
|
|
13053
|
-
|
|
13202
|
+
const absolute = path12.isAbsolute(resolved) ? resolved : path12.resolve(process.cwd(), resolved);
|
|
13203
|
+
fs12.mkdirSync(path12.dirname(absolute), { recursive: true });
|
|
13054
13204
|
return absolute;
|
|
13055
13205
|
}
|
|
13056
13206
|
/**
|
|
@@ -13062,7 +13212,7 @@ var FilenameResolver = class {
|
|
|
13062
13212
|
* // → '/out/2026-report-executive.pdf'
|
|
13063
13213
|
*/
|
|
13064
13214
|
injectTemplateSuffix(outputPath, suffix) {
|
|
13065
|
-
const ext =
|
|
13215
|
+
const ext = path12.extname(outputPath);
|
|
13066
13216
|
const base = outputPath.slice(0, outputPath.length - ext.length);
|
|
13067
13217
|
return `${base}-${suffix}${ext}`;
|
|
13068
13218
|
}
|
|
@@ -13120,8 +13270,8 @@ var PRESETS = {
|
|
|
13120
13270
|
|
|
13121
13271
|
// src/pdf/FailurePaginator.ts
|
|
13122
13272
|
init_esm_shims();
|
|
13123
|
-
import
|
|
13124
|
-
import
|
|
13273
|
+
import fs13 from "fs";
|
|
13274
|
+
import path13 from "path";
|
|
13125
13275
|
var FailurePaginator = class {
|
|
13126
13276
|
async paginate(failures, maxInline, pdfOutputPath) {
|
|
13127
13277
|
if (failures.length <= maxInline) {
|
|
@@ -13131,13 +13281,13 @@ var FailurePaginator = class {
|
|
|
13131
13281
|
const overflow = failures.slice(maxInline);
|
|
13132
13282
|
const sidecarPath = this.sidecarPathFor(pdfOutputPath);
|
|
13133
13283
|
try {
|
|
13134
|
-
await
|
|
13284
|
+
await fs13.promises.writeFile(
|
|
13135
13285
|
sidecarPath,
|
|
13136
13286
|
JSON.stringify(this.serialize(overflow), null, 2),
|
|
13137
13287
|
"utf8"
|
|
13138
13288
|
);
|
|
13139
13289
|
logger.info(
|
|
13140
|
-
`Emitted ${overflow.length} overflow failures \u2192 ${
|
|
13290
|
+
`Emitted ${overflow.length} overflow failures \u2192 ${path13.basename(sidecarPath)}`
|
|
13141
13291
|
);
|
|
13142
13292
|
} catch (e) {
|
|
13143
13293
|
logger.warn(`Could not write failure sidecar: ${e.message}`);
|
|
@@ -13146,9 +13296,9 @@ var FailurePaginator = class {
|
|
|
13146
13296
|
return { inline, overflowCount: overflow.length, sidecarPath };
|
|
13147
13297
|
}
|
|
13148
13298
|
sidecarPathFor(pdfPath) {
|
|
13149
|
-
const dir =
|
|
13150
|
-
const base =
|
|
13151
|
-
return
|
|
13299
|
+
const dir = path13.dirname(pdfPath);
|
|
13300
|
+
const base = path13.basename(pdfPath, path13.extname(pdfPath));
|
|
13301
|
+
return path13.join(dir, `${base}-failures.json`);
|
|
13152
13302
|
}
|
|
13153
13303
|
/**
|
|
13154
13304
|
* Drops the inlined image bytes — a 150-entry overflow would otherwise
|
|
@@ -13227,7 +13377,7 @@ var PdfGenerator = class {
|
|
|
13227
13377
|
const sources = this.resolveTemplateSources(options);
|
|
13228
13378
|
const isMulti = sources.length > 1;
|
|
13229
13379
|
for (const source of sources) {
|
|
13230
|
-
if (source.kind === "custom" && !
|
|
13380
|
+
if (source.kind === "custom" && !fs14.existsSync(source.absolutePath)) {
|
|
13231
13381
|
throw new Error(
|
|
13232
13382
|
`[reportforge] Custom template not found: ${source.absolutePath}`
|
|
13233
13383
|
);
|
|
@@ -13264,7 +13414,7 @@ var PdfGenerator = class {
|
|
|
13264
13414
|
await this.renderPdf(templateData, templateOptions, source, compression, outputPath, page);
|
|
13265
13415
|
const capBytes = (options.maxFileSizeMb ?? 0) * 1024 * 1024;
|
|
13266
13416
|
if (capBytes > 0) {
|
|
13267
|
-
const sizeBytes = (await
|
|
13417
|
+
const sizeBytes = (await fs14.promises.stat(outputPath)).size;
|
|
13268
13418
|
if (sizeBytes > capBytes) {
|
|
13269
13419
|
const inlinedCount = Math.min(templateData.failures.length, compression.maxInlineFailures);
|
|
13270
13420
|
const tighter = this.tightenForCap(compression, sizeBytes, capBytes, inlinedCount);
|
|
@@ -13272,7 +13422,7 @@ var PdfGenerator = class {
|
|
|
13272
13422
|
`PDF size ${fmtMb(sizeBytes)} exceeds cap ${fmtMb(capBytes)} \u2014 re-rendering (jpeg-q=${tighter.quality}, max-w=${tighter.maxWidth}px, inline-failures\u2264${tighter.maxInlineFailures}).`
|
|
13273
13423
|
);
|
|
13274
13424
|
await this.renderPdf(templateData, templateOptions, source, tighter, outputPath, page);
|
|
13275
|
-
const finalSize = (await
|
|
13425
|
+
const finalSize = (await fs14.promises.stat(outputPath)).size;
|
|
13276
13426
|
if (finalSize > capBytes) {
|
|
13277
13427
|
logger.warn(
|
|
13278
13428
|
`PDF still ${fmtMb(finalSize)} after retune. Consider lowering maxInlineFailures or splitting the report.`
|
|
@@ -13285,7 +13435,7 @@ var PdfGenerator = class {
|
|
|
13285
13435
|
if (options.pdfPassword) {
|
|
13286
13436
|
await this.pdfEncryptor.encrypt(outputPath, options.pdfPassword);
|
|
13287
13437
|
}
|
|
13288
|
-
const finalSizeMb = fmtMb((await
|
|
13438
|
+
const finalSizeMb = fmtMb((await fs14.promises.stat(outputPath)).size);
|
|
13289
13439
|
logger.info(`PDF report generated: ${outputPath} (${finalSizeMb})`);
|
|
13290
13440
|
outputPaths.push(outputPath);
|
|
13291
13441
|
}
|
|
@@ -13298,17 +13448,17 @@ var PdfGenerator = class {
|
|
|
13298
13448
|
if (options.templatePath && options.templatePath.length > 0) {
|
|
13299
13449
|
const byAbsolutePath = /* @__PURE__ */ new Map();
|
|
13300
13450
|
for (const p of options.templatePath) {
|
|
13301
|
-
const absolutePath =
|
|
13451
|
+
const absolutePath = path14.isAbsolute(p) ? p : path14.resolve(process.cwd(), p);
|
|
13302
13452
|
if (!byAbsolutePath.has(absolutePath)) byAbsolutePath.set(absolutePath, p);
|
|
13303
13453
|
}
|
|
13304
13454
|
const labelCounts = /* @__PURE__ */ new Map();
|
|
13305
13455
|
for (const rawPath of byAbsolutePath.values()) {
|
|
13306
|
-
const label =
|
|
13456
|
+
const label = path14.basename(rawPath, ".hbs");
|
|
13307
13457
|
labelCounts.set(label, (labelCounts.get(label) ?? 0) + 1);
|
|
13308
13458
|
}
|
|
13309
13459
|
const seenPerLabel = /* @__PURE__ */ new Map();
|
|
13310
13460
|
return Array.from(byAbsolutePath.entries()).map(([absolutePath, rawPath]) => {
|
|
13311
|
-
const baseLabel =
|
|
13461
|
+
const baseLabel = path14.basename(rawPath, ".hbs");
|
|
13312
13462
|
let label = baseLabel;
|
|
13313
13463
|
if ((labelCounts.get(baseLabel) ?? 0) > 1) {
|
|
13314
13464
|
const n = (seenPerLabel.get(baseLabel) ?? 0) + 1;
|
|
@@ -13368,7 +13518,7 @@ var PdfGenerator = class {
|
|
|
13368
13518
|
...data,
|
|
13369
13519
|
failures: paginated.inline,
|
|
13370
13520
|
overflowFailureCount: paginated.overflowCount,
|
|
13371
|
-
overflowSidecarName: paginated.sidecarPath ?
|
|
13521
|
+
overflowSidecarName: paginated.sidecarPath ? path14.basename(paginated.sidecarPath) : void 0
|
|
13372
13522
|
};
|
|
13373
13523
|
for (const f of renderData.failures) f.screenshotBase64 = void 0;
|
|
13374
13524
|
if (options.includeScreenshots !== false) {
|
|
@@ -13388,7 +13538,7 @@ var PdfGenerator = class {
|
|
|
13388
13538
|
await page.goto(fileUrl, { waitUntil: "domcontentloaded", timeout: 6e4 });
|
|
13389
13539
|
const showCharts = source.kind === "builtin" ? resolveSections(source.id, options.sections).charts : true;
|
|
13390
13540
|
await this.chartRenderer.waitForCharts(page, showCharts);
|
|
13391
|
-
logger.info(`Generating PDF \u2192 ${
|
|
13541
|
+
logger.info(`Generating PDF \u2192 ${path14.relative(process.cwd(), outputPath)}`);
|
|
13392
13542
|
await page.pdf({
|
|
13393
13543
|
path: outputPath,
|
|
13394
13544
|
format: "A4",
|
|
@@ -13405,19 +13555,19 @@ function fmtMb(bytes) {
|
|
|
13405
13555
|
}
|
|
13406
13556
|
|
|
13407
13557
|
// src/reporter.ts
|
|
13408
|
-
import
|
|
13558
|
+
import path16 from "path";
|
|
13409
13559
|
|
|
13410
13560
|
// src/history/HistoryManager.ts
|
|
13411
13561
|
init_esm_shims();
|
|
13412
|
-
import
|
|
13413
|
-
import
|
|
13562
|
+
import fs15 from "fs";
|
|
13563
|
+
import path15 from "path";
|
|
13414
13564
|
var HistoryManager = class {
|
|
13415
13565
|
constructor(filePath) {
|
|
13416
13566
|
this.filePath = filePath;
|
|
13417
13567
|
}
|
|
13418
13568
|
read() {
|
|
13419
13569
|
try {
|
|
13420
|
-
const raw =
|
|
13570
|
+
const raw = fs15.readFileSync(this.filePath, "utf8");
|
|
13421
13571
|
const parsed = JSON.parse(raw);
|
|
13422
13572
|
if (parsed.version !== 1) {
|
|
13423
13573
|
logger.warn(`history.version-mismatch: path=${this.filePath} version=${String(parsed.version)}`);
|
|
@@ -13431,12 +13581,12 @@ var HistoryManager = class {
|
|
|
13431
13581
|
}
|
|
13432
13582
|
append(entry, maxSize) {
|
|
13433
13583
|
try {
|
|
13434
|
-
|
|
13584
|
+
fs15.mkdirSync(path15.dirname(this.filePath), { recursive: true });
|
|
13435
13585
|
const next = {
|
|
13436
13586
|
version: 1,
|
|
13437
13587
|
entries: [entry, ...this.read()].slice(0, maxSize)
|
|
13438
13588
|
};
|
|
13439
|
-
|
|
13589
|
+
fs15.writeFileSync(this.filePath, JSON.stringify(next, null, 2), { mode: 420 });
|
|
13440
13590
|
return next.entries;
|
|
13441
13591
|
} catch (err) {
|
|
13442
13592
|
logger.warn(`history.write-failed: path=${this.filePath} error=${err.message}`);
|
|
@@ -14195,6 +14345,7 @@ function chunkToString2(chunk) {
|
|
|
14195
14345
|
|
|
14196
14346
|
// src/reporter.ts
|
|
14197
14347
|
var DEFAULT_SERVER_URL2 = "https://reportforge.org";
|
|
14348
|
+
var LICENSE_STALE_MARGIN_MS = 5 * 60 * 1e3;
|
|
14198
14349
|
var PdfReporter = class {
|
|
14199
14350
|
constructor(rawOptions = {}) {
|
|
14200
14351
|
this.cwd = process.cwd();
|
|
@@ -14205,7 +14356,7 @@ var PdfReporter = class {
|
|
|
14205
14356
|
this.options = parseOptions(rawOptions);
|
|
14206
14357
|
setLogLevel(this.options.logLevel);
|
|
14207
14358
|
this.dataCollector = new DataCollector(this.options.capture);
|
|
14208
|
-
this.version = true ? "0.
|
|
14359
|
+
this.version = true ? "0.20.1" : "0.x";
|
|
14209
14360
|
logger.info(`@reportforge/playwright-pdf v${this.version} initialised`);
|
|
14210
14361
|
this.licenseClient = new LicenseClient({
|
|
14211
14362
|
licenseKey: this.options.licenseKey,
|
|
@@ -14276,7 +14427,7 @@ var PdfReporter = class {
|
|
|
14276
14427
|
}
|
|
14277
14428
|
}
|
|
14278
14429
|
async onEnd(result) {
|
|
14279
|
-
const licenseInfo = await this.
|
|
14430
|
+
const licenseInfo = await this.freshLicense();
|
|
14280
14431
|
if (!licenseInfo) return;
|
|
14281
14432
|
const collected = this._collectData(result);
|
|
14282
14433
|
if (!collected) {
|
|
@@ -14395,6 +14546,31 @@ var PdfReporter = class {
|
|
|
14395
14546
|
license() {
|
|
14396
14547
|
return this.licensePromise ?? (this.licensePromise = this.resolveLicense());
|
|
14397
14548
|
}
|
|
14549
|
+
/**
|
|
14550
|
+
* onEnd entry point for licensing: the memoized resolution can be as old as
|
|
14551
|
+
* the whole run (it is shared with the live stream from onBegin), and a JWT
|
|
14552
|
+
* issued near the subscription's period end can expire MID-RUN while the
|
|
14553
|
+
* subscription itself renews and stays active — the exact case where the
|
|
14554
|
+
* admin dashboard shows "active" but generateAll's expiry gate would throw.
|
|
14555
|
+
* When the token is expired or about to be, re-resolve once: with < 24h TTL
|
|
14556
|
+
* the client always takes the network path, and its token_expired recovery
|
|
14557
|
+
* (clear cache → fresh activation) picks up the renewed period. A refresh
|
|
14558
|
+
* failure downgrades to the normal warn-and-skip, never a hard ERROR.
|
|
14559
|
+
*/
|
|
14560
|
+
async freshLicense() {
|
|
14561
|
+
const info = await this.license();
|
|
14562
|
+
if (!info) return null;
|
|
14563
|
+
if (info.expiry.getTime() - Date.now() > LICENSE_STALE_MARGIN_MS) return info;
|
|
14564
|
+
logger.info("License token expired or is about to expire \u2014 refreshing before PDF generation...");
|
|
14565
|
+
this.licensePromise = this.resolveLicense();
|
|
14566
|
+
const refreshed = await this.licensePromise;
|
|
14567
|
+
if (!refreshed) {
|
|
14568
|
+
logger.warn(
|
|
14569
|
+
"License could not be refreshed after expiring mid-run \u2014 PDF generation is skipped. If your subscription is active, the next run will recover automatically."
|
|
14570
|
+
);
|
|
14571
|
+
}
|
|
14572
|
+
return refreshed;
|
|
14573
|
+
}
|
|
14398
14574
|
async resolveLicense() {
|
|
14399
14575
|
try {
|
|
14400
14576
|
return await this.licenseClient.resolve(
|
|
@@ -14479,7 +14655,7 @@ var PdfReporter = class {
|
|
|
14479
14655
|
}
|
|
14480
14656
|
resolveProjectName() {
|
|
14481
14657
|
try {
|
|
14482
|
-
const pkgPath =
|
|
14658
|
+
const pkgPath = path16.resolve(process.cwd(), "package.json");
|
|
14483
14659
|
const pkg = __require(pkgPath);
|
|
14484
14660
|
return pkg.name ?? "Playwright Tests";
|
|
14485
14661
|
} catch {
|
|
@@ -14529,9 +14705,9 @@ function deriveVerdict(stats) {
|
|
|
14529
14705
|
}
|
|
14530
14706
|
function resolveHistoryPath(options, cwd) {
|
|
14531
14707
|
if (options.historyFile) {
|
|
14532
|
-
return
|
|
14708
|
+
return path16.isAbsolute(options.historyFile) ? options.historyFile : path16.resolve(cwd, options.historyFile);
|
|
14533
14709
|
}
|
|
14534
|
-
return
|
|
14710
|
+
return path16.join(resolveProjectDir(options, cwd), "history.json");
|
|
14535
14711
|
}
|
|
14536
14712
|
function flattenSuiteNodes(suites) {
|
|
14537
14713
|
return suites.flatMap((s) => [s, ...flattenSuiteNodes(s.suites)]);
|