Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 59 additions & 13 deletions test-issue-180-packets-url-modal-e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ async function fresh(page, url) {
await page.reload({ waitUntil: 'load' });
}

// The "Latest Packets (N)" count, once the list has rendered.
async function listCount(page) {
await page.waitForSelector('#pktLeft .count', { timeout: 15000 });
return page.evaluate(() => Number((document.querySelector('#pktLeft .count').textContent.match(/\d+/) || [])[0]));
}
function clearShown(page) {
return page.evaluate(() => {
const b = document.getElementById('clearFiltersBtn');
Expand Down Expand Up @@ -102,27 +97,78 @@ function detailPaneOpen(page) {
await waitFor(page, () => /\(1\)/.test(document.querySelector('#pktLeft .count').textContent), 'detail URL did not filter the list to 1 packet');
assert(await clearShown(page), 'Clear button hidden on the filtered detail URL');

// The fixture's packets may have aged out of the default 15 min window
// that Clear restores, so compare what Clear showed with what the
// reload shows rather than expecting a number of rows.
const listLoaded = () => page.waitForResponse((r) => /\/api\/packets\?/.test(r.url()), { timeout: 15000 });
await Promise.all([listLoaded(), page.click('#clearFiltersBtn')]);
await page.waitForTimeout(500);
let h = await page.evaluate(() => location.hash);
// What Clear itself must do, asserted right after the click: the bare
// list URL, the Clear button gone and the detail pane closed. These are
// what a "Clear keeps ?timeWindow=" or "Clear keeps the detail" mutant
// breaks. (The window reset to the default is not visible here beyond
// Clear being hidden; it is asserted across the reload below.)
assert(h === '#/packets', 'URL after Clear: ' + h);
const shown = await listCount(page);
assert(!(await clearShown(page)), 'Clear button still visible after Clear');
assert(!(await detailPaneOpen(page)), 'detail pane still open after Clear');

// Reloading the URL Clear wrote must give Clear's own state back —
// that is the "a reload shows the same list" half of this step, and the
// one a mutant where Clear's default no longer matches the default a
// cold load restores breaks. Compare STATE (URL, Clear button, the
// saved window, the detail pane, the hash input), all of which are
// clock-independent; the list contents are compared separately below at
// a pinned window, because row counts at the default window are not
// (#271).
const windowValue = () => page.evaluate(() => document.getElementById('fTimeWindow').value);
const twAfterClear = await windowValue();
await Promise.all([listLoaded(), page.reload({ waitUntil: 'load' })]);
await page.waitForTimeout(500);
h = await page.evaluate(() => location.hash);
assert(h === '#/packets', 'URL after reload: ' + h);
const reloaded = await listCount(page);
assert(reloaded === shown, 'reload shows ' + reloaded + ' packets, Clear showed ' + shown);
assert(h === '#/packets', 'URL after reloading the Clear state: ' + h);
assert(!(await clearShown(page)), 'Clear button back after reload');
assert(!(await detailPaneOpen(page)), 'detail pane open after reload');
const twAfterReload = await windowValue();
assert(twAfterReload === twAfterClear, 'time window after reload ' + twAfterReload + ', after Clear ' + twAfterClear);
assert(!(await detailPaneOpen(page)), 'detail pane open after reloading the Clear state');
assert(await page.evaluate(() => document.getElementById('fHash').value === ''), 'hash filter input filled after reload');

// #271: the list-contents half of this step used to compare row COUNTS
// at the default 15-min window across two renders (Clear's in-SPA list,
// then a full reload). Both compute `since = now - 15min` from the
// browser's live clock, so a fixture packet can cross that boundary in
// the real-time gap between the two fetches, and the CI fixture ages
// while the job runs (same class of problem #252 fixed for the Details
// test). Pin a wide window (24h; the widest option, same as #252) and
// compare the "Latest Packets (N)" total — the whole filtered set —
// plus the hashes of the rows actually rendered, so the comparison
// cannot depend on how old the fixture is.
await Promise.all([listLoaded(), page.evaluate(() => {
const sel = document.getElementById('fTimeWindow');
sel.value = '1440';
sel.dispatchEvent(new Event('change', { bubbles: true }));
})]);
await page.waitForTimeout(500);
// The table is virtualised, so only a window of rows is in the DOM at
// any time: `total` is the full filtered count, `hashes` is what is
// rendered. The two #vscroll-* spacer rows carry no data-hash and are
// dropped, so an empty table cannot pass as "a set of hashes".
const listState = async () => {
await page.waitForSelector('#pktLeft .count', { timeout: 15000 });
return page.evaluate(() => ({
total: Number((document.querySelector('#pktLeft .count').textContent.match(/\d+/) || [])[0]),
hashes: Array.from(document.querySelectorAll('#pktBody > tr:not(.group-child)')).map((tr) => tr.dataset.hash).filter(Boolean).sort(),
}));
};
const shown = await listState();
assert(shown.total > 0, 'no packets in the pinned 24h window');
assert(shown.hashes.length > 0, 'no rendered rows with a hash to compare at the pinned 24h window');

await Promise.all([listLoaded(), page.reload({ waitUntil: 'load' })]);
await page.waitForTimeout(500);
h = await page.evaluate(() => location.hash);
assert(h === '#/packets?timeWindow=1440', 'URL after reloading the pinned window: ' + h);
const reloaded = await listState();
assert(reloaded.total === shown.total, 'reload shows ' + reloaded.total + ' packets at the pinned window, before the reload it showed ' + shown.total);
assert(JSON.stringify(reloaded.hashes) === JSON.stringify(shown.hashes), 'reload renders ' + JSON.stringify(reloaded.hashes) + ' at the pinned window, before the reload it rendered ' + JSON.stringify(shown.hashes));
assert(!(await detailPaneOpen(page)), 'detail pane open after reloading the pinned window');
});
await context.close();
}
Expand Down
Loading