grafana/e2e-playwright/various-suite/exemplars.spec.ts

151 lines
5.4 KiB
TypeScript

import { Page } from '@playwright/test';
import { test, expect } from '@grafana/plugin-e2e';
test.describe(
'Exemplars',
{
tag: ['@various'],
},
() => {
const dataSourceName = 'PromExemplar';
async function addDataSource(page, selectors, createDataSourceConfigPage) {
// Navigate to add data source page
await createDataSourceConfigPage({ type: 'prometheus', name: dataSourceName });
// Add exemplars configuration
const exemplarsAddButton = page.getByTestId(
selectors.components.DataSource.Prometheus.configPage.exemplarsAddButton
);
await exemplarsAddButton.click();
const internalLinkSwitch = page.getByTestId(
selectors.components.DataSource.Prometheus.configPage.internalLinkSwitch
);
await internalLinkSwitch.check({ force: true });
const connectionSettings = page.getByLabel(
selectors.components.DataSource.Prometheus.configPage.connectionSettings
);
await connectionSettings.click();
await page.keyboard.type('http://prom-url:9090');
const dataSourcePicker = page.getByTestId(selectors.components.DataSourcePicker.container);
await dataSourcePicker.click();
const tempoOption = page.getByText('gdev-tempo');
await tempoOption.scrollIntoViewIfNeeded();
await expect(tempoOption).toBeVisible();
await tempoOption.click();
// Save the data source
const saveAndTestButton = page.getByTestId(selectors.pages.DataSource.saveAndTest);
await saveAndTestButton.click();
}
test.beforeEach(async ({ page, selectors, createDataSourceConfigPage }) => {
await addDataSource(page, selectors, createDataSourceConfigPage);
await page.goto('/');
});
test('should be able to navigate to configured data source', async ({ page, selectors }) => {
// Mock API responses
await page.route(/api\/ds\/query/, async (route) => {
const postData = route.request().postDataJSON();
const datasourceType = postData.queries[0].datasource.type;
if (datasourceType === 'prometheus') {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(require('../fixtures/exemplars-query-response.json')),
});
} else if (datasourceType === 'tempo') {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(require('../fixtures/tempo-response.json')),
});
} else {
await route.fulfill({ status: 200, body: '{}' });
}
});
// Navigate to explore
await page.goto('/explore');
// Select data source
const dataSourcePicker = page.getByTestId(selectors.components.DataSourcePicker.container);
await expect(dataSourcePicker).toBeVisible();
await dataSourcePicker.click();
const dataSourceOption = page.getByText(dataSourceName);
await dataSourceOption.scrollIntoViewIfNeeded();
await expect(dataSourceOption).toBeVisible();
await dataSourceOption.click();
// Switch to code editor
const codeRadioButton = page.getByTestId(selectors.components.RadioButton.container).filter({ hasText: 'Code' });
await codeRadioButton.click();
// Wait for lazy loading Monaco
await waitForMonacoToLoad(page);
// Set time range
const timePickerButton = page.getByTestId(selectors.components.TimePicker.openButton);
await timePickerButton.click();
const fromField = page.getByTestId(selectors.components.TimePicker.fromField);
await fromField.clear();
await fromField.fill('2021-07-10 17:10:00');
const toField = page.getByTestId(selectors.components.TimePicker.toField);
await toField.clear();
await toField.fill('2021-07-10 17:30:00');
const applyTimeRangeButton = page.getByTestId(selectors.components.TimePicker.applyTimeRange);
await applyTimeRangeButton.click();
// Type query
const queryField = page.getByTestId(selectors.components.QueryField.container);
await expect(queryField).toBeVisible();
await queryField.click();
await page.keyboard.type('exemplar-query_bucket');
await page.keyboard.press('Shift+Enter');
await page.waitForTimeout(1000);
// Click zoom to data
const zoomToDataButton = page.getByTestId('time-series-zoom-to-data');
await zoomToDataButton.click();
// Hover over exemplar marker and click
const exemplarMarker = page.getByTestId(selectors.components.DataSource.Prometheus.exemplarMarker).first();
await exemplarMarker.hover();
const queryWithTempoLink = page.getByText('Query with gdev-tempo');
await queryWithTempoLink.click();
// Verify trace viewer has span bars
const spanBars = page.getByTestId(selectors.components.TraceViewer.spanBar);
await expect(spanBars).toHaveCount(11);
});
}
);
export async function waitForMonacoToLoad(page: Page) {
// Wait for spinner to disappear
const spinner = page.getByTestId('Spinner');
await expect(spinner).toBeHidden();
// Wait for Monaco to be available in window
await page.waitForFunction(() => {
return window.monaco !== undefined;
});
// Wait for Monaco editor textarea to exist
const monacoTextarea = page.locator('.monaco-editor').first();
await expect(monacoTextarea).toBeVisible();
}