skopix 2.0.32 → 2.0.34

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/web/app/index.html +25 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skopix",
3
- "version": "2.0.32",
3
+ "version": "2.0.34",
4
4
  "description": "Browser-based QA tool — record tests by using your app, replay them deterministically, generate Playwright code automatically",
5
5
  "main": "cli/index.js",
6
6
  "bin": {
@@ -1591,15 +1591,9 @@ body.viewer-mode .saved-test-row { cursor: default !important; }
1591
1591
 
1592
1592
  <!-- Search + filter -->
1593
1593
  <div style="display:flex;gap:10px;margin-bottom:16px">
1594
- <input class="form-input" id="library-search" type="text" placeholder="Search steps..." oninput="filterLibrarySteps()" style="flex:1">
1595
- <select class="form-select" id="library-filter-action" onchange="filterLibrarySteps()" style="width:140px">
1596
- <option value="">All actions</option>
1597
- <option value="click">click</option>
1598
- <option value="type">type</option>
1599
- <option value="check">check</option>
1600
- <option value="assert">assert</option>
1601
- <option value="select">select</option>
1602
- <option value="scroll">scroll</option>
1594
+ <input class="form-input" id="library-search" type="text" placeholder="Search elements..." oninput="filterLibrarySteps()" style="flex:1">
1595
+ <select class="form-select" id="library-filter-tag" onchange="filterLibrarySteps()" style="width:140px">
1596
+ <option value="">All tags</option>
1603
1597
  </select>
1604
1598
  </div>
1605
1599
 
@@ -5620,8 +5614,8 @@ function renderLibrarySteps(steps) {
5620
5614
  </td>
5621
5615
  <td style="padding:12px 16px;font-family:var(--mono);font-size:12px;color:var(--muted)">${s.usageCount||0}</td>
5622
5616
  <td style="padding:12px 16px;text-align:right">
5623
- <button class="btn btn-ghost" style="padding:4px 10px;font-size:11px;margin-right:4px" onclick="editLibraryStep('${escapeAttr(s.id)}')">Edit</button>
5624
- <button class="btn btn-ghost" style="padding:4px 10px;font-size:11px;color:var(--red)" onclick="deleteLibraryStepUI('${escapeAttr(s.id)}','${escapeAttr(s.name||'')}')">Delete</button>
5617
+ <button class="btn btn-ghost lib-edit-btn" style="padding:4px 10px;font-size:11px;margin-right:4px" data-id="${escapeAttr(s.id)}">Edit</button>
5618
+ <button class="btn btn-ghost lib-delete-btn" style="padding:4px 10px;font-size:11px;color:var(--red)" data-id="${escapeAttr(s.id)}" data-name="${escapeAttr(s.name||'')}">Delete</button>
5625
5619
  </td>
5626
5620
  </tr>`;
5627
5621
  }).join('')}
@@ -5716,20 +5710,37 @@ async function confirmMergeSteps(ids) {
5716
5710
 
5717
5711
  function filterLibrarySteps() {
5718
5712
  const q = (document.getElementById('library-search')?.value || '').toLowerCase();
5719
- const action = document.getElementById('library-filter-action')?.value || '';
5713
+ const tag = document.getElementById('library-filter-tag')?.value || '';
5720
5714
  const filtered = libraryStepsCache.filter(s => {
5721
5715
  const matchQ = !q || (s.name||'').toLowerCase().includes(q) || (s.selector||'').toLowerCase().includes(q) || (s.description||'').toLowerCase().includes(q);
5722
- const matchA = !action || s.action === action;
5723
- return matchQ && matchA;
5716
+ const matchTag = !tag || (s.tags||[]).includes(tag);
5717
+ return matchQ && matchTag;
5724
5718
  });
5725
5719
  renderLibrarySteps(filtered);
5726
5720
  }
5727
5721
 
5722
+ function populateLibraryTagFilter() {
5723
+ const sel = document.getElementById('library-filter-tag');
5724
+ if (!sel) return;
5725
+ const allTags = [...new Set(libraryStepsCache.flatMap(s => s.tags || []))].sort();
5726
+ const current = sel.value;
5727
+ sel.innerHTML = '<option value="">All tags</option>' + allTags.map(t => `<option value="${escapeAttr(t)}" ${t===current?'selected':''}>${escapeHtml(t)}</option>`).join('');
5728
+ }
5729
+
5728
5730
  async function loadLibraryView() {
5729
5731
  const steps = await fetchLibrarySteps();
5732
+ populateLibraryTagFilter();
5730
5733
  renderLibrarySteps(steps);
5731
5734
  }
5732
5735
 
5736
+ // Event delegation for library table buttons
5737
+ document.addEventListener('click', (e) => {
5738
+ const editBtn = e.target.closest('.lib-edit-btn');
5739
+ const deleteBtn = e.target.closest('.lib-delete-btn');
5740
+ if (editBtn) { editLibraryStep(editBtn.dataset.id); }
5741
+ if (deleteBtn) { deleteLibraryStepUI(deleteBtn.dataset.id, deleteBtn.dataset.name); }
5742
+ });
5743
+
5733
5744
  function openAddLibraryStep() {
5734
5745
  document.getElementById('lib-step-id').value = '';
5735
5746
  document.getElementById('lib-step-name').value = '';