mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-10-11 20:57:19 +00:00
test(e2e): assert the configured-scope row after the theme-refresh re-render (#2180)
## What `test-issue-1648-m2-icons-e2e.js` now asserts the configured-scope row only after the page's `theme-refresh` re-render has fired and the detail has rendered again. ## Why On 2026-10-10 this assertion failed CI on four PRs (#2169, #2171, #2154, #2164), each time at the first live-map case: `confirmed scope row must be visible, including an empty scope`. A re-run of the failed jobs passed every time. The code path: - `customize-v2.js:814` dispatches `theme-changed` once `/api/config/theme` resolves, on every page load. - `app.js:1309-1315` turns that into `theme-refresh` 300 ms later. - `live.js:4713` re-runs `showNodeDetail(activeNodeDetailKey)` on `theme-refresh`, and `showNodeDetail` first sets `#nodeDetailContent` to "Loading…" (`live.js:2598`). This is the only caller besides the marker click (`live.js:3090`). - The test waited for `#nodeDetailContent table` and then called `row.isVisible()`, which does not wait. A refresh landing between the two fails the check. The same race could let the null-scope case pass on the "Loading…" panel, because `row.count() === 0` holds there too. The fix uses the same `addInitScript` flag pattern as `test-e2e-playwright.js:83`. ## Testing - Locally against a server on the E2E fixture: 5 of 5 runs pass, 27 of 27 checks each. - **Not reproduced locally.** The unchanged test also passed every local run: 5 plain, 3 with `/api/config/theme` delayed by 1 s, 5 with 8x CPU throttling. So the reasoning above comes from the code path and the four CI failures, not from a local red-then-green. - Test-only change, no product code touched. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
4e91c5cf0b
commit
55dd28164d
@@ -86,6 +86,12 @@ async function checkConfiguredScope(page) {
|
||||
await page.route(nodeListUrl, route => route.fulfill({
|
||||
json: { nodes: [{ ...node, lat: 1, lon: 1 }], total: 1 },
|
||||
}));
|
||||
// Every page load fires one 'theme-refresh' about 300ms after the theme
|
||||
// loads, and live.js re-runs showNodeDetail on it, which briefly swaps the
|
||||
// detail panel to "Loading…". Assert only after that re-render.
|
||||
await page.addInitScript(() => {
|
||||
window.addEventListener('theme-refresh', () => { window.__scopeThemeReady = true; }, { once: true });
|
||||
});
|
||||
try {
|
||||
for (const live of [false, true]) {
|
||||
for (const scope of ['#fixture', '', null]) {
|
||||
@@ -95,7 +101,10 @@ async function checkConfiguredScope(page) {
|
||||
const route = live ? '/live?lat=1&lon=1&zoom=10' : '/nodes/' + key;
|
||||
await page.goto(`${BASE}/#${route}`, { waitUntil: 'domcontentloaded' });
|
||||
if (live) await page.locator('#liveMap .live-node-marker').click();
|
||||
await page.locator(live ? '#nodeDetailContent table' : '#node-stats').waitFor({ state: 'visible', timeout: 8000 });
|
||||
const detail = page.locator(live ? '#nodeDetailContent table' : '#node-stats');
|
||||
await detail.waitFor({ state: 'visible', timeout: 8000 });
|
||||
await page.waitForFunction(() => window.__scopeThemeReady === true, null, { timeout: 8000 });
|
||||
await detail.waitFor({ state: 'visible', timeout: 8000 });
|
||||
const row = live
|
||||
? page.locator('#nodeDetailContent tr').filter({ hasText: 'Configured scope' })
|
||||
: page.locator('#row-configured-scope');
|
||||
|
||||
Reference in New Issue
Block a user