diff --git a/packages/kbn-unified-data-table/src/components/data_table.scss b/packages/kbn-unified-data-table/src/components/data_table.scss index f80b6cdab904c..44801b4052dfe 100644 --- a/packages/kbn-unified-data-table/src/components/data_table.scss +++ b/packages/kbn-unified-data-table/src/components/data_table.scss @@ -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; diff --git a/src/plugins/discover/public/application/context/context_app.test.tsx b/src/plugins/discover/public/application/context/context_app.test.tsx index 42ef78f6f757a..ccecd2d9b566e 100644 --- a/src/plugins/discover/public/application/context/context_app.test.tsx +++ b/src/plugins/discover/public/application/context/context_app.test.tsx @@ -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 = { diff --git a/src/plugins/discover/public/application/context/context_app_content.tsx b/src/plugins/discover/public/application/context/context_app_content.tsx index e0f0dbbd820cb..54c2be693df32 100644 --- a/src/plugins/discover/public/application/context/context_app_content.tsx +++ b/src/plugins/discover/public/application/context/context_app_content.tsx @@ -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 ( @@ -222,6 +229,7 @@ export function ContextAppContent({ configHeaderRowHeight={3} settings={grid} onResize={onResize} + externalCustomRenderers={cellRenderers} /> diff --git a/src/plugins/discover/public/application/context/services/anchor.ts b/src/plugins/discover/public/application/context/services/anchor.ts index b04ca0a0f4cfc..926044ebd4f20 100644 --- a/src/plugins/discover/public/application/context/services/anchor.ts +++ b/src/plugins/discover/public/application/context/services/anchor.ts @@ -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, }; } diff --git a/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts b/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts index bb99a305b7c6d..22af251d65ca8 100644 --- a/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts +++ b/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts @@ -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); diff --git a/src/plugins/discover/public/application/doc/components/doc.test.tsx b/src/plugins/discover/public/application/doc/components/doc.test.tsx index 79a1be2cf1751..262b5819f9397 100644 --- a/src/plugins/discover/public/application/doc/components/doc.test.tsx +++ b/src/plugins/discover/public/application/doc/components/doc.test.tsx @@ -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, diff --git a/src/plugins/discover/public/application/doc/components/doc.tsx b/src/plugins/discover/public/application/doc/components/doc.tsx index c604abcdd74df..eb706e59e2a34 100644 --- a/src/plugins/discover/public/application/doc/components/doc.tsx +++ b/src/plugins/discover/public/application/doc/components/doc.tsx @@ -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) { )} - {reqState === ElasticRequestState.Found && hit !== null && dataView && ( + {reqState === ElasticRequestState.Found && record !== null && dataView && (
- +
)} diff --git a/src/plugins/discover/public/application/doc/components/single_doc_viewer.tsx b/src/plugins/discover/public/application/doc/components/single_doc_viewer.tsx new file mode 100644 index 0000000000000..d22970c1635d7 --- /dev/null +++ b/src/plugins/discover/public/application/doc/components/single_doc_viewer.tsx @@ -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 = ({ 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 ( + + ); +}; diff --git a/src/plugins/unified_doc_viewer/public/hooks/use_es_doc_search.ts b/src/plugins/unified_doc_viewer/public/hooks/use_es_doc_search.ts index 57c816a2c8016..091df99c2e224 100644 --- a/src/plugins/unified_doc_viewer/public/hooks/use_es_doc_search.ts +++ b/src/plugins/unified_doc_viewer/public/hooks/use_es_doc_search.ts @@ -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; + /** + * 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(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) { diff --git a/test/functional/apps/discover/context_awareness/extensions/_get_cell_renderers.ts b/test/functional/apps/discover/context_awareness/extensions/_get_cell_renderers.ts index 00531b80f4a73..0bd0523365d83 100644 --- a/test/functional/apps/discover/context_awareness/extensions/_get_cell_renderers.ts +++ b/test/functional/apps/discover/context_awareness/extensions/_get_cell_renderers.ts @@ -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-'); }); diff --git a/test/functional/apps/discover/context_awareness/extensions/_get_doc_viewer.ts b/test/functional/apps/discover/context_awareness/extensions/_get_doc_viewer.ts index e2c91143d53f7..b739842703131 100644 --- a/test/functional/apps/discover/context_awareness/extensions/_get_doc_viewer.ts +++ b/test/functional/apps/discover/context_awareness/extensions/_get_doc_viewer.ts @@ -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'); }); }); }); diff --git a/test/functional/apps/discover/context_awareness/extensions/_get_row_additional_leading_controls.ts b/test/functional/apps/discover/context_awareness/extensions/_get_row_additional_leading_controls.ts index be536fd6cdbe9..533acd8fc128a 100644 --- a/test/functional/apps/discover/context_awareness/extensions/_get_row_additional_leading_controls.ts +++ b/test/functional/apps/discover/context_awareness/extensions/_get_row_additional_leading_controls.ts @@ -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'); }); }); }); diff --git a/test/functional/apps/discover/context_awareness/extensions/_get_row_indicator_provider.ts b/test/functional/apps/discover/context_awareness/extensions/_get_row_indicator_provider.ts index 8efa852cbfb2a..05250147cb559 100644 --- a/test/functional/apps/discover/context_awareness/extensions/_get_row_indicator_provider.ts +++ b/test/functional/apps/discover/context_awareness/extensions/_get_row_indicator_provider.ts @@ -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)' + ); + }); }); } diff --git a/test/functional/apps/discover/group1/_doc_accessibility.ts b/test/functional/apps/discover/group1/_doc_accessibility.ts index 5ecdef656b2ac..e6600c179ba55 100644 --- a/test/functional/apps/discover/group1/_doc_accessibility.ts +++ b/test/functional/apps/discover/group1/_doc_accessibility.ts @@ -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') diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_cell_renderers.ts b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_cell_renderers.ts index 7bce934099e18..4eaca072d3b1e 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_cell_renderers.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_cell_renderers.ts @@ -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-'); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_doc_viewer.ts b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_doc_viewer.ts index 52b514a6673b6..d214d295e1a7e 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_doc_viewer.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_doc_viewer.ts @@ -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'); }); }); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_row_additional_leading_controls.ts b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_row_additional_leading_controls.ts index c91dae10bc4ea..d69b155f44729 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_row_additional_leading_controls.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_row_additional_leading_controls.ts @@ -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'); }); }); }); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_row_indicator_provider.ts b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_row_indicator_provider.ts index c7b402665e689..0a5d4911275f0 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_row_indicator_provider.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_row_indicator_provider.ts @@ -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)' + ); + }); }); }