@yasserkhanorg/e2e-agents 0.3.2

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.
Files changed (221) hide show
  1. package/LICENSE +168 -0
  2. package/README.md +620 -0
  3. package/dist/agent/analysis.d.ts +62 -0
  4. package/dist/agent/analysis.d.ts.map +1 -0
  5. package/dist/agent/analysis.js +292 -0
  6. package/dist/agent/blast_radius.d.ts +4 -0
  7. package/dist/agent/blast_radius.d.ts.map +1 -0
  8. package/dist/agent/blast_radius.js +37 -0
  9. package/dist/agent/cache_utils.d.ts +38 -0
  10. package/dist/agent/cache_utils.d.ts.map +1 -0
  11. package/dist/agent/cache_utils.js +67 -0
  12. package/dist/agent/config.d.ts +148 -0
  13. package/dist/agent/config.d.ts.map +1 -0
  14. package/dist/agent/config.js +640 -0
  15. package/dist/agent/dependency_graph.d.ts +14 -0
  16. package/dist/agent/dependency_graph.d.ts.map +1 -0
  17. package/dist/agent/dependency_graph.js +227 -0
  18. package/dist/agent/feedback.d.ts +55 -0
  19. package/dist/agent/feedback.d.ts.map +1 -0
  20. package/dist/agent/feedback.js +257 -0
  21. package/dist/agent/flags.d.ts +23 -0
  22. package/dist/agent/flags.d.ts.map +1 -0
  23. package/dist/agent/flags.js +171 -0
  24. package/dist/agent/flow_catalog.d.ts +25 -0
  25. package/dist/agent/flow_catalog.d.ts.map +1 -0
  26. package/dist/agent/flow_catalog.js +106 -0
  27. package/dist/agent/flow_mapping.d.ts +10 -0
  28. package/dist/agent/flow_mapping.d.ts.map +1 -0
  29. package/dist/agent/flow_mapping.js +84 -0
  30. package/dist/agent/framework.d.ts +13 -0
  31. package/dist/agent/framework.d.ts.map +1 -0
  32. package/dist/agent/framework.js +149 -0
  33. package/dist/agent/gap_suggestions.d.ts +14 -0
  34. package/dist/agent/gap_suggestions.d.ts.map +1 -0
  35. package/dist/agent/gap_suggestions.js +101 -0
  36. package/dist/agent/generator.d.ts +10 -0
  37. package/dist/agent/generator.d.ts.map +1 -0
  38. package/dist/agent/generator.js +115 -0
  39. package/dist/agent/git.d.ts +11 -0
  40. package/dist/agent/git.d.ts.map +1 -0
  41. package/dist/agent/git.js +90 -0
  42. package/dist/agent/handoff.d.ts +22 -0
  43. package/dist/agent/handoff.d.ts.map +1 -0
  44. package/dist/agent/handoff.js +180 -0
  45. package/dist/agent/impact-analyzer.d.ts +114 -0
  46. package/dist/agent/impact-analyzer.d.ts.map +1 -0
  47. package/dist/agent/impact-analyzer.js +557 -0
  48. package/dist/agent/index.d.ts +21 -0
  49. package/dist/agent/index.d.ts.map +1 -0
  50. package/dist/agent/index.js +38 -0
  51. package/dist/agent/model-router.d.ts +57 -0
  52. package/dist/agent/model-router.d.ts.map +1 -0
  53. package/dist/agent/model-router.js +154 -0
  54. package/dist/agent/operational_insights.d.ts +41 -0
  55. package/dist/agent/operational_insights.d.ts.map +1 -0
  56. package/dist/agent/operational_insights.js +126 -0
  57. package/dist/agent/pipeline.d.ts +23 -0
  58. package/dist/agent/pipeline.d.ts.map +1 -0
  59. package/dist/agent/pipeline.js +609 -0
  60. package/dist/agent/plan.d.ts +91 -0
  61. package/dist/agent/plan.d.ts.map +1 -0
  62. package/dist/agent/plan.js +331 -0
  63. package/dist/agent/playwright_report.d.ts +8 -0
  64. package/dist/agent/playwright_report.d.ts.map +1 -0
  65. package/dist/agent/playwright_report.js +126 -0
  66. package/dist/agent/report-generator.d.ts +24 -0
  67. package/dist/agent/report-generator.d.ts.map +1 -0
  68. package/dist/agent/report-generator.js +250 -0
  69. package/dist/agent/report.d.ts +81 -0
  70. package/dist/agent/report.d.ts.map +1 -0
  71. package/dist/agent/report.js +147 -0
  72. package/dist/agent/runner.d.ts +7 -0
  73. package/dist/agent/runner.d.ts.map +1 -0
  74. package/dist/agent/runner.js +576 -0
  75. package/dist/agent/selectors.d.ts +10 -0
  76. package/dist/agent/selectors.d.ts.map +1 -0
  77. package/dist/agent/selectors.js +75 -0
  78. package/dist/agent/spec-bridge.d.ts +101 -0
  79. package/dist/agent/spec-bridge.d.ts.map +1 -0
  80. package/dist/agent/spec-bridge.js +273 -0
  81. package/dist/agent/spec-builder.d.ts +102 -0
  82. package/dist/agent/spec-builder.d.ts.map +1 -0
  83. package/dist/agent/spec-builder.js +273 -0
  84. package/dist/agent/subsystem_risk.d.ts +23 -0
  85. package/dist/agent/subsystem_risk.d.ts.map +1 -0
  86. package/dist/agent/subsystem_risk.js +207 -0
  87. package/dist/agent/telemetry.d.ts +84 -0
  88. package/dist/agent/telemetry.d.ts.map +1 -0
  89. package/dist/agent/telemetry.js +220 -0
  90. package/dist/agent/test_path.d.ts +2 -0
  91. package/dist/agent/test_path.d.ts.map +1 -0
  92. package/dist/agent/test_path.js +23 -0
  93. package/dist/agent/tests.d.ts +18 -0
  94. package/dist/agent/tests.d.ts.map +1 -0
  95. package/dist/agent/tests.js +106 -0
  96. package/dist/agent/traceability.d.ts +22 -0
  97. package/dist/agent/traceability.d.ts.map +1 -0
  98. package/dist/agent/traceability.js +183 -0
  99. package/dist/agent/traceability_capture.d.ts +18 -0
  100. package/dist/agent/traceability_capture.d.ts.map +1 -0
  101. package/dist/agent/traceability_capture.js +313 -0
  102. package/dist/agent/traceability_ingest.d.ts +21 -0
  103. package/dist/agent/traceability_ingest.d.ts.map +1 -0
  104. package/dist/agent/traceability_ingest.js +237 -0
  105. package/dist/agent/utils.d.ts +13 -0
  106. package/dist/agent/utils.d.ts.map +1 -0
  107. package/dist/agent/utils.js +152 -0
  108. package/dist/agent/validators/selector-validator.d.ts +74 -0
  109. package/dist/agent/validators/selector-validator.d.ts.map +1 -0
  110. package/dist/agent/validators/selector-validator.js +165 -0
  111. package/dist/anthropic_provider.d.ts +65 -0
  112. package/dist/anthropic_provider.d.ts.map +1 -0
  113. package/dist/anthropic_provider.js +332 -0
  114. package/dist/api.d.ts +48 -0
  115. package/dist/api.d.ts.map +1 -0
  116. package/dist/api.js +113 -0
  117. package/dist/base_provider.d.ts +53 -0
  118. package/dist/base_provider.d.ts.map +1 -0
  119. package/dist/base_provider.js +81 -0
  120. package/dist/cli.d.ts +3 -0
  121. package/dist/cli.d.ts.map +1 -0
  122. package/dist/cli.js +843 -0
  123. package/dist/custom_provider.d.ts +20 -0
  124. package/dist/custom_provider.d.ts.map +1 -0
  125. package/dist/custom_provider.js +276 -0
  126. package/dist/e2e-test-gen/index.d.ts +51 -0
  127. package/dist/e2e-test-gen/index.d.ts.map +1 -0
  128. package/dist/e2e-test-gen/index.js +57 -0
  129. package/dist/e2e-test-gen/spec_parser.d.ts +142 -0
  130. package/dist/e2e-test-gen/spec_parser.d.ts.map +1 -0
  131. package/dist/e2e-test-gen/spec_parser.js +786 -0
  132. package/dist/e2e-test-gen/types.d.ts +185 -0
  133. package/dist/e2e-test-gen/types.d.ts.map +1 -0
  134. package/dist/e2e-test-gen/types.js +4 -0
  135. package/dist/esm/agent/analysis.js +287 -0
  136. package/dist/esm/agent/blast_radius.js +34 -0
  137. package/dist/esm/agent/cache_utils.js +63 -0
  138. package/dist/esm/agent/config.js +637 -0
  139. package/dist/esm/agent/dependency_graph.js +224 -0
  140. package/dist/esm/agent/feedback.js +253 -0
  141. package/dist/esm/agent/flags.js +160 -0
  142. package/dist/esm/agent/flow_catalog.js +103 -0
  143. package/dist/esm/agent/flow_mapping.js +81 -0
  144. package/dist/esm/agent/framework.js +145 -0
  145. package/dist/esm/agent/gap_suggestions.js +98 -0
  146. package/dist/esm/agent/generator.js +112 -0
  147. package/dist/esm/agent/git.js +87 -0
  148. package/dist/esm/agent/handoff.js +177 -0
  149. package/dist/esm/agent/impact-analyzer.js +548 -0
  150. package/dist/esm/agent/index.js +22 -0
  151. package/dist/esm/agent/model-router.js +150 -0
  152. package/dist/esm/agent/operational_insights.js +123 -0
  153. package/dist/esm/agent/pipeline.js +605 -0
  154. package/dist/esm/agent/plan.js +324 -0
  155. package/dist/esm/agent/playwright_report.js +123 -0
  156. package/dist/esm/agent/report-generator.js +247 -0
  157. package/dist/esm/agent/report.js +144 -0
  158. package/dist/esm/agent/runner.js +572 -0
  159. package/dist/esm/agent/selectors.js +71 -0
  160. package/dist/esm/agent/spec-bridge.js +267 -0
  161. package/dist/esm/agent/spec-builder.js +267 -0
  162. package/dist/esm/agent/subsystem_risk.js +204 -0
  163. package/dist/esm/agent/telemetry.js +216 -0
  164. package/dist/esm/agent/test_path.js +20 -0
  165. package/dist/esm/agent/tests.js +101 -0
  166. package/dist/esm/agent/traceability.js +180 -0
  167. package/dist/esm/agent/traceability_capture.js +310 -0
  168. package/dist/esm/agent/traceability_ingest.js +234 -0
  169. package/dist/esm/agent/utils.js +138 -0
  170. package/dist/esm/agent/validators/selector-validator.js +160 -0
  171. package/dist/esm/anthropic_provider.js +324 -0
  172. package/dist/esm/api.js +105 -0
  173. package/dist/esm/base_provider.js +77 -0
  174. package/dist/esm/cli.js +841 -0
  175. package/dist/esm/custom_provider.js +272 -0
  176. package/dist/esm/e2e-test-gen/index.js +50 -0
  177. package/dist/esm/e2e-test-gen/spec_parser.js +782 -0
  178. package/dist/esm/e2e-test-gen/types.js +3 -0
  179. package/dist/esm/index.js +16 -0
  180. package/dist/esm/logger.js +89 -0
  181. package/dist/esm/mcp-server.js +465 -0
  182. package/dist/esm/ollama_provider.js +300 -0
  183. package/dist/esm/openai_provider.js +242 -0
  184. package/dist/esm/package.json +3 -0
  185. package/dist/esm/plan-and-test-constants.js +126 -0
  186. package/dist/esm/provider_factory.js +336 -0
  187. package/dist/esm/provider_interface.js +23 -0
  188. package/dist/esm/provider_utils.js +96 -0
  189. package/dist/index.d.ts +31 -0
  190. package/dist/index.d.ts.map +1 -0
  191. package/dist/index.js +41 -0
  192. package/dist/logger.d.ts +23 -0
  193. package/dist/logger.d.ts.map +1 -0
  194. package/dist/logger.js +93 -0
  195. package/dist/mcp-server.d.ts +35 -0
  196. package/dist/mcp-server.d.ts.map +1 -0
  197. package/dist/mcp-server.js +469 -0
  198. package/dist/ollama_provider.d.ts +65 -0
  199. package/dist/ollama_provider.d.ts.map +1 -0
  200. package/dist/ollama_provider.js +308 -0
  201. package/dist/openai_provider.d.ts +23 -0
  202. package/dist/openai_provider.d.ts.map +1 -0
  203. package/dist/openai_provider.js +250 -0
  204. package/dist/plan-and-test-constants.d.ts +110 -0
  205. package/dist/plan-and-test-constants.d.ts.map +1 -0
  206. package/dist/plan-and-test-constants.js +132 -0
  207. package/dist/provider_factory.d.ts +99 -0
  208. package/dist/provider_factory.d.ts.map +1 -0
  209. package/dist/provider_factory.js +341 -0
  210. package/dist/provider_interface.d.ts +358 -0
  211. package/dist/provider_interface.d.ts.map +1 -0
  212. package/dist/provider_interface.js +28 -0
  213. package/dist/provider_utils.d.ts +39 -0
  214. package/dist/provider_utils.d.ts.map +1 -0
  215. package/dist/provider_utils.js +103 -0
  216. package/package.json +101 -0
  217. package/schemas/gap.schema.json +18 -0
  218. package/schemas/impact.schema.json +418 -0
  219. package/schemas/plan.schema.json +285 -0
  220. package/schemas/subsystem-risk-map.schema.json +62 -0
  221. package/schemas/traceability-input.schema.json +122 -0
