viberadar 0.3.214 → 0.3.216
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 +178 -18
- package/package.json +1 -1
package/dist/ui/dashboard.html
CHANGED
|
@@ -1793,6 +1793,7 @@ let loadDurationDraft = '30s';
|
|
|
1793
1793
|
let loadDataDirDraft = '';
|
|
1794
1794
|
let loadResultDirDraft = '';
|
|
1795
1795
|
let loadAccountsJsonDraft = '';
|
|
1796
|
+
let loadImportedEnvVarsDraft = {};
|
|
1796
1797
|
let loadView = 'library'; // 'library' | 'editor'
|
|
1797
1798
|
|
|
1798
1799
|
function toggleObsHint(id) {
|
|
@@ -7767,6 +7768,8 @@ function applyLoadConfigToFields(cfg) {
|
|
|
7767
7768
|
loadDurationDraft = cfg.duration || loadDurationDraft;
|
|
7768
7769
|
loadDataDirDraft = cfg.dataDir || loadDataDirDraft;
|
|
7769
7770
|
loadResultDirDraft = cfg.resultDir || loadResultDirDraft;
|
|
7771
|
+
if (cfg.accountsJson) loadAccountsJsonDraft = cfg.accountsJson;
|
|
7772
|
+
if (cfg.accounts) loadAccountsJsonDraft = typeof cfg.accounts === 'string' ? cfg.accounts : JSON.stringify(cfg.accounts, null, 2);
|
|
7770
7773
|
const baseEl = document.getElementById('loadBaseUrl');
|
|
7771
7774
|
const vusEl = document.getElementById('loadVus');
|
|
7772
7775
|
const durEl = document.getElementById('loadDuration');
|
|
@@ -7800,6 +7803,155 @@ function normalizeAccountsJson(raw) {
|
|
|
7800
7803
|
}
|
|
7801
7804
|
}
|
|
7802
7805
|
|
|
7806
|
+
function normalizeLoadImport(raw, sourceName) {
|
|
7807
|
+
const root = raw && typeof raw === 'object' ? raw : {};
|
|
7808
|
+
const cfg = root.config && typeof root.config === 'object' ? { ...root.config, ...root } : root;
|
|
7809
|
+
const envVars = cfg.envVars && typeof cfg.envVars === 'object' && !Array.isArray(cfg.envVars) ? { ...cfg.envVars } : {};
|
|
7810
|
+
const imported = {
|
|
7811
|
+
scriptName: cfg.scriptName || cfg.name || (sourceName || '').replace(/\.json$/i, '') || '',
|
|
7812
|
+
script: cfg.script || cfg.k6Script || cfg.code || '',
|
|
7813
|
+
baseUrl: cfg.baseUrl || envVars.BASE_URL || '',
|
|
7814
|
+
vus: cfg.vus || cfg.VUs || cfg.users || '',
|
|
7815
|
+
duration: cfg.duration || cfg.testDuration || '',
|
|
7816
|
+
dataDir: cfg.dataDir || cfg.dataPath || '',
|
|
7817
|
+
resultDir: cfg.resultDir || cfg.resultsDir || '',
|
|
7818
|
+
accounts: cfg.accounts || cfg.usersJson || cfg.accountsJson || envVars.TEST_ACCOUNTS_JSON || '',
|
|
7819
|
+
envVars,
|
|
7820
|
+
};
|
|
7821
|
+
delete imported.envVars.BASE_URL;
|
|
7822
|
+
delete imported.envVars.TEST_ACCOUNTS_JSON;
|
|
7823
|
+
delete imported.envVars.TEST_EMAIL;
|
|
7824
|
+
delete imported.envVars.TEST_PASSWORD;
|
|
7825
|
+
return imported;
|
|
7826
|
+
}
|
|
7827
|
+
|
|
7828
|
+
function applyLoadImport(raw, sourceName) {
|
|
7829
|
+
const imported = normalizeLoadImport(raw, sourceName);
|
|
7830
|
+
if (imported.script) loadScriptDraft = String(imported.script);
|
|
7831
|
+
if (imported.scriptName) loadScriptNameDraft = String(imported.scriptName);
|
|
7832
|
+
if (imported.baseUrl) loadBaseUrlDraft = String(imported.baseUrl);
|
|
7833
|
+
if (imported.vus) loadVusDraft = parseInt(String(imported.vus), 10) || loadVusDraft;
|
|
7834
|
+
if (imported.duration) loadDurationDraft = String(imported.duration);
|
|
7835
|
+
if (imported.dataDir) loadDataDirDraft = String(imported.dataDir);
|
|
7836
|
+
if (imported.resultDir) loadResultDirDraft = String(imported.resultDir);
|
|
7837
|
+
if (imported.accounts) {
|
|
7838
|
+
loadAccountsJsonDraft = typeof imported.accounts === 'string'
|
|
7839
|
+
? imported.accounts
|
|
7840
|
+
: JSON.stringify(imported.accounts, null, 2);
|
|
7841
|
+
}
|
|
7842
|
+
loadImportedEnvVarsDraft = imported.envVars || {};
|
|
7843
|
+
loadView = 'editor';
|
|
7844
|
+
renderContent();
|
|
7845
|
+
}
|
|
7846
|
+
|
|
7847
|
+
function loadImportConfigClick() {
|
|
7848
|
+
openLoadImportConfigModal();
|
|
7849
|
+
}
|
|
7850
|
+
|
|
7851
|
+
function readLoadImportConfigText(text, sourceName) {
|
|
7852
|
+
const raw = JSON.parse(String(text || '{}'));
|
|
7853
|
+
applyLoadImport(raw, sourceName);
|
|
7854
|
+
}
|
|
7855
|
+
|
|
7856
|
+
function loadImportConfigFile(input) {
|
|
7857
|
+
const file = input && input.files && input.files[0];
|
|
7858
|
+
if (!file) return;
|
|
7859
|
+
const reader = new FileReader();
|
|
7860
|
+
reader.onload = () => {
|
|
7861
|
+
try {
|
|
7862
|
+
readLoadImportConfigText(reader.result || '{}', file.name);
|
|
7863
|
+
const overlay = document.getElementById('loadImportConfigOverlay');
|
|
7864
|
+
if (overlay) overlay.remove();
|
|
7865
|
+
} catch (e) {
|
|
7866
|
+
alert('Конфиг не импортирован: ' + e.message);
|
|
7867
|
+
}
|
|
7868
|
+
};
|
|
7869
|
+
reader.onerror = () => alert('Не удалось прочитать файл конфига');
|
|
7870
|
+
reader.readAsText(file);
|
|
7871
|
+
}
|
|
7872
|
+
|
|
7873
|
+
function openLoadImportConfigModal() {
|
|
7874
|
+
let overlay = document.getElementById('loadImportConfigOverlay');
|
|
7875
|
+
if (overlay) overlay.remove();
|
|
7876
|
+
overlay = document.createElement('div');
|
|
7877
|
+
overlay.id = 'loadImportConfigOverlay';
|
|
7878
|
+
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.62);display:flex;align-items:center;justify-content:center;z-index:9999;padding:18px';
|
|
7879
|
+
overlay.innerHTML = `
|
|
7880
|
+
<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:8px;padding:18px;width:720px;max-width:96vw;max-height:92vh;overflow:auto">
|
|
7881
|
+
<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px">
|
|
7882
|
+
<div>
|
|
7883
|
+
<div style="font-size:15px;font-weight:600;color:var(--text)">Импорт k6 конфига</div>
|
|
7884
|
+
<div style="font-size:12px;color:var(--muted);margin-top:3px">Вставь JSON из буфера или выбери файл. После импорта поля можно править вручную.</div>
|
|
7885
|
+
</div>
|
|
7886
|
+
<button id="loadImportClose" class="load-btn" style="padding:4px 9px">Закрыть</button>
|
|
7887
|
+
</div>
|
|
7888
|
+
<textarea id="loadImportConfigText" spellcheck="false" placeholder='{"name":"auth-browse","baseUrl":"https://demo.unica.hopper-it.ru","vus":10,"duration":"2m","accounts":[{"email":"user@example.com","password":"pass"}],"script":"import http from ..."}' style="width:100%;min-height:260px;resize:vertical;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:1.45;padding:10px;outline:none"></textarea>
|
|
7889
|
+
<div id="loadImportStatus" style="min-height:18px;margin-top:8px;font-size:12px;color:var(--muted)">JSON пока не вставлен</div>
|
|
7890
|
+
<div style="display:flex;gap:8px;justify-content:space-between;align-items:center;margin-top:14px;flex-wrap:wrap">
|
|
7891
|
+
<div>
|
|
7892
|
+
<input id="loadConfigImportFile" type="file" accept=".json,application/json" style="display:none" onchange="loadImportConfigFile(this)" />
|
|
7893
|
+
<button class="load-btn" id="loadImportFileBtn">Выбрать JSON-файл</button>
|
|
7894
|
+
</div>
|
|
7895
|
+
<div style="display:flex;gap:8px">
|
|
7896
|
+
<button class="load-btn" id="loadImportCancel">Отмена</button>
|
|
7897
|
+
<button class="load-btn load-btn-run" id="loadImportApply" disabled>Импорт</button>
|
|
7898
|
+
</div>
|
|
7899
|
+
</div>
|
|
7900
|
+
</div>`;
|
|
7901
|
+
document.body.appendChild(overlay);
|
|
7902
|
+
|
|
7903
|
+
const textEl = overlay.querySelector('#loadImportConfigText');
|
|
7904
|
+
const statusEl = overlay.querySelector('#loadImportStatus');
|
|
7905
|
+
const applyBtn = overlay.querySelector('#loadImportApply');
|
|
7906
|
+
const close = () => overlay.remove();
|
|
7907
|
+
const validate = () => {
|
|
7908
|
+
const text = textEl.value.trim();
|
|
7909
|
+
if (!text) {
|
|
7910
|
+
statusEl.textContent = 'JSON пока не вставлен';
|
|
7911
|
+
statusEl.style.color = 'var(--muted)';
|
|
7912
|
+
applyBtn.disabled = true;
|
|
7913
|
+
return;
|
|
7914
|
+
}
|
|
7915
|
+
try {
|
|
7916
|
+
const raw = JSON.parse(text);
|
|
7917
|
+
const imported = normalizeLoadImport(raw, 'clipboard');
|
|
7918
|
+
const parts = [];
|
|
7919
|
+
if (imported.scriptName) parts.push(imported.scriptName);
|
|
7920
|
+
if (imported.baseUrl) parts.push(imported.baseUrl);
|
|
7921
|
+
if (imported.vus) parts.push(`${imported.vus} VUs`);
|
|
7922
|
+
if (imported.duration) parts.push(imported.duration);
|
|
7923
|
+
statusEl.textContent = `JSON валидный${parts.length ? ': ' + parts.join(' · ') : ''}`;
|
|
7924
|
+
statusEl.style.color = 'var(--green)';
|
|
7925
|
+
applyBtn.disabled = false;
|
|
7926
|
+
} catch (e) {
|
|
7927
|
+
statusEl.textContent = 'JSON невалидный: ' + e.message;
|
|
7928
|
+
statusEl.style.color = 'var(--red)';
|
|
7929
|
+
applyBtn.disabled = true;
|
|
7930
|
+
}
|
|
7931
|
+
};
|
|
7932
|
+
|
|
7933
|
+
overlay.addEventListener('click', e => { if (e.target === overlay) close(); });
|
|
7934
|
+
overlay.querySelector('#loadImportClose').addEventListener('click', close);
|
|
7935
|
+
overlay.querySelector('#loadImportCancel').addEventListener('click', close);
|
|
7936
|
+
overlay.querySelector('#loadImportFileBtn').addEventListener('click', () => {
|
|
7937
|
+
const input = overlay.querySelector('#loadConfigImportFile');
|
|
7938
|
+
input.value = '';
|
|
7939
|
+
input.click();
|
|
7940
|
+
});
|
|
7941
|
+
textEl.addEventListener('input', validate);
|
|
7942
|
+
applyBtn.addEventListener('click', () => {
|
|
7943
|
+
try {
|
|
7944
|
+
readLoadImportConfigText(textEl.value, 'clipboard');
|
|
7945
|
+
close();
|
|
7946
|
+
} catch (e) {
|
|
7947
|
+
statusEl.textContent = 'Конфиг не импортирован: ' + e.message;
|
|
7948
|
+
statusEl.style.color = 'var(--red)';
|
|
7949
|
+
applyBtn.disabled = true;
|
|
7950
|
+
}
|
|
7951
|
+
});
|
|
7952
|
+
setTimeout(() => textEl.focus(), 0);
|
|
7953
|
+
}
|
|
7954
|
+
|
|
7803
7955
|
function renderLoad(c) {
|
|
7804
7956
|
const isRunning = loadState && loadState.status === 'running';
|
|
7805
7957
|
const isDone = loadState && (loadState.status === 'done' || loadState.status === 'stopped');
|
|
@@ -7853,12 +8005,15 @@ function renderLoad(c) {
|
|
|
7853
8005
|
<div class="load-library-header">
|
|
7854
8006
|
<div>
|
|
7855
8007
|
<div style="font-size:16px;font-weight:600;color:var(--fg)">Нагрузочные тесты</div>
|
|
7856
|
-
<div style="font-size:12px;color:var(--muted);margin-top:2px">${loadK6Version ? escapeHtml(loadK6Version) : ''} · ${loadSavedScripts.length} сохранённых</div>
|
|
7857
|
-
</div>
|
|
7858
|
-
<
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
8008
|
+
<div style="font-size:12px;color:var(--muted);margin-top:2px">${loadK6Version ? escapeHtml(loadK6Version) : ''} · ${loadSavedScripts.length} сохранённых</div>
|
|
8009
|
+
</div>
|
|
8010
|
+
<div class="load-btns" style="margin:0">
|
|
8011
|
+
<button class="load-btn" style="font-size:13px;padding:8px 14px" onclick="loadImportConfigClick()">Импорт конфига</button>
|
|
8012
|
+
<button class="load-btn load-btn-run" style="font-size:13px;padding:8px 20px" onclick="loadNewTest()">+ Новый тест</button>
|
|
8013
|
+
</div>
|
|
8014
|
+
</div>
|
|
8015
|
+
|
|
8016
|
+
${loadSavedScripts.length === 0
|
|
7862
8017
|
? `<div class="load-library-empty">
|
|
7863
8018
|
<div style="font-size:32px;margin-bottom:12px">📋</div>
|
|
7864
8019
|
<div style="font-size:14px;font-weight:500;margin-bottom:6px">Нет сохранённых тестов</div>
|
|
@@ -7905,10 +8060,11 @@ function renderLoad(c) {
|
|
|
7905
8060
|
|
|
7906
8061
|
c.innerHTML = `<div class="load-screen">
|
|
7907
8062
|
|
|
7908
|
-
<div class="load-editor-topbar">
|
|
7909
|
-
${!isRunning ? `<button class="load-back-btn" onclick="loadView='library';renderContent()">← Все тесты</button>` : ''}
|
|
7910
|
-
|
|
7911
|
-
|
|
8063
|
+
<div class="load-editor-topbar">
|
|
8064
|
+
${!isRunning ? `<button class="load-back-btn" onclick="loadView='library';renderContent()">← Все тесты</button>` : ''}
|
|
8065
|
+
${!isRunning ? `<button class="load-btn" style="font-size:12px;padding:5px 10px" onclick="loadImportConfigClick()">Импорт конфига</button>` : ''}
|
|
8066
|
+
<span style="font-size:12px;color:var(--muted);margin-left:4px">${statusBadge}</span>
|
|
8067
|
+
</div>
|
|
7912
8068
|
|
|
7913
8069
|
<div class="load-section">
|
|
7914
8070
|
<div class="load-section-title">Конфигурация ${loadK6Version ? `<span style="color:var(--dim);font-weight:400">${escapeHtml(loadK6Version)}</span>` : ''}</div>
|
|
@@ -8021,18 +8177,20 @@ function renderLoad(c) {
|
|
|
8021
8177
|
}
|
|
8022
8178
|
}
|
|
8023
8179
|
|
|
8024
|
-
function loadNewTest() {
|
|
8025
|
-
loadScriptDraft = '';
|
|
8026
|
-
loadScriptNameDraft = '';
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8180
|
+
function loadNewTest() {
|
|
8181
|
+
loadScriptDraft = '';
|
|
8182
|
+
loadScriptNameDraft = '';
|
|
8183
|
+
loadImportedEnvVarsDraft = {};
|
|
8184
|
+
loadView = 'editor';
|
|
8185
|
+
renderContent();
|
|
8186
|
+
}
|
|
8030
8187
|
|
|
8031
8188
|
function loadOpenScript(name) {
|
|
8032
8189
|
const s = loadSavedScripts.find(x => x.name === name);
|
|
8033
8190
|
if (!s) return;
|
|
8034
8191
|
loadScriptDraft = s.script;
|
|
8035
8192
|
loadScriptNameDraft = s.name;
|
|
8193
|
+
loadImportedEnvVarsDraft = {};
|
|
8036
8194
|
if (s.baseUrl) loadBaseUrlDraft = s.baseUrl;
|
|
8037
8195
|
if (s.vus) loadVusDraft = s.vus;
|
|
8038
8196
|
if (s.duration) loadDurationDraft = s.duration;
|
|
@@ -8082,8 +8240,8 @@ async function runLoadTest() {
|
|
|
8082
8240
|
loadLogLines = [];
|
|
8083
8241
|
loadBuckets = [];
|
|
8084
8242
|
|
|
8085
|
-
try {
|
|
8086
|
-
const envVars = {};
|
|
8243
|
+
try {
|
|
8244
|
+
const envVars = { ...(loadImportedEnvVarsDraft || {}) };
|
|
8087
8245
|
if (accountsInfo.accounts.length > 0) {
|
|
8088
8246
|
envVars.TEST_ACCOUNTS_JSON = accountsInfo.text;
|
|
8089
8247
|
envVars.TEST_EMAIL = accountsInfo.accounts[0].email;
|
|
@@ -8278,6 +8436,7 @@ async function loadOpenRun(runId) {
|
|
|
8278
8436
|
loadLogLines = d.logs || [];
|
|
8279
8437
|
loadScriptDraft = d.script || '';
|
|
8280
8438
|
loadScriptNameDraft = d.config?.scriptName || d.scriptName || '';
|
|
8439
|
+
loadImportedEnvVarsDraft = {};
|
|
8281
8440
|
if (d.config) applyLoadConfigToFields(d.config);
|
|
8282
8441
|
loadView = 'editor';
|
|
8283
8442
|
renderContent();
|
|
@@ -8321,6 +8480,7 @@ async function loadLoadScript(name) {
|
|
|
8321
8480
|
if (!s) return;
|
|
8322
8481
|
loadScriptDraft = s.script;
|
|
8323
8482
|
loadScriptNameDraft = s.name;
|
|
8483
|
+
loadImportedEnvVarsDraft = {};
|
|
8324
8484
|
if (s.baseUrl) loadBaseUrlDraft = s.baseUrl;
|
|
8325
8485
|
if (s.vus) loadVusDraft = s.vus;
|
|
8326
8486
|
if (s.duration) loadDurationDraft = s.duration;
|