executable-stories-formatters 0.7.15 → 0.8.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.
- package/dist/cli.js +217 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +217 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +217 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1434,11 +1434,53 @@ function initKeyboardShortcuts() {
|
|
|
1434
1434
|
});
|
|
1435
1435
|
}
|
|
1436
1436
|
|
|
1437
|
-
// Collapse/expand functionality
|
|
1437
|
+
// Collapse/expand functionality (persisted in localStorage)
|
|
1438
|
+
var COLLAPSE_KEY = 'es-collapsed-ids';
|
|
1439
|
+
|
|
1440
|
+
function loadCollapseState() {
|
|
1441
|
+
try {
|
|
1442
|
+
var raw = localStorage.getItem(COLLAPSE_KEY);
|
|
1443
|
+
return raw ? new Set(JSON.parse(raw)) : new Set();
|
|
1444
|
+
} catch (e) {
|
|
1445
|
+
return new Set();
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
function saveCollapseState(set) {
|
|
1450
|
+
try {
|
|
1451
|
+
localStorage.setItem(COLLAPSE_KEY, JSON.stringify(Array.from(set)));
|
|
1452
|
+
} catch (e) { /* quota or disabled */ }
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
function persistCollapse(container) {
|
|
1456
|
+
if (!container || !container.id) return;
|
|
1457
|
+
var state = loadCollapseState();
|
|
1458
|
+
if (container.classList.contains('collapsed')) {
|
|
1459
|
+
state.add(container.id);
|
|
1460
|
+
} else {
|
|
1461
|
+
state.delete(container.id);
|
|
1462
|
+
}
|
|
1463
|
+
saveCollapseState(state);
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1438
1466
|
function toggleCollapse(header, container) {
|
|
1439
1467
|
container?.classList.toggle('collapsed');
|
|
1440
1468
|
const isCollapsed = container?.classList.contains('collapsed');
|
|
1441
1469
|
header.setAttribute('aria-expanded', !isCollapsed);
|
|
1470
|
+
persistCollapse(container);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
function restoreCollapseState() {
|
|
1474
|
+
var state = loadCollapseState();
|
|
1475
|
+
if (state.size === 0) return;
|
|
1476
|
+
state.forEach(function(id) {
|
|
1477
|
+
var el = document.getElementById(id);
|
|
1478
|
+
if (!el) return;
|
|
1479
|
+
if (!el.classList.contains('feature') && !el.classList.contains('scenario')) return;
|
|
1480
|
+
el.classList.add('collapsed');
|
|
1481
|
+
var header = el.querySelector('.feature-header, .scenario-header');
|
|
1482
|
+
if (header) header.setAttribute('aria-expanded', 'false');
|
|
1483
|
+
});
|
|
1442
1484
|
}
|
|
1443
1485
|
|
|
1444
1486
|
function initCollapse() {
|
|
@@ -1485,14 +1527,20 @@ function expandAll() {
|
|
|
1485
1527
|
const header = el.querySelector('.feature-header, .scenario-header, .trace-view-header');
|
|
1486
1528
|
header?.setAttribute('aria-expanded', 'true');
|
|
1487
1529
|
});
|
|
1530
|
+
saveCollapseState(new Set());
|
|
1488
1531
|
}
|
|
1489
1532
|
|
|
1490
1533
|
function collapseAll() {
|
|
1534
|
+
var ids = new Set();
|
|
1491
1535
|
document.querySelectorAll('.feature, .scenario, .trace-view').forEach(el => {
|
|
1492
1536
|
el.classList.add('collapsed');
|
|
1493
1537
|
const header = el.querySelector('.feature-header, .scenario-header, .trace-view-header');
|
|
1494
1538
|
header?.setAttribute('aria-expanded', 'false');
|
|
1539
|
+
if (el.id && (el.classList.contains('feature') || el.classList.contains('scenario'))) {
|
|
1540
|
+
ids.add(el.id);
|
|
1541
|
+
}
|
|
1495
1542
|
});
|
|
1543
|
+
saveCollapseState(ids);
|
|
1496
1544
|
}
|
|
1497
1545
|
|
|
1498
1546
|
// Detail level toggle
|
|
@@ -1619,6 +1667,68 @@ function copyScenarioAsMarkdown(scenarioId) {
|
|
|
1619
1667
|
});
|
|
1620
1668
|
}
|
|
1621
1669
|
|
|
1670
|
+
// Copy scenario as Claude-ready prompt (failure investigation context)
|
|
1671
|
+
function copyScenarioAsPrompt(scenarioId) {
|
|
1672
|
+
var scenario = document.getElementById(scenarioId);
|
|
1673
|
+
if (!scenario) return;
|
|
1674
|
+
|
|
1675
|
+
var feature = scenario.closest('.feature');
|
|
1676
|
+
var featureTitle = feature ? (feature.querySelector('.feature-title') || {}).textContent || '' : '';
|
|
1677
|
+
var title = (scenario.querySelector('.scenario-name') || {}).textContent || '';
|
|
1678
|
+
var statusEl = scenario.querySelector('.status-icon');
|
|
1679
|
+
var status = statusEl && statusEl.classList.contains('status-passed') ? 'passed' :
|
|
1680
|
+
statusEl && statusEl.classList.contains('status-failed') ? 'failed' :
|
|
1681
|
+
statusEl && statusEl.classList.contains('status-skipped') ? 'skipped' : 'pending';
|
|
1682
|
+
var sourceLink = scenario.querySelector('.source-link');
|
|
1683
|
+
var source = sourceLink ? sourceLink.textContent || '' : '';
|
|
1684
|
+
var tags = Array.from(scenario.querySelectorAll('.scenario-meta .tag')).map(function(t) { return t.textContent.trim(); });
|
|
1685
|
+
var steps = scenario.querySelectorAll('.step, .step.continuation');
|
|
1686
|
+
|
|
1687
|
+
var lines = [];
|
|
1688
|
+
lines.push('I need help investigating a failing executable-story scenario.');
|
|
1689
|
+
lines.push('');
|
|
1690
|
+
if (featureTitle.trim()) lines.push('Feature: ' + featureTitle.trim());
|
|
1691
|
+
lines.push('Scenario: ' + title.trim());
|
|
1692
|
+
lines.push('Status: ' + status);
|
|
1693
|
+
if (source.trim()) lines.push('Source: ' + source.trim());
|
|
1694
|
+
if (tags.length > 0) lines.push('Tags: ' + tags.join(', '));
|
|
1695
|
+
lines.push('');
|
|
1696
|
+
lines.push('Steps:');
|
|
1697
|
+
steps.forEach(function(step) {
|
|
1698
|
+
var keyword = step.getAttribute('data-keyword') || '';
|
|
1699
|
+
var text = step.getAttribute('data-text') || '';
|
|
1700
|
+
var stepStatusEl = step.querySelector('.step-status');
|
|
1701
|
+
var marker = ' ';
|
|
1702
|
+
if (stepStatusEl) {
|
|
1703
|
+
if (stepStatusEl.classList.contains('status-failed')) marker = 'x ';
|
|
1704
|
+
else if (stepStatusEl.classList.contains('status-passed')) marker = '+ ';
|
|
1705
|
+
else if (stepStatusEl.classList.contains('status-skipped')) marker = '- ';
|
|
1706
|
+
}
|
|
1707
|
+
lines.push(marker + keyword + ' ' + text);
|
|
1708
|
+
});
|
|
1709
|
+
|
|
1710
|
+
var errorBox = scenario.querySelector('.error-message');
|
|
1711
|
+
if (errorBox) {
|
|
1712
|
+
lines.push('');
|
|
1713
|
+
lines.push('Error:');
|
|
1714
|
+
lines.push((errorBox.textContent || '').trim());
|
|
1715
|
+
}
|
|
1716
|
+
var stackBox = scenario.querySelector('.error-stack');
|
|
1717
|
+
if (stackBox) {
|
|
1718
|
+
lines.push('');
|
|
1719
|
+
lines.push('Stack:');
|
|
1720
|
+
lines.push((stackBox.textContent || '').trim());
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
lines.push('');
|
|
1724
|
+
lines.push('Please read the source file, identify the root cause, and propose a fix.');
|
|
1725
|
+
|
|
1726
|
+
var text = lines.join('\\n');
|
|
1727
|
+
navigator.clipboard.writeText(text).then(function() {
|
|
1728
|
+
showCopyToast(scenario);
|
|
1729
|
+
});
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1622
1732
|
// Hash scroll on load
|
|
1623
1733
|
function initHashScroll() {
|
|
1624
1734
|
if (!location.hash) return;
|
|
@@ -1788,6 +1898,7 @@ function generateScript(options) {
|
|
|
1788
1898
|
initCalls.push("initStatusFilter();");
|
|
1789
1899
|
initCalls.push("initKeyboardShortcuts();");
|
|
1790
1900
|
initCalls.push("initCollapse();");
|
|
1901
|
+
initCalls.push("restoreCollapseState();");
|
|
1791
1902
|
initCalls.push("initDetailLevel();");
|
|
1792
1903
|
initCalls.push("applyAllFilters();");
|
|
1793
1904
|
initCalls.push("initHashScroll();");
|
|
@@ -3895,6 +4006,33 @@ body {
|
|
|
3895
4006
|
color: var(--primary);
|
|
3896
4007
|
}
|
|
3897
4008
|
|
|
4009
|
+
.copy-prompt-btn {
|
|
4010
|
+
display: inline-flex;
|
|
4011
|
+
align-items: center;
|
|
4012
|
+
justify-content: center;
|
|
4013
|
+
width: 1.5rem;
|
|
4014
|
+
height: 1.5rem;
|
|
4015
|
+
border: none;
|
|
4016
|
+
background: none;
|
|
4017
|
+
color: var(--muted-foreground);
|
|
4018
|
+
cursor: pointer;
|
|
4019
|
+
opacity: 0.6;
|
|
4020
|
+
transition: opacity 0.15s ease, transform 0.15s ease;
|
|
4021
|
+
font-size: 0.95rem;
|
|
4022
|
+
padding: 0;
|
|
4023
|
+
flex-shrink: 0;
|
|
4024
|
+
}
|
|
4025
|
+
|
|
4026
|
+
.scenario-header:hover .copy-prompt-btn,
|
|
4027
|
+
.copy-prompt-btn:focus-visible {
|
|
4028
|
+
opacity: 1;
|
|
4029
|
+
}
|
|
4030
|
+
|
|
4031
|
+
.copy-prompt-btn:hover {
|
|
4032
|
+
color: var(--primary);
|
|
4033
|
+
transform: scale(1.15);
|
|
4034
|
+
}
|
|
4035
|
+
|
|
3898
4036
|
/* ============================================================================
|
|
3899
4037
|
Keyboard Navigation
|
|
3900
4038
|
============================================================================ */
|
|
@@ -4132,6 +4270,82 @@ a.toc-title:hover {
|
|
|
4132
4270
|
outline-offset: 2px;
|
|
4133
4271
|
}
|
|
4134
4272
|
|
|
4273
|
+
/* ============================================================================
|
|
4274
|
+
Mobile responsive refinements
|
|
4275
|
+
============================================================================ */
|
|
4276
|
+
@media (max-width: 640px) {
|
|
4277
|
+
.container {
|
|
4278
|
+
padding: 0.875rem;
|
|
4279
|
+
}
|
|
4280
|
+
|
|
4281
|
+
.header {
|
|
4282
|
+
flex-direction: column;
|
|
4283
|
+
align-items: stretch;
|
|
4284
|
+
gap: 0.75rem;
|
|
4285
|
+
}
|
|
4286
|
+
|
|
4287
|
+
.header-actions {
|
|
4288
|
+
flex-wrap: wrap;
|
|
4289
|
+
gap: 0.5rem;
|
|
4290
|
+
}
|
|
4291
|
+
|
|
4292
|
+
.search-input {
|
|
4293
|
+
width: 100%;
|
|
4294
|
+
flex: 1 1 100%;
|
|
4295
|
+
min-width: 0;
|
|
4296
|
+
}
|
|
4297
|
+
|
|
4298
|
+
.header h1 {
|
|
4299
|
+
font-size: 1.25rem;
|
|
4300
|
+
}
|
|
4301
|
+
|
|
4302
|
+
.scenario-header,
|
|
4303
|
+
.feature-header {
|
|
4304
|
+
flex-wrap: wrap;
|
|
4305
|
+
gap: 0.5rem;
|
|
4306
|
+
}
|
|
4307
|
+
|
|
4308
|
+
.scenario-meta {
|
|
4309
|
+
flex-wrap: wrap;
|
|
4310
|
+
}
|
|
4311
|
+
|
|
4312
|
+
.scenario-actions {
|
|
4313
|
+
flex-wrap: wrap;
|
|
4314
|
+
}
|
|
4315
|
+
|
|
4316
|
+
/* Always-visible action buttons on touch (no hover) */
|
|
4317
|
+
.copy-scenario-btn,
|
|
4318
|
+
.copy-prompt-btn,
|
|
4319
|
+
.permalink-anchor {
|
|
4320
|
+
opacity: 1 !important;
|
|
4321
|
+
}
|
|
4322
|
+
|
|
4323
|
+
.summary-card {
|
|
4324
|
+
padding: 0.75rem 0.875rem;
|
|
4325
|
+
}
|
|
4326
|
+
|
|
4327
|
+
.summary-card .value {
|
|
4328
|
+
font-size: 1.5rem;
|
|
4329
|
+
}
|
|
4330
|
+
|
|
4331
|
+
.tag-bar {
|
|
4332
|
+
overflow-x: auto;
|
|
4333
|
+
-webkit-overflow-scrolling: touch;
|
|
4334
|
+
}
|
|
4335
|
+
|
|
4336
|
+
.shortcuts-overlay {
|
|
4337
|
+
padding: 1rem;
|
|
4338
|
+
}
|
|
4339
|
+
}
|
|
4340
|
+
|
|
4341
|
+
@media (hover: none) and (pointer: coarse) {
|
|
4342
|
+
.copy-scenario-btn,
|
|
4343
|
+
.copy-prompt-btn,
|
|
4344
|
+
.permalink-anchor {
|
|
4345
|
+
opacity: 1;
|
|
4346
|
+
}
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4135
4349
|
`;
|
|
4136
4350
|
|
|
4137
4351
|
// src/formatters/html/themes/default.ts
|
|
@@ -13858,6 +14072,7 @@ function renderScenario(args, deps) {
|
|
|
13858
14072
|
</div>
|
|
13859
14073
|
<div class="scenario-actions">
|
|
13860
14074
|
<button class="copy-scenario-btn" onclick="copyScenarioAsMarkdown('scenario-${tc.id}')" aria-label="Copy scenario as markdown" title="Copy as Markdown"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>
|
|
14075
|
+
${tc.status === "failed" ? `<button class="copy-prompt-btn" onclick="copyScenarioAsPrompt('scenario-${tc.id}')" aria-label="Copy as Claude prompt" title="Copy as AI prompt">\u2728</button>` : ""}
|
|
13861
14076
|
<button class="permalink-anchor" onclick="copyPermalink('scenario-${tc.id}')" aria-label="Copy link to scenario" title="Copy link">#</button>
|
|
13862
14077
|
<span class="scenario-duration">${duration}</span>
|
|
13863
14078
|
</div>
|
|
@@ -19654,7 +19869,7 @@ var ReportGenerator = class {
|
|
|
19654
19869
|
exclude: options.exclude ?? [],
|
|
19655
19870
|
includeTags: options.includeTags ?? [],
|
|
19656
19871
|
excludeTags: options.excludeTags ?? [],
|
|
19657
|
-
formats: options.formats ?? ["
|
|
19872
|
+
formats: options.formats ?? ["html"],
|
|
19658
19873
|
outputDir: options.outputDir ?? "reports",
|
|
19659
19874
|
outputName: options.outputName ?? "index",
|
|
19660
19875
|
outputNameTimestamp: options.outputNameTimestamp ?? false,
|