viberadar 0.3.212 → 0.3.213
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/server/index.d.ts.map +1 -1
- package/dist/server/index.js +24 -7
- package/dist/server/index.js.map +1 -1
- package/dist/ui/dashboard.html +38 -6
- package/package.json +1 -1
package/dist/ui/dashboard.html
CHANGED
|
@@ -1782,6 +1782,8 @@ let loadSavedScripts = []; // [{ name, date, script }]
|
|
|
1782
1782
|
let loadRuns = []; // saved k6 run history
|
|
1783
1783
|
let loadScriptNameDraft = ''; // save name input draft
|
|
1784
1784
|
let loadBaseUrlDraft = 'http://localhost:5000';
|
|
1785
|
+
let loadVusDraft = 10;
|
|
1786
|
+
let loadDurationDraft = '30s';
|
|
1785
1787
|
let loadDataDirDraft = '';
|
|
1786
1788
|
let loadResultDirDraft = '';
|
|
1787
1789
|
let loadView = 'library'; // 'library' | 'editor'
|
|
@@ -7757,12 +7759,18 @@ function loadStatusLabel(status) {
|
|
|
7757
7759
|
function applyLoadConfigToFields(cfg) {
|
|
7758
7760
|
if (!cfg) return;
|
|
7759
7761
|
loadBaseUrlDraft = cfg.baseUrl || loadBaseUrlDraft;
|
|
7762
|
+
loadVusDraft = cfg.vus || loadVusDraft;
|
|
7763
|
+
loadDurationDraft = cfg.duration || loadDurationDraft;
|
|
7760
7764
|
loadDataDirDraft = cfg.dataDir || loadDataDirDraft;
|
|
7761
7765
|
loadResultDirDraft = cfg.resultDir || loadResultDirDraft;
|
|
7762
7766
|
const baseEl = document.getElementById('loadBaseUrl');
|
|
7767
|
+
const vusEl = document.getElementById('loadVus');
|
|
7768
|
+
const durEl = document.getElementById('loadDuration');
|
|
7763
7769
|
const dataEl = document.getElementById('loadDataDir');
|
|
7764
7770
|
const resultEl = document.getElementById('loadResultDir');
|
|
7765
7771
|
if (baseEl) baseEl.value = loadBaseUrlDraft;
|
|
7772
|
+
if (vusEl) vusEl.value = loadVusDraft;
|
|
7773
|
+
if (durEl) durEl.value = loadDurationDraft;
|
|
7766
7774
|
if (dataEl) dataEl.value = loadDataDirDraft;
|
|
7767
7775
|
if (resultEl) resultEl.value = loadResultDirDraft;
|
|
7768
7776
|
}
|
|
@@ -7799,7 +7807,7 @@ function renderLoad(c) {
|
|
|
7799
7807
|
const cards = loadSavedScripts.map(s => `
|
|
7800
7808
|
<div class="load-library-card" data-sname="${escapeHtml(s.name)}">
|
|
7801
7809
|
<div class="load-library-card-name">${escapeHtml(s.name)}</div>
|
|
7802
|
-
<div class="load-library-card-meta">${escapeHtml(s.date)}${s.dataDir ? ' · data: ' + escapeHtml(s.dataDir) : ''}</div>
|
|
7810
|
+
<div class="load-library-card-meta">${escapeHtml(s.date)} · ${s.vus || 10} VU · ${escapeHtml(s.duration || '30s')}${s.dataDir ? ' · data: ' + escapeHtml(s.dataDir) : ''}</div>
|
|
7803
7811
|
</div>`).join('');
|
|
7804
7812
|
const runRows = loadRuns.slice(0, 12).map(r => {
|
|
7805
7813
|
const summary = r.summary || {};
|
|
@@ -7808,7 +7816,7 @@ function renderLoad(c) {
|
|
|
7808
7816
|
return `<div class="load-run-item" data-run-id="${escapeHtml(r.runId)}">
|
|
7809
7817
|
<div class="load-run-main">
|
|
7810
7818
|
<div class="load-run-name">${escapeHtml(r.scriptName || 'Без названия')}</div>
|
|
7811
|
-
<div class="load-run-meta">${formatLoadRunDate(r.createdAt || r.startTime)} · ${escapeHtml(cfg.executionMode || 'auto')} · ${loadStatusLabel(r.status)}</div>
|
|
7819
|
+
<div class="load-run-meta">${formatLoadRunDate(r.createdAt || r.startTime)} · ${cfg.vus || '—'} VU · ${escapeHtml(cfg.duration || '—')} · ${escapeHtml(cfg.executionMode || 'auto')} · ${loadStatusLabel(r.status)}</div>
|
|
7812
7820
|
</div>
|
|
7813
7821
|
<div class="load-run-kpi" title="${escapeHtml(cfg.resultPath || '')}">${summary.rps != null ? Number(summary.rps || 0).toFixed(1) : '—'} RPS</div>
|
|
7814
7822
|
<div class="load-run-kpi">p95 ${summary.p95Duration != null ? Math.round(summary.p95Duration || 0) + 'ms' : '—'}</div>
|
|
@@ -7858,7 +7866,7 @@ function renderLoad(c) {
|
|
|
7858
7866
|
).join('');
|
|
7859
7867
|
|
|
7860
7868
|
if (!loadScriptDraft) {
|
|
7861
|
-
loadScriptDraft = buildDefaultScript({ baseUrl: loadBaseUrlDraft, endpoints: ['/'] });
|
|
7869
|
+
loadScriptDraft = buildDefaultScript({ baseUrl: loadBaseUrlDraft, vus: loadVusDraft, duration: loadDurationDraft, endpoints: ['/'] });
|
|
7862
7870
|
}
|
|
7863
7871
|
|
|
7864
7872
|
const statusBadge = !loadState || loadState.status === 'idle' ? '' :
|
|
@@ -7884,8 +7892,16 @@ function renderLoad(c) {
|
|
|
7884
7892
|
<label>Base URL</label>
|
|
7885
7893
|
<input id="loadBaseUrl" type="text" value="${escapeHtml(loadBaseUrlDraft)}" placeholder="http://localhost:5000" />
|
|
7886
7894
|
</div>
|
|
7895
|
+
<div class="load-config-field">
|
|
7896
|
+
<label>VUs</label>
|
|
7897
|
+
<input id="loadVus" type="number" value="${escapeHtml(String(loadVusDraft))}" min="1" max="10000" style="width:80px" />
|
|
7898
|
+
</div>
|
|
7899
|
+
<div class="load-config-field">
|
|
7900
|
+
<label>Duration</label>
|
|
7901
|
+
<input id="loadDuration" type="text" value="${escapeHtml(loadDurationDraft)}" style="width:90px" placeholder="30s" />
|
|
7902
|
+
</div>
|
|
7887
7903
|
</div>
|
|
7888
|
-
<div class="load-config-hint"
|
|
7904
|
+
<div class="load-config-hint">Если в скрипте есть <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>
|
|
7889
7905
|
<div class="load-config-row" style="margin-top:8px">
|
|
7890
7906
|
<div class="load-config-field" style="flex:1;min-width:260px">
|
|
7891
7907
|
<label>Data dir / file <span style="color:var(--dim);font-weight:400">(для <code>open('./users.csv')</code> и локальных lib)</span></label>
|
|
@@ -7966,9 +7982,13 @@ function renderLoad(c) {
|
|
|
7966
7982
|
const ta = document.getElementById('loadScriptEditor');
|
|
7967
7983
|
if (ta) { ta.addEventListener('input', () => { loadScriptDraft = ta.value; }); }
|
|
7968
7984
|
const baseInput = document.getElementById('loadBaseUrl');
|
|
7985
|
+
const vusInput = document.getElementById('loadVus');
|
|
7986
|
+
const durationInput = document.getElementById('loadDuration');
|
|
7969
7987
|
const dataInput = document.getElementById('loadDataDir');
|
|
7970
7988
|
const resultInput = document.getElementById('loadResultDir');
|
|
7971
7989
|
if (baseInput) baseInput.addEventListener('input', () => { loadBaseUrlDraft = baseInput.value || 'http://localhost:5000'; });
|
|
7990
|
+
if (vusInput) vusInput.addEventListener('input', () => { loadVusDraft = parseInt(vusInput.value || '10', 10) || 10; });
|
|
7991
|
+
if (durationInput) durationInput.addEventListener('input', () => { loadDurationDraft = durationInput.value || '30s'; });
|
|
7972
7992
|
if (dataInput) dataInput.addEventListener('input', () => { loadDataDirDraft = dataInput.value || ''; });
|
|
7973
7993
|
if (resultInput) resultInput.addEventListener('input', () => { loadResultDirDraft = resultInput.value || ''; });
|
|
7974
7994
|
|
|
@@ -7991,6 +8011,8 @@ function loadOpenScript(name) {
|
|
|
7991
8011
|
loadScriptDraft = s.script;
|
|
7992
8012
|
loadScriptNameDraft = s.name;
|
|
7993
8013
|
if (s.baseUrl) loadBaseUrlDraft = s.baseUrl;
|
|
8014
|
+
if (s.vus) loadVusDraft = s.vus;
|
|
8015
|
+
if (s.duration) loadDurationDraft = s.duration;
|
|
7994
8016
|
loadDataDirDraft = s.dataDir || loadDataDirDraft;
|
|
7995
8017
|
loadResultDirDraft = s.resultDir || loadResultDirDraft;
|
|
7996
8018
|
loadView = 'editor';
|
|
@@ -8018,10 +8040,14 @@ async function runLoadTest() {
|
|
|
8018
8040
|
const script = ta ? ta.value : loadScriptDraft;
|
|
8019
8041
|
if (!script.trim()) { alert('Скрипт пустой — сначала сгенерируйте или напишите k6-скрипт'); return; }
|
|
8020
8042
|
const baseUrl = (document.getElementById('loadBaseUrl')?.value || loadBaseUrlDraft || 'http://localhost:5000').trim();
|
|
8043
|
+
const vus = parseInt(document.getElementById('loadVus')?.value || String(loadVusDraft || 10), 10) || 10;
|
|
8044
|
+
const duration = (document.getElementById('loadDuration')?.value || loadDurationDraft || '30s').trim();
|
|
8021
8045
|
const scriptName = (document.getElementById('loadScriptName')?.value || loadScriptNameDraft || 'Новый тест').trim();
|
|
8022
8046
|
const dataDir = (document.getElementById('loadDataDir')?.value || loadDataDirDraft || '').trim();
|
|
8023
8047
|
const resultDir = (document.getElementById('loadResultDir')?.value || loadResultDirDraft || '').trim();
|
|
8024
8048
|
loadBaseUrlDraft = baseUrl;
|
|
8049
|
+
loadVusDraft = vus;
|
|
8050
|
+
loadDurationDraft = duration;
|
|
8025
8051
|
loadScriptNameDraft = scriptName;
|
|
8026
8052
|
loadDataDirDraft = dataDir;
|
|
8027
8053
|
loadResultDirDraft = resultDir;
|
|
@@ -8036,7 +8062,7 @@ async function runLoadTest() {
|
|
|
8036
8062
|
const r = await fetch('/api/load/run', {
|
|
8037
8063
|
method: 'POST',
|
|
8038
8064
|
headers: { 'Content-Type': 'application/json' },
|
|
8039
|
-
body: JSON.stringify({ script, baseUrl, scriptName, dataDir, resultDir, envVars }),
|
|
8065
|
+
body: JSON.stringify({ script, vus, duration, baseUrl, scriptName, dataDir, resultDir, envVars }),
|
|
8040
8066
|
});
|
|
8041
8067
|
const d = await r.json();
|
|
8042
8068
|
if (!r.ok) { alert('Ошибка запуска: ' + (d.error || r.status)); return; }
|
|
@@ -8234,17 +8260,21 @@ async function loadSaveScript() {
|
|
|
8234
8260
|
const script = taEl ? taEl.value : loadScriptDraft;
|
|
8235
8261
|
if (!script.trim()) { alert('Скрипт пустой'); return; }
|
|
8236
8262
|
const baseUrl = (document.getElementById('loadBaseUrl')?.value || loadBaseUrlDraft || 'http://localhost:5000').trim();
|
|
8263
|
+
const vus = parseInt(document.getElementById('loadVus')?.value || String(loadVusDraft || 10), 10) || 10;
|
|
8264
|
+
const duration = (document.getElementById('loadDuration')?.value || loadDurationDraft || '30s').trim();
|
|
8237
8265
|
const dataDir = (document.getElementById('loadDataDir')?.value || loadDataDirDraft || '').trim();
|
|
8238
8266
|
const resultDir = (document.getElementById('loadResultDir')?.value || loadResultDirDraft || '').trim();
|
|
8239
8267
|
loadScriptNameDraft = name;
|
|
8240
8268
|
loadBaseUrlDraft = baseUrl;
|
|
8269
|
+
loadVusDraft = vus;
|
|
8270
|
+
loadDurationDraft = duration;
|
|
8241
8271
|
loadDataDirDraft = dataDir;
|
|
8242
8272
|
loadResultDirDraft = resultDir;
|
|
8243
8273
|
try {
|
|
8244
8274
|
const r = await fetch('/api/load/scripts', {
|
|
8245
8275
|
method: 'POST',
|
|
8246
8276
|
headers: { 'Content-Type': 'application/json' },
|
|
8247
|
-
body: JSON.stringify({ name, script, baseUrl, dataDir, resultDir }),
|
|
8277
|
+
body: JSON.stringify({ name, script, baseUrl, vus, duration, dataDir, resultDir }),
|
|
8248
8278
|
});
|
|
8249
8279
|
if (!r.ok) { const d = await r.json().catch(() => ({})); alert('Ошибка: ' + (d.error || r.status)); return; }
|
|
8250
8280
|
await loadRefreshScripts();
|
|
@@ -8260,6 +8290,8 @@ async function loadLoadScript(name) {
|
|
|
8260
8290
|
loadScriptDraft = s.script;
|
|
8261
8291
|
loadScriptNameDraft = s.name;
|
|
8262
8292
|
if (s.baseUrl) loadBaseUrlDraft = s.baseUrl;
|
|
8293
|
+
if (s.vus) loadVusDraft = s.vus;
|
|
8294
|
+
if (s.duration) loadDurationDraft = s.duration;
|
|
8263
8295
|
loadDataDirDraft = s.dataDir || loadDataDirDraft;
|
|
8264
8296
|
loadResultDirDraft = s.resultDir || loadResultDirDraft;
|
|
8265
8297
|
const ta = document.getElementById('loadScriptEditor');
|