fix(packets): add Multipart/Control/Raw Custom to type filter checklist (#1798) (#1803)

## 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 <bot@openclaw.local>
This commit is contained in:
Kpa-clawbot
2026-06-28 01:23:47 -07:00
committed by GitHub
co-authored by openclaw-bot
parent 3efa37c46c
commit 120ac052d3
2 changed files with 49 additions and 1 deletions
+1 -1
View File
@@ -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;
+48
View File
@@ -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'));