[Discover] Context aware Single Document & Surrounding Documents pages (#190540)

- Closes https://github.com/elastic/kibana/issues/188178

## Summary

This PR makes sure to resolve profiles on:
- [x] Single document page (also added doc viewer extension support)
- [x] Surrounding documents page (also added cell renderes support)

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: Davis McPhee <davis.mcphee@elastic.co>
This commit is contained in:
Julia Rechkunova 2024-09-02 14:23:54 +03:00 committed by GitHub
parent f2aba46241
commit 00174635b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 465 additions and 25 deletions

View file

@ -63,6 +63,9 @@
border-left: 0;
border-right: 0;
}
.euiDataGridRowCell.euiDataGridRowCell--controlColumn[data-gridcell-column-id='additionalRowControl_menuControl'] .euiDataGridRowCell__content {
padding-bottom: 0;
}
.euiDataGridHeaderCell.euiDataGridHeaderCell--controlColumn[data-gridcell-column-id='select'] {
padding-left: $euiSizeXS;

View file

@ -24,11 +24,13 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
import type { HistoryLocationState } from '../../build_services';
import { createSearchSessionMock } from '../../__mocks__/search_session';
import { createDiscoverServicesMock } from '../../__mocks__/services';
const mockFilterManager = createFilterManagerMock();
const mockNavigationPlugin = {
ui: { TopNavMenu: mockTopNavMenu, AggregateQueryTopNavMenu: mockTopNavMenu },
};
const discoverServices = createDiscoverServicesMock();
describe('ContextApp test', () => {
const { history } = createSearchSessionMock();
@ -53,6 +55,7 @@ describe('ContextApp test', () => {
toastNotifications: { addDanger: () => {} },
navigation: mockNavigationPlugin,
core: {
...discoverServices.core,
executionContext: {
set: jest.fn(),
},
@ -75,6 +78,7 @@ describe('ContextApp test', () => {
},
contextLocator: { getRedirectUrl: jest.fn(() => '') },
singleDocLocator: { getRedirectUrl: jest.fn(() => '') },
profilesManager: discoverServices.profilesManager,
} as unknown as DiscoverServices;
const defaultProps = {

View file

@ -40,6 +40,7 @@ import { DocTableContext } from '../../components/doc_table/doc_table_context';
import { useDiscoverServices } from '../../hooks/use_discover_services';
import { DiscoverGridFlyout } from '../../components/discover_grid_flyout';
import { onResizeGridColumn } from '../../utils/on_resize_grid_column';
import { useProfileAccessor } from '../../context_awareness';
export interface ContextAppContentProps {
columns: string[];
@ -159,6 +160,12 @@ export function ContextAppContent({
[grid, setAppState]
);
const getCellRenderersAccessor = useProfileAccessor('getCellRenderers');
const cellRenderers = useMemo(() => {
const getCellRenderers = getCellRenderersAccessor(() => ({}));
return getCellRenderers();
}, [getCellRenderersAccessor]);
return (
<Fragment>
<WrapperWithPadding>
@ -222,6 +229,7 @@ export function ContextAppContent({
configHeaderRowHeight={3}
settings={grid}
onResize={onResize}
externalCustomRenderers={cellRenderers}
/>
</CellActionsProvider>
</div>

View file

@ -5,7 +5,7 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { lastValueFrom } from 'rxjs';
import { firstValueFrom, lastValueFrom } from 'rxjs';
import { i18n } from '@kbn/i18n';
import { ISearchSource, EsQuerySortValue } from '@kbn/data-plugin/public';
import type { DataView } from '@kbn/data-views-plugin/public';
@ -14,6 +14,7 @@ import { buildDataTableRecord } from '@kbn/discover-utils';
import type { DataTableRecord, EsHitRecord } from '@kbn/discover-utils/types';
import type { SearchResponseWarning } from '@kbn/search-response-warnings';
import type { DiscoverServices } from '../../../build_services';
import { createDataViewDataSource } from '../../../../common/data_sources';
export async function fetchAnchor(
anchorId: string,
@ -26,6 +27,16 @@ export async function fetchAnchor(
anchorRow: DataTableRecord;
interceptedWarnings: SearchResponseWarning[];
}> {
const { core, profilesManager } = services;
const solutionNavId = await firstValueFrom(core.chrome.getActiveSolutionNavId$());
await profilesManager.resolveRootProfile({ solutionNavId });
await profilesManager.resolveDataSourceProfile({
dataSource: dataView?.id ? createDataViewDataSource({ dataViewId: dataView.id }) : undefined,
dataView,
query: { query: '', language: 'kuery' },
});
updateSearchSource(searchSource, anchorId, sort, useNewFieldsApi, dataView);
const adapter = new RequestAdapter();
@ -55,7 +66,9 @@ export async function fetchAnchor(
});
return {
anchorRow: buildDataTableRecord(doc, dataView, true),
anchorRow: profilesManager.resolveDocumentProfile({
record: buildDataTableRecord(doc, dataView, true),
}),
interceptedWarnings,
};
}

View file

@ -46,6 +46,7 @@ export async function fetchHitsInInterval(
rows: DataTableRecord[];
interceptedWarnings: SearchResponseWarning[];
}> {
const { profilesManager } = services;
const range: RangeQuery = {
format: 'strict_date_optional_time',
};
@ -96,7 +97,11 @@ export async function fetchHitsInInterval(
const { rawResponse } = await lastValueFrom(fetch$);
const dataView = searchSource.getField('index');
const rows = rawResponse.hits?.hits.map((hit) => buildDataTableRecord(hit, dataView!));
const rows = rawResponse.hits?.hits.map((hit) =>
profilesManager.resolveDocumentProfile({
record: buildDataTableRecord(hit, dataView!),
})
);
const interceptedWarnings: SearchResponseWarning[] = [];
services.data.search.showWarnings(adapter, (warning) => {
interceptedWarnings.push(warning);

View file

@ -19,7 +19,9 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { setUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/plugin';
import { mockUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/__mocks__';
import type { UnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/types';
import { createDiscoverServicesMock } from '../../../__mocks__/services';
const discoverServices = createDiscoverServicesMock();
const mockSearchApi = jest.fn();
beforeEach(() => {
@ -68,6 +70,8 @@ async function mountDoc(update = false) {
},
locator: { getUrl: jest.fn(() => Promise.resolve('mock-url')) },
chrome: { setBreadcrumbs: jest.fn() },
profilesManager: discoverServices.profilesManager,
core: discoverServices.core,
};
setUnifiedDocViewerServices({
...mockUnifiedDocViewerServices,

View file

@ -6,15 +6,18 @@
* Side Public License, v 1.
*/
import React, { useEffect } from 'react';
import React, { useCallback, useEffect } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { firstValueFrom } from 'rxjs';
import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPage, EuiPageBody } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { ElasticRequestState } from '@kbn/unified-doc-viewer';
import { UnifiedDocViewer, useEsDocSearch } from '@kbn/unified-doc-viewer-plugin/public';
import { useEsDocSearch } from '@kbn/unified-doc-viewer-plugin/public';
import type { EsDocSearchProps } from '@kbn/unified-doc-viewer-plugin/public/types';
import { setBreadcrumbs } from '../../../utils/breadcrumbs';
import { useDiscoverServices } from '../../../hooks/use_discover_services';
import { SingleDocViewer } from './single_doc_viewer';
import { createDataViewDataSource } from '../../../../common/data_sources';
export interface DocProps extends EsDocSearchProps {
/**
@ -25,11 +28,33 @@ export interface DocProps extends EsDocSearchProps {
export function Doc(props: DocProps) {
const { dataView } = props;
const [reqState, hit] = useEsDocSearch(props);
const services = useDiscoverServices();
const { locator, chrome, docLinks } = services;
const { locator, chrome, docLinks, core, profilesManager } = services;
const indexExistsLink = docLinks.links.apis.indexExists;
const onBeforeFetch = useCallback(async () => {
const solutionNavId = await firstValueFrom(core.chrome.getActiveSolutionNavId$());
await profilesManager.resolveRootProfile({ solutionNavId });
await profilesManager.resolveDataSourceProfile({
dataSource: dataView?.id ? createDataViewDataSource({ dataViewId: dataView.id }) : undefined,
dataView,
query: { query: '', language: 'kuery' },
});
}, [profilesManager, core, dataView]);
const onProcessRecord = useCallback(
(record) => {
return profilesManager.resolveDocumentProfile({ record });
},
[profilesManager]
);
const [reqState, record] = useEsDocSearch({
...props,
onBeforeFetch,
onProcessRecord,
});
useEffect(() => {
setBreadcrumbs({
services,
@ -117,9 +142,9 @@ export function Doc(props: DocProps) {
</EuiCallOut>
)}
{reqState === ElasticRequestState.Found && hit !== null && dataView && (
{reqState === ElasticRequestState.Found && record !== null && dataView && (
<div data-test-subj="doc-hit">
<UnifiedDocViewer hit={hit} dataView={dataView} hideActionsColumn />
<SingleDocViewer record={record} dataView={dataView} />
</div>
)}
</EuiPageBody>

View file

@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { useMemo } from 'react';
import { UnifiedDocViewer } from '@kbn/unified-doc-viewer-plugin/public';
import type { DocViewsRegistry } from '@kbn/unified-doc-viewer';
import type { DataTableRecord } from '@kbn/discover-utils';
import type { DataView } from '@kbn/data-views-plugin/public';
import { useProfileAccessor } from '../../../context_awareness';
interface SingleDocViewerProps {
record: DataTableRecord;
dataView: DataView;
}
export const SingleDocViewer: React.FC<SingleDocViewerProps> = ({ record, dataView }) => {
const getDocViewerAccessor = useProfileAccessor('getDocViewer', {
record,
});
const docViewer = useMemo(() => {
const getDocViewer = getDocViewerAccessor(() => ({
title: undefined,
docViewsRegistry: (registry: DocViewsRegistry) => registry,
}));
return getDocViewer({ record });
}, [getDocViewerAccessor, record]);
return (
<UnifiedDocViewer
hit={record}
dataView={dataView}
hideActionsColumn
docViewsRegistry={docViewer.docViewsRegistry}
/>
);
};

View file

@ -39,6 +39,15 @@ export interface EsDocSearchProps {
* Records fetched from text based query
*/
textBasedHits?: DataTableRecord[];
/**
* An optional callback that will be called before fetching the doc
*/
onBeforeFetch?: () => Promise<void>;
/**
* An optional callback that will be called after fetching the doc
* @param record
*/
onProcessRecord?: (record: DataTableRecord) => DataTableRecord;
}
/**
@ -50,6 +59,8 @@ export function useEsDocSearch({
dataView,
requestSource,
textBasedHits,
onBeforeFetch,
onProcessRecord,
}: EsDocSearchProps): [ElasticRequestState, DataTableRecord | null, () => void] {
const [status, setStatus] = useState(ElasticRequestState.Loading);
const [hit, setHit] = useState<DataTableRecord | null>(null);
@ -63,6 +74,9 @@ export function useEsDocSearch({
const singleDocFetchingStartTime = window.performance.now();
try {
if (onBeforeFetch) {
await onBeforeFetch();
}
const result = await lastValueFrom(
data.search.search({
params: {
@ -77,7 +91,8 @@ export function useEsDocSearch({
if (hits?.hits?.[0]) {
setStatus(ElasticRequestState.Found);
setHit(buildDataTableRecord(hits.hits[0], dataView));
const record = buildDataTableRecord(hits?.hits?.[0], dataView);
setHit(onProcessRecord ? onProcessRecord(record) : record);
} else {
setStatus(ElasticRequestState.NotFound);
}
@ -98,7 +113,17 @@ export function useEsDocSearch({
duration: singleDocFetchingDuration,
});
}
}, [analytics, data.search, dataView, id, index, useNewFieldsApi, requestSource]);
}, [
analytics,
data.search,
dataView,
id,
index,
useNewFieldsApi,
requestSource,
onBeforeFetch,
onProcessRecord,
]);
useEffect(() => {
if (textBasedHits) {

View file

@ -11,12 +11,13 @@ import expect from '@kbn/expect';
import type { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'discover', 'unifiedFieldList']);
const PageObjects = getPageObjects(['common', 'discover', 'unifiedFieldList', 'header']);
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
const dataGrid = getService('dataGrid');
const dataViews = getService('dataViews');
const queryBar = getService('queryBar');
const browser = getService('browser');
describe('extension getCellRenderers', () => {
before(async () => {
@ -76,8 +77,23 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await queryBar.submitQuery();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
const logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
let firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
let logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
@ -93,7 +109,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await queryBar.submitQuery();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
let firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
firstCell = await dataGrid.getCellElementExcludingControlColumns(1, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
});

View file

@ -10,10 +10,11 @@ import kbnRison from '@kbn/rison';
import type { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'discover']);
const PageObjects = getPageObjects(['common', 'discover', 'header']);
const testSubjects = getService('testSubjects');
const dataViews = getService('dataViews');
const dataGrid = getService('dataGrid');
const browser = getService('browser');
describe('extension getDocViewer', () => {
describe('ES|QL mode', () => {
@ -60,6 +61,31 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview');
await dataGrid.clickDocViewerTab('doc_view_logs_overview');
await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader');
// check Surrounding docs page
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await dataGrid.clickRowToggle({ isAnchorRow: true });
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview');
await dataGrid.clickDocViewerTab('doc_view_logs_overview');
await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader');
// check Single doc page
const [singleDocActionEl] = await dataGrid.getRowActions();
await singleDocActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview');
await dataGrid.clickDocViewerTab('doc_view_logs_overview');
await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader');
});
it('should not render logs overview tab for non-logs data source', async () => {
@ -71,6 +97,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dataGrid.clickRowToggle();
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview');
// check Surrounding docs page
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await dataGrid.clickRowToggle({ isAnchorRow: true });
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview');
// check Single doc page
const [singleDocActionEl] = await dataGrid.getRowActions();
await singleDocActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview');
});
});
});

View file

@ -10,9 +10,11 @@ import kbnRison from '@kbn/rison';
import type { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'discover']);
const PageObjects = getPageObjects(['common', 'discover', 'header']);
const testSubjects = getService('testSubjects');
const dataViews = getService('dataViews');
const dataGrid = getService('dataGrid');
const browser = getService('browser');
describe('extension getRowAdditionalLeadingControls', () => {
describe('ES|QL mode', () => {
@ -50,6 +52,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.discover.waitUntilSearchingHasFinished();
await testSubjects.existOrFail('exampleLogsControl_visBarVerticalStacked');
await testSubjects.existOrFail('unifiedDataTable_additionalRowControl_menuControl');
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('exampleLogsControl_visBarVerticalStacked');
await testSubjects.existOrFail('unifiedDataTable_additionalRowControl_menuControl');
});
it('should not render logs controls for non-logs data source', async () => {
@ -58,6 +71,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.discover.waitUntilSearchingHasFinished();
await testSubjects.missingOrFail('exampleLogsControl_visBarVerticalStacked');
await testSubjects.missingOrFail('unifiedDataTable_additionalRowControl_menuControl');
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.missingOrFail('exampleLogsControl_visBarVerticalStacked');
await testSubjects.missingOrFail('unifiedDataTable_additionalRowControl_menuControl');
});
});
});

View file

@ -11,11 +11,18 @@ import expect from '@kbn/expect';
import type { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'timePicker', 'discover', 'unifiedFieldList']);
const PageObjects = getPageObjects([
'common',
'timePicker',
'discover',
'unifiedFieldList',
'header',
]);
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
const dataGrid = getService('dataGrid');
const browser = getService('browser');
const dataViews = getService('dataViews');
describe('extension getRowIndicatorProvider', () => {
before(async () => {
@ -91,5 +98,54 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
expect(await secondColorIndicator.getAttribute('title')).to.be('Error');
});
it('should render log.level row indicators on Surrounding documents page', async () => {
await PageObjects.common.navigateToApp('discover');
await dataViews.switchTo('my-example-logs,logstash*');
await PageObjects.discover.waitUntilSearchingHasFinished();
await dataGrid.clickRowToggle({ rowIndex: 0 });
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
let anchorCell = await dataGrid.getCellElement(0, 0);
let anchorColorIndicator = await anchorCell.findByTestSubject(
'unifiedDataTableRowColorIndicatorCell'
);
expect(await anchorColorIndicator.getAttribute('title')).to.be('Debug');
expect(await anchorColorIndicator.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
let nextCell = await dataGrid.getCellElement(1, 0);
let nextColorIndicator = await nextCell.findByTestSubject(
'unifiedDataTableRowColorIndicatorCell'
);
expect(await nextColorIndicator.getAttribute('title')).to.be('Error');
expect(await nextColorIndicator.getComputedStyle('background-color')).to.be(
'rgba(223, 147, 82, 1)'
);
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
anchorCell = await dataGrid.getCellElement(0, 0);
anchorColorIndicator = await anchorCell.findByTestSubject(
'unifiedDataTableRowColorIndicatorCell'
);
expect(await anchorColorIndicator.getAttribute('title')).to.be('Debug');
expect(await anchorColorIndicator.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
nextCell = await dataGrid.getCellElement(1, 0);
nextColorIndicator = await nextCell.findByTestSubject(
'unifiedDataTableRowColorIndicatorCell'
);
expect(await nextColorIndicator.getAttribute('title')).to.be('Error');
expect(await nextColorIndicator.getComputedStyle('background-color')).to.be(
'rgba(223, 147, 82, 1)'
);
});
});
}

View file

@ -48,7 +48,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await browser.pressKeys(browser.keys.TAB);
await browser.pressKeys(browser.keys.SPACE);
await browser.pressKeys(browser.keys.TAB);
const tableTab = await testSubjects.find('docViewerTab-doc_view_table');
const tableTab = await testSubjects.find('docViewerTab-doc_view_logs_overview');
const activeElement = await find.activeElement();
expect(await tableTab.getAttribute('data-test-subj')).to.eql(
await activeElement.getAttribute('data-test-subj')

View file

@ -10,12 +10,19 @@ import expect from '@kbn/expect';
import type { FtrProviderContext } from '../../../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'discover', 'unifiedFieldList', 'svlCommonPage']);
const PageObjects = getPageObjects([
'common',
'discover',
'unifiedFieldList',
'svlCommonPage',
'header',
]);
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
const dataGrid = getService('dataGrid');
const dataViews = getService('dataViews');
const queryBar = getService('queryBar');
const browser = getService('browser');
describe('extension getCellRenderers', () => {
before(async () => {
@ -76,8 +83,23 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await queryBar.submitQuery();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
const logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
let firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
let logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
@ -93,7 +115,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await queryBar.submitQuery();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
let firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
firstCell = await dataGrid.getCellElementExcludingControlColumns(1, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
});

View file

@ -9,10 +9,11 @@ import kbnRison from '@kbn/rison';
import type { FtrProviderContext } from '../../../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'discover', 'svlCommonPage']);
const PageObjects = getPageObjects(['common', 'discover', 'svlCommonPage', 'header']);
const testSubjects = getService('testSubjects');
const dataViews = getService('dataViews');
const dataGrid = getService('dataGrid');
const browser = getService('browser');
describe('extension getDocViewer', () => {
before(async () => {
@ -63,6 +64,31 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview');
await dataGrid.clickDocViewerTab('doc_view_logs_overview');
await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader');
// check Surrounding docs page
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await dataGrid.clickRowToggle({ isAnchorRow: true });
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview');
await dataGrid.clickDocViewerTab('doc_view_logs_overview');
await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader');
// check Single doc page
const [singleDocActionEl] = await dataGrid.getRowActions();
await singleDocActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview');
await dataGrid.clickDocViewerTab('doc_view_logs_overview');
await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader');
});
it('should not render logs overview tab for non-logs data source', async () => {
@ -74,6 +100,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dataGrid.clickRowToggle();
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview');
// check Surrounding docs page
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await dataGrid.clickRowToggle({ isAnchorRow: true });
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview');
// check Single doc page
const [singleDocActionEl] = await dataGrid.getRowActions();
await singleDocActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('docViewerTab-doc_view_table');
await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview');
});
});
});

View file

@ -9,9 +9,11 @@ import kbnRison from '@kbn/rison';
import type { FtrProviderContext } from '../../../../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'discover', 'svlCommonPage']);
const PageObjects = getPageObjects(['common', 'discover', 'svlCommonPage', 'header']);
const testSubjects = getService('testSubjects');
const dataViews = getService('dataViews');
const dataGrid = getService('dataGrid');
const browser = getService('browser');
describe('extension getRowAdditionalLeadingControls', () => {
before(async () => {
@ -52,6 +54,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.discover.waitUntilSearchingHasFinished();
await testSubjects.existOrFail('exampleLogsControl_visBarVerticalStacked');
await testSubjects.existOrFail('unifiedDataTable_additionalRowControl_menuControl');
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.existOrFail('exampleLogsControl_visBarVerticalStacked');
await testSubjects.existOrFail('unifiedDataTable_additionalRowControl_menuControl');
});
it('should not render logs controls for non-logs data source', async () => {
@ -60,6 +73,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.discover.waitUntilSearchingHasFinished();
await testSubjects.missingOrFail('exampleLogsControl_visBarVerticalStacked');
await testSubjects.missingOrFail('unifiedDataTable_additionalRowControl_menuControl');
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.missingOrFail('exampleLogsControl_visBarVerticalStacked');
await testSubjects.missingOrFail('unifiedDataTable_additionalRowControl_menuControl');
});
});
});

View file

@ -16,11 +16,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'discover',
'unifiedFieldList',
'svlCommonPage',
'header',
]);
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
const dataGrid = getService('dataGrid');
const browser = getService('browser');
const dataViews = getService('dataViews');
describe('extension getRowIndicatorProvider', () => {
before(async () => {
@ -88,5 +90,54 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
expect(await firstColorIndicator.getAttribute('title')).to.be('Debug');
});
it('should render log.level row indicators on Surrounding documents page', async () => {
await PageObjects.common.navigateToApp('discover');
await dataViews.switchTo('my-example-logs,logstash*');
await PageObjects.discover.waitUntilSearchingHasFinished();
await dataGrid.clickRowToggle({ rowIndex: 0 });
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
let anchorCell = await dataGrid.getCellElement(0, 0);
let anchorColorIndicator = await anchorCell.findByTestSubject(
'unifiedDataTableRowColorIndicatorCell'
);
expect(await anchorColorIndicator.getAttribute('title')).to.be('Debug');
expect(await anchorColorIndicator.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
let nextCell = await dataGrid.getCellElement(1, 0);
let nextColorIndicator = await nextCell.findByTestSubject(
'unifiedDataTableRowColorIndicatorCell'
);
expect(await nextColorIndicator.getAttribute('title')).to.be('Error');
expect(await nextColorIndicator.getComputedStyle('background-color')).to.be(
'rgba(223, 147, 82, 1)'
);
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
anchorCell = await dataGrid.getCellElement(0, 0);
anchorColorIndicator = await anchorCell.findByTestSubject(
'unifiedDataTableRowColorIndicatorCell'
);
expect(await anchorColorIndicator.getAttribute('title')).to.be('Debug');
expect(await anchorColorIndicator.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
nextCell = await dataGrid.getCellElement(1, 0);
nextColorIndicator = await nextCell.findByTestSubject(
'unifiedDataTableRowColorIndicatorCell'
);
expect(await nextColorIndicator.getAttribute('title')).to.be('Error');
expect(await nextColorIndicator.getComputedStyle('background-color')).to.be(
'rgba(223, 147, 82, 1)'
);
});
});
}