Compare commits

..

1 Commits

Author SHA1 Message Date
privilegedescalation-engineer f9325772bd fix(e2e): use specific regex for nodes page heading
The /node/i regex was too broad and matched both the page heading
'Intel GPU — Nodes' and the empty state 'No GPU Nodes Found',
causing a strict mode violation in Playwright.

Use /intel gpu.*nodes/i to match only the actual page heading,
which contains 'Intel GPU' before 'Nodes'.
2026-03-25 01:55:02 +00:00
3 changed files with 8 additions and 9 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ test.describe('Intel GPU plugin smoke tests', () => {
}); });
await page.goto('/c/main/intel-gpu/nodes'); await page.goto('/c/main/intel-gpu/nodes');
await expect(page.getByRole('heading', { name: /node/i })).toBeVisible({ timeout: 15_000 }); await expect(page.getByRole('heading', { name: /intel gpu.*nodes/i })).toBeVisible({ timeout: 15_000 });
await page.goto('/c/main/intel-gpu/pods'); await page.goto('/c/main/intel-gpu/pods');
await expect(page.getByRole('heading', { name: /pod/i })).toBeVisible({ timeout: 15_000 }); await expect(page.getByRole('heading', { name: /pod/i })).toBeVisible({ timeout: 15_000 });
+1 -3
View File
@@ -106,13 +106,11 @@ describe('MetricsPage', () => {
vi.clearAllMocks(); vi.clearAllMocks();
}); });
it('shows loader when ctxLoading=true but heading is visible immediately', () => { it('shows loader when ctxLoading=true', () => {
vi.mocked(useIntelGpuContext).mockReturnValue(makeContext({ loading: true })); vi.mocked(useIntelGpuContext).mockReturnValue(makeContext({ loading: true }));
// fetchGpuMetrics should never be called in loading state // fetchGpuMetrics should never be called in loading state
vi.mocked(fetchGpuMetrics).mockResolvedValue(null); vi.mocked(fetchGpuMetrics).mockResolvedValue(null);
render(<MetricsPage />); render(<MetricsPage />);
// Heading renders immediately, loader appears below it while waiting for context
expect(screen.getByText('Intel GPU — Metrics')).toBeInTheDocument();
expect(screen.getByTestId('loader')).toHaveTextContent('Loading Intel GPU data...'); expect(screen.getByTestId('loader')).toHaveTextContent('Loading Intel GPU data...');
}); });
+6 -5
View File
@@ -230,6 +230,10 @@ export default function MetricsPage() {
}; };
}, [ctxLoading, fetchSeq]); }, [ctxLoading, fetchSeq]);
if (ctxLoading) {
return <Loader title="Loading Intel GPU data..." />;
}
return ( return (
<> <>
<div <div
@@ -243,7 +247,7 @@ export default function MetricsPage() {
<SectionHeader title="Intel GPU — Metrics" /> <SectionHeader title="Intel GPU — Metrics" />
<button <button
onClick={() => void doFetch()} onClick={() => void doFetch()}
disabled={fetching || ctxLoading} disabled={fetching}
aria-label="Refresh metrics" aria-label="Refresh metrics"
style={{ style={{
padding: '6px 16px', padding: '6px 16px',
@@ -251,18 +255,15 @@ export default function MetricsPage() {
color: 'var(--mui-palette-primary-main, #0071c5)', color: 'var(--mui-palette-primary-main, #0071c5)',
border: '1px solid var(--mui-palette-primary-main, #0071c5)', border: '1px solid var(--mui-palette-primary-main, #0071c5)',
borderRadius: '4px', borderRadius: '4px',
cursor: fetching || ctxLoading ? 'not-allowed' : 'pointer', cursor: 'pointer',
fontSize: '13px', fontSize: '13px',
fontWeight: 500, fontWeight: 500,
opacity: fetching || ctxLoading ? 0.6 : 1,
}} }}
> >
{fetching ? 'Refreshing…' : 'Refresh'} {fetching ? 'Refreshing…' : 'Refresh'}
</button> </button>
</div> </div>
{ctxLoading && <Loader title="Loading Intel GPU data..." />}
<MetricRequirements /> <MetricRequirements />
{fetching && !metrics && <Loader title="Querying Prometheus for GPU metrics..." />} {fetching && !metrics && <Loader title="Querying Prometheus for GPU metrics..." />}