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.
@@ -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">Нагрузка, scenarios, thresholds и env-имена остаются в k6-скрипте. VibeRadar только передаёт <code>__ENV.BASE_URL</code>, файлы данных и сохраняет результаты.</div>
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');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viberadar",
3
- "version": "0.3.212",
3
+ "version": "0.3.213",
4
4
  "description": "Live module map with test coverage for vibecoding projects",
5
5
  "main": "./dist/cli.js",
6
6
  "bin": {