@@ -0,0 +1,101 @@
1
+ import type { ProviderConfig, HybridConfig } from '../index.js';
2
+ import type { FeatureSpecification } from '../e2e-test-gen/types';
3
+ /**
4
+ * Configuration for SpecBridge
5
+ */
6
+ export interface SpecBridgeConfig {
7
+ /**
8
+ * LLM provider configuration for PDF parsing
9
+ * Can be a single provider or hybrid config
10
+ */
11
+ llmConfig: ProviderConfig | HybridConfig;
12
+ /**
13
+ * Output directory for generated specs (default: 'specs/')
14
+ */
15
+ outputDir?: string;
16
+ /**
17
+ * Whether to overwrite existing spec files (default: true)
18
+ */
19
+ overwrite?: boolean;
20
+ }
21
+ /**
22
+ * Result of spec conversion
23
+ */
24
+ export interface ConversionResult {
25
+ /**
26
+ * Paths to generated spec files
27
+ */
28
+ specPaths: string[];
29
+ /**
30
+ * Parsed feature specifications
31
+ */
32
+ features: FeatureSpecification[];
33
+ /**
34
+ * Total number of scenarios extracted
35
+ */
36
+ totalScenarios: number;
37
+ /**
38
+ * Any warnings during conversion
39
+ */
40
+ warnings: string[];
41
+ }
42
+ /**
43
+ * Bridge between PDF/JSON specs and Playwright Agent workflow
44
+ *
45
+ * Converts specification documents into Playwright-compatible markdown
46
+ * that can be consumed by Playwright's native agents.
47
+ */
48
+ export declare class SpecBridge {
49
+ private parser;
50
+ private outputDir;
51
+ private overwrite;
52
+ constructor(config: SpecBridgeConfig);
53
+ /**
54
+ * Convert a specification file to Playwright-compatible markdown specs
55
+ *
56
+ * @param inputPath - Path to the input specification (PDF, MD, or JSON)
57
+ * @param outputDir - Optional override for output directory
58
+ * @returns Conversion result with paths and metadata
59
+ */
60
+ convertToPlaywrightSpecs(inputPath: string, outputDir?: string): Promise<ConversionResult>;
61
+ /**
62
+ * Convert a FeatureSpecification to Playwright Agent markdown format
63
+ *
64
+ * The format is designed to be consumed by Playwright's Planner and Generator agents.
65
+ * It includes structured test scenarios in Given-When-Then format.
66
+ */
67
+ private toPlaywrightMarkdown;
68
+ /**
69
+ * Format a business scenario in Playwright-friendly markdown
70
+ */
71
+ private formatScenario;
72
+ /**
73
+ * Parse a spec file without writing output
74
+ * Useful for validation or inspection
75
+ */
76
+ parseSpec(inputPath: string): Promise<FeatureSpecification[]>;
77
+ /**
78
+ * Validate a specification file
79
+ */
80
+ validateSpec(inputPath: string): Promise<{
81
+ valid: boolean;
82
+ errors: string[];
83
+ features: number;
84
+ scenarios: number;
85
+ }>;
86
+ /**
87
+ * Get a summary of the specification
88
+ */
89
+ getSpecSummary(inputPath: string): Promise<string>;
90
+ }
91
+ /**
92
+ * Create a SpecBridge with Anthropic provider
93
+ * Convenience function for common use case
94
+ */
95
+ export declare function createAnthropicBridge(apiKey?: string, outputDir?: string): SpecBridge;
96
+ /**
97
+ * Create a SpecBridge with Ollama provider (free, local)
98
+ * Convenience function for local development
99
+ */
100
+ export declare function createOllamaBridge(model?: string, outputDir?: string): SpecBridge;
101
+ //# sourceMappingURL=spec-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-bridge.d.ts","sourceRoot":"","sources":["../../src/agent/spec-bridge.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAc,cAAc,EAAE,YAAY,EAAC,MAAM,aAAa,CAAC;AAG3E,OAAO,KAAK,EAAC,oBAAoB,EAAmB,MAAM,uBAAuB,CAAC;AAElF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,SAAS,EAAE,cAAc,GAAG,YAAY,CAAC;IAEzC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IAEjC;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAU;gBAEf,MAAM,EAAE,gBAAgB;IAepC;;;;;;OAMG;IACG,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAkEhG;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA6D5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAqBtB;;;OAGG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAInE;;OAEG;IACG,YAAY,CACd,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAC;IAqBnF;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAuB3D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAUrF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAWjF"}
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
3
+ // See LICENSE.txt for license information.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.SpecBridge = void 0;
6
+ exports.createAnthropicBridge = createAnthropicBridge;
7
+ exports.createOllamaBridge = createOllamaBridge;
8
+ /**
9
+ * Spec Bridge - Bridge between PDF specs and Playwright Agent workflow
10
+ *
11
+ * This module converts specification documents (PDF, Markdown, JSON) into
12
+ * Playwright-compatible markdown files that can be consumed by Playwright's
13
+ * native agents (Planner, Generator, Healer).
14
+ *
15
+ * Flow: PDF → SpecParser → Markdown specs → Playwright Planner
16
+ *
17
+ * The Playwright agents (available in Playwright 1.56+) provide production-ready:
18
+ * - Test planning and exploration
19
+ * - Test code generation
20
+ * - Automatic test healing
21
+ *
22
+ * Usage:
23
+ * ```typescript
24
+ * const bridge = new SpecBridge({type: 'anthropic', apiKey: process.env.ANTHROPIC_API_KEY});
25
+ * const specPaths = await bridge.convertToPlaywrightSpecs('spec.pdf', 'specs/');
26
+ * // Now use Playwright agents: @planner, @generator, @healer
27
+ * ```
28
+ */
29
+ const fs_1 = require("fs");
30
+ const path_1 = require("path");
31
+ const index_js_1 = require("../index.js");
32
+ const spec_parser_1 = require("../e2e-test-gen/spec_parser");
33
+ /**
34
+ * Bridge between PDF/JSON specs and Playwright Agent workflow
35
+ *
36
+ * Converts specification documents into Playwright-compatible markdown
37
+ * that can be consumed by Playwright's native agents.
38
+ */
39
+ class SpecBridge {
40
+ constructor(config) {
41
+ // Handle both single provider and hybrid config
42
+ let llmProvider;
43
+ if ('primary' in config.llmConfig) {
44
+ // It's a HybridConfig
45
+ llmProvider = index_js_1.LLMProviderFactory.createHybrid(config.llmConfig);
46
+ }
47
+ else {
48
+ // It's a ProviderConfig
49
+ llmProvider = index_js_1.LLMProviderFactory.create(config.llmConfig);
50
+ }
51
+ this.parser = new spec_parser_1.SpecificationParser(llmProvider);
52
+ this.outputDir = config.outputDir || 'specs';
53
+ this.overwrite = config.overwrite !== false;
54
+ }
55
+ /**
56
+ * Convert a specification file to Playwright-compatible markdown specs
57
+ *
58
+ * @param inputPath - Path to the input specification (PDF, MD, or JSON)
59
+ * @param outputDir - Optional override for output directory
60
+ * @returns Conversion result with paths and metadata
61
+ */
62
+ async convertToPlaywrightSpecs(inputPath, outputDir) {
63
+ /* eslint-disable no-console */
64
+ const targetDir = outputDir || this.outputDir;
65
+ const warnings = [];
66
+ console.log(`Converting specification: ${inputPath}`);
67
+ // Parse the specification
68
+ const specs = await this.parser.parse(inputPath, 'file');
69
+ if (specs.length === 0) {
70
+ warnings.push('No features extracted from specification');
71
+ return {
72
+ specPaths: [],
73
+ features: [],
74
+ totalScenarios: 0,
75
+ warnings,
76
+ };
77
+ }
78
+ // Create output directory
79
+ (0, fs_1.mkdirSync)(targetDir, { recursive: true });
80
+ const specPaths = [];
81
+ let totalScenarios = 0;
82
+ for (const spec of specs) {
83
+ // Validate the spec
84
+ const validation = this.parser.validateSpec(spec);
85
+ if (!validation.valid) {
86
+ warnings.push(`Feature "${spec.name}": ${validation.errors.join(', ')}`);
87
+ }
88
+ // Convert to Playwright markdown format
89
+ const markdown = this.toPlaywrightMarkdown(spec);
90
+ // Generate output filename
91
+ const filename = `${spec.id}.md`;
92
+ const outputPath = (0, path_1.join)(targetDir, filename);
93
+ // Check for existing file
94
+ if ((0, fs_1.existsSync)(outputPath) && !this.overwrite) {
95
+ warnings.push(`Skipping existing file: ${outputPath}`);
96
+ continue;
97
+ }
98
+ // Write the spec file
99
+ (0, fs_1.writeFileSync)(outputPath, markdown, 'utf-8');
100
+ specPaths.push(outputPath);
101
+ totalScenarios += spec.scenarios.length;
102
+ console.log(` Created: ${outputPath} (${spec.scenarios.length} scenarios)`);
103
+ }
104
+ console.log(`Converted ${specs.length} feature(s) with ${totalScenarios} scenario(s)`);
105
+ /* eslint-enable no-console */
106
+ return {
107
+ specPaths,
108
+ features: specs,
109
+ totalScenarios,
110
+ warnings,
111
+ };
112
+ }
113
+ /**
114
+ * Convert a FeatureSpecification to Playwright Agent markdown format
115
+ *
116
+ * The format is designed to be consumed by Playwright's Planner and Generator agents.
117
+ * It includes structured test scenarios in Given-When-Then format.
118
+ */
119
+ toPlaywrightMarkdown(spec) {
120
+ const lines = [];
121
+ // Header
122
+ lines.push(`# ${spec.name}`);
123
+ lines.push('');
124
+ // Metadata
125
+ lines.push(`**Priority**: ${spec.priority}`);
126
+ if (spec.targetUrls.length > 0) {
127
+ lines.push(`**Target URLs**: ${spec.targetUrls.join(', ')}`);
128
+ }
129
+ lines.push('');
130
+ // Description
131
+ if (spec.description) {
132
+ lines.push('## Description');
133
+ lines.push('');
134
+ lines.push(spec.description);
135
+ lines.push('');
136
+ }
137
+ // Test Scenarios
138
+ if (spec.scenarios.length > 0) {
139
+ lines.push('## Test Scenarios');
140
+ lines.push('');
141
+ for (const scenario of spec.scenarios) {
142
+ lines.push(this.formatScenario(scenario));
143
+ lines.push('');
144
+ }
145
+ }
146
+ // Acceptance Criteria
147
+ if (spec.acceptanceCriteria.length > 0) {
148
+ lines.push('## Acceptance Criteria');
149
+ lines.push('');
150
+ for (const criterion of spec.acceptanceCriteria) {
151
+ lines.push(`- ${criterion}`);
152
+ }
153
+ lines.push('');
154
+ }
155
+ // Screenshots reference (if any)
156
+ if (spec.screenshots.length > 0) {
157
+ lines.push('## Reference Screenshots');
158
+ lines.push('');
159
+ for (const screenshot of spec.screenshots) {
160
+ lines.push(`- ${screenshot.description}: \`${screenshot.path}\``);
161
+ }
162
+ lines.push('');
163
+ }
164
+ // Metadata footer
165
+ lines.push('---');
166
+ lines.push(`*Generated from: ${(0, path_1.basename)(spec.sourcePath)}*`);
167
+ lines.push(`*Feature ID: ${spec.id}*`);
168
+ return lines.join('\n');
169
+ }
170
+ /**
171
+ * Format a business scenario in Playwright-friendly markdown
172
+ */
173
+ formatScenario(scenario) {
174
+ const lines = [];
175
+ lines.push(`### ${scenario.name}`);
176
+ lines.push('');
177
+ lines.push(`**Priority**: ${scenario.priority}`);
178
+ lines.push('');
179
+ if (scenario.given) {
180
+ lines.push(`**Given**: ${scenario.given}`);
181
+ }
182
+ if (scenario.when) {
183
+ lines.push(`**When**: ${scenario.when}`);
184
+ }
185
+ if (scenario.then) {
186
+ lines.push(`**Then**: ${scenario.then}`);
187
+ }
188
+ return lines.join('\n');
189
+ }
190
+ /**
191
+ * Parse a spec file without writing output
192
+ * Useful for validation or inspection
193
+ */
194
+ async parseSpec(inputPath) {
195
+ return this.parser.parse(inputPath, 'file');
196
+ }
197
+ /**
198
+ * Validate a specification file
199
+ */
200
+ async validateSpec(inputPath) {
201
+ const specs = await this.parser.parse(inputPath, 'file');
202
+ const allErrors = [];
203
+ let totalScenarios = 0;
204
+ for (const spec of specs) {
205
+ const validation = this.parser.validateSpec(spec);
206
+ if (!validation.valid) {
207
+ allErrors.push(...validation.errors.map((e) => `${spec.name}: ${e}`));
208
+ }
209
+ totalScenarios += spec.scenarios.length;
210
+ }
211
+ return {
212
+ valid: allErrors.length === 0,
213
+ errors: allErrors,
214
+ features: specs.length,
215
+ scenarios: totalScenarios,
216
+ };
217
+ }
218
+ /**
219
+ * Get a summary of the specification
220
+ */
221
+ async getSpecSummary(inputPath) {
222
+ const specs = await this.parser.parse(inputPath, 'file');
223
+ const lines = [];
224
+ lines.push(`Specification Summary: ${(0, path_1.basename)(inputPath)}`);
225
+ lines.push('='.repeat(50));
226
+ lines.push('');
227
+ for (const spec of specs) {
228
+ const summary = this.parser.getSpecSummary(spec);
229
+ lines.push(`Feature: ${summary.name}`);
230
+ lines.push(` Priority: ${summary.priority}`);
231
+ lines.push(` Scenarios: ${summary.scenarioCount}`);
232
+ lines.push(` - Must-have: ${summary.mustHaveScenarios}`);
233
+ lines.push(` - Should-have: ${summary.shouldHaveScenarios}`);
234
+ lines.push(` - Nice-to-have: ${summary.niceToHaveScenarios}`);
235
+ lines.push(` Acceptance Criteria: ${summary.acceptanceCriteriaCount}`);
236
+ lines.push(` Has Screenshots: ${summary.hasScreenshots ? 'Yes' : 'No'}`);
237
+ lines.push('');
238
+ }
239
+ return lines.join('\n');
240
+ }
241
+ }
242
+ exports.SpecBridge = SpecBridge;
243
+ /**
244
+ * Create a SpecBridge with Anthropic provider
245
+ * Convenience function for common use case
246
+ */
247
+ function createAnthropicBridge(apiKey, outputDir) {
248
+ return new SpecBridge({
249
+ llmConfig: {
250
+ type: 'anthropic',
251
+ config: {
252
+ apiKey: apiKey || process.env.ANTHROPIC_API_KEY || '',
253
+ },
254
+ },
255
+ outputDir,
256
+ });
257
+ }
258
+ /**
259
+ * Create a SpecBridge with Ollama provider (free, local)
260
+ * Convenience function for local development
261
+ */
262
+ function createOllamaBridge(model, outputDir) {
263
+ return new SpecBridge({
264
+ llmConfig: {
265
+ type: 'ollama',
266
+ config: {
267
+ model: model || 'deepseek-r1:7b',
268
+ baseUrl: process.env.OLLAMA_BASE_URL || 'http://localhost:11434',
269
+ },
270
+ },
271
+ outputDir,
272
+ });
273
+ }
@@ -0,0 +1,102 @@
1
+ import type { ProviderConfig } from '../provider_interface.js';
2
+ import type { HybridConfig } from '../provider_factory.js';
3
+ import type { FeatureSpecification } from '../e2e-test-gen/types.js';
4
+ /**
5
+ * Configuration for SpecBridge
6
+ */
7
+ export interface SpecBridgeConfig {
8
+ /**
9
+ * LLM provider configuration for PDF parsing
10
+ * Can be a single provider or hybrid config
11
+ */
12
+ llmConfig: ProviderConfig | HybridConfig;
13
+ /**
14
+ * Output directory for generated specs (default: 'specs/')
15
+ */
16
+ outputDir?: string;
17
+ /**
18
+ * Whether to overwrite existing spec files (default: true)
19
+ */
20
+ overwrite?: boolean;
21
+ }
22
+ /**
23
+ * Result of spec conversion
24
+ */
25
+ export interface ConversionResult {
26
+ /**
27
+ * Paths to generated spec files
28
+ */
29
+ specPaths: string[];
30
+ /**
31
+ * Parsed feature specifications
32
+ */
33
+ features: FeatureSpecification[];
34
+ /**
35
+ * Total number of scenarios extracted
36
+ */
37
+ totalScenarios: number;
38
+ /**
39
+ * Any warnings during conversion
40
+ */
41
+ warnings: string[];
42
+ }
43
+ /**
44
+ * Bridge between PDF/JSON specs and Playwright Agent workflow
45
+ *
46
+ * Converts specification documents into Playwright-compatible markdown
47
+ * that can be consumed by Playwright's native agents.
48
+ */
49
+ export declare class SpecBridge {
50
+ private parser;
51
+ private outputDir;
52
+ private overwrite;
53
+ constructor(config: SpecBridgeConfig);
54
+ /**
55
+ * Convert a specification file to Playwright-compatible markdown specs
56
+ *
57
+ * @param inputPath - Path to the input specification (PDF, MD, or JSON)
58
+ * @param outputDir - Optional override for output directory
59
+ * @returns Conversion result with paths and metadata
60
+ */
61
+ convertToPlaywrightSpecs(inputPath: string, outputDir?: string): Promise<ConversionResult>;
62
+ /**
63
+ * Convert a FeatureSpecification to Playwright Agent markdown format
64
+ *
65
+ * The format is designed to be consumed by Playwright's Planner and Generator agents.
66
+ * It includes structured test scenarios in Given-When-Then format.
67
+ */
68
+ private toPlaywrightMarkdown;
69
+ /**
70
+ * Format a business scenario in Playwright-friendly markdown
71
+ */
72
+ private formatScenario;
73
+ /**
74
+ * Parse a spec file without writing output
75
+ * Useful for validation or inspection
76
+ */
77
+ parseSpec(inputPath: string): Promise<FeatureSpecification[]>;
78
+ /**
79
+ * Validate a specification file
80
+ */
81
+ validateSpec(inputPath: string): Promise<{
82
+ valid: boolean;
83
+ errors: string[];
84
+ features: number;
85
+ scenarios: number;
86
+ }>;
87
+ /**
88
+ * Get a summary of the specification
89
+ */
90
+ getSpecSummary(inputPath: string): Promise<string>;
91
+ }
92
+ /**
93
+ * Create a SpecBridge with Anthropic provider
94
+ * Convenience function for common use case
95
+ */
96
+ export declare function createAnthropicBridge(apiKey?: string, outputDir?: string): SpecBridge;
97
+ /**
98
+ * Create a SpecBridge with Ollama provider (free, local)
99
+ * Convenience function for local development
100
+ */
101
+ export declare function createOllamaBridge(model?: string, outputDir?: string): SpecBridge;
102
+ //# sourceMappingURL=spec-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-builder.d.ts","sourceRoot":"","sources":["../../src/agent/spec-builder.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAc,cAAc,EAAC,MAAM,0BAA0B,CAAC;AAC1E,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,wBAAwB,CAAC;AAGzD,OAAO,KAAK,EAAC,oBAAoB,EAAmB,MAAM,0BAA0B,CAAC;AAErF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,SAAS,EAAE,cAAc,GAAG,YAAY,CAAC;IAEzC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IAEjC;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAU;gBAEf,MAAM,EAAE,gBAAgB;IAepC;;;;;;OAMG;IACG,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAkEhG;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA6D5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAqBtB;;;OAGG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAInE;;OAEG;IACG,YAAY,CACd,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,CAAC;IAqBnF;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAuB3D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAUrF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAWjF"}