From 7000a1f77f5e65aba8ce14aa3dfc1038f9f21cfb Mon Sep 17 00:00:00 2001 From: Gandalf the Greybeard Date: Tue, 17 Mar 2026 23:02:33 +0000 Subject: [PATCH] fix(e2e): use correct HOME-context URL for plugin settings page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The settings page is at /settings/plugins (HOME sidebar context), not /c/main/settings/plugins (in-cluster context). The in-cluster URL doesn't match any route, so PluginSettings never mounted and the plugin entry was never visible. With the correct URL, no preloading or client-side routing hacks are needed — PluginSettings uses useTypedSelector on the Redux plugin store, so it re-renders automatically when registerPluginSettings() fires. Co-Authored-By: Paperclip --- e2e/settings.spec.ts | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/e2e/settings.spec.ts b/e2e/settings.spec.ts index 6840aad..333a0b4 100644 --- a/e2e/settings.spec.ts +++ b/e2e/settings.spec.ts @@ -2,31 +2,17 @@ import { test, expect, Page } from '@playwright/test'; /** Navigate to the Polaris plugin settings page and wait for settings to render. */ async function goToPolarisSettings(page: Page) { - // Load the main page first so all plugin scripts execute and call - // registerPluginSettings(). Headlamp loads plugins asynchronously — the - // PluginSettings component reads the plugin registry once on mount and - // never re-renders when new plugins register. A full page.goto() to the - // settings URL would re-initialize the SPA, causing PluginSettings to - // mount before plugin scripts finish executing. - await page.goto('/'); - const sidebar = page.getByRole('navigation', { name: 'Navigation' }); - await expect(sidebar).toBeVisible({ timeout: 15_000 }); - await expect(sidebar.getByRole('button', { name: 'Polaris' })).toBeVisible({ - timeout: 15_000, - }); + // Headlamp's plugin settings page is a HOME-context route at /settings/plugins, + // not an in-cluster route (/c/main/settings/plugins would 404). Headlamp loads + // plugin scripts asynchronously on SPA init. When registerPluginSettings() fires, + // it dispatches a Redux action — PluginSettings uses useTypedSelector so it + // re-renders automatically once the plugin registers. No preloading needed. + await page.goto('/settings/plugins'); - // Navigate to plugin settings via client-side routing (pushState + popstate) - // instead of page.goto(). This preserves the already-loaded plugin scripts - // and their registerPluginSettings() registrations. React Router's history - // listener picks up the popstate event and re-renders with the new route. - await page.evaluate(() => { - window.history.pushState({}, '', '/c/main/settings/plugins'); - window.dispatchEvent(new PopStateEvent('popstate', { state: {} })); - }); - - // Find and click the Polaris plugin entry to open its settings + // Wait for the plugin to appear in the settings list. The timeout covers + // async plugin script loading + registration. const pluginEntry = page.locator('text=headlamp-polaris').first(); - await expect(pluginEntry).toBeVisible({ timeout: 15_000 }); + await expect(pluginEntry).toBeVisible({ timeout: 30_000 }); await pluginEntry.click(); // Wait for the PolarisSettings component to render