skopix 2.0.67 → 2.0.69
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/cli/commands/dashboard.js +21 -0
- package/package.json +1 -1
- package/web/app/index.html +27 -4
|
@@ -1919,6 +1919,27 @@ export async function dashboardCommand(options) {
|
|
|
1919
1919
|
sendJSON(res, 200, result);
|
|
1920
1920
|
return;
|
|
1921
1921
|
}
|
|
1922
|
+
if (pathname === '/api/step-library/sync-selectors' && method === 'POST') {
|
|
1923
|
+
const { fromSelectors, toSelector, toName } = JSON.parse(await readBody(req));
|
|
1924
|
+
const allTests = await listAllTests(suitesDir);
|
|
1925
|
+
let updated = 0;
|
|
1926
|
+
for (const test of allTests) {
|
|
1927
|
+
if (!test.steps || !test.steps.length) continue;
|
|
1928
|
+
let changed = false;
|
|
1929
|
+
const newSteps = test.steps.map(step => {
|
|
1930
|
+
const sSel = (step.stableSelector||step.selector||'').toLowerCase();
|
|
1931
|
+
if (fromSelectors.includes(sSel)) {
|
|
1932
|
+
changed = true;
|
|
1933
|
+
updated++;
|
|
1934
|
+
return { ...step, stableSelector: toSelector, selector: toSelector, description: toName || step.description };
|
|
1935
|
+
}
|
|
1936
|
+
return step;
|
|
1937
|
+
});
|
|
1938
|
+
if (changed) await updateTest(suitesDir, test.scope, test.id, { ...test, steps: newSteps });
|
|
1939
|
+
}
|
|
1940
|
+
sendJSON(res, 200, { updated });
|
|
1941
|
+
return;
|
|
1942
|
+
}
|
|
1922
1943
|
if (pathname === '/api/step-library/sync' && method === 'POST') {
|
|
1923
1944
|
const result = await syncTestsToLibrary(suitesDir);
|
|
1924
1945
|
sendJSON(res, 200, result);
|
package/package.json
CHANGED
package/web/app/index.html
CHANGED
|
@@ -5870,9 +5870,18 @@ function openMergeSteps() {
|
|
|
5870
5870
|
// Override the confirm button
|
|
5871
5871
|
const actions = document.querySelector('.confirm-actions');
|
|
5872
5872
|
if (actions) {
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5873
|
+
const mergeBtn = document.createElement('button');
|
|
5874
|
+
mergeBtn.className = 'btn btn-primary';
|
|
5875
|
+
mergeBtn.textContent = 'Merge';
|
|
5876
|
+
mergeBtn.dataset.mergeIds = JSON.stringify(ids);
|
|
5877
|
+
mergeBtn.addEventListener('click', () => confirmMergeSteps(JSON.parse(mergeBtn.dataset.mergeIds)));
|
|
5878
|
+
actions.innerHTML = '';
|
|
5879
|
+
const cancelBtn = document.createElement('button');
|
|
5880
|
+
cancelBtn.className = 'btn btn-ghost';
|
|
5881
|
+
cancelBtn.textContent = 'Cancel';
|
|
5882
|
+
cancelBtn.addEventListener('click', closeConfirm);
|
|
5883
|
+
actions.appendChild(cancelBtn);
|
|
5884
|
+
actions.appendChild(mergeBtn);
|
|
5876
5885
|
}
|
|
5877
5886
|
document.getElementById('confirm-overlay').classList.add('open');
|
|
5878
5887
|
}
|
|
@@ -5885,15 +5894,29 @@ async function confirmMergeSteps(ids) {
|
|
|
5885
5894
|
const toDelete = selected.filter(s => s.id !== canonicalId);
|
|
5886
5895
|
const totalUses = selected.reduce((sum, s) => sum + (s.usageCount||0), 0);
|
|
5887
5896
|
closeConfirm();
|
|
5897
|
+
|
|
5898
|
+
// Update canonical usage count
|
|
5888
5899
|
await fetch(API_BASE + '/api/step-library/' + encodeURIComponent(canonicalId), {
|
|
5889
5900
|
method: 'PUT',
|
|
5890
5901
|
headers: { 'Content-Type': 'application/json' },
|
|
5891
5902
|
body: JSON.stringify({ ...canonical, usageCount: totalUses })
|
|
5892
5903
|
});
|
|
5904
|
+
|
|
5905
|
+
// Delete the merged ones
|
|
5893
5906
|
for (const s of toDelete) {
|
|
5894
5907
|
await fetch(API_BASE + '/api/step-library/' + encodeURIComponent(s.id), { method: 'DELETE' });
|
|
5895
5908
|
}
|
|
5896
|
-
|
|
5909
|
+
|
|
5910
|
+
// Update all tests that used any of the merged selectors to use the canonical selector
|
|
5911
|
+
const allMergedSelectors = selected.map(s => (s.stableSelector||s.selector||'').toLowerCase());
|
|
5912
|
+
const canonicalSel = canonical.stableSelector || canonical.selector;
|
|
5913
|
+
const res = await fetch(API_BASE + '/api/step-library/sync-selectors', {
|
|
5914
|
+
method: 'POST',
|
|
5915
|
+
headers: { 'Content-Type': 'application/json' },
|
|
5916
|
+
body: JSON.stringify({ fromSelectors: allMergedSelectors, toSelector: canonicalSel, toName: canonical.name })
|
|
5917
|
+
});
|
|
5918
|
+
const data = await res.json();
|
|
5919
|
+
showToast(`Merged into "${canonical.name}" — ${data.updated || 0} test step${data.updated !== 1 ? 's' : ''} updated`);
|
|
5897
5920
|
await loadLibraryView();
|
|
5898
5921
|
}
|
|
5899
5922
|
|