mcprigor 1.3.0 → 1.4.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/README.md +1 -1
- package/dist/cli.js +42 -2
- package/dist/cli.js.map +1 -1
- package/dist/export.d.ts +16 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +366 -0
- package/dist/export.js.map +1 -0
- package/dist/reporters.d.ts +2 -1
- package/dist/reporters.d.ts.map +1 -1
- package/dist/reporters.js +5 -2
- package/dist/reporters.js.map +1 -1
- package/dist/schema.d.ts +77 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +16 -1
- package/dist/schema.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +58 -1
- package/dist/workspace.js.map +1 -1
- package/docs/CLI-REFERENCE.md +23 -0
- package/docs/ENGINEER-SETUP.md +1 -1
- package/package.json +2 -1
- package/workspace-assets/app.js +81 -0
- package/workspace-assets/index.html +14 -0
- package/workspace-assets/style.css +11 -2
package/workspace-assets/app.js
CHANGED
|
@@ -341,6 +341,7 @@ async function run(mode, paths) {
|
|
|
341
341
|
function renderRun() {
|
|
342
342
|
const run = state.run;
|
|
343
343
|
if (!run) return;
|
|
344
|
+
updateExportBar();
|
|
344
345
|
const query = $('results-filter').value.trim();
|
|
345
346
|
const list = $('run-list');
|
|
346
347
|
list.replaceChildren();
|
|
@@ -548,3 +549,83 @@ $('refresh').onclick = () => refreshList().then(n => { if (!n && !state.path) sh
|
|
|
548
549
|
$('filter').addEventListener('input', renderList);
|
|
549
550
|
setEnabled(false);
|
|
550
551
|
start().catch(show);
|
|
552
|
+
|
|
553
|
+
/* ---------- resizable panels ---------- */
|
|
554
|
+
(() => {
|
|
555
|
+
const mainEl = document.querySelector('main');
|
|
556
|
+
const KEY = 'mcprigor.panels';
|
|
557
|
+
const apply = (side, results) => {
|
|
558
|
+
if (side) mainEl.style.setProperty('--col-side', side);
|
|
559
|
+
if (results) mainEl.style.setProperty('--col-results', results);
|
|
560
|
+
};
|
|
561
|
+
try { const saved = JSON.parse(localStorage.getItem(KEY) || '{}'); apply(saved.side, saved.results); } catch {}
|
|
562
|
+
const save = () => {
|
|
563
|
+
try { localStorage.setItem(KEY, JSON.stringify({
|
|
564
|
+
side: mainEl.style.getPropertyValue('--col-side') || undefined,
|
|
565
|
+
results: mainEl.style.getPropertyValue('--col-results') || undefined,
|
|
566
|
+
})); } catch {}
|
|
567
|
+
};
|
|
568
|
+
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
569
|
+
const wire = (id, compute, keyboardStep) => {
|
|
570
|
+
const splitter = document.getElementById(id);
|
|
571
|
+
if (!splitter) return;
|
|
572
|
+
splitter.addEventListener('pointerdown', (event) => {
|
|
573
|
+
event.preventDefault();
|
|
574
|
+
splitter.setPointerCapture(event.pointerId);
|
|
575
|
+
splitter.classList.add('dragging');
|
|
576
|
+
document.body.classList.add('resizing');
|
|
577
|
+
const move = (ev) => compute(ev.clientX);
|
|
578
|
+
const stop = () => {
|
|
579
|
+
splitter.classList.remove('dragging');
|
|
580
|
+
document.body.classList.remove('resizing');
|
|
581
|
+
splitter.removeEventListener('pointermove', move);
|
|
582
|
+
splitter.removeEventListener('pointerup', stop);
|
|
583
|
+
splitter.removeEventListener('pointercancel', stop);
|
|
584
|
+
save();
|
|
585
|
+
};
|
|
586
|
+
splitter.addEventListener('pointermove', move);
|
|
587
|
+
splitter.addEventListener('pointerup', stop);
|
|
588
|
+
splitter.addEventListener('pointercancel', stop);
|
|
589
|
+
});
|
|
590
|
+
splitter.addEventListener('keydown', (event) => {
|
|
591
|
+
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return;
|
|
592
|
+
event.preventDefault();
|
|
593
|
+
keyboardStep(event.key === 'ArrowLeft' ? -16 : 16);
|
|
594
|
+
save();
|
|
595
|
+
});
|
|
596
|
+
splitter.addEventListener('dblclick', () => {
|
|
597
|
+
mainEl.style.removeProperty('--col-side');
|
|
598
|
+
mainEl.style.removeProperty('--col-results');
|
|
599
|
+
try { localStorage.removeItem(KEY); } catch {}
|
|
600
|
+
});
|
|
601
|
+
};
|
|
602
|
+
const sideWidth = () => document.querySelector('.sidebar').getBoundingClientRect().width;
|
|
603
|
+
const resultsWidth = () => document.querySelector('.results').getBoundingClientRect().width;
|
|
604
|
+
wire('split-left',
|
|
605
|
+
(x) => apply(`${clamp(x - mainEl.getBoundingClientRect().left, 160, 480)}px`, null),
|
|
606
|
+
(delta) => apply(`${clamp(sideWidth() + delta, 160, 480)}px`, null));
|
|
607
|
+
wire('split-right',
|
|
608
|
+
(x) => { const rect = mainEl.getBoundingClientRect(); apply(null, `${clamp(rect.right - x, 240, rect.width - 500)}px`); },
|
|
609
|
+
(delta) => { const rect = mainEl.getBoundingClientRect(); apply(null, `${clamp(resultsWidth() - delta, 240, rect.width - 500)}px`); });
|
|
610
|
+
})();
|
|
611
|
+
|
|
612
|
+
/* ---------- report exports ---------- */
|
|
613
|
+
function updateExportBar() {
|
|
614
|
+
const run = state.run;
|
|
615
|
+
const bar = $('export-run');
|
|
616
|
+
const index = state.runSel || 0;
|
|
617
|
+
const item = run && run.items && run.items[index];
|
|
618
|
+
bar.hidden = !(run && run.mode === 'test' && item && item.status !== 'running' && item.tests);
|
|
619
|
+
}
|
|
620
|
+
function exportRun(format) {
|
|
621
|
+
const run = state.run;
|
|
622
|
+
if (!run) return;
|
|
623
|
+
const index = state.runSel || 0;
|
|
624
|
+
window.open(`/api/v1/export/run?id=${encodeURIComponent(run.id)}&item=${index}&format=${format}`, '_blank');
|
|
625
|
+
}
|
|
626
|
+
$('export-run-pdf').onclick = () => exportRun('pdf');
|
|
627
|
+
$('export-run-csv').onclick = () => exportRun('csv');
|
|
628
|
+
$('export-run-junit').onclick = () => exportRun('junit');
|
|
629
|
+
$('export-trends-pdf').onclick = () => window.open('/api/v1/export/trends?format=pdf', '_blank');
|
|
630
|
+
$('export-trends-csv').onclick = () => window.open('/api/v1/export/trends?format=csv', '_blank');
|
|
631
|
+
$('export-trends-raw').onclick = () => window.open('/api/v1/export/trends?format=raw-csv', '_blank');
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
<a href="https://mcprigor.com/docs/plain-language-cookbook.html" target="_blank" rel="noreferrer">📖 Cookbook — copy-ready examples</a>
|
|
42
42
|
</div>
|
|
43
43
|
</aside>
|
|
44
|
+
<div class="splitter" id="split-left" role="separator" aria-orientation="vertical" aria-label="Resize file list" tabindex="0"></div>
|
|
44
45
|
|
|
45
46
|
<section class="workbench">
|
|
46
47
|
<div class="toolbar">
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
<div id="diagnostics" class="diagnostics" role="status" aria-live="polite" hidden></div>
|
|
77
78
|
</section>
|
|
78
79
|
|
|
80
|
+
<div class="splitter" id="split-right" role="separator" aria-orientation="vertical" aria-label="Resize results panel" tabindex="0"></div>
|
|
79
81
|
<aside class="results">
|
|
80
82
|
<div class="results-tabs" role="tablist">
|
|
81
83
|
<button id="tab-run" class="tab active" role="tab" aria-selected="true">Run</button>
|
|
@@ -88,6 +90,12 @@
|
|
|
88
90
|
<input id="results-filter" type="search" placeholder="Search tests and results…" aria-label="Search tests and results">
|
|
89
91
|
</div>
|
|
90
92
|
<div id="panel-run" class="panel" role="tabpanel">
|
|
93
|
+
<div id="export-run" class="export-bar" hidden>
|
|
94
|
+
<span class="export-label">Export report:</span>
|
|
95
|
+
<button id="export-run-pdf" class="ghost small" type="button">PDF</button>
|
|
96
|
+
<button id="export-run-csv" class="ghost small" type="button">CSV</button>
|
|
97
|
+
<button id="export-run-junit" class="ghost small" type="button">JUnit XML</button>
|
|
98
|
+
</div>
|
|
91
99
|
<div id="run-list"></div>
|
|
92
100
|
<pre id="output" class="output"><span class="muted">Nothing has run yet.
|
|
93
101
|
Open a test file and click ▶ Run tests — or select several files
|
|
@@ -97,6 +105,12 @@ with their checkboxes and run them together.</span></pre>
|
|
|
97
105
|
<div id="history-list" class="history-list"><p class="muted pad">No runs recorded yet. History appears after the first ▶ Run.</p></div>
|
|
98
106
|
</div>
|
|
99
107
|
<div id="panel-trends" class="panel" role="tabpanel" hidden>
|
|
108
|
+
<div class="export-bar">
|
|
109
|
+
<span class="export-label">Export trends:</span>
|
|
110
|
+
<button id="export-trends-pdf" class="ghost small" type="button">PDF</button>
|
|
111
|
+
<button id="export-trends-csv" class="ghost small" type="button">CSV</button>
|
|
112
|
+
<button id="export-trends-raw" class="ghost small" type="button">Raw history CSV</button>
|
|
113
|
+
</div>
|
|
100
114
|
<div id="trends" class="trends"><p class="muted pad">Trends appear after a few runs.</p></div>
|
|
101
115
|
</div>
|
|
102
116
|
</aside>
|
|
@@ -27,10 +27,15 @@ header{display:flex;align-items:center;justify-content:space-between;padding:0 1
|
|
|
27
27
|
footer{display:flex;align-items:center;justify-content:space-between;padding:0 18px;background:var(--bg-raised);border-top:1px solid var(--line);font-size:11.5px;color:var(--text-faint)}
|
|
28
28
|
|
|
29
29
|
/* ---------- layout ---------- */
|
|
30
|
-
main{display:grid;grid-template-columns:250px minmax(
|
|
30
|
+
main{display:grid;grid-template-columns:var(--col-side,250px) 5px minmax(360px,1fr) 5px var(--col-results,minmax(320px,36%));min-height:0}
|
|
31
|
+
.splitter{cursor:col-resize;background:transparent;position:relative;z-index:5}
|
|
32
|
+
.splitter::after{content:"";position:absolute;inset:0 1px;background:var(--line);transition:background .15s}
|
|
33
|
+
.splitter:hover::after,.splitter.dragging::after{background:var(--accent)}
|
|
34
|
+
body.resizing{cursor:col-resize;user-select:none}
|
|
35
|
+
body.resizing iframe,body.resizing textarea{pointer-events:none}
|
|
31
36
|
|
|
32
37
|
/* ---------- sidebar ---------- */
|
|
33
|
-
.sidebar{display:flex;flex-direction:column;gap:10px;padding:14px 12px;background:var(--bg-raised);
|
|
38
|
+
.sidebar{display:flex;flex-direction:column;gap:10px;padding:14px 12px;background:var(--bg-raised);min-height:0;overflow:hidden}
|
|
34
39
|
.search-row{display:flex;gap:6px}
|
|
35
40
|
#filter{flex:1;min-width:0;background:var(--bg-input);border:1px solid var(--line);border-radius:8px;color:var(--text);padding:7px 10px;font-size:13px;outline:none}
|
|
36
41
|
#filter:focus{border-color:var(--accent-strong)}
|
|
@@ -223,3 +228,7 @@ button.small{padding:4px 8px;font-size:11.5px;color:var(--text-faint)}
|
|
|
223
228
|
nav .suite-row button .rn{display:none;flex:none;font-size:10px;opacity:.6;padding:0 2px}
|
|
224
229
|
nav .suite-row:hover button .rn{display:inline}
|
|
225
230
|
nav .suite-row button .rn:hover{opacity:1}
|
|
231
|
+
|
|
232
|
+
.export-bar{display:flex;align-items:center;gap:6px;padding:8px 14px;border-bottom:1px solid var(--line-soft)}
|
|
233
|
+
.export-label{font-size:11px;color:var(--text-dim);margin-right:2px}
|
|
234
|
+
.export-bar .small{font-size:11px;padding:3px 10px}
|