[Lens] better missing fields test (#150466)

This commit is contained in:
Drew Tate 2023-02-08 11:26:08 -06:00 committed by GitHub
parent a9cd313de4
commit d528635279
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 331 additions and 18 deletions

View file

@ -47,6 +47,10 @@ export class TimePickerPageObject extends FtrService {
await this.setAbsoluteRange(this.defaultStartTime, this.defaultEndTime);
}
async waitForNoDataPopover() {
await this.testSubjects.find('noDataPopoverDismissButton');
}
async ensureHiddenNoDataPopover() {
const isVisible = await this.testSubjects.exists('noDataPopoverDismissButton', {
timeout: 100,

View file

@ -5,6 +5,8 @@
* 2.0.
*/
import expect from '@kbn/expect';
import { intersection, uniq } from 'lodash';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
@ -21,6 +23,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const listingTable = getService('listingTable');
const kibanaServer = getService('kibanaServer');
const dashboardPanelActions = getService('dashboardPanelActions');
const testSubjects = getService('testSubjects');
describe('Lens error handling', () => {
describe('Index Pattern missing', () => {
@ -85,20 +88,42 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.loadSavedDashboard('Dashboard with missing field Lens');
await PageObjects.lens.assertMessageListContains(
'Field missing field was not found.',
'error'
await PageObjects.dashboard.loadSavedDashboard(
'dashboard containing vis with missing fields'
);
await PageObjects.lens.waitForVisualization('mtrVis');
const expectedMessages = [
'Field @timestamp was not found.',
'Field kubernetes.node.memory.allocatable.bytes was not found.',
'Field kubernetes.node.name was not found.',
'Field kubernetes.container.memory.usage.bytes was not found.',
'Sort field @timestamp was not found.',
'Field @timestamp was not found.',
'Field kubernetes.container.name was not found.',
];
const dashboardMessageList = await PageObjects.lens.getMessageListTexts('error');
// make sure all the expected messages are there
expect(intersection(expectedMessages, dashboardMessageList).length).to.be(
uniq(expectedMessages).length
);
expect(dashboardMessageList.length).to.be(expectedMessages.length);
// make sure the visualization is rendering
await testSubjects.find('emptyPlaceholder');
await PageObjects.dashboard.switchToEditMode();
await dashboardPanelActions.editPanelByTitle();
await PageObjects.lens.assertMessageListContains(
'Field missing field was not found.',
'error'
await PageObjects.timePicker.waitForNoDataPopover();
await PageObjects.timePicker.ensureHiddenNoDataPopover();
const editorMessageList = await PageObjects.lens.getMessageListTexts('error');
expect(intersection(expectedMessages, editorMessageList).length).to.be(
uniq(expectedMessages).length
);
await PageObjects.lens.waitForVisualization('mtrVis');
expect(editorMessageList.length).to.be(expectedMessages.length);
await testSubjects.find('emptyPlaceholder');
await kibanaServer.importExport.unload(
'x-pack/test/functional/fixtures/kbn_archiver/lens/missing_fields'

View file

@ -1,3 +1,268 @@
{
"attributes": {
"allowNoIndex": true,
"fieldAttrs": "{\"kubernetes.node.fs.available.bytes\":{\"count\":2},\"kubernetes.node.fs.capacity.bytes\":{\"count\":2},\"kubernetes.node.fs.used.bytes\":{\"count\":2},\"kubernetes.node.name\":{\"count\":2},\"event.dataset\":{\"count\":3}}",
"fieldFormatMap": "{}",
"fields": "[]",
"name": "metrics-*",
"runtimeFieldMap": "{}",
"sourceFilters": "[]",
"timeFieldName": "@timestamp",
"title": "metrics-*",
"typeMeta": "{}"
},
"coreMigrationVersion": "8.7.0",
"created_at": "2023-02-07T14:48:09.633Z",
"id": "metrics-*",
"migrationVersion": { "index-pattern": "8.0.0" },
"references": [],
"type": "index-pattern",
"updated_at": "2023-02-07T14:48:09.633Z",
"version": "WzE1OSwxXQ=="
}
{
"attributes": {
"description": "",
"state": {
"adHocDataViews": {},
"datasourceStates": {
"formBased": {
"layers": {
"dfd1702f-213e-4fa2-98e3-5106657c62e7": {
"columnOrder": [
"f0953a4e-8498-4b22-a63a-d24e4a069ed3",
"5c33dcdb-21de-4bdc-b564-ba82ed037d11",
"62125b6d-3199-420b-9d3b-46f159e15d7f"
],
"columns": {
"5c33dcdb-21de-4bdc-b564-ba82ed037d11": {
"dataType": "date",
"isBucketed": true,
"label": "Missing field",
"operationType": "date_histogram",
"params": {
"dropPartials": false,
"includeEmptyRows": true,
"interval": "30s"
},
"scale": "interval",
"sourceField": "@timestamp"
},
"62125b6d-3199-420b-9d3b-46f159e15d7f": {
"customLabel": true,
"dataType": "number",
"isBucketed": false,
"label": "Total Memory",
"operationType": "formula",
"params": {
"format": { "id": "bytes", "params": { "decimals": 2 } },
"formula": "last_value(kubernetes.node.memory.allocatable.bytes, kql='kubernetes.node.status.ready:\"true\" and event.dataset :\"kubernetes.state_node\" ')",
"isFormulaBroken": true
},
"references": [],
"scale": "ratio"
},
"f0953a4e-8498-4b22-a63a-d24e4a069ed3": {
"dataType": "string",
"isBucketed": true,
"label": "Top 100000 values of Missing field",
"operationType": "terms",
"params": {
"missingBucket": false,
"orderAgg": {
"customLabel": false,
"dataType": "number",
"isBucketed": false,
"label": "Count of records",
"operationType": "count",
"params": {},
"scale": "ratio",
"sourceField": "___records___"
},
"orderBy": { "type": "custom" },
"orderDirection": "desc",
"otherBucket": false,
"parentFormat": { "id": "terms" },
"secondaryFields": [],
"size": 100000
},
"scale": "ordinal",
"sourceField": "kubernetes.node.name"
}
},
"incompleteColumns": {}
},
"dff09473-7596-48c7-bbf4-beccee70d845": {
"columnOrder": [
"6677e92c-5874-49c1-979e-c16c0d3838cd",
"46082fb5-9abc-42a0-8e4d-8a8d40a66ddf",
"307be273-94a6-41ab-b93b-0debde733492"
],
"columns": {
"307be273-94a6-41ab-b93b-0debde733492": {
"customLabel": true,
"dataType": "number",
"filter": {
"language": "kuery",
"query": "event.dataset :\"kubernetes.container\" "
},
"isBucketed": false,
"label": "Memory Used",
"operationType": "last_value",
"params": {
"format": { "id": "bytes", "params": { "decimals": 2 } },
"showArrayValues": false,
"sortField": "@timestamp"
},
"scale": "ratio",
"sourceField": "kubernetes.container.memory.usage.bytes"
},
"46082fb5-9abc-42a0-8e4d-8a8d40a66ddf": {
"dataType": "date",
"isBucketed": true,
"label": "@timestamp",
"operationType": "date_histogram",
"params": {
"dropPartials": false,
"includeEmptyRows": true,
"interval": "30s"
},
"scale": "interval",
"sourceField": "@timestamp"
},
"6677e92c-5874-49c1-979e-c16c0d3838cd": {
"dataType": "string",
"isBucketed": true,
"label": "Top 100000 values of kubernetes.container.name",
"operationType": "terms",
"params": {
"missingBucket": false,
"orderAgg": {
"customLabel": false,
"dataType": "number",
"isBucketed": false,
"label": "Count of records",
"operationType": "count",
"params": {},
"scale": "ratio",
"sourceField": "___records___"
},
"orderBy": { "type": "custom" },
"orderDirection": "desc",
"otherBucket": false,
"parentFormat": { "id": "terms" },
"secondaryFields": [],
"size": 100000
},
"scale": "ordinal",
"sourceField": "kubernetes.container.name"
}
},
"incompleteColumns": {}
}
}
}
},
"filters": [],
"internalReferences": [],
"query": { "language": "kuery", "query": "" },
"visualization": {
"axisTitlesVisibilitySettings": {
"x": false,
"yLeft": false,
"yRight": true
},
"fillOpacity": 0.5,
"fittingFunction": "None",
"gridlinesVisibilitySettings": {
"x": true,
"yLeft": true,
"yRight": true
},
"labelsOrientation": { "x": 0, "yLeft": 0, "yRight": 0 },
"layers": [
{
"accessors": ["307be273-94a6-41ab-b93b-0debde733492"],
"collapseFn": "sum",
"layerId": "dff09473-7596-48c7-bbf4-beccee70d845",
"layerType": "data",
"palette": { "name": "default", "type": "palette" },
"seriesType": "area",
"splitAccessor": "6677e92c-5874-49c1-979e-c16c0d3838cd",
"xAccessor": "46082fb5-9abc-42a0-8e4d-8a8d40a66ddf",
"yConfig": [
{
"axisMode": "left",
"color": "#00bfb3",
"forAccessor": "307be273-94a6-41ab-b93b-0debde733492"
}
]
},
{
"accessors": ["62125b6d-3199-420b-9d3b-46f159e15d7f"],
"collapseFn": "sum",
"layerId": "dfd1702f-213e-4fa2-98e3-5106657c62e7",
"layerType": "data",
"palette": { "name": "negative", "type": "palette" },
"seriesType": "line",
"splitAccessor": "f0953a4e-8498-4b22-a63a-d24e4a069ed3",
"xAccessor": "5c33dcdb-21de-4bdc-b564-ba82ed037d11",
"yConfig": [
{
"axisMode": "left",
"color": "#bd271e",
"forAccessor": "62125b6d-3199-420b-9d3b-46f159e15d7f"
}
]
}
],
"legend": {
"isVisible": true,
"maxLines": 1,
"position": "top",
"shouldTruncate": true,
"showSingleSeries": true
},
"preferredSeriesType": "bar_stacked",
"tickLabelsVisibilitySettings": {
"x": true,
"yLeft": true,
"yRight": true
},
"valueLabels": "hide",
"xTitle": "",
"yLeftExtent": { "mode": "full" },
"yLeftScale": "linear",
"yRightExtent": { "mode": "full" },
"yRightScale": "linear",
"yTitle": ""
}
},
"title": "vis with several missing fields",
"visualizationType": "lnsXY"
},
"coreMigrationVersion": "8.7.0",
"created_at": "2023-02-07T14:58:51.333Z",
"id": "eee2b040-a6f7-11ed-8332-9375ae88137b",
"migrationVersion": { "lens": "8.6.0" },
"references": [
{
"id": "metrics-*",
"name": "indexpattern-datasource-layer-dfd1702f-213e-4fa2-98e3-5106657c62e7",
"type": "index-pattern"
},
{
"id": "metrics-*",
"name": "indexpattern-datasource-layer-dff09473-7596-48c7-bbf4-beccee70d845",
"type": "index-pattern"
}
],
"type": "lens",
"updated_at": "2023-02-07T14:58:51.333Z",
"version": "WzM0MiwxXQ=="
}
{
"attributes": {
"description": "",
@ -5,23 +270,23 @@
"searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"
},
"optionsJSON": "{\"useMargins\":true,\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false,\"hidePanelTitles\":false}",
"panelsJSON": "[{\"version\":\"8.7.0\",\"type\":\"lens\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"7d75b51d-19fc-4dba-8174-b82e2905745d\"},\"panelIndex\":\"7d75b51d-19fc-4dba-8174-b82e2905745d\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"visualizationType\":\"lnsMetric\",\"type\":\"lens\",\"references\":[{\"type\":\"index-pattern\",\"id\":\"logstash-*\",\"name\":\"indexpattern-datasource-layer-78c0d2e4-4bb8-49e7-ae98-cbe5851bb959\"}],\"state\":{\"visualization\":{\"layerId\":\"78c0d2e4-4bb8-49e7-ae98-cbe5851bb959\",\"layerType\":\"data\",\"metricAccessor\":\"8630dc6f-828f-4a7d-8283-821cf6b54e4f\"},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[],\"datasourceStates\":{\"formBased\":{\"layers\":{\"78c0d2e4-4bb8-49e7-ae98-cbe5851bb959\":{\"columns\":{\"8630dc6f-828f-4a7d-8283-821cf6b54e4f\":{\"label\":\"Median of missing field\",\"dataType\":\"number\",\"operationType\":\"median\",\"sourceField\":\"missing field\",\"isBucketed\":false,\"scale\":\"ratio\",\"params\":{\"emptyAsNull\":true}}},\"columnOrder\":[\"8630dc6f-828f-4a7d-8283-821cf6b54e4f\"],\"incompleteColumns\":{},\"sampling\":1}}},\"textBased\":{\"layers\":{}}},\"internalReferences\":[],\"adHocDataViews\":{}}},\"enhancements\":{}}}]",
"panelsJSON": "[{\"version\":\"8.7.0\",\"type\":\"lens\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"4373fcf6-6f6d-470f-b06c-92ebac15210b\"},\"panelIndex\":\"4373fcf6-6f6d-470f-b06c-92ebac15210b\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_4373fcf6-6f6d-470f-b06c-92ebac15210b\"}]",
"timeRestore": false,
"title": "Dashboard with missing field Lens",
"title": "dashboard containing vis with missing fields",
"version": 1
},
"coreMigrationVersion": "8.7.0",
"created_at": "2023-01-28T17:47:28.069Z",
"id": "d4cc9840-9f33-11ed-896f-1111cbb8731e",
"created_at": "2023-02-07T14:59:20.822Z",
"id": "00768160-a6f8-11ed-8332-9375ae88137b",
"migrationVersion": { "dashboard": "8.7.0" },
"references": [
{
"id": "logstash-*",
"name": "7d75b51d-19fc-4dba-8174-b82e2905745d:indexpattern-datasource-layer-78c0d2e4-4bb8-49e7-ae98-cbe5851bb959",
"type": "index-pattern"
"id": "eee2b040-a6f7-11ed-8332-9375ae88137b",
"name": "4373fcf6-6f6d-470f-b06c-92ebac15210b:panel_4373fcf6-6f6d-470f-b06c-92ebac15210b",
"type": "lens"
}
],
"type": "dashboard",
"updated_at": "2023-01-28T17:47:28.069Z",
"version": "WzM0OCwxXQ=="
"updated_at": "2023-02-07T14:59:20.822Z",
"version": "WzM5MCwxXQ=="
}

View file

@ -1602,6 +1602,9 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
/**
* Applicable both on the embeddable and in the editor. In both scenarios, a popover containing user messages (errors, warnings) is shown.
*
* If you're going to use this many times in your test consider retrieving all the messages in one go using getMessageListTexts
* and running your own assertions for performance reasons.
*/
async assertMessageListContains(assertText: string, severity: 'warning' | 'error') {
await testSubjects.click('lens-message-list-trigger');
@ -1622,6 +1625,22 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
}
},
async getMessageListTexts(severity: 'warning' | 'error') {
await testSubjects.click('lens-message-list-trigger');
const messageSelector = `lens-message-list-${severity}`;
await testSubjects.existOrFail(messageSelector);
const messageEls = await testSubjects.findAll(messageSelector);
const messages = await Promise.all(messageEls.map((el) => el.getVisibleText()));
await testSubjects.click('lens-message-list-trigger');
return messages;
},
async getPaletteColorStops() {
const stops = await find.allByCssSelector(
`[data-test-subj^="lnsPalettePanel_dynamicColoring_range_value_"]`