mirror of https://github.com/grafana/grafana.git
113 lines
4.7 KiB
TypeScript
113 lines
4.7 KiB
TypeScript
import { test, expect } from '@grafana/plugin-e2e';
|
|
|
|
const MISSING_LABEL_FILTER_ERROR_MESSAGE = 'Select at least 1 label filter (label and value)';
|
|
const dataSourceName = 'LokiBuilder';
|
|
const finalQuery = 'rate({instance=~"instance1|instance2"} | logfmt | __error__=`` [$__auto]';
|
|
|
|
test.describe(
|
|
'Loki query builder',
|
|
{
|
|
tag: ['@various'],
|
|
},
|
|
() => {
|
|
test('should be able to use all modes', async ({ createDataSource, page, dashboardPage, selectors }) => {
|
|
await createDataSource({ type: 'loki', name: dataSourceName });
|
|
// Mock API responses
|
|
await page.route(/labels\?/, async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ status: 'success', data: ['instance', 'job', 'source'] }),
|
|
});
|
|
});
|
|
|
|
await page.route(/series?/, async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ status: 'success', data: [{ instance: 'instance1' }] }),
|
|
});
|
|
});
|
|
|
|
await page.route(/values/, async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ status: 'success', data: ['instance1', 'instance2'] }),
|
|
});
|
|
});
|
|
|
|
await page.route(/index\/stats/, async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ streams: 2, chunks: 2660, bytes: 2721792, entries: 14408 }),
|
|
});
|
|
});
|
|
|
|
// Go to Explore and choose Loki data source
|
|
await page.goto('/explore');
|
|
await dashboardPage.getByGrafanaSelector(selectors.components.DataSourcePicker.container).click();
|
|
await page.getByRole('button', { name: dataSourceName }).click();
|
|
|
|
// Start in builder mode, click and choose query pattern
|
|
await page.getByTestId(selectors.components.QueryBuilder.queryPatterns).click();
|
|
await page.getByRole('button', { name: 'Log query starters' }).click();
|
|
await page.getByRole('button', { name: 'Use this query' }).first().click();
|
|
await expect(page.getByText('No pipeline errors')).toBeVisible();
|
|
await expect(page.getByText('{} | logfmt | __error__=``')).toBeVisible();
|
|
|
|
// Add operation
|
|
await page.getByRole('button', { name: 'Operations', exact: true }).click();
|
|
await page.getByText('Range functions').click();
|
|
await page.getByText('Rate', { exact: true }).click();
|
|
await expect(page.getByText('rate({} | logfmt | __error__=`` [$__auto]')).toBeVisible();
|
|
|
|
// Check for expected error
|
|
await expect(page.getByText(MISSING_LABEL_FILTER_ERROR_MESSAGE)).toBeVisible();
|
|
|
|
// Add labels to remove error
|
|
await dashboardPage.getByGrafanaSelector(selectors.components.QueryBuilder.labelSelect).click();
|
|
await dashboardPage.getByGrafanaSelector(selectors.components.QueryBuilder.inputSelect).fill('instance');
|
|
await page.keyboard.press('Enter');
|
|
|
|
const matchOperatorSelect = dashboardPage.getByGrafanaSelector(
|
|
selectors.components.QueryBuilder.matchOperatorSelect
|
|
);
|
|
await expect(matchOperatorSelect).toBeVisible();
|
|
await matchOperatorSelect.click({ force: true });
|
|
|
|
const matchOperatorInput = matchOperatorSelect.locator('div').locator('input');
|
|
await matchOperatorInput.fill('=~');
|
|
await page.keyboard.press('Enter');
|
|
|
|
const valueSelect = dashboardPage.getByGrafanaSelector(selectors.components.QueryBuilder.valueSelect);
|
|
await expect(valueSelect).toBeVisible();
|
|
await valueSelect.click();
|
|
|
|
const valueInput = valueSelect.locator('div').locator('input');
|
|
await valueInput.fill('instance1');
|
|
await page.keyboard.press('Enter');
|
|
await valueInput.fill('instance2');
|
|
await page.keyboard.press('Enter');
|
|
|
|
await expect(page.getByText(MISSING_LABEL_FILTER_ERROR_MESSAGE)).toBeHidden();
|
|
await expect(page.getByText(finalQuery)).toBeVisible();
|
|
|
|
// Change to code editor
|
|
await page.getByRole('radio', { name: 'Code' }).click();
|
|
|
|
// We need to test this manually because the final query is split into separate DOM elements
|
|
await expect(page.getByText('rate')).toBeVisible();
|
|
await expect(page.getByText('instance1|instance2')).toBeVisible();
|
|
await expect(page.getByText('logfmt')).toBeVisible();
|
|
await expect(page.getByText('__error__')).toBeVisible();
|
|
await expect(page.getByText('$__auto')).toBeVisible();
|
|
|
|
// Checks the explain mode toggle
|
|
await page.getByText('Explain').click();
|
|
await expect(page.getByText('Fetch all log lines matching label filters.')).toBeVisible();
|
|
});
|
|
}
|
|
);
|