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:
Ivana Huckova 2022-06-29 11:04:27 +02:00 committed by GitHub
parent ed56755dd7
commit 60454192b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 107 additions and 14 deletions

View File

@ -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"]

View 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');
});
});

View File

@ -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}`,

View File

@ -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 || '');

View File

@ -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={