@yasserkhanorg/e2e-agents 0.7.5 → 0.7.7

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.
@@ -361,61 +361,61 @@ function renderCiSummaryMarkdown(plan) {
361
361
  // ── Blocking gaps ──────────────────────────────────────────────────────────
362
362
  if (mustAddTests && plan.requiredNewTests.length > 0) {
363
363
  lines.push('');
364
- lines.push('### ⚠️ Add E2E tests for these uncovered P0/P1 features');
365
- lines.push('');
366
- lines.push(`The following ${uncoveredP0P1Flows} feature(s) have no test coverage and must be covered before merge:`);
364
+ lines.push(`### ⚠️ Missing coverage for ${uncoveredP0P1Flows} P0/P1 flow(s)`);
367
365
  lines.push('');
368
366
  for (const gap of plan.gapDetails.filter((g) => !g.name.includes('(partial)'))) {
369
367
  const aiLabel = gap.source === 'ai+deterministic' ? ' ✦ AI-enriched' : '';
368
+ // Warning box: name + priority + AI reason (always visible)
370
369
  lines.push(`> [!WARNING]`);
371
370
  lines.push(`> **${gap.name}** · ${gap.priority}${aiLabel}`);
372
- // AI-provided reasons (skip the first generic deterministic reason)
373
371
  const aiReasons = gap.reasons.slice(1);
374
372
  if (aiReasons.length > 0) {
375
373
  lines.push(`> ${aiReasons.join(' ')}`);
376
374
  }
375
+ lines.push('');
376
+ // Scenarios: collapsible below the warning box
377
377
  if (gap.missingScenarios && gap.missingScenarios.length > 0) {
378
- lines.push(`>`);
379
- lines.push(`> **Suggested test scenarios:**`);
378
+ lines.push(`<details><summary>📋 Suggested test scenarios (${gap.missingScenarios.length})</summary>`);
379
+ lines.push('');
380
380
  for (const scenario of gap.missingScenarios) {
381
- lines.push(`> - [ ] ${scenario}`);
381
+ lines.push(`- [ ] ${scenario}`);
382
382
  }
383
+ lines.push('');
384
+ lines.push('</details>');
385
+ lines.push('');
383
386
  }
384
- lines.push('');
385
387
  }
386
388
  }
387
- // ── Advisory: covered flows with new behavior detected ────────────────────
389
+ // ── Advisory: covered flows with new behavior ─────────────────────────────
388
390
  if (flowsWithAdvisory.length > 0) {
389
391
  lines.push('');
390
- lines.push(`### 💡 New behavior detected in ${flowsWithAdvisory.length} covered feature${flowsWithAdvisory.length !== 1 ? 's' : ''}`);
391
- lines.push('');
392
- lines.push('These features already have E2E tests, but this PR introduces new behavior worth covering:');
392
+ lines.push(`### 💡 New behavior detected in ${flowsWithAdvisory.length} covered feature${flowsWithAdvisory.length !== 1 ? 's' : ''} — consider adding tests`);
393
393
  lines.push('');
394
394
  for (const flow of flowsWithAdvisory) {
395
+ // Green [!TIP] box: just the name (always visible, compact)
395
396
  lines.push(`> [!TIP]`);
396
- lines.push(`> **${flow.name}** · ${flow.priority} — ${flow.coveredBy.join(', ')}`);
397
- lines.push(`>`);
398
- lines.push(`> Consider adding tests for:`);
397
+ lines.push(`> **${flow.name}** · ${flow.priority}`);
398
+ lines.push('');
399
+ // Specs + scenarios: collapsible below
400
+ const coverageSummary = flow.coveredBy.join(', ');
401
+ lines.push(`<details><summary>${coverageSummary} — click to see suggested scenarios</summary>`);
402
+ lines.push('');
399
403
  for (const s of flow.advisoryScenarios) {
400
- lines.push(`> - [ ] ${s}`);
404
+ lines.push(`- [ ] ${s}`);
401
405
  }
402
406
  lines.push('');
407
+ lines.push('</details>');
408
+ lines.push('');
403
409
  }
404
410
  }
405
411
  // ── Clean covered flows (collapsed) ───────────────────────────────────────
406
- if (cleanFlows.length > 0 || flowsWithAdvisory.length > 0) {
412
+ if (cleanFlows.length > 0) {
407
413
  lines.push('');
408
- const label = cleanFlows.length > 0
409
- ? `✅ Covered flows (${cleanFlows.length})`
410
- : `✅ All covered flows have advisory notes above`;
411
- lines.push(`<details><summary>${label}</summary>`);
414
+ lines.push(`<details><summary>✅ Covered flows (${cleanFlows.length})</summary>`);
412
415
  lines.push('');
413
416
  for (const flow of cleanFlows) {
414
417
  lines.push(`- **${flow.name}** [${flow.priority}] — ${flow.coveredBy.join(', ')}`);
415
418
  }
416
- for (const flow of flowsWithAdvisory) {
417
- lines.push(`- **${flow.name}** [${flow.priority}] — ${flow.coveredBy.join(', ')} 💡`);
418
- }
419
419
  lines.push('');
420
420
  lines.push('</details>');
421
421
  }
@@ -355,61 +355,61 @@ export function renderCiSummaryMarkdown(plan) {
355
355
  // ── Blocking gaps ──────────────────────────────────────────────────────────
356
356
  if (mustAddTests && plan.requiredNewTests.length > 0) {
357
357
  lines.push('');
358
- lines.push('### ⚠️ Add E2E tests for these uncovered P0/P1 features');
359
- lines.push('');
360
- lines.push(`The following ${uncoveredP0P1Flows} feature(s) have no test coverage and must be covered before merge:`);
358
+ lines.push(`### ⚠️ Missing coverage for ${uncoveredP0P1Flows} P0/P1 flow(s)`);
361
359
  lines.push('');
362
360
  for (const gap of plan.gapDetails.filter((g) => !g.name.includes('(partial)'))) {
363
361
  const aiLabel = gap.source === 'ai+deterministic' ? ' ✦ AI-enriched' : '';
362
+ // Warning box: name + priority + AI reason (always visible)
364
363
  lines.push(`> [!WARNING]`);
365
364
  lines.push(`> **${gap.name}** · ${gap.priority}${aiLabel}`);
366
- // AI-provided reasons (skip the first generic deterministic reason)
367
365
  const aiReasons = gap.reasons.slice(1);
368
366
  if (aiReasons.length > 0) {
369
367
  lines.push(`> ${aiReasons.join(' ')}`);
370
368
  }
369
+ lines.push('');
370
+ // Scenarios: collapsible below the warning box
371
371
  if (gap.missingScenarios && gap.missingScenarios.length > 0) {
372
- lines.push(`>`);
373
- lines.push(`> **Suggested test scenarios:**`);
372
+ lines.push(`<details><summary>📋 Suggested test scenarios (${gap.missingScenarios.length})</summary>`);
373
+ lines.push('');
374
374
  for (const scenario of gap.missingScenarios) {
375
- lines.push(`> - [ ] ${scenario}`);
375
+ lines.push(`- [ ] ${scenario}`);
376
376
  }
377
+ lines.push('');
378
+ lines.push('</details>');
379
+ lines.push('');
377
380
  }
378
- lines.push('');
379
381
  }
380
382
  }
381
- // ── Advisory: covered flows with new behavior detected ────────────────────
383
+ // ── Advisory: covered flows with new behavior ─────────────────────────────
382
384
  if (flowsWithAdvisory.length > 0) {
383
385
  lines.push('');
384
- lines.push(`### 💡 New behavior detected in ${flowsWithAdvisory.length} covered feature${flowsWithAdvisory.length !== 1 ? 's' : ''}`);
385
- lines.push('');
386
- lines.push('These features already have E2E tests, but this PR introduces new behavior worth covering:');
386
+ lines.push(`### 💡 New behavior detected in ${flowsWithAdvisory.length} covered feature${flowsWithAdvisory.length !== 1 ? 's' : ''} — consider adding tests`);
387
387
  lines.push('');
388
388
  for (const flow of flowsWithAdvisory) {
389
+ // Green [!TIP] box: just the name (always visible, compact)
389
390
  lines.push(`> [!TIP]`);
390
- lines.push(`> **${flow.name}** · ${flow.priority} — ${flow.coveredBy.join(', ')}`);
391
- lines.push(`>`);
392
- lines.push(`> Consider adding tests for:`);
391
+ lines.push(`> **${flow.name}** · ${flow.priority}`);
392
+ lines.push('');
393
+ // Specs + scenarios: collapsible below
394
+ const coverageSummary = flow.coveredBy.join(', ');
395
+ lines.push(`<details><summary>${coverageSummary} — click to see suggested scenarios</summary>`);
396
+ lines.push('');
393
397
  for (const s of flow.advisoryScenarios) {
394
- lines.push(`> - [ ] ${s}`);
398
+ lines.push(`- [ ] ${s}`);
395
399
  }
396
400
  lines.push('');
401
+ lines.push('</details>');
402
+ lines.push('');
397
403
  }
398
404
  }
399
405
  // ── Clean covered flows (collapsed) ───────────────────────────────────────
400
- if (cleanFlows.length > 0 || flowsWithAdvisory.length > 0) {
406
+ if (cleanFlows.length > 0) {
401
407
  lines.push('');
402
- const label = cleanFlows.length > 0
403
- ? `✅ Covered flows (${cleanFlows.length})`
404
- : `✅ All covered flows have advisory notes above`;
405
- lines.push(`<details><summary>${label}</summary>`);
408
+ lines.push(`<details><summary>✅ Covered flows (${cleanFlows.length})</summary>`);
406
409
  lines.push('');
407
410
  for (const flow of cleanFlows) {
408
411
  lines.push(`- **${flow.name}** [${flow.priority}] — ${flow.coveredBy.join(', ')}`);
409
412
  }
410
- for (const flow of flowsWithAdvisory) {
411
- lines.push(`- **${flow.name}** [${flow.priority}] — ${flow.coveredBy.join(', ')} 💡`);
412
- }
413
413
  lines.push('');
414
414
  lines.push('</details>');
415
415
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yasserkhanorg/e2e-agents",
3
- "version": "0.7.5",
3
+ "version": "0.7.7",
4
4
  "description": "Pluggable LLM provider library for AI-powered test automation. Use Claude, Ollama, or your own LLM. Integrate with Playwright, Jest, or any test framework. MCP server for test agents, cost tracking, and hybrid provider mode.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",