mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki: Add e2e test for query builder (#51314)
* Loki: Add e2e test for query builder * Update * Update test * Update test * Update test * Update test * Add more checks in test * Update betterer * Update betterer
This commit is contained in:
parent
ed56755dd7
commit
60454192b7
@ -10406,20 +10406,20 @@ exports[`better eslint`] = {
|
||||
[163, 25, 27, "Do not use any type assertions.", "3051431932"],
|
||||
[163, 49, 3, "Unexpected any. Specify a different type.", "193409811"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilterItem.tsx:3990888924": [
|
||||
[65, 23, 155, "Do not use any type assertions.", "2419762696"],
|
||||
[65, 23, 128, "Do not use any type assertions.", "1950878359"],
|
||||
[69, 19, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[80, 23, 63, "Do not use any type assertions.", "168255657"],
|
||||
[80, 23, 36, "Do not use any type assertions.", "381764118"],
|
||||
[80, 56, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[108, 23, 92, "Do not use any type assertions.", "511072900"],
|
||||
[108, 23, 65, "Do not use any type assertions.", "791801755"],
|
||||
[108, 85, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[111, 30, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[115, 23, 87, "Do not use any type assertions.", "1044305842"],
|
||||
[115, 23, 60, "Do not use any type assertions.", "4026468781"],
|
||||
[115, 80, 3, "Unexpected any. Specify a different type.", "193409811"]
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilterItem.tsx:2056401604": [
|
||||
[67, 23, 155, "Do not use any type assertions.", "2419762696"],
|
||||
[67, 23, 128, "Do not use any type assertions.", "1950878359"],
|
||||
[71, 19, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[83, 23, 63, "Do not use any type assertions.", "168255657"],
|
||||
[83, 23, 36, "Do not use any type assertions.", "381764118"],
|
||||
[83, 56, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[112, 23, 92, "Do not use any type assertions.", "511072900"],
|
||||
[112, 23, 65, "Do not use any type assertions.", "791801755"],
|
||||
[112, 85, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[115, 30, 3, "Unexpected any. Specify a different type.", "193409811"],
|
||||
[119, 23, 87, "Do not use any type assertions.", "1044305842"],
|
||||
[119, 23, 60, "Do not use any type assertions.", "4026468781"],
|
||||
[119, 80, 3, "Unexpected any. Specify a different type.", "193409811"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters.tsx:1456752614": [
|
||||
[36, 15, 38, "Do not use any type assertions.", "1544016021"]
|
||||
|
81
e2e/various-suite/loki-query-builder.spec.ts
Normal file
81
e2e/various-suite/loki-query-builder.spec.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import { e2e } from '@grafana/e2e';
|
||||
|
||||
const dataSourceName = 'LokiBuilder';
|
||||
const addDataSource = () => {
|
||||
e2e.flows.addDataSource({
|
||||
type: 'Loki',
|
||||
expectedAlertMessage:
|
||||
'Unable to fetch labels from Loki (Failed to call resource), please check the server logs for more details',
|
||||
name: dataSourceName,
|
||||
form: () => {
|
||||
e2e.components.DataSource.DataSourceHttpSettings.urlInput().type('http://loki-url:3100');
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
describe('Loki query builder', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login('admin', 'admin');
|
||||
|
||||
e2e()
|
||||
.request({ url: `${e2e.env('BASE_URL')}/api/datasources/name/${dataSourceName}`, failOnStatusCode: false })
|
||||
.then((response) => {
|
||||
if (response.isOkStatusCode) {
|
||||
return;
|
||||
}
|
||||
addDataSource();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to use all modes', () => {
|
||||
e2e().intercept(/labels?/, (req) => {
|
||||
req.reply({ status: 'success', data: ['instance', 'job', 'source'] });
|
||||
});
|
||||
|
||||
e2e().intercept(/series?/, (req) => {
|
||||
req.reply({ status: 'success', data: [{ instance: 'instance1' }] });
|
||||
});
|
||||
|
||||
const finalQuery = 'rate({instance=~"instance1|instance2"} | logfmt | __error__=`` [$__interval]';
|
||||
|
||||
// Go to Explore and choose Loki data source
|
||||
e2e.pages.Explore.visit();
|
||||
e2e.components.DataSourcePicker.container().should('be.visible').click();
|
||||
e2e().contains(dataSourceName).scrollIntoView().should('be.visible').click();
|
||||
|
||||
// Start in builder mode, click and choose query pattern
|
||||
e2e.components.QueryBuilder.queryPatterns().click().type('Log query with parsing{enter}');
|
||||
e2e().contains('No pipeline errors').should('be.visible');
|
||||
e2e().contains('Logfmt').should('be.visible');
|
||||
e2e().contains('{} | logfmt | __error__=``').should('be.visible');
|
||||
|
||||
// Add operation
|
||||
e2e().contains('Operations').should('be.visible').click();
|
||||
e2e().contains('Range functions').should('be.visible').click();
|
||||
e2e().contains('Rate').should('be.visible').click();
|
||||
e2e().contains('rate({} | logfmt | __error__=`` [$__interval]').should('be.visible');
|
||||
|
||||
// Check for expected error
|
||||
e2e().contains('You need to specify at least 1 label filter (stream selector)').should('be.visible');
|
||||
|
||||
// Add labels to remove error
|
||||
e2e.components.QueryBuilder.labelSelect().should('be.visible').click().type('instance{enter}');
|
||||
e2e.components.QueryBuilder.matchOperatorSelect().should('be.visible').click().type('=~{enter}');
|
||||
e2e.components.QueryBuilder.valueSelect()
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.type('instance1{enter}')
|
||||
.type('instance2{enter}');
|
||||
e2e().contains('You need to specify at least 1 label filter (stream selector)').should('not.exist');
|
||||
e2e().contains(finalQuery).should('be.visible');
|
||||
|
||||
// Switch to code editor and check if query was parsed
|
||||
for (const word of finalQuery.split(' ')) {
|
||||
e2e().contains(word).should('be.visible');
|
||||
}
|
||||
|
||||
// Switch to explain mode and check if query is visible
|
||||
e2e().contains('label', 'Explain').click();
|
||||
e2e().contains(finalQuery).should('be.visible');
|
||||
});
|
||||
});
|
@ -268,6 +268,12 @@ export const Components = {
|
||||
spanBar: 'data-testid SpanBar--wrapper',
|
||||
},
|
||||
QueryField: { container: 'Query field' },
|
||||
QueryBuilder: {
|
||||
queryPatterns: 'Query patterns',
|
||||
labelSelect: 'Select label',
|
||||
valueSelect: 'Select value',
|
||||
matchOperatorSelect: 'Select match operator',
|
||||
},
|
||||
ValuePicker: {
|
||||
button: (name: string) => `Value picker button ${name}`,
|
||||
select: (name: string) => `Value picker select ${name}`,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { CoreApp, LoadingState } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { EditorHeader, EditorRows, FlexItem, InlineSelect, Space } from '@grafana/experimental';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { Button, ConfirmModal } from '@grafana/ui';
|
||||
@ -83,6 +84,7 @@ export const LokiQueryEditorSelector = React.memo<LokiQueryEditorProps>((props)
|
||||
<InlineSelect
|
||||
value={null}
|
||||
placeholder="Query patterns"
|
||||
aria-label={selectors.components.QueryBuilder.queryPatterns}
|
||||
allowCustomValue
|
||||
onChange={({ value }) => {
|
||||
const result = buildVisualQueryFromString(query.expr || '');
|
||||
|
@ -2,6 +2,7 @@ import { uniqBy } from 'lodash';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { SelectableValue, toOption } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { AccessoryButton, InputGroup } from '@grafana/experimental';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
@ -50,6 +51,7 @@ export function LabelFilterItem({ item, defaultOp, onChange, onDelete, onGetLabe
|
||||
<div data-testid="prometheus-dimensions-filter-item">
|
||||
<InputGroup>
|
||||
<Select
|
||||
aria-label={selectors.components.QueryBuilder.labelSelect}
|
||||
inputId="prometheus-dimensions-filter-item-key"
|
||||
width="auto"
|
||||
value={item.label ? toOption(item.label) : null}
|
||||
@ -73,6 +75,7 @@ export function LabelFilterItem({ item, defaultOp, onChange, onDelete, onGetLabe
|
||||
/>
|
||||
|
||||
<Select
|
||||
aria-label={selectors.components.QueryBuilder.matchOperatorSelect}
|
||||
value={toOption(item.op ?? defaultOp)}
|
||||
options={operators}
|
||||
width="auto"
|
||||
@ -84,6 +87,7 @@ export function LabelFilterItem({ item, defaultOp, onChange, onDelete, onGetLabe
|
||||
/>
|
||||
|
||||
<Select
|
||||
aria-label={selectors.components.QueryBuilder.valueSelect}
|
||||
inputId="prometheus-dimensions-filter-item-value"
|
||||
width="auto"
|
||||
value={
|
||||
|
Loading…
Reference in New Issue
Block a user