@vibe-validate/extractors 0.12.1 → 0.13.0

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 (44) hide show
  1. package/README.md +68 -9
  2. package/dist/ava-extractor.d.ts +24 -0
  3. package/dist/ava-extractor.d.ts.map +1 -0
  4. package/dist/ava-extractor.js +367 -0
  5. package/dist/ava-extractor.js.map +1 -0
  6. package/dist/index.d.ts +6 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +6 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/jasmine-extractor.d.ts +23 -0
  11. package/dist/jasmine-extractor.d.ts.map +1 -0
  12. package/dist/jasmine-extractor.js +254 -0
  13. package/dist/jasmine-extractor.js.map +1 -0
  14. package/dist/jest-extractor.d.ts +29 -0
  15. package/dist/jest-extractor.d.ts.map +1 -0
  16. package/dist/jest-extractor.js +115 -0
  17. package/dist/jest-extractor.js.map +1 -0
  18. package/dist/junit-extractor.d.ts +24 -0
  19. package/dist/junit-extractor.d.ts.map +1 -0
  20. package/dist/junit-extractor.js +264 -0
  21. package/dist/junit-extractor.js.map +1 -0
  22. package/dist/mocha-extractor.d.ts +23 -0
  23. package/dist/mocha-extractor.d.ts.map +1 -0
  24. package/dist/mocha-extractor.js +263 -0
  25. package/dist/mocha-extractor.js.map +1 -0
  26. package/dist/playwright-extractor.d.ts +38 -0
  27. package/dist/playwright-extractor.d.ts.map +1 -0
  28. package/dist/playwright-extractor.js +230 -0
  29. package/dist/playwright-extractor.js.map +1 -0
  30. package/dist/smart-extractor.d.ts +9 -0
  31. package/dist/smart-extractor.d.ts.map +1 -1
  32. package/dist/smart-extractor.js +25 -0
  33. package/dist/smart-extractor.js.map +1 -1
  34. package/dist/tap-extractor.d.ts +24 -0
  35. package/dist/tap-extractor.d.ts.map +1 -0
  36. package/dist/tap-extractor.js +227 -0
  37. package/dist/tap-extractor.js.map +1 -0
  38. package/dist/types.d.ts +21 -2
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/vitest-extractor.d.ts +9 -1
  41. package/dist/vitest-extractor.d.ts.map +1 -1
  42. package/dist/vitest-extractor.js +112 -16
  43. package/dist/vitest-extractor.js.map +1 -1
  44. package/package.json +3 -5
