From 120ac052d389f60314dd6f92678a22e929b16514 Mon Sep 17 00:00:00 2001 From: Kpa-clawbot Date: Sun, 28 Jun 2026 01:23:47 -0700 Subject: [PATCH] fix(packets): add Multipart/Control/Raw Custom to type filter checklist (#1798) (#1803) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes #1798. Extends the Packets-page `typeMap` in `public/packets.js` to include three firmware payload types that were previously missing from the multi-select checklist: - `10` — Multipart - `11` — Control - `15` — Raw Custom Other surfaces (`public/packet-filter.js` `FW_PAYLOAD_TYPES`, `public/live.js` `TYPE_COLORS`, `public/map.js`) already knew about these types; only the Packets-page checklist UI omitted them, forcing operators to hand-type filter expressions to filter on them. ## Red → green - Red commit: `359e3645ac41506e563c19dfbd49983fb4ec9638` — adds E2E that opens `#typeMenu` and asserts each new `data-type-id="10|11|15"` checkbox renders with the exact label. Fails on assertion (DOM selectors return null) against the pre-fix `typeMap`. - Green commit: `f484e8cb88659b14fed7aa7fefcdfb3f0eb6c186` — single-line literal extension; test goes green. ## E2E assertion added `test-e2e-playwright.js:576` — `Packets type filter includes Multipart/Control/Raw Custom (#1798)` (asserts the three new `data-type-id` checkboxes render with their exact labels in the rendered Packets-page checklist DOM). ## Files touched - `public/packets.js` — extend `typeMap` literal - `test-e2e-playwright.js` — new E2E test asserting the three checkboxes render ## Browser verified E2E test scrapes the rendered Packets-page DOM via Playwright; CI runs it against the local Go server fixture in the `e2e-test` job. Fixes #1798 --------- Co-authored-by: openclaw-bot --- public/packets.js | 2 +- test-e2e-playwright.js | 48 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/public/packets.js b/public/packets.js index 0eeeae05..4bb4f518 100644 --- a/public/packets.js +++ b/public/packets.js @@ -1745,7 +1745,7 @@ // --- Type multi-select --- const typeMenu = document.getElementById('typeMenu'); const typeTrigger = document.getElementById('typeTrigger'); - const typeMap = {0:'Request',1:'Response',2:'Direct Msg',3:'ACK',4:'Advert',5:'Channel Msg',6:'Group Data',7:'Anon Req',8:'Path',9:'Trace'}; + const typeMap = {0:'Request',1:'Response',2:'Direct Msg',3:'ACK',4:'Advert',5:'Channel Msg',6:'Group Data',7:'Anon Req',8:'Path',9:'Trace',10:'Multipart',11:'Control',15:'Raw Custom'}; const selectedTypes = new Set(filters.type ? String(filters.type).split(',') : []); function buildTypeMenu() { const allChecked = selectedTypes.size === 0; diff --git a/test-e2e-playwright.js b/test-e2e-playwright.js index cd84cb1a..a307959a 100644 --- a/test-e2e-playwright.js +++ b/test-e2e-playwright.js @@ -573,6 +573,54 @@ async function run() { await page.reload({ waitUntil: 'load' }); }); + // Test (#1798): The Packets-page type checklist must include the three + // firmware payload types currently missing from `typeMap` in `public/packets.js`: + // 10 — Multipart + // 11 — Control + // 15 — Raw Custom + // Other surfaces (`packet-filter.js`, `live.js`, `map.js`) already know about + // these three types; only the Packets checklist UI omits them. This regression + // test renders the checklist and asserts each new `data-type-id` checkbox is + // present with the expected label. + await test('Packets type filter includes Multipart/Control/Raw Custom (#1798)', async () => { + const EXPECTED = [ + { id: '10', label: 'Multipart' }, + { id: '11', label: 'Control' }, + { id: '15', label: 'Raw Custom' }, + ]; + await page.setViewportSize({ width: 1280, height: 720 }); + await page.goto(`${BASE}/#/packets`, { waitUntil: 'domcontentloaded' }); + await page.evaluate(() => { + localStorage.setItem('meshcore-time-window', '525600'); + localStorage.removeItem('meshcore-type-filter'); + }); + await page.reload({ waitUntil: 'load' }); + await page.waitForSelector('[data-loaded="true"]', { timeout: 15000 }); + + // Open the type multi-select menu. + const typeTrigger = await page.$('#typeTrigger'); + assert(typeTrigger, 'Type filter trigger (#typeTrigger) not found'); + await typeTrigger.click(); + await page.waitForSelector('#typeMenu.open', { timeout: 5000 }); + + for (const { id, label } of EXPECTED) { + const sel = `#typeMenu input[data-type-id="${id}"]`; + const cb = await page.$(sel); + assert(cb, `#1798: checkbox for data-type-id="${id}" (${label}) missing from type filter menu`); + const rendered = await page.$eval(sel, el => (el.parentElement && el.parentElement.textContent || '').trim()); + assert(rendered === label, `#1798: checkbox for type ${id} should be labeled exactly "${label}", got "${rendered}"`); + } + + // Cleanup: close menu and reset state for subsequent tests. + await typeTrigger.click(); + await page.waitForSelector('#typeMenu:not(.open)', { timeout: 5000 }).catch(() => {}); + await page.evaluate(() => { + localStorage.removeItem('meshcore-type-filter'); + localStorage.removeItem('meshcore-time-window'); + }); + await page.reload({ waitUntil: 'load' }); + }); + await test('Packets initial fetch honors persisted time window', async () => { // Set persisted time window to 60 min and reload so the IIFE reads it await page.evaluate(() => localStorage.setItem('meshcore-time-window', '60'));