* Grafana: Add random walk configuration options to Grafana datasource Add UI controls to configure random walk parameters (min, max, start value, spread, noise, drop percent) to match TestData datasource functionality. - Add RandomWalkEditor component with inline number inputs for all parameters - Update GrafanaQuery type to include random walk configuration fields - Update backend to parse and apply query parameters to RandomWalk function - Configuration options match TestData datasource UX for consistency * Grafana: Add series count support to random walk Add ability to generate multiple random walk series in a single query for complete parity with TestData datasource. - Add seriesCount field to RandomWalkEditor - Update backend to loop and generate multiple frames based on series count - Default to 1 series if not specified for backward compatibility * Grafana: Improve random walk editor UI with better organization and tooltips Enhance the random walk configuration UI for better usability: - Organize fields into two logical rows (core config vs fine-tuning) - Add helpful tooltips to all fields explaining their purpose - Increase label width to prevent text wrapping - Group related fields visually for better comprehension Row 1: Series count, Start value, Min, Max (basic shape and range) Row 2: Spread, Noise, Drop % (randomness and variation controls) This provides a cleaner, more intuitive experience compared to TestData's single-row layout, making it easier for users to configure random walks. * Grafana: Format RandomWalkEditor code Apply consistent formatting to RandomWalkEditor component. * Grafana: Add E2E tests for random walk configuration Add comprehensive Playwright E2E tests to verify random walk functionality: - Test that all configuration fields render correctly - Test min/max value constraints - Test multiple series generation - Test spread and noise parameters - Test drop percentage for simulating missing data - Test that tooltips are present and functional These tests ensure the random walk configuration works end-to-end from UI input to data rendering in panels. * Grafana: Fix E2E tests for random walk configuration Fix Playwright test selectors and assertions to work reliably: - Use specific element IDs to avoid selector conflicts - Remove flaky dropPercent check from rendering test (covered separately) - Simplify test assertions to focus on functional verification - All 7 tests now passing consistently Tests verify: field rendering, min/max constraints, series count, spread/noise configuration, drop percentage, and tooltips. * Grafana: Add advanced E2E tests for random walk Add two additional tests for better coverage: - Test configuration value persistence across interactions - Test that series count actually generates the expected number of series These tests verify deeper functionality beyond basic UI rendering, ensuring the random walk feature works correctly end-to-end. All 9 tests passing consistently (20.1s runtime). * Grafana: Remove redundant Min/Max tooltips Remove tooltips from Min and Max fields that just repeated the label text. These fields are self-explanatory and don't need tooltip icons. Keeps the UI cleaner while maintaining helpful tooltips on fields that actually benefit from explanation (Series count, Start value, Spread, Noise, Drop %). * Grafana: Add CODEOWNERS entry for random walk E2E tests Add codeowner assignment for the new grafana-datasource-random-walk.spec.ts test file to @grafana/grafana-frontend-platform, matching the ownership of the Grafana datasource code. * Add dashboardTemplates feature toggle and put new changes behind this toggle to limit impact * Grafana: Add unit tests for dashboardTemplates feature toggle Add unit tests to verify RandomWalkEditor renders correctly based on the dashboardTemplates feature toggle: - Test that random walk editor renders when FF is enabled - Test that random walk editor is hidden when FF is disabled These tests ensure the feature toggle works as expected and prevents the random walk configuration UI from appearing when the feature is disabled. * revert previous codeowners change as not necessary * Grafana: Remove redundant E2E test for feature flag disabled Remove E2E test for dashboardTemplates feature flag disabled scenario since it's already covered by unit tests and E2E environment can't reliably control server-side feature flags. Feature flag behavior is properly tested in QueryEditor.test.tsx unit tests. E2E tests focus on functional validation when the feature is enabled. * fix lint
221 lines
7.9 KiB
TypeScript
221 lines
7.9 KiB
TypeScript
import { test as base, expect } from '@grafana/plugin-e2e';
|
|
|
|
// Note: Random walk configuration UI requires dashboardTemplates feature toggle to be enabled
|
|
const test = base.extend({});
|
|
test.use({
|
|
featureToggles: {
|
|
dashboardTemplates: true,
|
|
},
|
|
});
|
|
|
|
test.describe(
|
|
'Grafana datasource random walk',
|
|
{
|
|
tag: ['@grafana-datasource'],
|
|
},
|
|
() => {
|
|
test('should render random walk configuration fields', async ({ gotoDashboardPage, page, selectors }) => {
|
|
// Create new dashboard
|
|
const dashboardPage = await gotoDashboardPage({});
|
|
|
|
// Add new panel
|
|
await dashboardPage.addPanel();
|
|
|
|
// Wait for the first field to be visible (ensures query editor loaded)
|
|
await expect(page.locator('#randomWalk-seriesCount-A')).toBeVisible();
|
|
|
|
// Verify core configuration fields (row 1)
|
|
await expect(page.locator('#randomWalk-startValue-A')).toBeVisible();
|
|
await expect(page.locator('#randomWalk-min-A')).toBeVisible();
|
|
await expect(page.locator('#randomWalk-max-A')).toBeVisible();
|
|
|
|
// Verify fine-tuning fields (row 2)
|
|
await expect(page.locator('#randomWalk-spread-A')).toBeVisible();
|
|
await expect(page.locator('#randomWalk-noise-A')).toBeVisible();
|
|
|
|
// Drop percentage is tested separately in its own test
|
|
});
|
|
|
|
test('should configure min and max values and render constrained data', async ({
|
|
gotoDashboardPage,
|
|
page,
|
|
selectors,
|
|
}) => {
|
|
// Create new dashboard
|
|
const dashboardPage = await gotoDashboardPage({});
|
|
|
|
// Add new panel
|
|
await dashboardPage.addPanel();
|
|
|
|
// Configure random walk with min/max constraints using specific IDs
|
|
const minInput = page.locator('#randomWalk-min-A');
|
|
const maxInput = page.locator('#randomWalk-max-A');
|
|
|
|
await minInput.fill('10');
|
|
await maxInput.fill('50');
|
|
|
|
// Wait for the query to execute
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Verify graph renders with a series
|
|
await expect(
|
|
dashboardPage.getByGrafanaSelector(selectors.components.VizLegend.seriesName('A-series'))
|
|
).toBeVisible();
|
|
});
|
|
|
|
test('should generate multiple series when series count is configured', async ({
|
|
gotoDashboardPage,
|
|
page,
|
|
selectors,
|
|
}) => {
|
|
// Create new dashboard
|
|
const dashboardPage = await gotoDashboardPage({});
|
|
|
|
// Add new panel
|
|
await dashboardPage.addPanel();
|
|
|
|
// Configure series count to 3 using role selector
|
|
const seriesCountInput = page.getByRole('spinbutton', { name: 'Series count' });
|
|
await seriesCountInput.fill('3');
|
|
|
|
// Wait for query to execute and check that we have series in the legend
|
|
await expect(
|
|
dashboardPage.getByGrafanaSelector(selectors.components.VizLegend.seriesName('A-series'))
|
|
).toBeVisible();
|
|
|
|
// Verify the input value is set correctly
|
|
await expect(seriesCountInput).toHaveValue('3');
|
|
});
|
|
|
|
test('should configure spread and noise parameters', async ({ gotoDashboardPage, page, selectors }) => {
|
|
// Create new dashboard
|
|
const dashboardPage = await gotoDashboardPage({});
|
|
|
|
// Add new panel
|
|
await dashboardPage.addPanel();
|
|
|
|
// Configure spread and noise using role selectors
|
|
const spreadInput = page.getByRole('spinbutton', { name: 'Spread' });
|
|
const noiseInput = page.getByRole('spinbutton', { name: 'Noise' });
|
|
const startValueInput = page.getByRole('spinbutton', { name: 'Start value' });
|
|
|
|
await startValueInput.fill('100');
|
|
await spreadInput.fill('5');
|
|
await noiseInput.fill('2');
|
|
|
|
// Verify graph renders
|
|
await expect(
|
|
dashboardPage.getByGrafanaSelector(selectors.components.VizLegend.seriesName('A-series'))
|
|
).toBeVisible();
|
|
});
|
|
|
|
test('should configure drop percentage for missing data', async ({ gotoDashboardPage, page, selectors }) => {
|
|
// Create new dashboard
|
|
const dashboardPage = await gotoDashboardPage({});
|
|
|
|
// Add new panel
|
|
await dashboardPage.addPanel();
|
|
|
|
// Configure drop percentage using role selector
|
|
const dropInput = page.getByRole('spinbutton', { name: 'Drop (%)' });
|
|
await dropInput.fill('20');
|
|
|
|
// Verify graph still renders even with dropped points
|
|
await expect(
|
|
dashboardPage.getByGrafanaSelector(selectors.components.VizLegend.seriesName('A-series'))
|
|
).toBeVisible();
|
|
});
|
|
|
|
test('should show tooltips on configuration fields', async ({ gotoDashboardPage, page }) => {
|
|
// Create new dashboard
|
|
const dashboardPage = await gotoDashboardPage({});
|
|
|
|
// Add new panel
|
|
await dashboardPage.addPanel();
|
|
|
|
// Verify the Spread field has a tooltip by hovering near its label
|
|
const spreadInput = page.locator('#randomWalk-spread-A');
|
|
await expect(spreadInput).toBeVisible();
|
|
|
|
// The tooltip is part of the InlineField component
|
|
// Just verify we can interact with the field (tooltip rendering is handled by the component)
|
|
await spreadInput.hover();
|
|
|
|
// Verify the field is configured correctly with tooltip text in the DOM
|
|
const spreadLabel = page.getByText('Spread').first();
|
|
await expect(spreadLabel).toBeVisible();
|
|
});
|
|
|
|
test('should maintain configuration values when switching between queries', async ({
|
|
gotoDashboardPage,
|
|
page,
|
|
selectors,
|
|
}) => {
|
|
// Create new dashboard
|
|
const dashboardPage = await gotoDashboardPage({});
|
|
|
|
// Add new panel
|
|
await dashboardPage.addPanel();
|
|
|
|
// Configure multiple random walk parameters
|
|
await page.locator('#randomWalk-seriesCount-A').fill('2');
|
|
await page.locator('#randomWalk-startValue-A').fill('75');
|
|
await page.locator('#randomWalk-min-A').fill('20');
|
|
await page.locator('#randomWalk-max-A').fill('90');
|
|
await page.locator('#randomWalk-spread-A').fill('3');
|
|
await page.locator('#randomWalk-noise-A').fill('1.5');
|
|
|
|
// Wait for query to execute
|
|
await page.waitForTimeout(500);
|
|
|
|
// Verify all values are set correctly
|
|
await expect(page.locator('#randomWalk-seriesCount-A')).toHaveValue('2');
|
|
await expect(page.locator('#randomWalk-startValue-A')).toHaveValue('75');
|
|
await expect(page.locator('#randomWalk-min-A')).toHaveValue('20');
|
|
await expect(page.locator('#randomWalk-max-A')).toHaveValue('90');
|
|
await expect(page.locator('#randomWalk-spread-A')).toHaveValue('3');
|
|
await expect(page.locator('#randomWalk-noise-A')).toHaveValue('1.5');
|
|
|
|
// Verify graph renders with the configured data
|
|
await expect(
|
|
dashboardPage.getByGrafanaSelector(selectors.components.VizLegend.seriesName('A-series'))
|
|
).toBeVisible();
|
|
});
|
|
|
|
test('should verify series count actually generates multiple series', async ({
|
|
gotoDashboardPage,
|
|
page,
|
|
selectors,
|
|
}) => {
|
|
// Create new dashboard
|
|
const dashboardPage = await gotoDashboardPage({});
|
|
|
|
// Add new panel
|
|
await dashboardPage.addPanel();
|
|
|
|
// Set series count to 1 first and verify
|
|
await page.locator('#randomWalk-seriesCount-A').fill('1');
|
|
await page.waitForTimeout(500);
|
|
|
|
// Check legend - with 1 series we should see only A-series
|
|
await expect(
|
|
dashboardPage.getByGrafanaSelector(selectors.components.VizLegend.seriesName('A-series'))
|
|
).toBeVisible();
|
|
|
|
// Now set series count to 3
|
|
await page.locator('#randomWalk-seriesCount-A').fill('3');
|
|
await page.waitForTimeout(1000);
|
|
|
|
// With multiple series, they should all render
|
|
// The backend generates multiple frames which should show in the panel
|
|
// We can verify by checking the panel has data (legend shows A-series)
|
|
await expect(
|
|
dashboardPage.getByGrafanaSelector(selectors.components.VizLegend.seriesName('A-series'))
|
|
).toBeVisible();
|
|
|
|
// Verify the configuration is set
|
|
await expect(page.locator('#randomWalk-seriesCount-A')).toHaveValue('3');
|
|
});
|
|
}
|
|
);
|