viberadar 0.3.209 → 0.3.210
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 +80 -16
- package/dist/server/index.js.map +1 -1
- package/dist/ui/dashboard.html +42 -5
- package/package.json +1 -1
package/dist/ui/dashboard.html
CHANGED
|
@@ -1784,6 +1784,8 @@ let loadScriptNameDraft = ''; // save name input draft
|
|
|
1784
1784
|
let loadBaseUrlDraft = 'http://localhost:5000';
|
|
1785
1785
|
let loadVusDraft = 10;
|
|
1786
1786
|
let loadDurationDraft = '30s';
|
|
1787
|
+
let loadDataDirDraft = '';
|
|
1788
|
+
let loadResultDirDraft = '';
|
|
1787
1789
|
let loadView = 'library'; // 'library' | 'editor'
|
|
1788
1790
|
|
|
1789
1791
|
function toggleObsHint(id) {
|
|
@@ -7759,12 +7761,18 @@ function applyLoadConfigToFields(cfg) {
|
|
|
7759
7761
|
loadBaseUrlDraft = cfg.baseUrl || loadBaseUrlDraft;
|
|
7760
7762
|
loadVusDraft = cfg.vus || loadVusDraft;
|
|
7761
7763
|
loadDurationDraft = cfg.duration || loadDurationDraft;
|
|
7764
|
+
loadDataDirDraft = cfg.dataDir || loadDataDirDraft;
|
|
7765
|
+
loadResultDirDraft = cfg.resultDir || loadResultDirDraft;
|
|
7762
7766
|
const baseEl = document.getElementById('loadBaseUrl');
|
|
7763
7767
|
const vusEl = document.getElementById('loadVus');
|
|
7764
7768
|
const durEl = document.getElementById('loadDuration');
|
|
7769
|
+
const dataEl = document.getElementById('loadDataDir');
|
|
7770
|
+
const resultEl = document.getElementById('loadResultDir');
|
|
7765
7771
|
if (baseEl) baseEl.value = loadBaseUrlDraft;
|
|
7766
7772
|
if (vusEl) vusEl.value = loadVusDraft;
|
|
7767
7773
|
if (durEl) durEl.value = loadDurationDraft;
|
|
7774
|
+
if (dataEl) dataEl.value = loadDataDirDraft;
|
|
7775
|
+
if (resultEl) resultEl.value = loadResultDirDraft;
|
|
7768
7776
|
}
|
|
7769
7777
|
|
|
7770
7778
|
function renderLoad(c) {
|
|
@@ -7810,7 +7818,7 @@ function renderLoad(c) {
|
|
|
7810
7818
|
<div class="load-run-name">${escapeHtml(r.scriptName || 'Без названия')}</div>
|
|
7811
7819
|
<div class="load-run-meta">${formatLoadRunDate(r.createdAt || r.startTime)} · ${cfg.vus || '—'} VU · ${escapeHtml(cfg.duration || '—')} · ${loadStatusLabel(r.status)}</div>
|
|
7812
7820
|
</div>
|
|
7813
|
-
<div class="load-run-kpi">${summary.rps != null ? Number(summary.rps || 0).toFixed(1) : '—'} RPS</div>
|
|
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>
|
|
7815
7823
|
<div class="load-run-kpi" style="color:${Number(summary.errorPct || 0) > 5 ? 'var(--red)' : 'var(--muted)'}">${err}</div>
|
|
7816
7824
|
</div>`;
|
|
@@ -7894,6 +7902,17 @@ function renderLoad(c) {
|
|
|
7894
7902
|
</div>
|
|
7895
7903
|
</div>
|
|
7896
7904
|
<div class="load-config-hint">VUs и Duration применяются через CLI k6 и переопределяют значения из <code>export const options</code>. Base URL доступен в скрипте как <code>__ENV.BASE_URL</code>.</div>
|
|
7905
|
+
<div class="load-config-row" style="margin-top:8px">
|
|
7906
|
+
<div class="load-config-field" style="flex:1;min-width:260px">
|
|
7907
|
+
<label>Data dir / file <span style="color:var(--dim);font-weight:400">(для <code>open('./users.csv')</code> и локальных lib)</span></label>
|
|
7908
|
+
<input id="loadDataDir" type="text" value="${escapeHtml(loadDataDirDraft)}" placeholder="load-tests/k6 или C:\\path\\to\\k6-data" />
|
|
7909
|
+
</div>
|
|
7910
|
+
<div class="load-config-field" style="flex:1;min-width:260px">
|
|
7911
|
+
<label>Results dir <span style="color:var(--dim);font-weight:400">(необязательно)</span></label>
|
|
7912
|
+
<input id="loadResultDir" type="text" value="${escapeHtml(loadResultDirDraft)}" placeholder=".viberadar/load-runs или C:\\path\\to\\results" />
|
|
7913
|
+
</div>
|
|
7914
|
+
</div>
|
|
7915
|
+
<div class="load-config-hint">Если указать Data dir, VibeRadar скопирует его содержимое рядом со скриптом перед запуском. Результаты сохраняются в <code>results/<runId></code>: summary.json, metrics.ndjson, k6.log, config.json.</div>
|
|
7897
7916
|
<div class="load-config-row" style="margin-top:8px">
|
|
7898
7917
|
<div class="load-config-field" style="flex:1;min-width:300px">
|
|
7899
7918
|
<label>Bearer Token <span style="color:var(--dim);font-weight:400;font-size:11px">(→ <code style="background:var(--bg2);padding:1px 4px;border-radius:3px">__ENV.TOKEN</code>)</span></label>
|
|
@@ -7983,9 +8002,13 @@ function renderLoad(c) {
|
|
|
7983
8002
|
const baseInput = document.getElementById('loadBaseUrl');
|
|
7984
8003
|
const vusInput = document.getElementById('loadVus');
|
|
7985
8004
|
const durationInput = document.getElementById('loadDuration');
|
|
8005
|
+
const dataInput = document.getElementById('loadDataDir');
|
|
8006
|
+
const resultInput = document.getElementById('loadResultDir');
|
|
7986
8007
|
if (baseInput) baseInput.addEventListener('input', () => { loadBaseUrlDraft = baseInput.value || 'http://localhost:5000'; });
|
|
7987
8008
|
if (vusInput) vusInput.addEventListener('input', () => { loadVusDraft = parseInt(vusInput.value || '10', 10) || 10; });
|
|
7988
8009
|
if (durationInput) durationInput.addEventListener('input', () => { loadDurationDraft = durationInput.value || '30s'; });
|
|
8010
|
+
if (dataInput) dataInput.addEventListener('input', () => { loadDataDirDraft = dataInput.value || ''; });
|
|
8011
|
+
if (resultInput) resultInput.addEventListener('input', () => { loadResultDirDraft = resultInput.value || ''; });
|
|
7989
8012
|
|
|
7990
8013
|
// Feature selector auto-generates script
|
|
7991
8014
|
const featSel = document.getElementById('loadFeature');
|
|
@@ -8023,6 +8046,8 @@ function loadOpenScript(name) {
|
|
|
8023
8046
|
if (s.baseUrl) loadBaseUrlDraft = s.baseUrl;
|
|
8024
8047
|
if (s.vus) loadVusDraft = s.vus;
|
|
8025
8048
|
if (s.duration) loadDurationDraft = s.duration;
|
|
8049
|
+
loadDataDirDraft = s.dataDir || loadDataDirDraft;
|
|
8050
|
+
loadResultDirDraft = s.resultDir || loadResultDirDraft;
|
|
8026
8051
|
loadView = 'editor';
|
|
8027
8052
|
renderContent();
|
|
8028
8053
|
}
|
|
@@ -8051,10 +8076,14 @@ async function runLoadTest() {
|
|
|
8051
8076
|
const vus = parseInt(document.getElementById('loadVus')?.value || String(loadVusDraft || 10), 10) || 10;
|
|
8052
8077
|
const duration = (document.getElementById('loadDuration')?.value || loadDurationDraft || '30s').trim();
|
|
8053
8078
|
const scriptName = (document.getElementById('loadScriptName')?.value || loadScriptNameDraft || 'Новый тест').trim();
|
|
8079
|
+
const dataDir = (document.getElementById('loadDataDir')?.value || loadDataDirDraft || '').trim();
|
|
8080
|
+
const resultDir = (document.getElementById('loadResultDir')?.value || loadResultDirDraft || '').trim();
|
|
8054
8081
|
loadBaseUrlDraft = baseUrl;
|
|
8055
8082
|
loadVusDraft = vus;
|
|
8056
8083
|
loadDurationDraft = duration;
|
|
8057
8084
|
loadScriptNameDraft = scriptName;
|
|
8085
|
+
loadDataDirDraft = dataDir;
|
|
8086
|
+
loadResultDirDraft = resultDir;
|
|
8058
8087
|
|
|
8059
8088
|
loadLogLines = [];
|
|
8060
8089
|
loadBuckets = [];
|
|
@@ -8066,7 +8095,7 @@ async function runLoadTest() {
|
|
|
8066
8095
|
const r = await fetch('/api/load/run', {
|
|
8067
8096
|
method: 'POST',
|
|
8068
8097
|
headers: { 'Content-Type': 'application/json' },
|
|
8069
|
-
body: JSON.stringify({ script, vus, duration, baseUrl, scriptName, envVars }),
|
|
8098
|
+
body: JSON.stringify({ script, vus, duration, baseUrl, scriptName, dataDir, resultDir, envVars }),
|
|
8070
8099
|
});
|
|
8071
8100
|
const d = await r.json();
|
|
8072
8101
|
if (!r.ok) { alert('Ошибка запуска: ' + (d.error || r.status)); return; }
|
|
@@ -8152,8 +8181,10 @@ ${featureList || '(нет данных)'}
|
|
|
8152
8181
|
4. Base URL бери из \`__ENV.BASE_URL || '${baseUrl}'\`
|
|
8153
8182
|
5. Если нужна авторизация — добавь заголовок Authorization (Bearer-токен как переменную __ENV.TOKEN)
|
|
8154
8183
|
6. Если нужна загрузка файла — используй \`http.file()\` и \`open()\`
|
|
8155
|
-
7.
|
|
8156
|
-
8.
|
|
8184
|
+
7. Если нужны CSV/JSON/локальные helper-модули, используй относительные пути от Data dir: \`open('./users.csv')\`, \`import './lib/helper.js'\`
|
|
8185
|
+
8. Не добавляй \`handleSummary\` и не пиши результаты сам: VibeRadar сохраняет summary.json, metrics.ndjson, k6.log
|
|
8186
|
+
9. Добавь \`sleep(1)\` между запросами
|
|
8187
|
+
10. Добавь комментарий в начале: что тестируется и какой эндпоинт
|
|
8157
8188
|
|
|
8158
8189
|
**Шаг 3 — сохрани ТОЛЬКО скрипт в файл.**
|
|
8159
8190
|
Запиши итоговый JavaScript-код в файл: \`.viberadar/load-script-generated.js\`
|
|
@@ -8264,15 +8295,19 @@ async function loadSaveScript() {
|
|
|
8264
8295
|
const baseUrl = (document.getElementById('loadBaseUrl')?.value || loadBaseUrlDraft || 'http://localhost:5000').trim();
|
|
8265
8296
|
const vus = parseInt(document.getElementById('loadVus')?.value || String(loadVusDraft || 10), 10) || 10;
|
|
8266
8297
|
const duration = (document.getElementById('loadDuration')?.value || loadDurationDraft || '30s').trim();
|
|
8298
|
+
const dataDir = (document.getElementById('loadDataDir')?.value || loadDataDirDraft || '').trim();
|
|
8299
|
+
const resultDir = (document.getElementById('loadResultDir')?.value || loadResultDirDraft || '').trim();
|
|
8267
8300
|
loadScriptNameDraft = name;
|
|
8268
8301
|
loadBaseUrlDraft = baseUrl;
|
|
8269
8302
|
loadVusDraft = vus;
|
|
8270
8303
|
loadDurationDraft = duration;
|
|
8304
|
+
loadDataDirDraft = dataDir;
|
|
8305
|
+
loadResultDirDraft = resultDir;
|
|
8271
8306
|
try {
|
|
8272
8307
|
const r = await fetch('/api/load/scripts', {
|
|
8273
8308
|
method: 'POST',
|
|
8274
8309
|
headers: { 'Content-Type': 'application/json' },
|
|
8275
|
-
body: JSON.stringify({ name, script, baseUrl, vus, duration }),
|
|
8310
|
+
body: JSON.stringify({ name, script, baseUrl, vus, duration, dataDir, resultDir }),
|
|
8276
8311
|
});
|
|
8277
8312
|
if (!r.ok) { const d = await r.json().catch(() => ({})); alert('Ошибка: ' + (d.error || r.status)); return; }
|
|
8278
8313
|
await loadRefreshScripts();
|
|
@@ -8290,6 +8325,8 @@ async function loadLoadScript(name) {
|
|
|
8290
8325
|
if (s.baseUrl) loadBaseUrlDraft = s.baseUrl;
|
|
8291
8326
|
if (s.vus) loadVusDraft = s.vus;
|
|
8292
8327
|
if (s.duration) loadDurationDraft = s.duration;
|
|
8328
|
+
loadDataDirDraft = s.dataDir || loadDataDirDraft;
|
|
8329
|
+
loadResultDirDraft = s.resultDir || loadResultDirDraft;
|
|
8293
8330
|
const ta = document.getElementById('loadScriptEditor');
|
|
8294
8331
|
if (ta) { ta.value = s.script; ta.style.borderColor = 'var(--blue)'; setTimeout(() => { ta.style.borderColor = ''; }, 1500); }
|
|
8295
8332
|
const nameEl = document.getElementById('loadScriptName');
|