viberadar 0.3.219 → 0.3.220
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/ui/dashboard.html +50 -20
- package/package.json +1 -1
package/dist/ui/dashboard.html
CHANGED
|
@@ -1810,7 +1810,7 @@ let loadRuns = []; // saved k6 run history
|
|
|
1810
1810
|
let loadScriptNameDraft = ''; // save name input draft
|
|
1811
1811
|
let loadBaseUrlDraft = 'http://localhost:5000';
|
|
1812
1812
|
let loadVusDraft = 10;
|
|
1813
|
-
let loadDurationDraft = '
|
|
1813
|
+
let loadDurationDraft = '1m';
|
|
1814
1814
|
let loadDataDirDraft = '';
|
|
1815
1815
|
let loadResultDirDraft = '';
|
|
1816
1816
|
let loadAccountsJsonDraft = '';
|
|
@@ -7706,6 +7706,23 @@ function parseLoadDurationMs(value) {
|
|
|
7706
7706
|
return Number.isFinite(asNum) ? asNum * 1000 : 0;
|
|
7707
7707
|
}
|
|
7708
7708
|
|
|
7709
|
+
function durationToMinutesValue(value) {
|
|
7710
|
+
const text = String(value || '').trim();
|
|
7711
|
+
if (!text) return '';
|
|
7712
|
+
if (/^\d+(?:\.\d+)?$/.test(text)) return text;
|
|
7713
|
+
const ms = parseLoadDurationMs(text);
|
|
7714
|
+
if (!ms) return text;
|
|
7715
|
+
const min = ms / 60000;
|
|
7716
|
+
return Number.isInteger(min) ? String(min) : String(Math.round(min * 100) / 100);
|
|
7717
|
+
}
|
|
7718
|
+
|
|
7719
|
+
function durationInputToK6(value) {
|
|
7720
|
+
const text = String(value || '').trim();
|
|
7721
|
+
if (!text) return '1m';
|
|
7722
|
+
if (/^\d+(?:\.\d+)?$/.test(text)) return `${text}m`;
|
|
7723
|
+
return text;
|
|
7724
|
+
}
|
|
7725
|
+
|
|
7709
7726
|
function estimateLoadDurationMs(state) {
|
|
7710
7727
|
const cfg = state?.config || {};
|
|
7711
7728
|
const base = parseLoadDurationMs(cfg.duration || loadDurationDraft);
|
|
@@ -7753,6 +7770,10 @@ function updateLoadLiveStats() {
|
|
|
7753
7770
|
setText('loadAvgValue', stats.avgMs ? `${Math.round(stats.avgMs)} ms` : '—');
|
|
7754
7771
|
setText('loadErrorValue', `${stats.errorPct.toFixed(2)}%`);
|
|
7755
7772
|
setText('loadVuValue', String(Math.round(stats.vus || 0)));
|
|
7773
|
+
setText('loadChartRpsValue', stats.currentRps.toFixed(1));
|
|
7774
|
+
setText('loadChartLatencyValue', stats.avgMs ? `${Math.round(stats.avgMs)} ms` : '—');
|
|
7775
|
+
setText('loadChartErrorsValue', `${stats.errorPct.toFixed(2)}%`);
|
|
7776
|
+
setText('loadChartVusValue', String(Math.round(stats.vus || 0)));
|
|
7756
7777
|
const fill = document.getElementById('loadProgressFill');
|
|
7757
7778
|
if (fill) fill.style.width = `${stats.progressPct}%`;
|
|
7758
7779
|
}
|
|
@@ -7850,12 +7871,21 @@ function drawLoadChart(id, buckets, valFn, color, label) {
|
|
|
7850
7871
|
// Resolve CSS variable colors to actual colors
|
|
7851
7872
|
const colorMap = { 'var(--blue)': '#58a6ff', 'var(--green)': '#3fb950', 'var(--red)': '#f85149', 'var(--yellow)': '#e3b341' };
|
|
7852
7873
|
ctx.strokeStyle = colorMap[color] || color;
|
|
7853
|
-
vals.forEach((v, i) => {
|
|
7854
|
-
const x = pad.l + i * step;
|
|
7855
|
-
const y = pad.t + cH * (1 - v / maxVal);
|
|
7856
|
-
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
|
|
7857
|
-
});
|
|
7858
|
-
ctx.stroke();
|
|
7874
|
+
vals.forEach((v, i) => {
|
|
7875
|
+
const x = pad.l + i * step;
|
|
7876
|
+
const y = pad.t + cH * (1 - v / maxVal);
|
|
7877
|
+
if (i === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
|
|
7878
|
+
});
|
|
7879
|
+
ctx.stroke();
|
|
7880
|
+
|
|
7881
|
+
ctx.fillStyle = ctx.strokeStyle;
|
|
7882
|
+
vals.forEach((v, i) => {
|
|
7883
|
+
const x = pad.l + i * step;
|
|
7884
|
+
const y = pad.t + cH * (1 - v / maxVal);
|
|
7885
|
+
ctx.beginPath();
|
|
7886
|
+
ctx.arc(x, y, vals.length === 1 ? 3.5 : 2.2, 0, Math.PI * 2);
|
|
7887
|
+
ctx.fill();
|
|
7888
|
+
});
|
|
7859
7889
|
|
|
7860
7890
|
// Label
|
|
7861
7891
|
ctx.fillStyle = 'rgba(125,133,144,0.9)';
|
|
@@ -7894,7 +7924,7 @@ function applyLoadConfigToFields(cfg) {
|
|
|
7894
7924
|
const accountsEl = document.getElementById('loadAccountsJson');
|
|
7895
7925
|
if (baseEl) baseEl.value = loadBaseUrlDraft;
|
|
7896
7926
|
if (vusEl) vusEl.value = loadVusDraft;
|
|
7897
|
-
if (durEl) durEl.value = loadDurationDraft;
|
|
7927
|
+
if (durEl) durEl.value = durationToMinutesValue(loadDurationDraft);
|
|
7898
7928
|
if (dataEl) dataEl.value = loadDataDirDraft;
|
|
7899
7929
|
if (resultEl) resultEl.value = loadResultDirDraft;
|
|
7900
7930
|
if (accountsEl) accountsEl.value = loadAccountsJsonDraft;
|
|
@@ -8197,11 +8227,11 @@ function renderLoad(c) {
|
|
|
8197
8227
|
<input id="loadVus" type="number" value="${escapeHtml(String(loadVusDraft))}" min="1" max="10000" style="width:80px" />
|
|
8198
8228
|
</div>
|
|
8199
8229
|
<div class="load-config-field">
|
|
8200
|
-
<label>Duration</label>
|
|
8201
|
-
<input id="loadDuration" type="
|
|
8230
|
+
<label>Duration, min</label>
|
|
8231
|
+
<input id="loadDuration" type="number" value="${escapeHtml(durationToMinutesValue(loadDurationDraft))}" min="0.1" step="0.1" style="width:90px" placeholder="10" />
|
|
8202
8232
|
</div>
|
|
8203
8233
|
</div>
|
|
8204
|
-
<div class="load-config-hint"
|
|
8234
|
+
<div class="load-config-hint">Duration задаётся в минутах: введи <code>10</code>, VibeRadar передаст в k6 <code>10m</code>. Если в скрипте есть <code>options.scenarios</code>, VibeRadar не ломает stages через CLI, а передаёт значения как <code>__ENV.LOAD_VUS</code>/<code>__ENV.LOAD_DURATION</code> и совместимые <code>SMOKE_*</code>/<code>AUTH_*</code>. Если scenarios нет, будут использованы CLI <code>--vus</code>/<code>--duration</code>.</div>
|
|
8205
8235
|
<div class="load-config-row" style="margin-top:8px">
|
|
8206
8236
|
<div class="load-config-field" style="flex:1;min-width:260px">
|
|
8207
8237
|
<label>Data dir / file <span style="color:var(--dim);font-weight:400">(только если скрипт использует <code>open('./file')</code> или локальные imports)</span></label>
|
|
@@ -8262,10 +8292,10 @@ function renderLoad(c) {
|
|
|
8262
8292
|
</div>
|
|
8263
8293
|
</div>
|
|
8264
8294
|
<div class="load-charts" style="margin-top:12px">
|
|
8265
|
-
<div class="load-chart-box"><div class="load-chart-label"><span>Запросов/сек</span><span class="load-chart-value">${liveStats.currentRps.toFixed(1)}</span></div>${liveStats.hasBuckets ? '<canvas id="loadChartRps"></canvas>' : chartEmpty}</div>
|
|
8266
|
-
<div class="load-chart-box"><div class="load-chart-label"><span>Среднее время ответа</span><span class="load-chart-value">${liveStats.avgMs ? `${Math.round(liveStats.avgMs)} ms` : '—'}</span></div>${liveStats.hasBuckets ? '<canvas id="loadChartLatency"></canvas>' : chartEmpty}</div>
|
|
8267
|
-
<div class="load-chart-box"><div class="load-chart-label"><span>Ошибки</span><span class="load-chart-value">${liveStats.errorPct.toFixed(2)}%</span></div>${liveStats.hasBuckets ? '<canvas id="loadChartErrors"></canvas>' : chartEmpty}</div>
|
|
8268
|
-
<div class="load-chart-box"><div class="load-chart-label"><span>Активные VUs</span><span class="load-chart-value">${Math.round(liveStats.vus || 0)}</span></div>${liveStats.hasBuckets ? '<canvas id="loadChartVus"></canvas>' : chartEmpty}</div>
|
|
8295
|
+
<div class="load-chart-box"><div class="load-chart-label"><span>Запросов/сек</span><span class="load-chart-value" id="loadChartRpsValue">${liveStats.currentRps.toFixed(1)}</span></div>${liveStats.hasBuckets ? '<canvas id="loadChartRps"></canvas>' : chartEmpty}</div>
|
|
8296
|
+
<div class="load-chart-box"><div class="load-chart-label"><span>Среднее время ответа</span><span class="load-chart-value" id="loadChartLatencyValue">${liveStats.avgMs ? `${Math.round(liveStats.avgMs)} ms` : '—'}</span></div>${liveStats.hasBuckets ? '<canvas id="loadChartLatency"></canvas>' : chartEmpty}</div>
|
|
8297
|
+
<div class="load-chart-box"><div class="load-chart-label"><span>Ошибки</span><span class="load-chart-value" id="loadChartErrorsValue">${liveStats.errorPct.toFixed(2)}%</span></div>${liveStats.hasBuckets ? '<canvas id="loadChartErrors"></canvas>' : chartEmpty}</div>
|
|
8298
|
+
<div class="load-chart-box"><div class="load-chart-label"><span>Активные VUs</span><span class="load-chart-value" id="loadChartVusValue">${Math.round(liveStats.vus || 0)}</span></div>${liveStats.hasBuckets ? '<canvas id="loadChartVus"></canvas>' : chartEmpty}</div>
|
|
8269
8299
|
</div>
|
|
8270
8300
|
</div>` : ''}
|
|
8271
8301
|
|
|
@@ -8313,7 +8343,7 @@ function renderLoad(c) {
|
|
|
8313
8343
|
const accountsInput = document.getElementById('loadAccountsJson');
|
|
8314
8344
|
if (baseInput) baseInput.addEventListener('input', () => { loadBaseUrlDraft = baseInput.value || 'http://localhost:5000'; });
|
|
8315
8345
|
if (vusInput) vusInput.addEventListener('input', () => { loadVusDraft = parseInt(vusInput.value || '10', 10) || 10; });
|
|
8316
|
-
if (durationInput) durationInput.addEventListener('input', () => { loadDurationDraft = durationInput.value || '
|
|
8346
|
+
if (durationInput) durationInput.addEventListener('input', () => { loadDurationDraft = durationInputToK6(durationInput.value || '1'); });
|
|
8317
8347
|
if (dataInput) dataInput.addEventListener('input', () => { loadDataDirDraft = dataInput.value || ''; });
|
|
8318
8348
|
if (resultInput) resultInput.addEventListener('input', () => { loadResultDirDraft = resultInput.value || ''; });
|
|
8319
8349
|
if (accountsInput) accountsInput.addEventListener('input', () => { loadAccountsJsonDraft = accountsInput.value || ''; });
|
|
@@ -8350,7 +8380,7 @@ function loadOpenScript(name) {
|
|
|
8350
8380
|
function loadGenerateScript() {
|
|
8351
8381
|
const baseUrl = document.getElementById('loadBaseUrl')?.value || 'http://localhost:5000';
|
|
8352
8382
|
const vus = parseInt(document.getElementById('loadVus')?.value || '10');
|
|
8353
|
-
const duration = document.getElementById('loadDuration')?.value || '
|
|
8383
|
+
const duration = durationInputToK6(document.getElementById('loadDuration')?.value || '1');
|
|
8354
8384
|
const featKey = document.getElementById('loadFeature')?.value || '';
|
|
8355
8385
|
let script;
|
|
8356
8386
|
if (featKey) {
|
|
@@ -8369,7 +8399,7 @@ async function runLoadTest() {
|
|
|
8369
8399
|
if (!script.trim()) { alert('Скрипт пустой — сначала сгенерируйте или напишите k6-скрипт'); return; }
|
|
8370
8400
|
const baseUrl = (document.getElementById('loadBaseUrl')?.value || loadBaseUrlDraft || 'http://localhost:5000').trim();
|
|
8371
8401
|
const vus = parseInt(document.getElementById('loadVus')?.value || String(loadVusDraft || 10), 10) || 10;
|
|
8372
|
-
const duration = (document.getElementById('loadDuration')?.value || loadDurationDraft || '
|
|
8402
|
+
const duration = durationInputToK6(document.getElementById('loadDuration')?.value || loadDurationDraft || '1');
|
|
8373
8403
|
const scriptName = (document.getElementById('loadScriptName')?.value || loadScriptNameDraft || 'Новый тест').trim();
|
|
8374
8404
|
const dataDir = (document.getElementById('loadDataDir')?.value || loadDataDirDraft || '').trim();
|
|
8375
8405
|
const resultDir = (document.getElementById('loadResultDir')?.value || loadResultDirDraft || '').trim();
|
|
@@ -8451,7 +8481,7 @@ async function loadAiGenerateScript() {
|
|
|
8451
8481
|
|
|
8452
8482
|
const baseUrl = document.getElementById('loadBaseUrl')?.value || 'http://localhost:5000';
|
|
8453
8483
|
const vus = document.getElementById('loadVus')?.value || '10';
|
|
8454
|
-
const duration = document.getElementById('loadDuration')?.value || '
|
|
8484
|
+
const duration = durationInputToK6(document.getElementById('loadDuration')?.value || '1');
|
|
8455
8485
|
|
|
8456
8486
|
const featureList = (D && D.features || []).map(f => `- ${f.label} (key: ${f.key})`).join('\n');
|
|
8457
8487
|
|
|
@@ -8599,7 +8629,7 @@ async function loadSaveScript() {
|
|
|
8599
8629
|
if (!script.trim()) { alert('Скрипт пустой'); return; }
|
|
8600
8630
|
const baseUrl = (document.getElementById('loadBaseUrl')?.value || loadBaseUrlDraft || 'http://localhost:5000').trim();
|
|
8601
8631
|
const vus = parseInt(document.getElementById('loadVus')?.value || String(loadVusDraft || 10), 10) || 10;
|
|
8602
|
-
const duration = (document.getElementById('loadDuration')?.value || loadDurationDraft || '
|
|
8632
|
+
const duration = durationInputToK6(document.getElementById('loadDuration')?.value || loadDurationDraft || '1');
|
|
8603
8633
|
const dataDir = (document.getElementById('loadDataDir')?.value || loadDataDirDraft || '').trim();
|
|
8604
8634
|
const resultDir = (document.getElementById('loadResultDir')?.value || loadResultDirDraft || '').trim();
|
|
8605
8635
|
const accountsRaw = document.getElementById('loadAccountsJson')?.value || loadAccountsJsonDraft || '';
|