From 73ceb4779e1ad0a327fa2b5b837b8be9de72f483 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Tue, 2 Jun 2026 01:06:56 +0200 Subject: [PATCH] fix: sync packet hash into URL after trace (#1523) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #1522 ## Summary - Call `history.replaceState` in `doTrace()` after the hash is validated, so the URL becomes `#/tools/trace/` and can be shared directly. ## Change `public/traces.js` — one line added: ```js history.replaceState(null, '', `#/tools/trace/${encodeURIComponent(hash)}`); ``` The read path (`init()` picks up the hash from the URL on load) already existed — only the write path was missing. --- public/traces.js | 1 + test-issue-1522-trace-url-sync-e2e.js | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 test-issue-1522-trace-url-sync-e2e.js diff --git a/public/traces.js b/public/traces.js index 3adb5be4..e1020fc4 100644 --- a/public/traces.js +++ b/public/traces.js @@ -51,6 +51,7 @@ const hash = input.value.trim(); if (!hash) return; currentHash = hash; + history.replaceState(null, '', `#/tools/trace/${encodeURIComponent(hash)}`); const results = document.getElementById('traceResults'); results.innerHTML = '
Tracing…
'; diff --git a/test-issue-1522-trace-url-sync-e2e.js b/test-issue-1522-trace-url-sync-e2e.js new file mode 100644 index 00000000..4a9fa6cd --- /dev/null +++ b/test-issue-1522-trace-url-sync-e2e.js @@ -0,0 +1,26 @@ +// E2E test for issue #1522 — trace hash written into URL after doTrace(). +// Run: npx playwright test test-issue-1522-trace-url-sync-e2e.js +// Requires: running server on BASE_URL (default http://localhost:3000). +'use strict'; + +const { test, expect } = require('@playwright/test'); +const BASE_URL = process.env.BASE_URL || 'http://localhost:3000'; + +test.describe('Trace URL sync — issue #1522', () => { + test('hash written into URL after clicking Trace', async ({ page }) => { + await page.goto(`${BASE_URL}/#/tools/trace/`); + await page.waitForSelector('#traceHashInput', { timeout: 8000 }); + await page.fill('#traceHashInput', 'deadbeef'); + await page.click('#traceBtn'); + await expect(page).toHaveURL(/#\/tools\/trace\/deadbeef$/); + }); + + test('deep-link pre-fills input and fires trace on load', async ({ page }) => { + await page.goto(`${BASE_URL}/#/tools/trace/cafebabe`); + await page.waitForSelector('#traceHashInput', { timeout: 8000 }); + const value = await page.inputValue('#traceHashInput'); + expect(value).toBe('cafebabe'); + // URL must remain unchanged (no extra replaceState pollution) + await expect(page).toHaveURL(/#\/tools\/trace\/cafebabe$/); + }); +});