or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

benchmark.mdflows.mdindex.mdscenarios.mdselectors.md
tile.json

selectors.mddocs/

Selector Utilities

CSS selector utilities for creating robust element selectors for Grafana's UI components, providing consistent and reliable element targeting across different Grafana versions.

Capabilities

Selector Object

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;
}

Aria-Label Selectors

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();

Data-TestId Selectors

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");

Custom Selectors

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");

Selector Factory Integration

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();

Built-in Selector Categories

The e2e object provides pre-built selector categories:

Pages Selectors

/** Page-level selectors for navigation and routing */
const pages: E2ESelectors;

// Examples:
// e2e.pages.Dashboard.url()
// e2e.pages.DataSources.url()
// e2e.pages.Explore.url()

Components Selectors

/** 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()

Selector Best Practices

Reliability Hierarchy

  1. data-testid: Most reliable for automation (highest priority)
  2. aria-label: Good for accessibility and stability
  3. CSS classes: Use sparingly, may change between versions
  4. Text content: Avoid for internationalization compatibility

Usage Patterns

// 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");

Combining Selectors

// 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");

Type Safety

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