@healflow/playwright 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -21
- package/dist/index.d.ts +2 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -691
- package/dist/index.js.map +1 -1
- package/dist/plugin/classification.d.ts +6 -0
- package/dist/plugin/classification.d.ts.map +1 -0
- package/dist/plugin/classification.js +343 -0
- package/dist/plugin/classification.js.map +1 -0
- package/dist/plugin/constants.d.ts +5 -0
- package/dist/plugin/constants.d.ts.map +1 -0
- package/dist/plugin/constants.js +55 -0
- package/dist/plugin/constants.js.map +1 -0
- package/dist/plugin/heal-emit.d.ts +5 -0
- package/dist/plugin/heal-emit.d.ts.map +1 -0
- package/dist/plugin/heal-emit.js +69 -0
- package/dist/plugin/heal-emit.js.map +1 -0
- package/dist/plugin/index.d.ts +5 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +11 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/locator-wrap.d.ts +4 -0
- package/dist/plugin/locator-wrap.d.ts.map +1 -0
- package/dist/plugin/locator-wrap.js +68 -0
- package/dist/plugin/locator-wrap.js.map +1 -0
- package/dist/plugin/options.d.ts +3 -0
- package/dist/plugin/options.d.ts.map +1 -0
- package/dist/plugin/options.js +25 -0
- package/dist/plugin/options.js.map +1 -0
- package/dist/plugin/page-wrap.d.ts +9 -0
- package/dist/plugin/page-wrap.d.ts.map +1 -0
- package/dist/plugin/page-wrap.js +99 -0
- package/dist/plugin/page-wrap.js.map +1 -0
- package/dist/plugin/types.d.ts +19 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin/types.js +3 -0
- package/dist/plugin/types.js.map +1 -0
- package/dist/report-html/build.d.ts +7 -0
- package/dist/report-html/build.d.ts.map +1 -0
- package/dist/report-html/build.js +138 -0
- package/dist/report-html/build.js.map +1 -0
- package/dist/report-html/format.d.ts +6 -0
- package/dist/report-html/format.d.ts.map +1 -0
- package/dist/report-html/format.js +37 -0
- package/dist/report-html/format.js.map +1 -0
- package/dist/report-html/icons.d.ts +4 -0
- package/dist/report-html/icons.d.ts.map +1 -0
- package/dist/report-html/icons.js +7 -0
- package/dist/report-html/icons.js.map +1 -0
- package/dist/report-html/index.d.ts +3 -0
- package/dist/report-html/index.d.ts.map +1 -0
- package/dist/report-html/index.js +6 -0
- package/dist/report-html/index.js.map +1 -0
- package/dist/report-html/render.d.ts +6 -0
- package/dist/report-html/render.d.ts.map +1 -0
- package/dist/report-html/render.js +139 -0
- package/dist/report-html/render.js.map +1 -0
- package/dist/report-html/script.d.ts +2 -0
- package/dist/report-html/script.d.ts.map +1 -0
- package/dist/report-html/script.js +75 -0
- package/dist/report-html/script.js.map +1 -0
- package/dist/report-html/status.d.ts +2 -0
- package/dist/report-html/status.d.ts.map +1 -0
- package/dist/report-html/status.js +13 -0
- package/dist/report-html/status.js.map +1 -0
- package/dist/report-html/styles.d.ts +2 -0
- package/dist/report-html/styles.d.ts.map +1 -0
- package/dist/report-html/styles.js +441 -0
- package/dist/report-html/styles.js.map +1 -0
- package/dist/report-html/tree.d.ts +8 -0
- package/dist/report-html/tree.d.ts.map +1 -0
- package/dist/report-html/tree.js +57 -0
- package/dist/report-html/tree.js.map +1 -0
- package/dist/report-html/types.d.ts +19 -0
- package/dist/report-html/types.d.ts.map +1 -0
- package/dist/report-html/types.js +3 -0
- package/dist/report-html/types.js.map +1 -0
- package/dist/report-html.d.ts +2 -6
- package/dist/report-html.d.ts.map +1 -1
- package/dist/report-html.js +3 -859
- package/dist/report-html.js.map +1 -1
- package/dist/runtime-ladder.d.ts +17 -0
- package/dist/runtime-ladder.d.ts.map +1 -0
- package/dist/runtime-ladder.js +61 -0
- package/dist/runtime-ladder.js.map +1 -0
- package/dist/runtime-techniques/heal-helpers.d.ts +10 -0
- package/dist/runtime-techniques/heal-helpers.d.ts.map +1 -0
- package/dist/runtime-techniques/heal-helpers.js +304 -0
- package/dist/runtime-techniques/heal-helpers.js.map +1 -0
- package/dist/runtime-techniques/index.d.ts +11 -0
- package/dist/runtime-techniques/index.d.ts.map +1 -0
- package/dist/runtime-techniques/index.js +34 -0
- package/dist/runtime-techniques/index.js.map +1 -0
- package/dist/runtime-techniques/registry.d.ts +5 -0
- package/dist/runtime-techniques/registry.d.ts.map +1 -0
- package/dist/runtime-techniques/registry.js +29 -0
- package/dist/runtime-techniques/registry.js.map +1 -0
- package/dist/runtime-techniques/shared/constants.d.ts +4 -0
- package/dist/runtime-techniques/shared/constants.d.ts.map +1 -0
- package/dist/runtime-techniques/shared/constants.js +7 -0
- package/dist/runtime-techniques/shared/constants.js.map +1 -0
- package/dist/runtime-techniques/shared/error-utils.d.ts +9 -0
- package/dist/runtime-techniques/shared/error-utils.d.ts.map +1 -0
- package/dist/runtime-techniques/shared/error-utils.js +27 -0
- package/dist/runtime-techniques/shared/error-utils.js.map +1 -0
- package/dist/runtime-techniques/shared/heal-alternate.d.ts +6 -0
- package/dist/runtime-techniques/shared/heal-alternate.d.ts.map +1 -0
- package/dist/runtime-techniques/shared/heal-alternate.js +130 -0
- package/dist/runtime-techniques/shared/heal-alternate.js.map +1 -0
- package/dist/runtime-techniques/shared/heal-candidates.d.ts +11 -0
- package/dist/runtime-techniques/shared/heal-candidates.d.ts.map +1 -0
- package/dist/runtime-techniques/shared/heal-candidates.js +127 -0
- package/dist/runtime-techniques/shared/heal-candidates.js.map +1 -0
- package/dist/runtime-techniques/shared/heal-history.d.ts +10 -0
- package/dist/runtime-techniques/shared/heal-history.d.ts.map +1 -0
- package/dist/runtime-techniques/shared/heal-history.js +42 -0
- package/dist/runtime-techniques/shared/heal-history.js.map +1 -0
- package/dist/runtime-techniques/shared/locator-actions.d.ts +6 -0
- package/dist/runtime-techniques/shared/locator-actions.d.ts.map +1 -0
- package/dist/runtime-techniques/shared/locator-actions.js +66 -0
- package/dist/runtime-techniques/shared/locator-actions.js.map +1 -0
- package/dist/runtime-techniques/shared/page-waits.d.ts +6 -0
- package/dist/runtime-techniques/shared/page-waits.d.ts.map +1 -0
- package/dist/runtime-techniques/shared/page-waits.js +57 -0
- package/dist/runtime-techniques/shared/page-waits.js.map +1 -0
- package/dist/runtime-techniques/shared.d.ts +8 -0
- package/dist/runtime-techniques/shared.d.ts.map +1 -0
- package/dist/runtime-techniques/shared.js +24 -0
- package/dist/runtime-techniques/shared.js.map +1 -0
- package/dist/runtime-techniques/t0-retry.d.ts +4 -0
- package/dist/runtime-techniques/t0-retry.d.ts.map +1 -0
- package/dist/runtime-techniques/t0-retry.js +334 -0
- package/dist/runtime-techniques/t0-retry.js.map +1 -0
- package/dist/runtime-techniques/t1-scope.d.ts +4 -0
- package/dist/runtime-techniques/t1-scope.d.ts.map +1 -0
- package/dist/runtime-techniques/t1-scope.js +70 -0
- package/dist/runtime-techniques/t1-scope.js.map +1 -0
- package/dist/runtime-techniques/t2-normalize.d.ts +3 -0
- package/dist/runtime-techniques/t2-normalize.d.ts.map +1 -0
- package/dist/runtime-techniques/t2-normalize.js +12 -0
- package/dist/runtime-techniques/t2-normalize.js.map +1 -0
- package/dist/runtime-techniques/t3-fingerprint.d.ts +4 -0
- package/dist/runtime-techniques/t3-fingerprint.d.ts.map +1 -0
- package/dist/runtime-techniques/t3-fingerprint.js +13 -0
- package/dist/runtime-techniques/t3-fingerprint.js.map +1 -0
- package/dist/runtime-techniques/t4-trace.d.ts +4 -0
- package/dist/runtime-techniques/t4-trace.d.ts.map +1 -0
- package/dist/runtime-techniques/t4-trace.js +125 -0
- package/dist/runtime-techniques/t4-trace.js.map +1 -0
- package/dist/runtime-techniques/t5-history.d.ts +3 -0
- package/dist/runtime-techniques/t5-history.d.ts.map +1 -0
- package/dist/runtime-techniques/t5-history.js +50 -0
- package/dist/runtime-techniques/t5-history.js.map +1 -0
- package/dist/runtime-techniques/types.d.ts +36 -0
- package/dist/runtime-techniques/types.d.ts.map +1 -0
- package/dist/runtime-techniques/types.js +3 -0
- package/dist/runtime-techniques/types.js.map +1 -0
- package/dist/runtime-techniques.d.ts +2 -0
- package/dist/runtime-techniques.d.ts.map +1 -0
- package/dist/runtime-techniques.js +18 -0
- package/dist/runtime-techniques.js.map +1 -0
- package/dist/terminal.d.ts.map +1 -1
- package/dist/terminal.js +52 -3
- package/dist/terminal.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapLocator = wrapLocator;
|
|
4
|
+
const config_1 = require("@healflow/shared/config");
|
|
5
|
+
const runtime_ladder_js_1 = require("../runtime-ladder.js");
|
|
6
|
+
const constants_js_1 = require("./constants.js");
|
|
7
|
+
const classification_js_1 = require("./classification.js");
|
|
8
|
+
const heal_emit_js_1 = require("./heal-emit.js");
|
|
9
|
+
async function prepareHeal(rawPage, locator, action, args, error, opts, testFile) {
|
|
10
|
+
const classification = (0, classification_js_1.classifyRuntimeError)(error, action);
|
|
11
|
+
if (!(0, classification_js_1.canRuntimeHeal)(classification)) {
|
|
12
|
+
return { type: 'abort' };
|
|
13
|
+
}
|
|
14
|
+
const key = (0, classification_js_1.categoryKey)(classification.category);
|
|
15
|
+
if (key && !(0, config_1.isHealingCategoryEnabled)(opts.config, key)) {
|
|
16
|
+
return { type: 'abort' };
|
|
17
|
+
}
|
|
18
|
+
return (0, runtime_ladder_js_1.executeRuntimeTechniqueLadder)(rawPage, locator, action, args, error, classification, opts.config, testFile);
|
|
19
|
+
}
|
|
20
|
+
function wrapLocator(locator, rawPage, options, healContext) {
|
|
21
|
+
const handler = {
|
|
22
|
+
get(target, prop, receiver) {
|
|
23
|
+
if (prop === 'constructor')
|
|
24
|
+
return target.constructor;
|
|
25
|
+
const value = Reflect.get(target, prop, receiver);
|
|
26
|
+
if (typeof value !== 'function')
|
|
27
|
+
return value;
|
|
28
|
+
const method = prop;
|
|
29
|
+
if (constants_js_1.LOCATOR_CHAIN_METHODS.has(method)) {
|
|
30
|
+
return (...args) => {
|
|
31
|
+
const next = value.apply(target, args);
|
|
32
|
+
return wrapLocator(next, rawPage, options, healContext);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (!constants_js_1.HEALABLE_LOCATOR_ACTIONS.has(method)) {
|
|
36
|
+
return value.bind(target);
|
|
37
|
+
}
|
|
38
|
+
const bound = value.bind(target);
|
|
39
|
+
return async (...args) => {
|
|
40
|
+
let lastError;
|
|
41
|
+
for (let attempt = 0; attempt <= options.maxAttempts; attempt++) {
|
|
42
|
+
healContext.attempts = attempt + 1;
|
|
43
|
+
try {
|
|
44
|
+
return await bound(...(0, heal_emit_js_1.resolveActionArgs)(args, attempt, method));
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
lastError = error;
|
|
48
|
+
if (!options.autoHeal || attempt >= options.maxAttempts)
|
|
49
|
+
break;
|
|
50
|
+
const outcome = await prepareHeal(rawPage, target, method, args, error, options, healContext.testFile);
|
|
51
|
+
if (outcome.type !== 'abort' && outcome.heal) {
|
|
52
|
+
healContext.healedActions.push(method);
|
|
53
|
+
(0, heal_emit_js_1.emitHeal)(options, outcome.heal, healContext);
|
|
54
|
+
}
|
|
55
|
+
if (outcome.type === 'done')
|
|
56
|
+
return outcome.result;
|
|
57
|
+
if (outcome.type === 'retry')
|
|
58
|
+
continue;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
throw lastError;
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
return new Proxy(locator, handler);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=locator-wrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locator-wrap.js","sourceRoot":"","sources":["../../src/plugin/locator-wrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/plugin/options.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvE,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,aAAa,CAsBjF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveOptions = resolveOptions;
|
|
4
|
+
const config_1 = require("@healflow/shared/config");
|
|
5
|
+
function resolveOptions(options = {}) {
|
|
6
|
+
const fileConfig = options.config ?? (0, config_1.loadHealFlowConfig)();
|
|
7
|
+
return {
|
|
8
|
+
autoHeal: options.autoHeal ?? true,
|
|
9
|
+
maxAttempts: options.maxAttempts ?? 3,
|
|
10
|
+
apiUrl: options.apiUrl ??
|
|
11
|
+
fileConfig.backend?.url ??
|
|
12
|
+
process.env.HEALFLOW_API_URL ??
|
|
13
|
+
'http://localhost:3001',
|
|
14
|
+
organizationId: options.organizationId ??
|
|
15
|
+
fileConfig.backend?.organizationId ??
|
|
16
|
+
process.env.HEALFLOW_ORG_ID ??
|
|
17
|
+
'',
|
|
18
|
+
repositoryId: options.repositoryId ??
|
|
19
|
+
fileConfig.backend?.repositoryId ??
|
|
20
|
+
process.env.HEALFLOW_REPO_ID ??
|
|
21
|
+
'',
|
|
22
|
+
config: fileConfig,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/plugin/options.ts"],"names":[],"mappings":";;AAIA,wCAsBC;AAzBD,oDAA6D;AAG7D,SAAgB,cAAc,CAAC,UAAiC,EAAE;IAChE,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,IAAI,IAAA,2BAAkB,GAAE,CAAC;IAC1D,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;QAClC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC;QACrC,MAAM,EACJ,OAAO,CAAC,MAAM;YACd,UAAU,CAAC,OAAO,EAAE,GAAG;YACvB,OAAO,CAAC,GAAG,CAAC,gBAAgB;YAC5B,uBAAuB;QACzB,cAAc,EACZ,OAAO,CAAC,cAAc;YACtB,UAAU,CAAC,OAAO,EAAE,cAAc;YAClC,OAAO,CAAC,GAAG,CAAC,eAAe;YAC3B,EAAE;QACJ,YAAY,EACV,OAAO,CAAC,YAAY;YACpB,UAAU,CAAC,OAAO,EAAE,YAAY;YAChC,OAAO,CAAC,GAAG,CAAC,gBAAgB;YAC5B,EAAE;QACJ,MAAM,EAAE,UAAU;KACnB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Page, TestInfo } from '@playwright/test';
|
|
2
|
+
import type { HealContext, HealFlowPluginOptions } from './types.js';
|
|
3
|
+
export declare function wrapPage(page: Page, options?: HealFlowPluginOptions, healContext?: HealContext): Page;
|
|
4
|
+
export declare function healflowFixture(options?: HealFlowPluginOptions): {
|
|
5
|
+
page: ({ page }: {
|
|
6
|
+
page: Page;
|
|
7
|
+
}, use: (p: Page) => Promise<void>, testInfo: TestInfo) => Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=page-wrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-wrap.d.ts","sourceRoot":"","sources":["../../src/plugin/page-wrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQvD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAErE,wBAAgB,QAAQ,CACtB,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,qBAA0B,EACnC,WAAW,CAAC,EAAE,WAAW,GACxB,IAAI,CAiGN;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,qBAA0B;qBAInD;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,OACnB,CAAC,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,YACrB,QAAQ,KACjB,OAAO,CAAC,IAAI,CAAC;EAUnB"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapPage = wrapPage;
|
|
4
|
+
exports.healflowFixture = healflowFixture;
|
|
5
|
+
const shared_1 = require("@healflow/shared");
|
|
6
|
+
const config_1 = require("@healflow/shared/config");
|
|
7
|
+
const constants_js_1 = require("./constants.js");
|
|
8
|
+
const classification_js_1 = require("./classification.js");
|
|
9
|
+
const heal_emit_js_1 = require("./heal-emit.js");
|
|
10
|
+
const locator_wrap_js_1 = require("./locator-wrap.js");
|
|
11
|
+
const options_js_1 = require("./options.js");
|
|
12
|
+
function wrapPage(page, options = {}, healContext) {
|
|
13
|
+
const opts = (0, options_js_1.resolveOptions)(options);
|
|
14
|
+
const context = healContext ?? { attempts: 0, healedActions: [] };
|
|
15
|
+
const handler = {
|
|
16
|
+
get(target, prop, receiver) {
|
|
17
|
+
if (prop === 'constructor')
|
|
18
|
+
return target.constructor;
|
|
19
|
+
const value = Reflect.get(target, prop, receiver);
|
|
20
|
+
if (typeof value !== 'function')
|
|
21
|
+
return value;
|
|
22
|
+
const method = prop;
|
|
23
|
+
if (constants_js_1.PAGE_LOCATOR_FACTORIES.has(method)) {
|
|
24
|
+
return (...args) => {
|
|
25
|
+
const nextLocator = value.apply(target, args);
|
|
26
|
+
return (0, locator_wrap_js_1.wrapLocator)(nextLocator, target, opts, context);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (!constants_js_1.HEALABLE_PAGE_ACTIONS.has(method)) {
|
|
30
|
+
return value.bind(target);
|
|
31
|
+
}
|
|
32
|
+
const bound = value.bind(target);
|
|
33
|
+
return async (...args) => {
|
|
34
|
+
let lastError;
|
|
35
|
+
for (let attempt = 0; attempt <= opts.maxAttempts; attempt++) {
|
|
36
|
+
context.attempts = attempt + 1;
|
|
37
|
+
try {
|
|
38
|
+
return await bound(...args);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
lastError = error;
|
|
42
|
+
if (!opts.autoHeal || attempt >= opts.maxAttempts)
|
|
43
|
+
break;
|
|
44
|
+
const classification = (0, classification_js_1.classifyRuntimeError)(error, method);
|
|
45
|
+
if (classification.category === shared_1.FailureCategory.NETWORK &&
|
|
46
|
+
(0, config_1.isHealingCategoryEnabled)(opts.config, 'network')) {
|
|
47
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
48
|
+
(0, heal_emit_js_1.emitHeal)(opts, {
|
|
49
|
+
category: shared_1.FailureCategory.NETWORK,
|
|
50
|
+
rootCause: 'Network Retry',
|
|
51
|
+
confidence: classification.confidence,
|
|
52
|
+
}, context);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (classification.category === shared_1.FailureCategory.TIMING &&
|
|
56
|
+
(0, config_1.isHealingCategoryEnabled)(opts.config, 'timing')) {
|
|
57
|
+
await target.waitForLoadState('networkidle').catch(() => { });
|
|
58
|
+
(0, heal_emit_js_1.emitHeal)(opts, {
|
|
59
|
+
category: shared_1.FailureCategory.TIMING,
|
|
60
|
+
rootCause: 'Timing',
|
|
61
|
+
confidence: classification.confidence,
|
|
62
|
+
}, context);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (classification.category === shared_1.FailureCategory.NAVIGATION &&
|
|
66
|
+
(0, config_1.isHealingCategoryEnabled)(opts.config, 'navigation')) {
|
|
67
|
+
await target.waitForLoadState('domcontentloaded').catch(() => { });
|
|
68
|
+
await target.waitForLoadState('networkidle').catch(() => { });
|
|
69
|
+
(0, heal_emit_js_1.emitHeal)(opts, {
|
|
70
|
+
category: shared_1.FailureCategory.NAVIGATION,
|
|
71
|
+
rootCause: 'Navigation',
|
|
72
|
+
confidence: classification.confidence,
|
|
73
|
+
}, context);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
throw lastError;
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
return new Proxy(page, handler);
|
|
84
|
+
}
|
|
85
|
+
function healflowFixture(options = {}) {
|
|
86
|
+
const opts = (0, options_js_1.resolveOptions)(options);
|
|
87
|
+
return {
|
|
88
|
+
page: async ({ page }, use, testInfo) => {
|
|
89
|
+
const healContext = {
|
|
90
|
+
attempts: 0,
|
|
91
|
+
healedActions: [],
|
|
92
|
+
testFile: testInfo.file,
|
|
93
|
+
testTitle: testInfo.title,
|
|
94
|
+
};
|
|
95
|
+
await use(wrapPage(page, opts, healContext));
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=page-wrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-wrap.js","sourceRoot":"","sources":["../../src/plugin/page-wrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HealFlowConfig } from '@healflow/shared';
|
|
2
|
+
export interface HealFlowPluginOptions {
|
|
3
|
+
autoHeal?: boolean;
|
|
4
|
+
maxAttempts?: number;
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
organizationId?: string;
|
|
7
|
+
repositoryId?: string;
|
|
8
|
+
config?: HealFlowConfig;
|
|
9
|
+
}
|
|
10
|
+
export interface HealContext {
|
|
11
|
+
attempts: number;
|
|
12
|
+
healedActions: string[];
|
|
13
|
+
testFile?: string;
|
|
14
|
+
testTitle?: string;
|
|
15
|
+
}
|
|
16
|
+
export type PluginOptions = Required<Omit<HealFlowPluginOptions, 'config'>> & {
|
|
17
|
+
config: HealFlowConfig;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC,GAAG;IAC5E,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/plugin/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HealFlowRunArtifacts } from '@healflow/shared';
|
|
2
|
+
export interface ReportHtmlOptions {
|
|
3
|
+
passedCount?: number;
|
|
4
|
+
durationMs?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function buildReportHtml(artifacts: HealFlowRunArtifacts, options?: ReportHtmlOptions): string;
|
|
7
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/report-html/build.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAS7D,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,oBAAoB,EAC/B,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAuIR"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildReportHtml = buildReportHtml;
|
|
4
|
+
const format_js_1 = require("./format.js");
|
|
5
|
+
const icons_js_1 = require("./icons.js");
|
|
6
|
+
const render_js_1 = require("./render.js");
|
|
7
|
+
const script_js_1 = require("./script.js");
|
|
8
|
+
const styles_js_1 = require("./styles.js");
|
|
9
|
+
const tree_js_1 = require("./tree.js");
|
|
10
|
+
const status_js_1 = require("./status.js");
|
|
11
|
+
function buildReportHtml(artifacts, options = {}) {
|
|
12
|
+
const groups = (0, tree_js_1.buildTestTree)(artifacts);
|
|
13
|
+
const durationMs = options.durationMs ??
|
|
14
|
+
Math.max(0, new Date(artifacts.completedAt).getTime() - new Date(artifacts.startedAt).getTime());
|
|
15
|
+
const passedCount = options.passedCount ?? 0;
|
|
16
|
+
const runStatus = (0, status_js_1.statusLabel)(artifacts.status, artifacts.failureCount);
|
|
17
|
+
const statusIcon = runStatus === 'passed' ? icons_js_1.STATUS_ICON_PASSED : icons_js_1.STATUS_ICON_FAILED;
|
|
18
|
+
const embeddedData = {
|
|
19
|
+
runId: artifacts.runId,
|
|
20
|
+
};
|
|
21
|
+
const passedChip = passedCount > 0 ? `<span class="summary-chip passed">${passedCount} passed</span>` : '';
|
|
22
|
+
const failedChip = artifacts.failureCount > 0
|
|
23
|
+
? `<span class="summary-chip failed">${artifacts.failureCount} failed</span>`
|
|
24
|
+
: '';
|
|
25
|
+
const healedChip = artifacts.healCount > 0
|
|
26
|
+
? `<span class="summary-chip healed">⚡ ${artifacts.healCount} healed</span>`
|
|
27
|
+
: `<span class="summary-chip neutral">0 healed</span>`;
|
|
28
|
+
return `<!DOCTYPE html>
|
|
29
|
+
<html lang="en">
|
|
30
|
+
<head>
|
|
31
|
+
<meta charset="UTF-8" />
|
|
32
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
33
|
+
<title>HealFlow Report</title>
|
|
34
|
+
<style>${styles_js_1.REPORT_STYLES}</style>
|
|
35
|
+
</head>
|
|
36
|
+
<body>
|
|
37
|
+
<div class="app">
|
|
38
|
+
<header class="header-view">
|
|
39
|
+
<div class="header-brand">
|
|
40
|
+
<div class="header-logo" aria-hidden="true">HF</div>
|
|
41
|
+
<div>
|
|
42
|
+
<div class="header-title">HealFlow Report</div>
|
|
43
|
+
<div class="header-subtitle">${(0, format_js_1.escapeHtml)((0, format_js_1.formatTimestamp)(artifacts.completedAt))}</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="header-view-status-container">
|
|
47
|
+
${passedChip}
|
|
48
|
+
${failedChip}
|
|
49
|
+
${healedChip}
|
|
50
|
+
<span class="summary-chip neutral">${(0, format_js_1.escapeHtml)((0, format_js_1.formatDuration)(durationMs))}</span>
|
|
51
|
+
<span class="summary-chip neutral">${(0, format_js_1.escapeHtml)(artifacts.mode)} mode</span>
|
|
52
|
+
</div>
|
|
53
|
+
</header>
|
|
54
|
+
|
|
55
|
+
<div class="main-layout">
|
|
56
|
+
<aside class="sidebar" aria-label="Test tree">
|
|
57
|
+
<div class="sidebar-toolbar">
|
|
58
|
+
<input id="tree-search" class="search-input" type="search" placeholder="Search tests…" aria-label="Search tests" />
|
|
59
|
+
</div>
|
|
60
|
+
<div class="tree-panel">
|
|
61
|
+
<div class="tree-item test-tree-item overview-tree-item selected" data-test-id="" role="button" tabindex="0">
|
|
62
|
+
<span class="status-icon" aria-hidden="true">${statusIcon}</span>
|
|
63
|
+
<span class="tree-item-title">Run summary</span>
|
|
64
|
+
</div>
|
|
65
|
+
${(0, render_js_1.renderSidebarTree)(groups)}
|
|
66
|
+
</div>
|
|
67
|
+
</aside>
|
|
68
|
+
|
|
69
|
+
<main class="content">
|
|
70
|
+
<section class="overview-panel" id="overview-panel">
|
|
71
|
+
<div class="test-file-title-row">
|
|
72
|
+
<span class="status-icon" aria-hidden="true">${statusIcon}</span>
|
|
73
|
+
<h2 class="test-file-title">Run summary</h2>
|
|
74
|
+
</div>
|
|
75
|
+
<p class="muted">Status: <span class="run-status ${runStatus}">${(0, format_js_1.escapeHtml)(runStatus)}</span></p>
|
|
76
|
+
|
|
77
|
+
<div class="overview-grid">
|
|
78
|
+
<div class="meta-card">
|
|
79
|
+
<div class="label">Heals</div>
|
|
80
|
+
<div class="value">${artifacts.healCount}</div>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="meta-card">
|
|
83
|
+
<div class="label">Failures</div>
|
|
84
|
+
<div class="value">${artifacts.failureCount}</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="meta-card">
|
|
87
|
+
<div class="label">Fix proposals</div>
|
|
88
|
+
<div class="value">${artifacts.fixes.length}</div>
|
|
89
|
+
</div>
|
|
90
|
+
<div class="meta-card">
|
|
91
|
+
<div class="label">Duration</div>
|
|
92
|
+
<div class="value">${(0, format_js_1.escapeHtml)((0, format_js_1.formatDuration)(durationMs))}</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<section class="detail-section">
|
|
97
|
+
<div class="chip-header">Run metadata</div>
|
|
98
|
+
<div class="chip-body">
|
|
99
|
+
<div class="detail-grid">
|
|
100
|
+
<div class="detail-row">
|
|
101
|
+
<span class="detail-label">Run ID</span>
|
|
102
|
+
<span class="detail-value mono">${(0, format_js_1.escapeHtml)(artifacts.runId)}</span>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="detail-row">
|
|
105
|
+
<span class="detail-label">Started</span>
|
|
106
|
+
<span class="detail-value">${(0, format_js_1.escapeHtml)((0, format_js_1.formatTimestamp)(artifacts.startedAt))}</span>
|
|
107
|
+
</div>
|
|
108
|
+
<div class="detail-row">
|
|
109
|
+
<span class="detail-label">Completed</span>
|
|
110
|
+
<span class="detail-value">${(0, format_js_1.escapeHtml)((0, format_js_1.formatTimestamp)(artifacts.completedAt))}</span>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="detail-row">
|
|
113
|
+
<span class="detail-label">Mode</span>
|
|
114
|
+
<span class="detail-value">${(0, format_js_1.escapeHtml)(artifacts.mode)}</span>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</section>
|
|
119
|
+
|
|
120
|
+
<section class="detail-section">
|
|
121
|
+
<div class="chip-header">Heal categories</div>
|
|
122
|
+
<div class="chip-body">
|
|
123
|
+
${(0, render_js_1.renderCategorySummary)(artifacts.heals)}
|
|
124
|
+
</div>
|
|
125
|
+
</section>
|
|
126
|
+
</section>
|
|
127
|
+
|
|
128
|
+
${(0, render_js_1.renderTestDetailPanels)(groups)}
|
|
129
|
+
</main>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<script id="healflow-data" type="application/json">${(0, format_js_1.escapeHtml)(JSON.stringify(embeddedData))}</script>
|
|
134
|
+
<script>${script_js_1.REPORT_SCRIPT}</script>
|
|
135
|
+
</body>
|
|
136
|
+
</html>`;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/report-html/build.ts"],"names":[],"mappings":";;AAcA,0CA0IC;AAvJD,2CAA0E;AAC1E,yCAAoE;AACpE,2CAA+F;AAC/F,2CAA4C;AAC5C,2CAA4C;AAC5C,uCAA0C;AAC1C,2CAA0C;AAO1C,SAAgB,eAAe,CAC7B,SAA+B,EAC/B,UAA6B,EAAE;IAE/B,MAAM,MAAM,GAAG,IAAA,uBAAa,EAAC,SAAS,CAAC,CAAC;IACxC,MAAM,UAAU,GACd,OAAO,CAAC,UAAU;QAClB,IAAI,CAAC,GAAG,CACN,CAAC,EACD,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CACpF,CAAC;IACJ,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAA,uBAAW,EAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,6BAAkB,CAAC,CAAC,CAAC,6BAAkB,CAAC;IACpF,MAAM,YAAY,GAAG;QACnB,KAAK,EAAE,SAAS,CAAC,KAAK;KACvB,CAAC;IAEF,MAAM,UAAU,GACd,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,qCAAqC,WAAW,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1F,MAAM,UAAU,GACd,SAAS,CAAC,YAAY,GAAG,CAAC;QACxB,CAAC,CAAC,qCAAqC,SAAS,CAAC,YAAY,gBAAgB;QAC7E,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,UAAU,GACd,SAAS,CAAC,SAAS,GAAG,CAAC;QACrB,CAAC,CAAC,uCAAuC,SAAS,CAAC,SAAS,gBAAgB;QAC5E,CAAC,CAAC,oDAAoD,CAAC;IAE3D,OAAO;;;;;;WAME,yBAAa;;;;;;;;;yCASiB,IAAA,sBAAU,EAAC,IAAA,2BAAe,EAAC,SAAS,CAAC,WAAW,CAAC,CAAC;;;;UAIjF,UAAU;UACV,UAAU;UACV,UAAU;6CACyB,IAAA,sBAAU,EAAC,IAAA,0BAAc,EAAC,UAAU,CAAC,CAAC;6CACtC,IAAA,sBAAU,EAAC,SAAS,CAAC,IAAI,CAAC;;;;;;;;;;;2DAWZ,UAAU;;;YAGzD,IAAA,6BAAiB,EAAC,MAAM,CAAC;;;;;;;2DAOsB,UAAU;;;6DAGR,SAAS,KAAK,IAAA,sBAAU,EAAC,SAAS,CAAC;;;;;mCAK7D,SAAS,CAAC,SAAS;;;;mCAInB,SAAS,CAAC,YAAY;;;;mCAItB,SAAS,CAAC,KAAK,CAAC,MAAM;;;;mCAItB,IAAA,sBAAU,EAAC,IAAA,0BAAc,EAAC,UAAU,CAAC,CAAC;;;;;;;;;;oDAUrB,IAAA,sBAAU,EAAC,SAAS,CAAC,KAAK,CAAC;;;;+CAIhC,IAAA,sBAAU,EAAC,IAAA,2BAAe,EAAC,SAAS,CAAC,SAAS,CAAC,CAAC;;;;+CAIhD,IAAA,sBAAU,EAAC,IAAA,2BAAe,EAAC,SAAS,CAAC,WAAW,CAAC,CAAC;;;;+CAIlD,IAAA,sBAAU,EAAC,SAAS,CAAC,IAAI,CAAC;;;;;;;;;gBASzD,IAAA,iCAAqB,EAAC,SAAS,CAAC,KAAK,CAAC;;;;;UAK5C,IAAA,kCAAsB,EAAC,MAAM,CAAC;;;;;uDAKe,IAAA,sBAAU,EAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YACnF,yBAAa;;QAEjB,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function escapeHtml(value: string): string;
|
|
2
|
+
export declare function formatDuration(ms: number): string;
|
|
3
|
+
export declare function formatTimestamp(iso: string): string;
|
|
4
|
+
export declare function formatConfidence(confidence: number): string;
|
|
5
|
+
export declare function slugify(value: string): string;
|
|
6
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/report-html/format.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK7C"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.escapeHtml = escapeHtml;
|
|
4
|
+
exports.formatDuration = formatDuration;
|
|
5
|
+
exports.formatTimestamp = formatTimestamp;
|
|
6
|
+
exports.formatConfidence = formatConfidence;
|
|
7
|
+
exports.slugify = slugify;
|
|
8
|
+
function escapeHtml(value) {
|
|
9
|
+
return value
|
|
10
|
+
.replace(/&/g, '&')
|
|
11
|
+
.replace(/</g, '<')
|
|
12
|
+
.replace(/>/g, '>')
|
|
13
|
+
.replace(/"/g, '"');
|
|
14
|
+
}
|
|
15
|
+
function formatDuration(ms) {
|
|
16
|
+
if (ms < 1000)
|
|
17
|
+
return `${Math.round(ms)}ms`;
|
|
18
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
19
|
+
}
|
|
20
|
+
function formatTimestamp(iso) {
|
|
21
|
+
try {
|
|
22
|
+
return new Date(iso).toLocaleString();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return iso;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function formatConfidence(confidence) {
|
|
29
|
+
return `${Math.round(confidence * 100)}%`;
|
|
30
|
+
}
|
|
31
|
+
function slugify(value) {
|
|
32
|
+
return value
|
|
33
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
34
|
+
.replace(/^-|-$/g, '')
|
|
35
|
+
.toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/report-html/format.ts"],"names":[],"mappings":";;AAAA,gCAMC;AAED,wCAGC;AAED,0CAMC;AAED,4CAEC;AAED,0BAKC;AA9BD,SAAgB,UAAU,CAAC,KAAa;IACtC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,cAAc,CAAC,EAAU;IACvC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;IAC5C,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACtC,CAAC;AAED,SAAgB,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAgB,gBAAgB,CAAC,UAAkB;IACjD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC;AAC5C,CAAC;AAED,SAAgB,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;SAC9B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,WAAW,EAAE,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const STATUS_ICON_PASSED = "<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\"><circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#1a7f37\"/><path d=\"M6.5 10.5 4 8l1-1 1.5 1.5L11 4l1 1-5.5 5.5Z\" fill=\"#fff\"/></svg>";
|
|
2
|
+
export declare const STATUS_ICON_FAILED = "<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\"><circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#cf222e\"/><path d=\"M5 5l6 6M11 5l-6 6\" stroke=\"#fff\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg>";
|
|
3
|
+
export declare const STATUS_ICON_HEALED = "<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\"><circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#0969da\"/><path d=\"M8 3.5a1 1 0 0 1 .9.6l1.4 2.8 3.1.5a1 1 0 0 1 .55 1.7l-2.2 2.2.5 3.1a1 1 0 0 1-1.45 1.05L8 13.2l-2.8 1.5a1 1 0 0 1-1.45-1.05l.5-3.1-2.2-2.2a1 1 0 0 1 .55-1.7l3.1-.5 1.4-2.8A1 1 0 0 1 8 3.5Z\" fill=\"#fff\"/></svg>";
|
|
4
|
+
//# sourceMappingURL=icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/report-html/icons.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,4LAC0I,CAAC;AAE1K,eAAO,MAAM,kBAAkB,mNAC6J,CAAC;AAE7L,eAAO,MAAM,kBAAkB,8UAC4R,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STATUS_ICON_HEALED = exports.STATUS_ICON_FAILED = exports.STATUS_ICON_PASSED = void 0;
|
|
4
|
+
exports.STATUS_ICON_PASSED = '<svg viewBox="0 0 16 16" width="16" height="16"><circle cx="8" cy="8" r="8" fill="#1a7f37"/><path d="M6.5 10.5 4 8l1-1 1.5 1.5L11 4l1 1-5.5 5.5Z" fill="#fff"/></svg>';
|
|
5
|
+
exports.STATUS_ICON_FAILED = '<svg viewBox="0 0 16 16" width="16" height="16"><circle cx="8" cy="8" r="8" fill="#cf222e"/><path d="M5 5l6 6M11 5l-6 6" stroke="#fff" stroke-width="1.5" stroke-linecap="round"/></svg>';
|
|
6
|
+
exports.STATUS_ICON_HEALED = '<svg viewBox="0 0 16 16" width="16" height="16"><circle cx="8" cy="8" r="8" fill="#0969da"/><path d="M8 3.5a1 1 0 0 1 .9.6l1.4 2.8 3.1.5a1 1 0 0 1 .55 1.7l-2.2 2.2.5 3.1a1 1 0 0 1-1.45 1.05L8 13.2l-2.8 1.5a1 1 0 0 1-1.45-1.05l.5-3.1-2.2-2.2a1 1 0 0 1 .55-1.7l3.1-.5 1.4-2.8A1 1 0 0 1 8 3.5Z" fill="#fff"/></svg>';
|
|
7
|
+
//# sourceMappingURL=icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/report-html/icons.ts"],"names":[],"mappings":";;;AAAa,QAAA,kBAAkB,GAC7B,uKAAuK,CAAC;AAE7J,QAAA,kBAAkB,GAC7B,0LAA0L,CAAC;AAEhL,QAAA,kBAAkB,GAC7B,yTAAyT,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report-html/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildReportHtml = void 0;
|
|
4
|
+
var build_js_1 = require("./build.js");
|
|
5
|
+
Object.defineProperty(exports, "buildReportHtml", { enumerable: true, get: function () { return build_js_1.buildReportHtml; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/report-html/index.ts"],"names":[],"mappings":";;;AACA,uCAA6C;AAApC,2GAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RuntimeHealRecord } from '@healflow/shared';
|
|
2
|
+
import type { FileGroup } from './types.js';
|
|
3
|
+
export declare function renderSidebarTree(groups: FileGroup[]): string;
|
|
4
|
+
export declare function renderTestDetailPanels(groups: FileGroup[]): string;
|
|
5
|
+
export declare function renderCategorySummary(heals: RuntimeHealRecord[]): string;
|
|
6
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/report-html/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAK7E,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,YAAY,CAAC;AAE3D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CA6B7D;AAsED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAuBlE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAkBxE"}
|