@yasserkhanorg/e2e-agents 1.8.4 → 1.8.5
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan_crew.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plan_crew.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAC,gBAAgB,EAAE,UAAU,EAAC,MAAM,qBAAqB,CAAC;AAUtE,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAgC5C,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkD5H;AAWD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAwEnF;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAE3G;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"plan_crew.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plan_crew.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAC,gBAAgB,EAAE,UAAU,EAAC,MAAM,qBAAqB,CAAC;AAUtE,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAgC5C,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkD5H;AAWD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAwEnF;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAE3G;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAsJnF;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAC,CAa/K"}
|
|
@@ -95,11 +95,11 @@ function buildCrewMarkdown(crew, plan) {
|
|
|
95
95
|
const totalCases = crew.testDesigns.reduce((n, td) => n + td.testCases.length, 0);
|
|
96
96
|
const gapFamilies = new Set((plan?.gapDetails ?? []).map((g) => g.id));
|
|
97
97
|
const lines = [
|
|
98
|
-
'### Crew
|
|
98
|
+
'### Crew Analysis — What to Test',
|
|
99
99
|
'',
|
|
100
|
-
`
|
|
101
|
-
|
|
102
|
-
`Strategy entries: **${crew.summary.strategyEntries}**`,
|
|
100
|
+
`Crew analyzed the diff and recommends what to verify before merging.`,
|
|
101
|
+
'',
|
|
102
|
+
`Impacted flows: **${crew.summary.impactedFlows}** | Strategy entries: **${crew.summary.strategyEntries}**`,
|
|
103
103
|
];
|
|
104
104
|
if (totalCases > 0) {
|
|
105
105
|
const gapDesigns = gapFamilies.size > 0
|
|
@@ -184,37 +184,48 @@ function buildCrewTestPlan(crew, plan) {
|
|
|
184
184
|
const gapCases = gapDesigns.reduce((n, td) => n + td.testCases.length, 0);
|
|
185
185
|
const coveredCases = coveredDesigns.reduce((n, td) => n + td.testCases.length, 0);
|
|
186
186
|
const lines = [
|
|
187
|
-
'# Crew Test Plan',
|
|
187
|
+
'# Crew Test Plan — What to Verify',
|
|
188
|
+
'',
|
|
189
|
+
'> **This is a test recommendation, not a test execution report.**',
|
|
190
|
+
'> Crew analyzed the code diff and identified what needs to be tested.',
|
|
191
|
+
'> Use this plan to guide manual QA or write automated E2E tests.',
|
|
188
192
|
'',
|
|
189
|
-
|
|
193
|
+
`_Auto-generated by e2e-agents crew (\`${crew.workflow}\` workflow)_`,
|
|
190
194
|
'',
|
|
191
195
|
'## Summary',
|
|
192
196
|
'',
|
|
193
197
|
`| Metric | Count |`,
|
|
194
198
|
`|--------|-------|`,
|
|
195
|
-
`| Gap flows
|
|
196
|
-
`| Covered flows
|
|
197
|
-
`| Total
|
|
199
|
+
`| Gap flows — **no existing tests, must verify** | ${gapStrategies.length} flows${hasTestDesigns ? `, **${gapCases} test cases**` : ''} |`,
|
|
200
|
+
`| Covered flows — **has tests, verify no regressions** | ${coveredStrategies.length} flows${hasTestDesigns ? `, ${coveredCases} test cases` : ''} |`,
|
|
201
|
+
`| Total | ${crew.strategyEntries.length} flows${hasTestDesigns ? `, ${totalCases} test cases` : ''} |`,
|
|
198
202
|
`| High-risk cross-impacts | ${crew.summary.highRiskCrossImpacts} |`,
|
|
199
203
|
`| AI cost | $${crew.summary.totalCostUSD.toFixed(4)} |`,
|
|
200
204
|
'',
|
|
201
205
|
];
|
|
202
206
|
// ── Gap flows ──
|
|
203
207
|
if (gapStrategies.length > 0) {
|
|
204
|
-
lines.push('##
|
|
208
|
+
lines.push('## Action Required: Gap Flows (No Existing Tests)');
|
|
205
209
|
lines.push('');
|
|
206
|
-
lines.push('These flows have **no
|
|
210
|
+
lines.push('These flows have **no automated E2E coverage**. Before merging, either:');
|
|
211
|
+
lines.push('1. **Write E2E tests** for the critical scenarios below, or');
|
|
212
|
+
lines.push('2. **Manually verify** each flow works as expected');
|
|
207
213
|
lines.push('');
|
|
208
214
|
for (const strategy of gapStrategies) {
|
|
209
215
|
const td = crew.testDesigns.find((d) => d.flowId === strategy.flowId);
|
|
210
216
|
lines.push(`### ${strategy.flowName}`);
|
|
211
217
|
lines.push('');
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
218
|
+
const actionVerb = strategy.approach === 'full-test' ? 'Write full E2E test or verify manually'
|
|
219
|
+
: strategy.approach === 'smoke-test' ? 'Smoke-test manually or add basic E2E coverage'
|
|
220
|
+
: strategy.approach === 'manual-review' ? 'Manual review required'
|
|
221
|
+
: 'Can skip — low risk';
|
|
222
|
+
lines.push(`**${strategy.priority}** | Recommended: **${strategy.approach}** | Cross-impact risk: **${strategy.crossImpactRisk}**`);
|
|
223
|
+
lines.push(`> ${actionVerb}`);
|
|
224
|
+
if (strategy.rationale && !strategy.rationale.includes('Default strategy')) {
|
|
225
|
+
lines.push(`> Rationale: ${strategy.rationale}`);
|
|
215
226
|
}
|
|
216
227
|
if (strategy.testCategories.length > 0) {
|
|
217
|
-
lines.push(
|
|
228
|
+
lines.push(`> Test types to cover: ${strategy.testCategories.join(', ')}`);
|
|
218
229
|
}
|
|
219
230
|
lines.push('');
|
|
220
231
|
// If test designs exist, show P0/P1 cases
|
|
@@ -249,9 +260,10 @@ function buildCrewTestPlan(crew, plan) {
|
|
|
249
260
|
}
|
|
250
261
|
// ── Covered flows ──
|
|
251
262
|
if (coveredStrategies.length > 0) {
|
|
252
|
-
lines.push('## Covered Flows (
|
|
263
|
+
lines.push('## Regression Check: Covered Flows (Already Have Tests)');
|
|
253
264
|
lines.push('');
|
|
254
|
-
lines.push('These flows
|
|
265
|
+
lines.push('These flows have existing E2E specs. The existing tests should catch regressions automatically.');
|
|
266
|
+
lines.push('**No manual action required** unless CI tests fail on these flows.');
|
|
255
267
|
lines.push('');
|
|
256
268
|
for (const strategy of coveredStrategies) {
|
|
257
269
|
const td = crew.testDesigns.find((d) => d.flowId === strategy.flowId);
|
|
@@ -259,8 +271,8 @@ function buildCrewTestPlan(crew, plan) {
|
|
|
259
271
|
const detail = caseCount > 0 ? ` | ${caseCount} cases` : '';
|
|
260
272
|
lines.push(`<details><summary><strong>${strategy.flowName}</strong> — ${strategy.approach}${detail} (${strategy.priority})</summary>`);
|
|
261
273
|
lines.push('');
|
|
262
|
-
lines.push(`Cross-impact risk: ${strategy.crossImpactRisk}`);
|
|
263
|
-
if (strategy.rationale) {
|
|
274
|
+
lines.push(`Existing tests should cover this. Cross-impact risk: ${strategy.crossImpactRisk}`);
|
|
275
|
+
if (strategy.rationale && !strategy.rationale.includes('Default strategy')) {
|
|
264
276
|
lines.push(`> ${strategy.rationale}`);
|
|
265
277
|
}
|
|
266
278
|
if (strategy.testCategories.length > 0) {
|
|
@@ -280,9 +292,9 @@ function buildCrewTestPlan(crew, plan) {
|
|
|
280
292
|
// ── Cross-impacts ──
|
|
281
293
|
const highRisk = crew.crossImpacts.filter((ci) => ci.riskLevel === 'high');
|
|
282
294
|
if (highRisk.length > 0) {
|
|
283
|
-
lines.push('## High-Risk Cross-Impacts');
|
|
295
|
+
lines.push('## High-Risk Cross-Impacts — Verify Before Release');
|
|
284
296
|
lines.push('');
|
|
285
|
-
lines.push('
|
|
297
|
+
lines.push('Changes in one area may break these related areas. Manually verify or ensure E2E tests cover both sides:');
|
|
286
298
|
lines.push('');
|
|
287
299
|
for (const ci of highRisk) {
|
|
288
300
|
lines.push(`- **${ci.sourceFamily}** → **${ci.affectedFamily}**: ${ci.sharedDependency}`);
|
|
@@ -88,11 +88,11 @@ export function buildCrewMarkdown(crew, plan) {
|
|
|
88
88
|
const totalCases = crew.testDesigns.reduce((n, td) => n + td.testCases.length, 0);
|
|
89
89
|
const gapFamilies = new Set((plan?.gapDetails ?? []).map((g) => g.id));
|
|
90
90
|
const lines = [
|
|
91
|
-
'### Crew
|
|
91
|
+
'### Crew Analysis — What to Test',
|
|
92
92
|
'',
|
|
93
|
-
`
|
|
94
|
-
|
|
95
|
-
`Strategy entries: **${crew.summary.strategyEntries}**`,
|
|
93
|
+
`Crew analyzed the diff and recommends what to verify before merging.`,
|
|
94
|
+
'',
|
|
95
|
+
`Impacted flows: **${crew.summary.impactedFlows}** | Strategy entries: **${crew.summary.strategyEntries}**`,
|
|
96
96
|
];
|
|
97
97
|
if (totalCases > 0) {
|
|
98
98
|
const gapDesigns = gapFamilies.size > 0
|
|
@@ -177,37 +177,48 @@ export function buildCrewTestPlan(crew, plan) {
|
|
|
177
177
|
const gapCases = gapDesigns.reduce((n, td) => n + td.testCases.length, 0);
|
|
178
178
|
const coveredCases = coveredDesigns.reduce((n, td) => n + td.testCases.length, 0);
|
|
179
179
|
const lines = [
|
|
180
|
-
'# Crew Test Plan',
|
|
180
|
+
'# Crew Test Plan — What to Verify',
|
|
181
|
+
'',
|
|
182
|
+
'> **This is a test recommendation, not a test execution report.**',
|
|
183
|
+
'> Crew analyzed the code diff and identified what needs to be tested.',
|
|
184
|
+
'> Use this plan to guide manual QA or write automated E2E tests.',
|
|
181
185
|
'',
|
|
182
|
-
|
|
186
|
+
`_Auto-generated by e2e-agents crew (\`${crew.workflow}\` workflow)_`,
|
|
183
187
|
'',
|
|
184
188
|
'## Summary',
|
|
185
189
|
'',
|
|
186
190
|
`| Metric | Count |`,
|
|
187
191
|
`|--------|-------|`,
|
|
188
|
-
`| Gap flows
|
|
189
|
-
`| Covered flows
|
|
190
|
-
`| Total
|
|
192
|
+
`| Gap flows — **no existing tests, must verify** | ${gapStrategies.length} flows${hasTestDesigns ? `, **${gapCases} test cases**` : ''} |`,
|
|
193
|
+
`| Covered flows — **has tests, verify no regressions** | ${coveredStrategies.length} flows${hasTestDesigns ? `, ${coveredCases} test cases` : ''} |`,
|
|
194
|
+
`| Total | ${crew.strategyEntries.length} flows${hasTestDesigns ? `, ${totalCases} test cases` : ''} |`,
|
|
191
195
|
`| High-risk cross-impacts | ${crew.summary.highRiskCrossImpacts} |`,
|
|
192
196
|
`| AI cost | $${crew.summary.totalCostUSD.toFixed(4)} |`,
|
|
193
197
|
'',
|
|
194
198
|
];
|
|
195
199
|
// ── Gap flows ──
|
|
196
200
|
if (gapStrategies.length > 0) {
|
|
197
|
-
lines.push('##
|
|
201
|
+
lines.push('## Action Required: Gap Flows (No Existing Tests)');
|
|
198
202
|
lines.push('');
|
|
199
|
-
lines.push('These flows have **no
|
|
203
|
+
lines.push('These flows have **no automated E2E coverage**. Before merging, either:');
|
|
204
|
+
lines.push('1. **Write E2E tests** for the critical scenarios below, or');
|
|
205
|
+
lines.push('2. **Manually verify** each flow works as expected');
|
|
200
206
|
lines.push('');
|
|
201
207
|
for (const strategy of gapStrategies) {
|
|
202
208
|
const td = crew.testDesigns.find((d) => d.flowId === strategy.flowId);
|
|
203
209
|
lines.push(`### ${strategy.flowName}`);
|
|
204
210
|
lines.push('');
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
211
|
+
const actionVerb = strategy.approach === 'full-test' ? 'Write full E2E test or verify manually'
|
|
212
|
+
: strategy.approach === 'smoke-test' ? 'Smoke-test manually or add basic E2E coverage'
|
|
213
|
+
: strategy.approach === 'manual-review' ? 'Manual review required'
|
|
214
|
+
: 'Can skip — low risk';
|
|
215
|
+
lines.push(`**${strategy.priority}** | Recommended: **${strategy.approach}** | Cross-impact risk: **${strategy.crossImpactRisk}**`);
|
|
216
|
+
lines.push(`> ${actionVerb}`);
|
|
217
|
+
if (strategy.rationale && !strategy.rationale.includes('Default strategy')) {
|
|
218
|
+
lines.push(`> Rationale: ${strategy.rationale}`);
|
|
208
219
|
}
|
|
209
220
|
if (strategy.testCategories.length > 0) {
|
|
210
|
-
lines.push(
|
|
221
|
+
lines.push(`> Test types to cover: ${strategy.testCategories.join(', ')}`);
|
|
211
222
|
}
|
|
212
223
|
lines.push('');
|
|
213
224
|
// If test designs exist, show P0/P1 cases
|
|
@@ -242,9 +253,10 @@ export function buildCrewTestPlan(crew, plan) {
|
|
|
242
253
|
}
|
|
243
254
|
// ── Covered flows ──
|
|
244
255
|
if (coveredStrategies.length > 0) {
|
|
245
|
-
lines.push('## Covered Flows (
|
|
256
|
+
lines.push('## Regression Check: Covered Flows (Already Have Tests)');
|
|
246
257
|
lines.push('');
|
|
247
|
-
lines.push('These flows
|
|
258
|
+
lines.push('These flows have existing E2E specs. The existing tests should catch regressions automatically.');
|
|
259
|
+
lines.push('**No manual action required** unless CI tests fail on these flows.');
|
|
248
260
|
lines.push('');
|
|
249
261
|
for (const strategy of coveredStrategies) {
|
|
250
262
|
const td = crew.testDesigns.find((d) => d.flowId === strategy.flowId);
|
|
@@ -252,8 +264,8 @@ export function buildCrewTestPlan(crew, plan) {
|
|
|
252
264
|
const detail = caseCount > 0 ? ` | ${caseCount} cases` : '';
|
|
253
265
|
lines.push(`<details><summary><strong>${strategy.flowName}</strong> — ${strategy.approach}${detail} (${strategy.priority})</summary>`);
|
|
254
266
|
lines.push('');
|
|
255
|
-
lines.push(`Cross-impact risk: ${strategy.crossImpactRisk}`);
|
|
256
|
-
if (strategy.rationale) {
|
|
267
|
+
lines.push(`Existing tests should cover this. Cross-impact risk: ${strategy.crossImpactRisk}`);
|
|
268
|
+
if (strategy.rationale && !strategy.rationale.includes('Default strategy')) {
|
|
257
269
|
lines.push(`> ${strategy.rationale}`);
|
|
258
270
|
}
|
|
259
271
|
if (strategy.testCategories.length > 0) {
|
|
@@ -273,9 +285,9 @@ export function buildCrewTestPlan(crew, plan) {
|
|
|
273
285
|
// ── Cross-impacts ──
|
|
274
286
|
const highRisk = crew.crossImpacts.filter((ci) => ci.riskLevel === 'high');
|
|
275
287
|
if (highRisk.length > 0) {
|
|
276
|
-
lines.push('## High-Risk Cross-Impacts');
|
|
288
|
+
lines.push('## High-Risk Cross-Impacts — Verify Before Release');
|
|
277
289
|
lines.push('');
|
|
278
|
-
lines.push('
|
|
290
|
+
lines.push('Changes in one area may break these related areas. Manually verify or ensure E2E tests cover both sides:');
|
|
279
291
|
lines.push('');
|
|
280
292
|
for (const ci of highRisk) {
|
|
281
293
|
lines.push(`- **${ci.sourceFamily}** → **${ci.affectedFamily}**: ${ci.sharedDependency}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yasserkhanorg/e2e-agents",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.5",
|
|
4
4
|
"description": "AI-powered E2E test impact analysis, generation, and healing. Analyzes code changes to identify affected Playwright tests, detects coverage gaps, and generates or repairs specs using pluggable LLM providers (Claude, OpenAI, Ollama). Includes MCP server, traceability, and CI/CD integration.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|