@@ -0,0 +1,264 @@
1
+ /**
2
+ * JUnit XML Error Extractor
3
+ *
4
+ * Parses JUnit XML test reports and formats failures for LLM consumption.
5
+ * Supports Vitest, Jest, and other test frameworks that output JUnit XML.
6
+ *
7
+ * @package @vibe-validate/extractors
8
+ */
9
+ import { stripAnsiCodes } from './utils.js';
10
+ /**
11
+ * Extract errors from JUnit XML test output
12
+ *
13
+ * @param output - JUnit XML string
14
+ * @returns Structured error information
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const junitXml = fs.readFileSync('junit.xml', 'utf-8');
19
+ * const result = extractJUnitErrors(junitXml);
20
+ * console.log(result.summary); // "5 test(s) failed"
21
+ * ```
22
+ */
23
+ export function extractJUnitErrors(output) {
24
+ const cleanOutput = stripAnsiCodes(output);
25
+ // Try to parse XML
26
+ let isValidXml = false;
27
+ try {
28
+ // Simple XML parsing - look for <testsuite> and <testcase> elements
29
+ isValidXml = parseSimpleXML(cleanOutput);
30
+ }
31
+ catch (_error) {
32
+ return {
33
+ summary: 'Unable to parse JUnit XML - invalid format',
34
+ errors: [],
35
+ totalCount: 0,
36
+ cleanOutput: cleanOutput.trim(),
37
+ guidance: 'Ensure the input is valid JUnit XML format',
38
+ metadata: {
39
+ confidence: 0,
40
+ completeness: 0,
41
+ issues: ['Failed to parse XML']
42
+ }
43
+ };
44
+ }
45
+ if (!isValidXml) {
46
+ return {
47
+ summary: '0 test(s) failed',
48
+ errors: [],
49
+ totalCount: 0,
50
+ cleanOutput: '',
51
+ guidance: '',
52
+ metadata: {
53
+ confidence: 100,
54
+ completeness: 100,
55
+ issues: []
56
+ }
57
+ };
58
+ }
59
+ // Extract all failure elements
60
+ const failures = extractFailures(cleanOutput);
61
+ const errors = [];
62
+ let completeCount = 0;
63
+ for (const failure of failures) {
64
+ const file = failure.file || 'unknown';
65
+ const location = failure.location || `${file}:0`;
66
+ const message = failure.message || 'Test failed';
67
+ const context = failure.testName || '';
68
+ const isComplete = file !== 'unknown' && failure.location && message;
69
+ if (isComplete) {
70
+ completeCount++;
71
+ }
72
+ // Parse location to get line/column (only if location exists)
73
+ let line;
74
+ if (location) {
75
+ const locationParts = location.split(':');
76
+ line = locationParts[1] ? parseInt(locationParts[1], 10) : undefined;
77
+ }
78
+ errors.push({
79
+ file,
80
+ line,
81
+ message: decodeHtmlEntities(message),
82
+ context: decodeHtmlEntities(context)
83
+ });
84
+ }
85
+ // Generate summary
86
+ const failureCount = failures.length;
87
+ const summary = `${failureCount} test(s) failed`;
88
+ // Generate guidance based on error types
89
+ const guidance = generateGuidance(failures);
90
+ // Calculate quality metadata
91
+ const completeness = failures.length > 0 ? (completeCount / failures.length) * 100 : 100;
92
+ const confidence = failures.length > 0 ? 95 : 100; // High confidence for JUnit XML
93
+ const metadata = {
94
+ confidence,
95
+ completeness,
96
+ issues: []
97
+ };
98
+ return {
99
+ summary,
100
+ errors,
101
+ totalCount: failures.length,
102
+ cleanOutput: formatCleanOutput(errors),
103
+ guidance,
104
+ metadata
105
+ };
106
+ }
107
+ /**
108
+ * Simple XML parser for JUnit format
109
+ * (We avoid full XML parsers to minimize dependencies)
110
+ */
111
+ function parseSimpleXML(xml) {
112
+ // Check if it contains testsuite elements
113
+ if (!xml.includes('<testsuite') && !xml.includes('<testsuites')) {
114
+ throw new Error('Not JUnit XML format');
115
+ }
116
+ // Validate basic XML structure
117
+ if (!xml.includes('<?xml') && !xml.includes('<testsuite')) {
118
+ throw new Error('Invalid XML structure');
119
+ }
120
+ // Return that XML is valid
121
+ return true;
122
+ }
123
+ function extractFailures(xml) {
124
+ const failures = [];
125
+ // Match all <testcase> elements with <failure> children
126
+ const testcasePattern = /<testcase[^>]*>([\s\S]*?)<\/testcase>/g;
127
+ let testcaseMatch;
128
+ while ((testcaseMatch = testcasePattern.exec(xml)) !== null) {
129
+ const testcaseContent = testcaseMatch[0];
130
+ const testcaseInner = testcaseMatch[1];
131
+ // Check if this testcase has a failure
132
+ if (!testcaseInner.includes('<failure')) {
133
+ continue; // Skip passing tests
134
+ }
135
+ // Extract attributes from testcase opening tag using more reliable string extraction
136
+ const testcaseTagMatch = testcaseContent.match(/<testcase([^>]*)>/);
137
+ const testcaseTag = testcaseTagMatch ? testcaseTagMatch[1] : '';
138
+ // Extract classname using indexOf/substring (more reliable than regex for attributes with special chars)
139
+ let file;
140
+ const classnameIdx = testcaseTag.indexOf('classname="');
141
+ if (classnameIdx !== -1) {
142
+ const start = classnameIdx + 'classname="'.length;
143
+ const end = testcaseTag.indexOf('"', start);
144
+ file = testcaseTag.substring(start, end);
145
+ }
146
+ // Extract name (test hierarchy) similarly
147
+ let testName;
148
+ const nameIdx = testcaseTag.indexOf('name="');
149
+ if (nameIdx !== -1) {
150
+ const start = nameIdx + 'name="'.length;
151
+ const end = testcaseTag.indexOf('"', start);
152
+ testName = testcaseTag.substring(start, end);
153
+ }
154
+ // Extract failure element
155
+ const failurePattern = /<failure[^>]*>([\s\S]*?)<\/failure>/;
156
+ const failureMatch = testcaseInner.match(failurePattern);
157
+ if (!failureMatch) {
158
+ continue;
159
+ }
160
+ const failureContent = failureMatch[0];
161
+ const failureText = failureMatch[1];
162
+ // Extract message attribute
163
+ const messageMatch = failureContent.match(/message="([^"]+)"/);
164
+ const message = messageMatch ? messageMatch[1] : undefined;
165
+ // Extract error type
166
+ const typeMatch = failureContent.match(/type="([^"]+)"/);
167
+ const errorType = typeMatch ? typeMatch[1] : undefined;
168
+ // Extract location from failure text (❯ file:line:column)
169
+ // Note: We strip column number to keep format consistent (file:line)
170
+ // Pattern allows word chars, forward slashes, dots, hyphens, and underscores in paths
171
+ const locationPattern = /❯\s+([\w/._-]+):(\d+)(?::\d+)?/;
172
+ const locationMatch = failureText.match(locationPattern);
173
+ let location;
174
+ let extractedFile;
175
+ if (locationMatch) {
176
+ extractedFile = locationMatch[1];
177
+ const line = locationMatch[2];
178
+ location = `${extractedFile}:${line}`;
179
+ }
180
+ // No fallback - if no location found in failure text, leave location undefined
181
+ failures.push({
182
+ file: extractedFile || file,
183
+ location,
184
+ message,
185
+ testName,
186
+ errorType
187
+ });
188
+ }
189
+ return failures;
190
+ }
191
+ /**
192
+ * Decode HTML entities in XML content
193
+ */
194
+ function decodeHtmlEntities(text) {
195
+ return text
196
+ .replace(/&gt;/g, '>')
197
+ .replace(/&lt;/g, '<')
198
+ .replace(/&quot;/g, '"')
199
+ .replace(/&apos;/g, "'")
200
+ .replace(/&amp;/g, '&'); // Must be last to avoid double-decoding
201
+ }
202
+ /**
203
+ * Generate guidance based on failure types
204
+ */
205
+ function generateGuidance(failures) {
206
+ const guidances = [];
207
+ const seen = new Set();
208
+ for (const failure of failures) {
209
+ const message = failure.message || '';
210
+ const errorType = failure.errorType;
211
+ // Assertion errors
212
+ if (errorType === 'AssertionError' || message.includes('expected')) {
213
+ if (!seen.has('assertion')) {
214
+ guidances.push('Review test assertions and expected values');
215
+ seen.add('assertion');
216
+ }
217
+ }
218
+ // Timeout errors
219
+ if (message.includes('timed out') || message.includes('timeout')) {
220
+ if (!seen.has('timeout')) {
221
+ guidances.push('Increase test timeout or optimize async operations');
222
+ seen.add('timeout');
223
+ }
224
+ }
225
+ // Type errors
226
+ if (errorType === 'TypeError') {
227
+ if (!seen.has('type')) {
228
+ guidances.push('Check for null/undefined values and type mismatches');
229
+ seen.add('type');
230
+ }
231
+ }
232
+ // File errors
233
+ if (message.includes('ENOENT') || message.includes('no such file')) {
234
+ if (!seen.has('file')) {
235
+ guidances.push('Verify file paths and ensure test fixtures exist');
236
+ seen.add('file');
237
+ }
238
+ }
239
+ // Module errors
240
+ if (message.includes('Cannot find package') || message.includes('Cannot find module')) {
241
+ if (!seen.has('module')) {
242
+ guidances.push('Install missing dependencies or check import paths');
243
+ seen.add('module');
244
+ }
245
+ }
246
+ }
247
+ return guidances.join('\n');
248
+ }
249
+ /**
250
+ * Format clean output for LLM consumption
251
+ */
252
+ function formatCleanOutput(errors) {
253
+ if (errors.length === 0) {
254
+ return '';
255
+ }
256
+ return errors
257
+ .map((error) => {
258
+ const location = error.line ? `${error.file}:${error.line}` : error.file;
259
+ const contextStr = error.context ? ` (${error.context})` : '';
260
+ return `${location}: ${error.message}${contextStr}`;
261
+ })
262
+ .join('\n');
263
+ }
264
+ //# sourceMappingURL=junit-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"junit-extractor.js","sourceRoot":"","sources":["../src/junit-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Mocha Error Extractor
3
+ *
4
+ * Parses Mocha test output and formats failures for LLM consumption.
5
+ *
6
+ * @package @vibe-validate/extractors
7
+ */
8
+ import type { ErrorExtractorResult } from './types.js';
9
+ /**
10
+ * Extract errors from Mocha test output
11
+ *
12
+ * @param output - Mocha text output
13
+ * @returns Structured error information
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const mochaOutput = execSync('mocha tests/**\/*.test.js', { encoding: 'utf-8' });
18
+ * const result = extractMochaErrors(mochaOutput);
19
+ * console.log(result.summary); // "5 test(s) failed"
20
+ * ```
21
+ */
22
+ export declare function extractMochaErrors(output: string): ErrorExtractorResult;
23
+ //# sourceMappingURL=mocha-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mocha-extractor.d.ts","sourceRoot":"","sources":["../src/mocha-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAsC,MAAM,YAAY,CAAC;AAG3F;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAsFvE"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Mocha Error Extractor
3
+ *
4
+ * Parses Mocha test output and formats failures for LLM consumption.
5
+ *
6
+ * @package @vibe-validate/extractors
7
+ */
8
+ import { stripAnsiCodes } from './utils.js';
9
+ /**
10
+ * Extract errors from Mocha test output
11
+ *
12
+ * @param output - Mocha text output
13
+ * @returns Structured error information
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const mochaOutput = execSync('mocha tests/**\/*.test.js', { encoding: 'utf-8' });
18
+ * const result = extractMochaErrors(mochaOutput);
19
+ * console.log(result.summary); // "5 test(s) failed"
20
+ * ```
21
+ */
22
+ export function extractMochaErrors(output) {
23
+ const cleanOutput = stripAnsiCodes(output);
24
+ // Check if this looks like Mocha output
25
+ if (!cleanOutput.includes('failing') && !cleanOutput.includes('passing')) {
26
+ return {
27
+ summary: 'Unable to parse Mocha output - invalid format',
28
+ errors: [],
29
+ totalCount: 0,
30
+ cleanOutput: cleanOutput.trim(),
31
+ guidance: 'Ensure the input is valid Mocha test output',
32
+ metadata: {
33
+ confidence: 0,
34
+ completeness: 0,
35
+ issues: ['Not Mocha output format']
36
+ }
37
+ };
38
+ }
39
+ // Extract failure count
40
+ const failingMatch = cleanOutput.match(/(\d+) failing/);
41
+ const failureCount = failingMatch ? parseInt(failingMatch[1], 10) : 0;
42
+ if (failureCount === 0) {
43
+ return {
44
+ summary: '0 test(s) failed',
45
+ errors: [],
46
+ totalCount: 0,
47
+ cleanOutput: '',
48
+ guidance: '',
49
+ metadata: {
50
+ confidence: 100,
51
+ completeness: 100,
52
+ issues: []
53
+ }
54
+ };
55
+ }
56
+ // Extract all failures
57
+ const failures = extractFailures(cleanOutput);
58
+ const errors = [];
59
+ let completeCount = 0;
60
+ for (const failure of failures) {
61
+ const file = failure.file || 'unknown';
62
+ const message = failure.message || 'Test failed';
63
+ const context = failure.testName || '';
64
+ const isComplete = file !== 'unknown' && failure.line && message;
65
+ if (isComplete) {
66
+ completeCount++;
67
+ }
68
+ errors.push({
69
+ file,
70
+ line: failure.line,
71
+ message,
72
+ context
73
+ });
74
+ }
75
+ // Generate summary
76
+ const summary = `${failures.length} test(s) failed`;
77
+ // Generate guidance
78
+ const guidance = generateGuidance(failures);
79
+ // Calculate quality metadata
80
+ const completeness = failures.length > 0 ? (completeCount / failures.length) * 100 : 100;
81
+ const confidence = failures.length > 0 ? 95 : 100; // High confidence for Mocha
82
+ const metadata = {
83
+ confidence,
84
+ completeness,
85
+ issues: []
86
+ };
87
+ return {
88
+ summary,
89
+ errors,
90
+ totalCount: failures.length,
91
+ cleanOutput: formatCleanOutput(errors),
92
+ guidance,
93
+ metadata
94
+ };
95
+ }
96
+ /**
97
+ * Extract failure information from Mocha output
98
+ */
99
+ function extractFailures(output) {
100
+ const failures = [];
101
+ const lines = output.split('\n');
102
+ let i = 0;
103
+ while (i < lines.length) {
104
+ const line = lines[i];
105
+ // Look for numbered failure markers (e.g., " 1) ")
106
+ // Only match detailed format (2 spaces), not summary format (6+ spaces)
107
+ const failureMatch = line.match(/^ {2}(\d+)\)\s+(.*)$/);
108
+ if (failureMatch) {
109
+ const _failureNumber = failureMatch[1]; // Extracted but not used (test name is more important)
110
+ const firstPart = failureMatch[2].trim();
111
+ // Collect test hierarchy lines
112
+ const testNameParts = [];
113
+ // Check if first part ends with colon (simple format: "1) Test:")
114
+ const isSimpleFormat = firstPart.endsWith(':');
115
+ if (firstPart) {
116
+ testNameParts.push(firstPart.replace(/:$/, '')); // Remove trailing colon
117
+ }
118
+ let j = i + 1;
119
+ // If simple format, don't try to collect more hierarchy
120
+ if (!isSimpleFormat) {
121
+ // Continue collecting hierarchy lines until we hit blank line or error
122
+ while (j < lines.length) {
123
+ const nextLine = lines[j];
124
+ // Blank line marks end of hierarchy
125
+ if (nextLine.trim() === '') {
126
+ break;
127
+ }
128
+ // Error line marks end of hierarchy
129
+ if (nextLine.match(/^\s+(Error|AssertionError|TypeError)/)) {
130
+ break;
131
+ }
132
+ // Indented lines are part of hierarchy (at least 5 spaces for Mocha)
133
+ if (nextLine.match(/^\s{5,}\S/)) {
134
+ const part = nextLine.trim().replace(/:$/, ''); // Remove trailing colon
135
+ testNameParts.push(part);
136
+ }
137
+ j++;
138
+ }
139
+ }
140
+ const testName = testNameParts.join(' > ');
141
+ // Now scan for error message and stack trace
142
+ let message;
143
+ let errorType;
144
+ let file;
145
+ let lineNumber;
146
+ // Continue from where we left off
147
+ while (j < lines.length && j < i + 40) {
148
+ const nextLine = lines[j];
149
+ // Stop if we hit the next failure
150
+ if (nextLine.match(/^\s+\d+\)\s+/)) {
151
+ break;
152
+ }
153
+ // Extract error type and message
154
+ // Pattern 1: " AssertionError [ERR_ASSERTION]: Expected..."
155
+ // Pattern 2: " Error: ENOENT: no such file..."
156
+ // Pattern 3: " TypeError: Cannot read..."
157
+ if (!message) {
158
+ // Match plain "Error" or prefixed errors like "TypeError", "AssertionError"
159
+ const errorMatch = nextLine.match(/^\s+([A-Za-z]*Error)(?:\s\[[\w_]+\])?\s*:\s*(.+)/);
160
+ if (errorMatch) {
161
+ errorType = errorMatch[1];
162
+ message = errorMatch[2].trim();
163
+ }
164
+ }
165
+ // Extract file location from stack trace
166
+ if (!file && nextLine.includes('at Context.<anonymous>')) {
167
+ // Match various path formats:
168
+ // - file:///path/to/file.js:10:20
169
+ // - /absolute/path/file.js:10:20
170
+ // - relative/path/file.js:10:20
171
+ const locationMatch = nextLine.match(/at Context\.<anonymous> \((?:file:\/\/)?([^:)]+):(\d+)(?::(\d+))?\)/);
172
+ if (locationMatch) {
173
+ file = locationMatch[1];
174
+ lineNumber = parseInt(locationMatch[2], 10);
175
+ }
176
+ }
177
+ // Extract file from timeout error messages: "Error: Timeout... (/path/to/file.js)"
178
+ if (!file && message && message.includes('Timeout')) {
179
+ const timeoutFileMatch = message.match(/\(([^)]+\.(?:js|ts|mjs|cjs))\)/);
180
+ if (timeoutFileMatch) {
181
+ file = timeoutFileMatch[1];
182
+ }
183
+ }
184
+ j++;
185
+ }
186
+ failures.push({
187
+ testName,
188
+ message,
189
+ errorType,
190
+ file,
191
+ line: lineNumber
192
+ });
193
+ i = j; // Skip to after this failure
194
+ }
195
+ else {
196
+ i++;
197
+ }
198
+ }
199
+ return failures;
200
+ }
201
+ /**
202
+ * Generate guidance based on failure types
203
+ */
204
+ function generateGuidance(failures) {
205
+ const guidances = [];
206
+ const seen = new Set();
207
+ for (const failure of failures) {
208
+ const message = failure.message || '';
209
+ const errorType = failure.errorType;
210
+ // Assertion errors
211
+ if (errorType === 'AssertionError' || message.includes('expected') || message.includes('Expected')) {
212
+ if (!seen.has('assertion')) {
213
+ guidances.push('Review test assertions and expected values');
214
+ seen.add('assertion');
215
+ }
216
+ }
217
+ // Timeout errors
218
+ if (message.includes('Timeout') || message.includes('timeout') || message.includes('exceeded')) {
219
+ if (!seen.has('timeout')) {
220
+ guidances.push('Increase test timeout or optimize async operations');
221
+ seen.add('timeout');
222
+ }
223
+ }
224
+ // Type errors
225
+ if (errorType === 'TypeError') {
226
+ if (!seen.has('type')) {
227
+ guidances.push('Check for null/undefined values and type mismatches');
228
+ seen.add('type');
229
+ }
230
+ }
231
+ // File errors
232
+ if (message.includes('ENOENT') || message.includes('no such file')) {
233
+ if (!seen.has('file')) {
234
+ guidances.push('Verify file paths and ensure test fixtures exist');
235
+ seen.add('file');
236
+ }
237
+ }
238
+ // Module errors
239
+ if (message.includes('Cannot find package') || message.includes('Cannot find module')) {
240
+ if (!seen.has('module')) {
241
+ guidances.push('Install missing dependencies or check import paths');
242
+ seen.add('module');
243
+ }
244
+ }
245
+ }
246
+ return guidances.join('\n');
247
+ }
248
+ /**
249
+ * Format clean output for LLM consumption
250
+ */
251
+ function formatCleanOutput(errors) {
252
+ if (errors.length === 0) {
253
+ return '';
254
+ }
255
+ return errors
256
+ .map((error) => {
257
+ const location = error.line ? `${error.file}:${error.line}` : error.file;
258
+ const contextStr = error.context ? ` (${error.context})` : '';
259
+ return `${location}: ${error.message}${contextStr}`;
260
+ })
261
+ .join('\n');
262
+ }
263
+ //# sourceMappingURL=mocha-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mocha-extractor.js","sourceRoot":"","sources":["../src/mocha-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Playwright Test Error Extractor
3
+ *
4
+ * Extracts error information from Playwright test output.
5
+ *
6
+ * Output format:
7
+ * ```
8
+ * Running N tests using M workers
9
+ *
10
+ * ✘ 1 test.spec.ts:10:5 › Describe › test name (100ms)
11
+ * ✓ 2 test.spec.ts:20:5 › passing test (50ms)
12
+ *
13
+ * 1) test.spec.ts:10:5 › Describe › test name
14
+ *
15
+ * Error: expect(received).toBe(expected)
16
+ *
17
+ * Expected: "foo"
18
+ * Received: "bar"
19
+ *
20
+ * 10 | test('test name', async () => {
21
+ * 11 | const value = 'bar';
22
+ * > 12 | expect(value).toBe('foo');
23
+ * | ^
24
+ * 13 | });
25
+ *
26
+ * at test.spec.ts:12:21
27
+ * ```
28
+ */
29
+ import type { ErrorExtractorResult } from './types.js';
30
+ /**
31
+ * Extract errors from Playwright test output
32
+ */
33
+ export declare function extractPlaywrightErrors(output: string): ErrorExtractorResult;
34
+ /**
35
+ * Check if output is from Playwright
36
+ */
37
+ export declare function isPlaywrightOutput(output: string): boolean;
38
+ //# sourceMappingURL=playwright-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright-extractor.d.ts","sourceRoot":"","sources":["../src/playwright-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAkB,oBAAoB,EAAsB,MAAM,YAAY,CAAC;AAG3F;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CA8H5E;AAoGD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAW1D"}