CSS selector utilities for creating robust element selectors for Grafana's UI components, providing consistent and reliable element targeting across different Grafana versions.
Static utility methods for generating CSS selectors optimized for Grafana's UI structure.
interface Selector {
/** Create aria-label based selector */
fromAriaLabel(selector: string): string;
/** Create data-testid based selector */
fromDataTestId(selector: string): string;
/** Pass-through for custom selectors */
fromSelector(selector: string): string;
}Create selectors based on ARIA labels for accessibility-first element targeting.
/**
* Create selector targeting elements with specific aria-label
* @param selector - Aria-label value to target
* @returns CSS selector string
*/
function fromAriaLabel(selector: string): string;Usage Examples:
import { e2e } from "@grafana/e2e";
// Target button by aria-label
const saveButton = e2e.components.Selector.fromAriaLabel("Save dashboard");
// Target navigation elements
const dashboardNav = e2e.components.Selector.fromAriaLabel("Dashboard navigation");
// Use in Cypress commands
cy.get(e2e.components.Selector.fromAriaLabel("Add panel")).click();Create selectors based on data-testid attributes for reliable test automation.
/**
* Create selector targeting elements with specific data-testid
* @param selector - Data-testid value to target
* @returns CSS selector string
*/
function fromDataTestId(selector: string): string;Usage Examples:
import { e2e } from "@grafana/e2e";
// Target specific test elements
const panelMenu = e2e.components.Selector.fromDataTestId("panel-menu");
// Target form inputs
const dashboardTitle = e2e.components.Selector.fromDataTestId("dashboard-title-input");
// Use in test assertions
cy.get(e2e.components.Selector.fromDataTestId("success-alert"))
.should("be.visible");Pass-through method for using custom CSS selectors when needed.
/**
* Pass-through for custom CSS selectors
* @param selector - Custom CSS selector string
* @returns CSS selector string (unchanged)
*/
function fromSelector(selector: string): string;Usage Examples:
import { e2e } from "@grafana/e2e";
// Use custom CSS selectors
const customElement = e2e.components.Selector.fromSelector(".custom-class > .nested");
// Complex selectors
const specificPanel = e2e.components.Selector.fromSelector(
"[data-panel-id='1'] .panel-title"
);
// Combine with Cypress
cy.get(e2e.components.Selector.fromSelector(".grafana-app")).should("exist");The selector utilities integrate with the e2e selector factory system:
/**
* Generate typed selector functions from selector definitions
* @param selectors - Selector definitions object
* @returns Typed selector factory with chainable functions
*/
function getSelectors<T>(selectors: E2ESelectors<T>): E2ESelectors<T>;
interface E2ESelectors<T> {
[key: string]: string | E2ESelectors<any>;
}Usage Examples:
import { e2e } from "@grafana/e2e";
// Create custom selector factory
const customSelectors = e2e.getSelectors({
myPanel: {
title: '[data-testid="panel-title"]',
menu: '[aria-label="Panel menu"]',
content: '.panel-content'
}
});
// Use generated selectors
cy.get(customSelectors.myPanel.title()).should("contain", "My Panel");
cy.get(customSelectors.myPanel.menu()).click();The e2e object provides pre-built selector categories:
/** Page-level selectors for navigation and routing */
const pages: E2ESelectors;
// Examples:
// e2e.pages.Dashboard.url()
// e2e.pages.DataSources.url()
// e2e.pages.Explore.url()/** Component-level selectors for UI elements */
const components: E2ESelectors;
// Examples:
// e2e.components.Panels.Panel.title()
// e2e.components.DataSource.TestData.QueryTab.scenarioSelect()
// e2e.components.Drawer.General.title()// Preferred: Use data-testid when available
const element1 = e2e.components.Selector.fromDataTestId("save-button");
// Good: Use aria-label for accessible elements
const element2 = e2e.components.Selector.fromAriaLabel("Close dialog");
// Last resort: Custom selectors for unique cases
const element3 = e2e.components.Selector.fromSelector(".unique-grafana-class");// Combine different selector types for specificity
cy.get(e2e.components.Selector.fromDataTestId("panel-container"))
.find(e2e.components.Selector.fromAriaLabel("Edit panel"))
.click();
// Use within specific contexts
cy.get(e2e.pages.Dashboard.url())
.find(e2e.components.Selector.fromDataTestId("add-panel-button"))
.should("be.visible");Selector utilities maintain TypeScript type safety:
// Type-safe selector generation
interface CustomSelectors {
button: string;
input: string;
}
const typedSelectors = e2e.getSelectors<CustomSelectors>({
button: '[data-testid="custom-button"]',
input: '[data-testid="custom-input"]'
});
// TypeScript knows available methods
typedSelectors.button(); // ✓ Valid
typedSelectors.invalidMethod(); // ✗ TypeScript error