mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-03-30 14:45:52 +00:00
feat(coverage): add targeted Playwright interactions for higher frontend coverage
Add redundant selectors (data-sort, data-role, data-status, data-tab, placeholder-based search, emoji theme toggle, .cust-close, #fTimeWindow, broader preset selectors) to exercise more frontend code paths. All interactions wrapped in try/catch for resilience.
This commit is contained in:
@@ -86,24 +86,40 @@ async function collectCoverage() {
|
||||
// Click first header again for reverse sort
|
||||
if (headers.length > 0) try { await headers[0].click(); await page.waitForTimeout(300); } catch {}
|
||||
|
||||
// Click sort headers by data-sort attribute
|
||||
try { await page.click('th[data-sort="name"]'); await page.waitForTimeout(300); } catch {}
|
||||
try { await page.click('th[data-sort="last_seen"]'); await page.waitForTimeout(300); } catch {}
|
||||
|
||||
// Click role tabs using data-tab attribute
|
||||
const roleTabs = await page.$$('.node-tab[data-tab]');
|
||||
for (const tab of roleTabs) {
|
||||
try { await tab.click(); await page.waitForTimeout(600); } catch {}
|
||||
}
|
||||
|
||||
// Click role tabs by data-role attribute
|
||||
try { await page.click('[data-role="repeater"]'); await page.waitForTimeout(500); } catch {}
|
||||
try { await page.click('[data-role="all"]'); await page.waitForTimeout(300); } catch {}
|
||||
|
||||
// Status filter buttons
|
||||
const statusBtns = await page.$$('#nodeStatusFilter .btn, [data-status]');
|
||||
for (const btn of statusBtns) {
|
||||
try { await btn.click(); await page.waitForTimeout(400); } catch {}
|
||||
}
|
||||
|
||||
// Click status filters by data-status attribute
|
||||
try { await page.click('[data-status="active"]'); await page.waitForTimeout(300); } catch {}
|
||||
try { await page.click('[data-status="all"]'); await page.waitForTimeout(300); } catch {}
|
||||
|
||||
// Use search box
|
||||
await safeFill('#nodeSearch', 'test');
|
||||
await page.waitForTimeout(500);
|
||||
await safeFill('#nodeSearch', '');
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Search by placeholder
|
||||
try { await page.fill('input[placeholder*="Search"]', 'test'); await page.waitForTimeout(500); } catch {}
|
||||
try { await page.fill('input[placeholder*="Search"]', ''); await page.waitForTimeout(300); } catch {};
|
||||
|
||||
// Use dropdowns (Last Heard, etc.)
|
||||
const selects = await page.$$('select');
|
||||
for (const sel of selects) {
|
||||
@@ -162,6 +178,17 @@ async function collectCoverage() {
|
||||
}
|
||||
}
|
||||
|
||||
// Direct filter interactions
|
||||
try { await page.fill('#packetFilterInput', 'type == ADVERT'); await page.waitForTimeout(500); } catch {}
|
||||
try { await page.fill('#packetFilterInput', ''); await page.waitForTimeout(300); } catch {}
|
||||
// Change time window via select
|
||||
try { await page.selectOption('#fTimeWindow', '60'); await page.waitForTimeout(500); } catch {}
|
||||
// Click a packet row
|
||||
try {
|
||||
const pktRows2 = await page.$$('table tbody tr');
|
||||
if (pktRows2.length) { await pktRows2[0].click(); await page.waitForTimeout(1000); }
|
||||
} catch {}
|
||||
|
||||
// Click Group by Hash button
|
||||
await safeClick('#fGroup');
|
||||
await page.waitForTimeout(800);
|
||||
@@ -211,6 +238,13 @@ async function collectCoverage() {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// Toggle role filters by data-role
|
||||
try { await page.click('input[data-role="companion"]'); await page.waitForTimeout(300); } catch {}
|
||||
try { await page.click('input[data-role="companion"]'); await page.waitForTimeout(300); } catch {}
|
||||
// Status filter on map
|
||||
try { await page.click('[data-status="active"]'); await page.waitForTimeout(300); } catch {}
|
||||
try { await page.click('[data-status="all"]'); await page.waitForTimeout(300); } catch {}
|
||||
|
||||
// Toggle dark mode while on map
|
||||
await safeClick('#darkModeToggle');
|
||||
await page.waitForTimeout(800);
|
||||
@@ -231,6 +265,11 @@ async function collectCoverage() {
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// Click analytics tabs by data-tab directly (broader selector)
|
||||
for (const tab of ['rf', 'topology', 'channels', 'hashsizes', 'collisions', 'subpaths', 'nodes', 'distance']) {
|
||||
try { await page.click(`[data-tab="${tab}"]`); await page.waitForTimeout(800); } catch {}
|
||||
}
|
||||
|
||||
// Also test deep-link tabs
|
||||
for (const tab of ['collisions', 'rf', 'distance', 'topology', 'nodes', 'subpaths']) {
|
||||
await page.goto(`${BASE}/#/analytics?tab=${tab}`, { waitUntil: 'networkidle', timeout: 15000 }).catch(() => {});
|
||||
@@ -256,6 +295,12 @@ async function collectCoverage() {
|
||||
try { await presets[i].click(); await page.waitForTimeout(400); } catch {}
|
||||
}
|
||||
|
||||
// Click presets by broader selector
|
||||
try {
|
||||
const presets2 = await page.$$('.cust-preset, [data-preset]');
|
||||
if (presets2.length) { await presets2[0].click(); await page.waitForTimeout(500); }
|
||||
} catch {}
|
||||
|
||||
// Change a color input
|
||||
const colorInputs = await page.$$('input[type="color"]');
|
||||
for (let i = 0; i < Math.min(colorInputs.length, 3); i++) {
|
||||
@@ -276,6 +321,13 @@ async function collectCoverage() {
|
||||
// Close customizer
|
||||
await safeClick('#customizeToggle');
|
||||
|
||||
// Re-open customizer and use broader selectors
|
||||
try { await page.click('#customizeToggle'); await page.waitForTimeout(500); } catch {}
|
||||
for (const tab of ['branding', 'theme', 'nodes', 'home', 'export']) {
|
||||
try { await page.click(`[data-tab="${tab}"]`); await page.waitForTimeout(300); } catch {}
|
||||
}
|
||||
try { await page.click('.cust-close'); await page.waitForTimeout(300); } catch {}
|
||||
|
||||
// ── CHANNELS PAGE ──
|
||||
console.log(' [coverage] Channels page...');
|
||||
await page.goto(`${BASE}/#/channels`, { waitUntil: 'networkidle', timeout: 15000 }).catch(() => {});
|
||||
@@ -334,6 +386,12 @@ async function collectCoverage() {
|
||||
await safeClick('#darkModeToggle');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Toggle via emoji button selector
|
||||
try {
|
||||
const themeBtn = await page.$('button:has-text("☀️"), button:has-text("🌙")');
|
||||
if (themeBtn) { await themeBtn.click(); await page.waitForTimeout(500); }
|
||||
} catch {}
|
||||
|
||||
// ── KEYBOARD SHORTCUT (Ctrl+K for search) ──
|
||||
try {
|
||||
await page.keyboard.press('Control+k');
|
||||
|
||||
Reference in New Issue
Block a user