Files
grafana/e2e-playwright/dashboard-cujs/dashboard-navigation.spec.ts
Tobias Skarhed d1064da4cd Scopes: Add RTK Query API client for caching (#115494)
* Scopes API client

* Initial RTK query commit

* Copy API client from generated enterprise folder

* Mock ScopesApiClient for integration tests

* Update e2e tests

* Handle group expansion for dashboard navigation

* Extract integration test mocks

* Move mock to only be for integration tests

* Update path for enterprise sync script

* Re-export mockData

* Disregard caching for search

* Leave name parameters empty

* Disable subscriptions for client requests

* Add functionality to reset cache between mocked requests

* Use grafana-test-utils for scopes integration tests

* Rollback mock setup

* Remove store form window object

* Remove cache helper

* Restore scopenode search functionality

* Improve request erro handling

* Clean up subscription in case subscription: false lies

* Fix logging security risk

* Rewrite tests to cover RTK query usage and improve error catching

* Update USE_LIVE_DATA to be consistent

* Remove unused timout parameter

* Fix error handling

* Make dashboard-navigation test pass
2026-01-13 13:09:08 +01:00

182 lines
6.6 KiB
TypeScript

import { test, expect } from '@grafana/plugin-e2e';
import { setScopes, setupScopeRoutes } from '../utils/scope-helpers';
import { testScopes } from '../utils/scopes';
import {
clickFirstScopesDashboard,
getAdHocFilterPills,
getGroupByInput,
getGroupByValues,
getMarkdownHTMLContent,
getScopesDashboards,
getScopesDashboardsSearchInput,
getScopesSelectorInput,
} from './cuj-selectors';
import { checkDashboardReloadBehavior, getConfigDashboards, trackDashboardReloadRequests } from './utils';
test.use({
featureToggles: {
scopeFilters: true,
groupByVariable: true,
reloadDashboardsOnParamsChange: true,
},
});
const USE_LIVE_DATA = Boolean(process.env.API_CONFIG_PATH);
const DASHBOARD_UNDER_TEST = 'cuj-dashboard-1';
const DASHBOARD_UNDER_TEST_2 = 'cuj-dashboard-2';
const NAVIGATE_TO = 'cuj-dashboard-3';
test.describe(
'Dashboard navigation CUJs',
{
tag: ['@dashboard-cujs'],
},
() => {
test('Navigate between dashboards', async ({ page, gotoDashboardPage, selectors }) => {
const scopeSelectorInput = getScopesSelectorInput(page);
const scopesDashboards = getScopesDashboards(page);
const scopesDashboardsSearchInput = getScopesDashboardsSearchInput(page);
const adhocFilterPills = getAdHocFilterPills(page);
const groupByValues = getGroupByValues(page);
// Set up routes before any navigation (only for mocked mode)
if (!USE_LIVE_DATA) {
await setupScopeRoutes(page, testScopes());
}
await test.step('1.Search dashboard', async () => {
await gotoDashboardPage({ uid: DASHBOARD_UNDER_TEST });
await setScopes(page);
await expect(scopeSelectorInput).toHaveAttribute('data-value', /.+/);
const firstDbName = await scopesDashboards.first().textContent();
const scopeDashboardsCount = await scopesDashboards.count();
expect(scopeDashboardsCount).toBeGreaterThan(0);
await scopesDashboardsSearchInput.fill(firstDbName!.trim().slice(0, 5));
await expect(scopesDashboards).not.toHaveCount(scopeDashboardsCount);
});
await test.step('2.Time selection persisting', async () => {
const dashboardPage = await gotoDashboardPage({ uid: DASHBOARD_UNDER_TEST });
await setScopes(page);
await expect(scopeSelectorInput).toHaveAttribute('data-value', /.+/);
// assert the panel is visible and has the correct value
const markdownContent = await getMarkdownHTMLContent(dashboardPage, selectors);
await expect(markdownContent).toContainText(`now-6h`);
const timePickerButton = page.getByTestId(selectors.components.TimePicker.openButton);
await timePickerButton.click();
const label = page.getByText('Last 12 hours');
await label.click();
await expect(markdownContent).toContainText(`now-12h`);
await clickFirstScopesDashboard(page);
await page.waitForURL('**/d/**');
await expect(markdownContent).toBeVisible();
await expect(markdownContent).toContainText(`now-12h`);
});
const dashboards = await getConfigDashboards();
if (dashboards.length === 0) {
dashboards.push(DASHBOARD_UNDER_TEST_2);
}
for (const db of dashboards) {
await test.step(
'3.See filter/groupby selection persisting when navigating from dashboard to dashboard - ' + db,
async () => {
const dashboardPage = await gotoDashboardPage({ uid: db });
await setScopes(page, { title: 'CUJ Dashboard 3', uid: NAVIGATE_TO });
await expect(scopeSelectorInput).toHaveAttribute('data-value', /.+/);
const pills = await adhocFilterPills.allTextContents();
const processedPills = pills
.map((p) => {
const parts = p.split(' ');
return `${parts[0]}${parts[1]}"${parts[2]}"`;
})
.join(',');
// assert the panel is visible and has the correct value
const markdownContent = await getMarkdownHTMLContent(dashboardPage, selectors);
// no groupBy value
await expect(markdownContent).toContainText(`GroupByVar: \n\nAdHocVar: ${processedPills}`);
const groupByVariable = getGroupByInput(dashboardPage, selectors);
// add a custom groupBy value
await groupByVariable.click();
await groupByVariable.fill('dev');
await groupByVariable.press('Enter');
await groupByVariable.press('Escape');
const { getRequests, waitForExpectedRequests } = await trackDashboardReloadRequests(page);
await clickFirstScopesDashboard(page);
await page.waitForURL('**/d/**');
await waitForExpectedRequests();
await page.waitForLoadState('networkidle');
const requests = getRequests();
expect(checkDashboardReloadBehavior(requests)).toBe(true);
//all values are set after dashboard switch
await expect(markdownContent).toContainText(`GroupByVar: dev\n\nAdHocVar: ${processedPills}`);
}
);
}
await test.step('4.Unmodified default filters and groupBy keys are not propagated to a different dashboard', async () => {
const dashboardPage = await gotoDashboardPage({ uid: DASHBOARD_UNDER_TEST });
await setScopes(page, { title: 'CUJ Dashboard 2', uid: 'cuj-dashboard-2' });
await expect(scopeSelectorInput).toHaveAttribute('data-value', /.+/);
const pillCount = await adhocFilterPills.count();
const pillTexts = await adhocFilterPills.allTextContents();
const processedPills = pillTexts
.map((p) => {
const parts = p.split(' ');
return `${parts[0]}${parts[1]}"${parts[2]}"`;
})
.join(',');
const groupByCount = await groupByValues.count();
const selectedValues = (await groupByValues.allTextContents()).join(', ');
// assert the panel is visible and has the correct value
const markdownContent = await getMarkdownHTMLContent(dashboardPage, selectors);
const oldFilters = `GroupByVar: ${selectedValues}\n\nAdHocVar: ${processedPills}`;
await expect(markdownContent).toContainText(oldFilters);
await clickFirstScopesDashboard(page);
await page.waitForURL('**/d/**');
const newPillCount = await adhocFilterPills.count();
const newGroupByCount = await groupByValues.count();
expect(newPillCount).not.toEqual(pillCount);
expect(newGroupByCount).not.toEqual(groupByCount);
expect(newGroupByCount).toBe(0);
});
});
}
);