donobu 5.8.5 → 5.9.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.
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Donobu HTML Reporter for Playwright
4
+ *
5
+ * A Playwright reporter that generates a Donobu-branded HTML report directly,
6
+ * without requiring a separate JSON post-processing step.
7
+ *
8
+ * @usage
9
+ * ```ts
10
+ * // playwright.config.ts
11
+ * import { defineConfig } from 'donobu';
12
+ * export default defineConfig({
13
+ * reporter: [
14
+ * ['donobu/reporter/html', { outputFile: 'test-results/donobu-report.html' }],
15
+ * ],
16
+ * });
17
+ * ```
18
+ *
19
+ * Optionally enrich the report with Donobu AI triage data:
20
+ * ```ts
21
+ * reporter: [
22
+ * ['donobu/reporter/html', {
23
+ * outputFile: 'test-results/donobu-report.html',
24
+ * triageDir: process.env.DONOBU_TRIAGE_DIR,
25
+ * }],
26
+ * ],
27
+ * ```
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ const fs_1 = require("fs");
31
+ const path_1 = require("path");
32
+ const playwright_json_to_html_1 = require("../cli/playwright-json-to-html");
33
+ class DonobuHtmlReporter {
34
+ constructor(options = {}) {
35
+ /** Accumulates all TestResult objects per TestCase (one per retry attempt). */
36
+ this.resultsByTest = new Map();
37
+ this.options = options;
38
+ }
39
+ onTestEnd(test, result) {
40
+ const existing = this.resultsByTest.get(test);
41
+ if (existing) {
42
+ existing.push(result);
43
+ }
44
+ else {
45
+ this.resultsByTest.set(test, [result]);
46
+ }
47
+ }
48
+ async onEnd(_result) {
49
+ // During an auto-heal rerun the CLI will regenerate the HTML from the
50
+ // merged report (which combines both runs and includes self-heal context).
51
+ // Generating here would overwrite the initial run's HTML with incomplete data.
52
+ if (process.env.DONOBU_AUTO_HEAL_ACTIVE === '1') {
53
+ return;
54
+ }
55
+ const outputFile = (0, path_1.resolve)(this.options.outputFile ?? 'test-results/donobu-report.html');
56
+ const outputDir = (0, path_1.dirname)(outputFile);
57
+ const triage = this.options.triageDir
58
+ ? (0, playwright_json_to_html_1.loadTriageData)((0, path_1.resolve)(this.options.triageDir))
59
+ : { plans: [], evidence: [] };
60
+ const jsonData = this.buildJsonData();
61
+ const html = (0, playwright_json_to_html_1.generateHtml)(jsonData, triage, outputDir);
62
+ (0, fs_1.mkdirSync)(outputDir, { recursive: true });
63
+ (0, fs_1.writeFileSync)(outputFile, html, 'utf8');
64
+ console.error(`Donobu report written to ${outputFile}`);
65
+ // Write a sidecar so the CLI can find and regenerate this report from the
66
+ // merged JSON after an auto-heal run completes.
67
+ const playwrightOutputDir = process.env.PLAYWRIGHT_JSON_OUTPUT_DIR;
68
+ if (playwrightOutputDir) {
69
+ const sidecarPath = (0, path_1.join)(playwrightOutputDir, '.donobu-html-reporter.json');
70
+ try {
71
+ (0, fs_1.writeFileSync)(sidecarPath, JSON.stringify({ outputFile }), 'utf8');
72
+ }
73
+ catch {
74
+ // Non-fatal — worst case the CLI falls back to no HTML regeneration.
75
+ }
76
+ }
77
+ }
78
+ printsToStdio() {
79
+ return false;
80
+ }
81
+ /**
82
+ * Reconstruct the JSON structure that `generateHtml` / `extractTests` expects,
83
+ * from the TestCase + TestResult objects collected during the run.
84
+ *
85
+ * Structure: suites (one per file) → specs (one per test title) → tests (one per project).
86
+ */
87
+ buildJsonData() {
88
+ // Group tests by file path, then by test title.
89
+ // Multiple TestCase objects with the same (file, title) represent the same
90
+ // spec running under different Playwright projects.
91
+ const byFile = new Map();
92
+ for (const test of this.resultsByTest.keys()) {
93
+ const file = test.location.file;
94
+ if (!byFile.has(file)) {
95
+ byFile.set(file, new Map());
96
+ }
97
+ const byTitle = byFile.get(file);
98
+ if (!byTitle.has(test.title)) {
99
+ byTitle.set(test.title, []);
100
+ }
101
+ byTitle.get(test.title).push(test);
102
+ }
103
+ const suites = [];
104
+ for (const [file, titleMap] of byFile) {
105
+ const specs = [];
106
+ for (const [title, tests] of titleMap) {
107
+ const testEntries = tests.map((test) => {
108
+ const results = this.resultsByTest.get(test) ?? [];
109
+ return {
110
+ annotations: test.annotations,
111
+ projectName: this.getProjectName(test),
112
+ // Signal "skipped" tests to extractTests the same way the JSON reporter does.
113
+ status: test.expectedStatus === 'skipped' ? 'skipped' : undefined,
114
+ results: results.map((r) => ({
115
+ status: r.status,
116
+ duration: r.duration,
117
+ retry: r.retry,
118
+ startTime: r.startTime?.toISOString() ?? null,
119
+ // Pass errors through; cast to any to preserve runtime-only fields
120
+ // (snippet, actual, expected) that Playwright adds to assertion errors.
121
+ errors: r.errors.map((e) => ({
122
+ message: e.message,
123
+ stack: e.stack,
124
+ snippet: e.snippet,
125
+ actual: e.actual,
126
+ expected: e.expected,
127
+ location: e.location,
128
+ })),
129
+ attachments: r.attachments.map((a) => ({
130
+ name: a.name,
131
+ contentType: a.contentType,
132
+ path: a.path ?? null,
133
+ // Playwright Reporter API provides body as a Buffer; the HTML
134
+ // generator expects a base64-encoded string (matching JSON format).
135
+ body: a.body ? a.body.toString('base64') : undefined,
136
+ })),
137
+ // TestResult.stderr is already Array<{text?: string; buffer?: string}>,
138
+ // which is the same shape parseStderrSteps expects.
139
+ stderr: r.stderr,
140
+ })),
141
+ };
142
+ });
143
+ specs.push({ title, tests: testEntries });
144
+ }
145
+ suites.push({ file, specs });
146
+ }
147
+ return { suites, metadata: {} };
148
+ }
149
+ /** Walk up the suite chain to find the enclosing project suite's title. */
150
+ getProjectName(test) {
151
+ let suite = test.parent;
152
+ while (suite) {
153
+ if (suite.type === 'project') {
154
+ return suite.title;
155
+ }
156
+ suite = suite.parent;
157
+ }
158
+ return '';
159
+ }
160
+ }
161
+ exports.default = DonobuHtmlReporter;
162
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/reporter/html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @fileoverview Donobu HTML Reporter for Playwright
3
+ *
4
+ * A Playwright reporter that generates a Donobu-branded HTML report directly,
5
+ * without requiring a separate JSON post-processing step.
6
+ *
7
+ * @usage
8
+ * ```ts
9
+ * // playwright.config.ts
10
+ * import { defineConfig } from 'donobu';
11
+ * export default defineConfig({
12
+ * reporter: [
13
+ * ['donobu/reporter/html', { outputFile: 'test-results/donobu-report.html' }],
14
+ * ],
15
+ * });
16
+ * ```
17
+ *
18
+ * Optionally enrich the report with Donobu AI triage data:
19
+ * ```ts
20
+ * reporter: [
21
+ * ['donobu/reporter/html', {
22
+ * outputFile: 'test-results/donobu-report.html',
23
+ * triageDir: process.env.DONOBU_TRIAGE_DIR,
24
+ * }],
25
+ * ],
26
+ * ```
27
+ */
28
+ import type { FullResult, Reporter, TestCase, TestResult } from '@playwright/test/reporter';
29
+ export interface DonobuHtmlReporterOptions {
30
+ /** Path to write the HTML report. Defaults to `test-results/donobu-report.html`. */
31
+ outputFile?: string;
32
+ /**
33
+ * Path to a Donobu triage run directory containing `treatment-plan-*.json`
34
+ * and `failure-evidence-*.json` files. When provided, the report is enriched
35
+ * with AI failure analysis. Corresponds to `--triage-dir` in the CLI.
36
+ */
37
+ triageDir?: string;
38
+ }
39
+ export default class DonobuHtmlReporter implements Reporter {
40
+ private readonly options;
41
+ /** Accumulates all TestResult objects per TestCase (one per retry attempt). */
42
+ private readonly resultsByTest;
43
+ constructor(options?: DonobuHtmlReporterOptions);
44
+ onTestEnd(test: TestCase, result: TestResult): void;
45
+ onEnd(_result: FullResult): Promise<void>;
46
+ printsToStdio(): boolean;
47
+ /**
48
+ * Reconstruct the JSON structure that `generateHtml` / `extractTests` expects,
49
+ * from the TestCase + TestResult objects collected during the run.
50
+ *
51
+ * Structure: suites (one per file) → specs (one per test title) → tests (one per project).
52
+ */
53
+ private buildJsonData;
54
+ /** Walk up the suite chain to find the enclosing project suite's title. */
55
+ private getProjectName;
56
+ }
57
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/reporter/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EAER,QAAQ,EACR,UAAU,EACX,MAAM,2BAA2B,CAAC;AAMnC,MAAM,WAAW,yBAAyB;IACxC,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,CAAC,OAAO,OAAO,kBAAmB,YAAW,QAAQ;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,+EAA+E;IAC/E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqC;gBAEvD,OAAO,GAAE,yBAA8B;IAInD,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAS7C,KAAK,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAwC/C,aAAa,IAAI,OAAO;IAIxB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAkErB,2EAA2E;IAC3E,OAAO,CAAC,cAAc;CAUvB"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ /**
3
+ * @fileoverview Donobu HTML Reporter for Playwright
4
+ *
5
+ * A Playwright reporter that generates a Donobu-branded HTML report directly,
6
+ * without requiring a separate JSON post-processing step.
7
+ *
8
+ * @usage
9
+ * ```ts
10
+ * // playwright.config.ts
11
+ * import { defineConfig } from 'donobu';
12
+ * export default defineConfig({
13
+ * reporter: [
14
+ * ['donobu/reporter/html', { outputFile: 'test-results/donobu-report.html' }],
15
+ * ],
16
+ * });
17
+ * ```
18
+ *
19
+ * Optionally enrich the report with Donobu AI triage data:
20
+ * ```ts
21
+ * reporter: [
22
+ * ['donobu/reporter/html', {
23
+ * outputFile: 'test-results/donobu-report.html',
24
+ * triageDir: process.env.DONOBU_TRIAGE_DIR,
25
+ * }],
26
+ * ],
27
+ * ```
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ const fs_1 = require("fs");
31
+ const path_1 = require("path");
32
+ const playwright_json_to_html_1 = require("../cli/playwright-json-to-html");
33
+ class DonobuHtmlReporter {
34
+ constructor(options = {}) {
35
+ /** Accumulates all TestResult objects per TestCase (one per retry attempt). */
36
+ this.resultsByTest = new Map();
37
+ this.options = options;
38
+ }
39
+ onTestEnd(test, result) {
40
+ const existing = this.resultsByTest.get(test);
41
+ if (existing) {
42
+ existing.push(result);
43
+ }
44
+ else {
45
+ this.resultsByTest.set(test, [result]);
46
+ }
47
+ }
48
+ async onEnd(_result) {
49
+ // During an auto-heal rerun the CLI will regenerate the HTML from the
50
+ // merged report (which combines both runs and includes self-heal context).
51
+ // Generating here would overwrite the initial run's HTML with incomplete data.
52
+ if (process.env.DONOBU_AUTO_HEAL_ACTIVE === '1') {
53
+ return;
54
+ }
55
+ const outputFile = (0, path_1.resolve)(this.options.outputFile ?? 'test-results/donobu-report.html');
56
+ const outputDir = (0, path_1.dirname)(outputFile);
57
+ const triage = this.options.triageDir
58
+ ? (0, playwright_json_to_html_1.loadTriageData)((0, path_1.resolve)(this.options.triageDir))
59
+ : { plans: [], evidence: [] };
60
+ const jsonData = this.buildJsonData();
61
+ const html = (0, playwright_json_to_html_1.generateHtml)(jsonData, triage, outputDir);
62
+ (0, fs_1.mkdirSync)(outputDir, { recursive: true });
63
+ (0, fs_1.writeFileSync)(outputFile, html, 'utf8');
64
+ console.error(`Donobu report written to ${outputFile}`);
65
+ // Write a sidecar so the CLI can find and regenerate this report from the
66
+ // merged JSON after an auto-heal run completes.
67
+ const playwrightOutputDir = process.env.PLAYWRIGHT_JSON_OUTPUT_DIR;
68
+ if (playwrightOutputDir) {
69
+ const sidecarPath = (0, path_1.join)(playwrightOutputDir, '.donobu-html-reporter.json');
70
+ try {
71
+ (0, fs_1.writeFileSync)(sidecarPath, JSON.stringify({ outputFile }), 'utf8');
72
+ }
73
+ catch {
74
+ // Non-fatal — worst case the CLI falls back to no HTML regeneration.
75
+ }
76
+ }
77
+ }
78
+ printsToStdio() {
79
+ return false;
80
+ }
81
+ /**
82
+ * Reconstruct the JSON structure that `generateHtml` / `extractTests` expects,
83
+ * from the TestCase + TestResult objects collected during the run.
84
+ *
85
+ * Structure: suites (one per file) → specs (one per test title) → tests (one per project).
86
+ */
87
+ buildJsonData() {
88
+ // Group tests by file path, then by test title.
89
+ // Multiple TestCase objects with the same (file, title) represent the same
90
+ // spec running under different Playwright projects.
91
+ const byFile = new Map();
92
+ for (const test of this.resultsByTest.keys()) {
93
+ const file = test.location.file;
94
+ if (!byFile.has(file)) {
95
+ byFile.set(file, new Map());
96
+ }
97
+ const byTitle = byFile.get(file);
98
+ if (!byTitle.has(test.title)) {
99
+ byTitle.set(test.title, []);
100
+ }
101
+ byTitle.get(test.title).push(test);
102
+ }
103
+ const suites = [];
104
+ for (const [file, titleMap] of byFile) {
105
+ const specs = [];
106
+ for (const [title, tests] of titleMap) {
107
+ const testEntries = tests.map((test) => {
108
+ const results = this.resultsByTest.get(test) ?? [];
109
+ return {
110
+ annotations: test.annotations,
111
+ projectName: this.getProjectName(test),
112
+ // Signal "skipped" tests to extractTests the same way the JSON reporter does.
113
+ status: test.expectedStatus === 'skipped' ? 'skipped' : undefined,
114
+ results: results.map((r) => ({
115
+ status: r.status,
116
+ duration: r.duration,
117
+ retry: r.retry,
118
+ startTime: r.startTime?.toISOString() ?? null,
119
+ // Pass errors through; cast to any to preserve runtime-only fields
120
+ // (snippet, actual, expected) that Playwright adds to assertion errors.
121
+ errors: r.errors.map((e) => ({
122
+ message: e.message,
123
+ stack: e.stack,
124
+ snippet: e.snippet,
125
+ actual: e.actual,
126
+ expected: e.expected,
127
+ location: e.location,
128
+ })),
129
+ attachments: r.attachments.map((a) => ({
130
+ name: a.name,
131
+ contentType: a.contentType,
132
+ path: a.path ?? null,
133
+ // Playwright Reporter API provides body as a Buffer; the HTML
134
+ // generator expects a base64-encoded string (matching JSON format).
135
+ body: a.body ? a.body.toString('base64') : undefined,
136
+ })),
137
+ // TestResult.stderr is already Array<{text?: string; buffer?: string}>,
138
+ // which is the same shape parseStderrSteps expects.
139
+ stderr: r.stderr,
140
+ })),
141
+ };
142
+ });
143
+ specs.push({ title, tests: testEntries });
144
+ }
145
+ suites.push({ file, specs });
146
+ }
147
+ return { suites, metadata: {} };
148
+ }
149
+ /** Walk up the suite chain to find the enclosing project suite's title. */
150
+ getProjectName(test) {
151
+ let suite = test.parent;
152
+ while (suite) {
153
+ if (suite.type === 'project') {
154
+ return suite.title;
155
+ }
156
+ suite = suite.parent;
157
+ }
158
+ return '';
159
+ }
160
+ }
161
+ exports.default = DonobuHtmlReporter;
162
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/reporter/html.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;AASH,2BAA8C;AAC9C,+BAA8C;AAE9C,4EAA8E;AAa9E,MAAqB,kBAAkB;IAKrC,YAAY,UAAqC,EAAE;QAHnD,+EAA+E;QAC9D,kBAAa,GAAG,IAAI,GAAG,EAA0B,CAAC;QAGjE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,SAAS,CAAC,IAAc,EAAE,MAAkB;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAmB;QAC7B,sEAAsE;QACtE,2EAA2E;QAC3E,+EAA+E;QAC/E,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,GAAG,EAAE,CAAC;YAChD,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,IAAA,cAAO,EACxB,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,iCAAiC,CAC7D,CAAC;QACF,MAAM,SAAS,GAAG,IAAA,cAAO,EAAC,UAAU,CAAC,CAAC;QAEtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS;YACnC,CAAC,CAAC,IAAA,wCAAc,EAAC,IAAA,cAAO,EAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACjD,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,IAAA,sCAAY,EAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAEvD,IAAA,cAAS,EAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAA,kBAAa,EAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAC;QAExD,0EAA0E;QAC1E,gDAAgD;QAChD,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;QACnE,IAAI,mBAAmB,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG,IAAA,WAAI,EACtB,mBAAmB,EACnB,4BAA4B,CAC7B,CAAC;YACF,IAAI,CAAC;gBACH,IAAA,kBAAa,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YACrE,CAAC;YAAC,MAAM,CAAC;gBACP,qEAAqE;YACvE,CAAC;QACH,CAAC;IACH,CAAC;IAED,aAAa;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;OAKG;IACK,aAAa;QACnB,gDAAgD;QAChD,2EAA2E;QAC3E,oDAAoD;QACpD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAmC,CAAC;QAE1D,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;YAC9B,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC;YACtC,MAAM,KAAK,GAAc,EAAE,CAAC;YAC5B,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACtC,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;oBACrC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACnD,OAAO;wBACL,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;wBACtC,8EAA8E;wBAC9E,MAAM,EAAE,IAAI,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;wBACjE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC3B,MAAM,EAAE,CAAC,CAAC,MAAM;4BAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ;4BACpB,KAAK,EAAE,CAAC,CAAC,KAAK;4BACd,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,IAAI;4BAC7C,mEAAmE;4BACnE,wEAAwE;4BACxE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gCAC3B,OAAO,EAAG,CAAS,CAAC,OAAO;gCAC3B,KAAK,EAAG,CAAS,CAAC,KAAK;gCACvB,OAAO,EAAG,CAAS,CAAC,OAAO;gCAC3B,MAAM,EAAG,CAAS,CAAC,MAAM;gCACzB,QAAQ,EAAG,CAAS,CAAC,QAAQ;gCAC7B,QAAQ,EAAE,CAAC,CAAC,QAAQ;6BACrB,CAAC,CAAC;4BACH,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gCACrC,IAAI,EAAE,CAAC,CAAC,IAAI;gCACZ,WAAW,EAAE,CAAC,CAAC,WAAW;gCAC1B,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI;gCACpB,8DAA8D;gCAC9D,oEAAoE;gCACpE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;6BACrD,CAAC,CAAC;4BACH,wEAAwE;4BACxE,oDAAoD;4BACpD,MAAM,EAAE,CAAC,CAAC,MAAM;yBACjB,CAAC,CAAC;qBACJ,CAAC;gBACJ,CAAC,CAAC,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAClC,CAAC;IAED,2EAA2E;IACnE,cAAc,CAAC,IAAc;QACnC,IAAI,KAAK,GAAsB,IAAI,CAAC,MAAM,CAAC;QAC3C,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,KAAK,CAAC,KAAK,CAAC;YACrB,CAAC;YACD,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;QACvB,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAjJD,qCAiJC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "donobu",
3
- "version": "5.8.5",
3
+ "version": "5.9.1",
4
4
  "description": "Create browser automations with an LLM agent and replay them as Playwright scripts.",
5
5
  "main": "dist/main.js",
6
6
  "module": "dist/esm/main.js",
@@ -10,9 +10,15 @@
10
10
  "npm": ">=8"
11
11
  },
12
12
  "exports": {
13
- "types": "./dist/main.d.ts",
14
- "import": "./dist/esm/main.js",
15
- "require": "./dist/main.js"
13
+ ".": {
14
+ "types": "./dist/main.d.ts",
15
+ "import": "./dist/esm/main.js",
16
+ "require": "./dist/main.js"
17
+ },
18
+ "./reporter/html": {
19
+ "types": "./dist/reporter/html.d.ts",
20
+ "require": "./dist/reporter/html.js"
21
+ }
16
22
  },
17
23
  "bin": {
18
24
  "donobu": "./dist/cli/donobu-cli.js",