diff --git a/src/plugins/discover/public/__mocks__/index_pattern.ts b/src/plugins/discover/public/__mocks__/index_pattern.ts
index 8101590f029e1..e74046e9dc1ec 100644
--- a/src/plugins/discover/public/__mocks__/index_pattern.ts
+++ b/src/plugins/discover/public/__mocks__/index_pattern.ts
@@ -52,6 +52,13 @@ const fields = [
scripted: true,
filterable: false,
},
+ {
+ name: 'object.value',
+ type: 'number',
+ scripted: false,
+ filterable: true,
+ aggregatable: true,
+ },
] as IIndexPatternFieldList;
fields.getByName = (name: string) => {
@@ -64,13 +71,14 @@ const indexPattern = ({
metaFields: ['_index', '_score'],
formatField: jest.fn(),
flattenHit: undefined,
- formatHit: jest.fn((hit) => hit._source),
+ formatHit: jest.fn((hit) => (hit.fields ? hit.fields : hit._source)),
fields,
getComputedFields: () => ({ docvalueFields: [], scriptFields: {}, storedFields: ['*'] }),
getSourceFiltering: () => ({}),
- getFieldByName: () => ({}),
+ getFieldByName: jest.fn(() => ({})),
timeFieldName: '',
docvalueFields: [],
+ getFormatterForField: () => ({ convert: () => 'formatted' }),
} as unknown) as IndexPattern;
indexPattern.flattenHit = indexPatterns.flattenHitWrapper(indexPattern, indexPattern.metaFields);
diff --git a/src/plugins/discover/public/application/angular/doc_table/components/table_row.ts b/src/plugins/discover/public/application/angular/doc_table/components/table_row.ts
index b527b202ad87d..12ec9445f4afc 100644
--- a/src/plugins/discover/public/application/angular/doc_table/components/table_row.ts
+++ b/src/plugins/discover/public/application/angular/doc_table/components/table_row.ts
@@ -16,7 +16,7 @@ import cellTemplateHtml from '../components/table_row/cell.html';
import truncateByHeightTemplateHtml from '../components/table_row/truncate_by_height.html';
import { getServices } from '../../../../kibana_services';
import { getContextUrl } from '../../../helpers/get_context_url';
-import { formatRow } from '../../helpers';
+import { formatRow, formatTopLevelObject } from '../../helpers';
const TAGS_WITH_WS = />\s+ {
+ return key.indexOf(`${column}.`) === 0;
+ })
+ );
+ newHtmls.push(
+ cellTemplate({
+ timefield: false,
+ sourcefield: true,
+ formatted: formatTopLevelObject(row, innerColumns, indexPattern),
+ filterable: false,
+ column,
+ })
+ );
+ } else {
+ newHtmls.push(
+ cellTemplate({
+ timefield: false,
+ sourcefield: column === '_source',
+ formatted: _displayField(row, column, true),
+ filterable: isFilterable,
+ column,
+ })
+ );
+ }
});
}
diff --git a/src/plugins/discover/public/application/angular/helpers/index.ts b/src/plugins/discover/public/application/angular/helpers/index.ts
index 3d4893268fdee..1dd194436cdfb 100644
--- a/src/plugins/discover/public/application/angular/helpers/index.ts
+++ b/src/plugins/discover/public/application/angular/helpers/index.ts
@@ -7,5 +7,5 @@
*/
export { buildPointSeriesData } from './point_series';
-export { formatRow } from './row_formatter';
+export { formatRow, formatTopLevelObject } from './row_formatter';
export { handleSourceColumnState } from './state_helpers';
diff --git a/src/plugins/discover/public/application/angular/helpers/row_formatter.test.ts b/src/plugins/discover/public/application/angular/helpers/row_formatter.test.ts
index 259ad2c2d3d1b..abbc529460591 100644
--- a/src/plugins/discover/public/application/angular/helpers/row_formatter.test.ts
+++ b/src/plugins/discover/public/application/angular/helpers/row_formatter.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { formatRow } from './row_formatter';
+import { formatRow, formatTopLevelObject } from './row_formatter';
import { stubbedSavedObjectIndexPattern } from '../../../__mocks__/stubbed_saved_object_index_pattern';
import { IndexPattern } from '../../../../../data/common/index_patterns/index_patterns';
import { fieldFormatsMock } from '../../../../../data/common/field_formats/mocks';
@@ -43,16 +43,97 @@ describe('Row formatter', () => {
foo: 'bar',
hello: '<h1>World</h1>',
};
- const formatHitMock = jest.fn().mockReturnValueOnce(formatHitReturnValue);
+ const formatHitMock = jest.fn().mockReturnValue(formatHitReturnValue);
beforeEach(() => {
- // @ts-ignore
+ // @ts-expect-error
indexPattern.formatHit = formatHitMock;
});
it('formats document properly', () => {
- expect(formatRow(hit, indexPattern).trim()).toBe(
- '
- also:
- with \\"quotes\\" or 'single qoutes'
- number:
- 42
- foo:
- bar
- hello:
- <h1>World</h1>
'
+ expect(formatRow(hit, indexPattern).trim()).toMatchInlineSnapshot(
+ `"- also:
- with \\\\"quotes\\\\" or 'single qoutes'
- number:
- 42
- foo:
- bar
- hello:
- <h1>World</h1>
"`
+ );
+ });
+
+ it('formats document with highlighted fields first', () => {
+ expect(
+ formatRow({ ...hit, highlight: { number: '42' } }, indexPattern).trim()
+ ).toMatchInlineSnapshot(
+ `"- number:
- 42
- also:
- with \\\\"quotes\\\\" or 'single qoutes'
- foo:
- bar
- hello:
- <h1>World</h1>
"`
+ );
+ });
+
+ it('formats top level objects using formatter', () => {
+ indexPattern.getFieldByName = jest.fn().mockReturnValue({
+ name: 'subfield',
+ });
+ indexPattern.getFormatterForField = jest.fn().mockReturnValue({
+ convert: () => 'formatted',
+ });
+ expect(
+ formatTopLevelObject(
+ {
+ fields: {
+ 'object.value': [5, 10],
+ },
+ },
+ {
+ 'object.value': [5, 10],
+ },
+ indexPattern
+ ).trim()
+ ).toMatchInlineSnapshot(
+ `"- object.value:
- formatted, formatted
"`
+ );
+ });
+
+ it('formats top level objects with subfields and highlights', () => {
+ indexPattern.getFieldByName = jest.fn().mockReturnValue({
+ name: 'subfield',
+ });
+ indexPattern.getFormatterForField = jest.fn().mockReturnValue({
+ convert: () => 'formatted',
+ });
+ expect(
+ formatTopLevelObject(
+ {
+ fields: {
+ 'object.value': [5, 10],
+ 'object.keys': ['a', 'b'],
+ },
+ highlight: {
+ 'object.keys': 'a',
+ },
+ },
+ {
+ 'object.value': [5, 10],
+ 'object.keys': ['a', 'b'],
+ },
+ indexPattern
+ ).trim()
+ ).toMatchInlineSnapshot(
+ `"- object.keys:
- formatted, formatted
- object.value:
- formatted, formatted
"`
+ );
+ });
+
+ it('formats top level objects, converting unknown fields to string', () => {
+ indexPattern.getFieldByName = jest.fn();
+ indexPattern.getFormatterForField = jest.fn();
+ expect(
+ formatTopLevelObject(
+ {
+ fields: {
+ 'object.value': [5, 10],
+ },
+ },
+ {
+ 'object.value': [5, 10],
+ },
+ indexPattern
+ ).trim()
+ ).toMatchInlineSnapshot(
+ `"- object.value:
- 5, 10
"`
);
});
});
diff --git a/src/plugins/discover/public/application/angular/helpers/row_formatter.ts b/src/plugins/discover/public/application/angular/helpers/row_formatter.ts
index 1291bce23c5f3..e17e840e40484 100644
--- a/src/plugins/discover/public/application/angular/helpers/row_formatter.ts
+++ b/src/plugins/discover/public/application/angular/helpers/row_formatter.ts
@@ -35,3 +35,31 @@ export const formatRow = (hit: Record, indexPattern: IndexPattern)
});
return doTemplate({ defPairs: [...highlightPairs, ...sourcePairs] });
};
+
+export const formatTopLevelObject = (
+ row: Record,
+ fields: Record,
+ indexPattern: IndexPattern
+) => {
+ const highlights = row.highlight ?? {};
+ const highlightPairs: Array<[string, unknown]> = [];
+ const sourcePairs: Array<[string, unknown]> = [];
+ Object.entries(fields).forEach(([key, values]) => {
+ const field = indexPattern.getFieldByName(key);
+ const formatter = field
+ ? indexPattern.getFormatterForField(field)
+ : { convert: (v: string, ...rest: unknown[]) => String(v) };
+ const formatted = values
+ .map((val: unknown) =>
+ formatter.convert(val, 'html', {
+ field,
+ hit: row,
+ indexPattern,
+ })
+ )
+ .join(', ');
+ const pairs = highlights[key] ? highlightPairs : sourcePairs;
+ pairs.push([key, formatted]);
+ });
+ return doTemplate({ defPairs: [...highlightPairs, ...sourcePairs] });
+};
diff --git a/src/plugins/discover/public/application/components/discover.tsx b/src/plugins/discover/public/application/components/discover.tsx
index e62dccbadcbd0..d0c839aac5a6c 100644
--- a/src/plugins/discover/public/application/components/discover.tsx
+++ b/src/plugins/discover/public/application/components/discover.tsx
@@ -410,6 +410,7 @@ export function Discover({
onSetColumns={onSetColumns}
onSort={onSort}
onResize={onResize}
+ useNewFieldsApi={useNewFieldsApi}
/>
)}
diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx
index 4f92a49abd292..a0dcc2c2af466 100644
--- a/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx
+++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid.tsx
@@ -120,6 +120,10 @@ export interface DiscoverGridProps {
* Current sort setting
*/
sort: SortPairArr[];
+ /**
+ * How the data is fetched
+ */
+ useNewFieldsApi: boolean;
}
export const EuiDataGridMemoized = React.memo((props: EuiDataGridProps) => {
@@ -146,6 +150,7 @@ export const DiscoverGrid = ({
settings,
showTimeCol,
sort,
+ useNewFieldsApi,
}: DiscoverGridProps) => {
const displayedColumns = getDisplayedColumns(columns, indexPattern);
const defaultColumns = displayedColumns.includes('_source');
@@ -197,9 +202,10 @@ export const DiscoverGrid = ({
getRenderCellValueFn(
indexPattern,
rows,
- rows ? rows.map((hit) => indexPattern.flattenHit(hit)) : []
+ rows ? rows.map((hit) => indexPattern.flattenHit(hit)) : [],
+ useNewFieldsApi
),
- [rows, indexPattern]
+ [rows, indexPattern, useNewFieldsApi]
);
/**
diff --git a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx b/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx
index 786d7bc74bf6b..a1447a9a83672 100644
--- a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx
+++ b/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx
@@ -10,13 +10,45 @@ import React from 'react';
import { shallow } from 'enzyme';
import { getRenderCellValueFn } from './get_render_cell_value';
import { indexPatternMock } from '../../../__mocks__/index_pattern';
-const rows = [
+
+const rowsSource = [
+ {
+ _id: '1',
+ _index: 'test',
+ _type: 'test',
+ _score: 1,
+ _source: { bytes: 100, extension: '.gz' },
+ highlight: {
+ extension: '@kibana-highlighted-field.gz@/kibana-highlighted-field',
+ },
+ },
+];
+
+const rowsFields = [
{
_id: '1',
_index: 'test',
_type: 'test',
_score: 1,
- _source: { bytes: 100 },
+ _source: undefined,
+ fields: { bytes: [100], extension: ['.gz'] },
+ highlight: {
+ extension: '@kibana-highlighted-field.gz@/kibana-highlighted-field',
+ },
+ },
+];
+
+const rowsFieldsWithTopLevelObject = [
+ {
+ _id: '1',
+ _index: 'test',
+ _type: 'test',
+ _score: 1,
+ _source: undefined,
+ fields: { 'object.value': [100], extension: ['.gz'] },
+ highlight: {
+ extension: '@kibana-highlighted-field.gz@/kibana-highlighted-field',
+ },
},
];
@@ -24,8 +56,9 @@ describe('Discover grid cell rendering', function () {
it('renders bytes column correctly', () => {
const DiscoverGridCellValue = getRenderCellValueFn(
indexPatternMock,
- rows,
- rows.map((row) => indexPatternMock.flattenHit(row))
+ rowsSource,
+ rowsSource.map((row) => indexPatternMock.flattenHit(row)),
+ false
);
const component = shallow(
100"`);
});
+
it('renders _source column correctly', () => {
const DiscoverGridCellValue = getRenderCellValueFn(
indexPatternMock,
- rows,
- rows.map((row) => indexPatternMock.flattenHit(row))
+ rowsSource,
+ rowsSource.map((row) => indexPatternMock.flattenHit(row)),
+ false
);
const component = shallow(
);
- expect(component.html()).toMatchInlineSnapshot(
- `"- bytes
- 100
"`
- );
+ expect(component).toMatchInlineSnapshot(`
+
+
+ extension
+
+
+
+ bytes
+
+
+
+ `);
});
it('renders _source column correctly when isDetails is set to true', () => {
const DiscoverGridCellValue = getRenderCellValueFn(
indexPatternMock,
- rows,
- rows.map((row) => indexPatternMock.flattenHit(row))
+ rowsSource,
+ rowsSource.map((row) => indexPatternMock.flattenHit(row)),
+ false
);
const component = shallow(
"
+ `);
+ });
+
+ it('renders fields-based column correctly', () => {
+ const DiscoverGridCellValue = getRenderCellValueFn(
+ indexPatternMock,
+ rowsFields,
+ rowsFields.map((row) => indexPatternMock.flattenHit(row)),
+ true
+ );
+ const component = shallow(
+
+ );
+ expect(component).toMatchInlineSnapshot(`
+
+
+ extension
+
+
+
+ bytes
+
+
+
+ `);
+ });
+
+ it('renders fields-based column correctly when isDetails is set to true', () => {
+ const DiscoverGridCellValue = getRenderCellValueFn(
+ indexPatternMock,
+ rowsFields,
+ rowsFields.map((row) => indexPatternMock.flattenHit(row)),
+ true
+ );
+ const component = shallow(
+
+ );
+ expect(component.html()).toMatchInlineSnapshot(`
+ "{
+ "_id": "1",
+ "_index": "test",
+ "_type": "test",
+ "_score": 1,
+ "fields": {
+ "bytes": [
+ 100
+ ],
+ "extension": [
+ ".gz"
+ ]
+ },
+ "highlight": {
+ "extension": "@kibana-highlighted-field.gz@/kibana-highlighted-field"
}
}"
`);
});
+ it('collect object fields and renders them like _source', () => {
+ const DiscoverGridCellValue = getRenderCellValueFn(
+ indexPatternMock,
+ rowsFieldsWithTopLevelObject,
+ rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)),
+ true
+ );
+ const component = shallow(
+
+ );
+ expect(component).toMatchInlineSnapshot(`
+
+
+ object.value
+
+
+
+ `);
+ });
+
+ it('collect object fields and renders them like _source with fallback for unmapped', () => {
+ (indexPatternMock.getFieldByName as jest.Mock).mockReturnValueOnce(undefined);
+ const DiscoverGridCellValue = getRenderCellValueFn(
+ indexPatternMock,
+ rowsFieldsWithTopLevelObject,
+ rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)),
+ true
+ );
+ const component = shallow(
+
+ );
+ expect(component).toMatchInlineSnapshot(`
+
+
+ object.value
+
+
+
+ `);
+ });
+
+ it('collect object fields and renders them as json in details', () => {
+ const DiscoverGridCellValue = getRenderCellValueFn(
+ indexPatternMock,
+ rowsFieldsWithTopLevelObject,
+ rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)),
+ true
+ );
+ const component = shallow(
+
+ );
+ expect(component).toMatchInlineSnapshot(`
+
+ {
+ "object.value": [
+ 100
+ ]
+ }
+
+ `);
+ });
+
+ it('does not collect subfields when the the column is unmapped but part of fields response', () => {
+ (indexPatternMock.getFieldByName as jest.Mock).mockReturnValueOnce(undefined);
+ const DiscoverGridCellValue = getRenderCellValueFn(
+ indexPatternMock,
+ rowsFieldsWithTopLevelObject,
+ rowsFieldsWithTopLevelObject.map((row) => indexPatternMock.flattenHit(row)),
+ true
+ );
+ const component = shallow(
+
+ );
+ expect(component).toMatchInlineSnapshot(`
+
+ `);
+ });
+
it('renders correctly when invalid row is given', () => {
const DiscoverGridCellValue = getRenderCellValueFn(
indexPatternMock,
- rows,
- rows.map((row) => indexPatternMock.flattenHit(row))
+ rowsSource,
+ rowsSource.map((row) => indexPatternMock.flattenHit(row)),
+ false
);
const component = shallow(
-"`);
});
+
it('renders correctly when invalid column is given', () => {
const DiscoverGridCellValue = getRenderCellValueFn(
indexPatternMock,
- rows,
- rows.map((row) => indexPatternMock.flattenHit(row))
+ rowsSource,
+ rowsSource.map((row) => indexPatternMock.flattenHit(row)),
+ false
);
const component = shallow(
>
+ rowsFlattened: Array>,
+ useNewFieldsApi: boolean
) => ({ rowIndex, columnId, isDetails, setCellProps }: EuiDataGridCellValueElementProps) => {
const row = rows ? (rows[rowIndex] as Record) : undefined;
const rowFlattened = rowsFlattened
@@ -51,6 +52,60 @@ export const getRenderCellValueFn = (
return -;
}
+ if (
+ useNewFieldsApi &&
+ !field &&
+ row &&
+ row.fields &&
+ !(row.fields as Record)[columnId]
+ ) {
+ const innerColumns = Object.fromEntries(
+ Object.entries(row.fields as Record).filter(([key]) => {
+ return key.indexOf(`${columnId}.`) === 0;
+ })
+ );
+ if (isDetails) {
+ // nicely formatted JSON for the expanded view
+ return {JSON.stringify(innerColumns, null, 2)};
+ }
+
+ // Put the most important fields first
+ const highlights: Record = (row.highlight as Record) ?? {};
+ const highlightPairs: Array<[string, string]> = [];
+ const sourcePairs: Array<[string, string]> = [];
+ Object.entries(innerColumns).forEach(([key, values]) => {
+ const subField = indexPattern.getFieldByName(key);
+ const formatter = subField
+ ? indexPattern.getFormatterForField(subField)
+ : { convert: (v: string, ...rest: unknown[]) => String(v) };
+ const formatted = (values as unknown[])
+ .map((val: unknown) =>
+ formatter.convert(val, 'html', {
+ field: subField,
+ hit: row,
+ indexPattern,
+ })
+ )
+ .join(', ');
+ const pairs = highlights[key] ? highlightPairs : sourcePairs;
+ pairs.push([key, formatted]);
+ });
+
+ return (
+
+ {[...highlightPairs, ...sourcePairs].map(([key, value]) => (
+
+ {key}
+
+
+ ))}
+
+ );
+ }
+
if (field && field.type === '_source') {
if (isDetails) {
// nicely formatted JSON for the expanded view
@@ -58,13 +113,23 @@ export const getRenderCellValueFn = (
}
const formatted = indexPattern.formatHit(row);
+ // Put the most important fields first
+ const highlights: Record = (row.highlight as Record) ?? {};
+ const highlightPairs: Array<[string, string]> = [];
+ const sourcePairs: Array<[string, string]> = [];
+
+ Object.entries(formatted).forEach(([key, val]) => {
+ const pairs = highlights[key] ? highlightPairs : sourcePairs;
+ pairs.push([key, val as string]);
+ });
+
return (
- {Object.keys(formatted).map((key) => (
+ {[...highlightPairs, ...sourcePairs].map(([key, value]) => (
{key}
diff --git a/test/functional/apps/discover/_field_data.ts b/test/functional/apps/discover/_field_data.ts
index 3a84158609a18..3583a8b12c415 100644
--- a/test/functional/apps/discover/_field_data.ts
+++ b/test/functional/apps/discover/_field_data.ts
@@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const kibanaServer = getService('kibanaServer');
const toasts = getService('toasts');
const queryBar = getService('queryBar');
+ const browser = getService('browser');
const PageObjects = getPageObjects(['common', 'header', 'discover', 'visualize', 'timePicker']);
describe('discover tab', function describeIndexTests() {
@@ -89,6 +90,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(message).to.contain(expectedError);
await toasts.dismissToast();
});
+
+ it('shows top-level object keys', async function () {
+ await queryBar.setQuery('election');
+ await queryBar.submitQuery();
+ const currentUrl = await browser.getCurrentUrl();
+ const [, hash] = currentUrl.split('#/');
+ await PageObjects.common.navigateToUrl(
+ 'discover',
+ hash.replace('columns:!(_source)', 'columns:!(relatedContent)'),
+ { useActualUrl: true }
+ );
+ await retry.try(async function tryingForTime() {
+ expect(await PageObjects.discover.getDocHeader()).to.be('Time relatedContent');
+ });
+
+ const field = await PageObjects.discover.getDocTableField(1, 1);
+ expect(field).to.include.string('"og:description":');
+
+ const marks = await PageObjects.discover.getMarks();
+ expect(marks.length).to.be(0);
+ });
});
});
}
diff --git a/test/functional/apps/discover/_field_data_with_fields_api.ts b/test/functional/apps/discover/_field_data_with_fields_api.ts
index 73864377476b2..168f718c38602 100644
--- a/test/functional/apps/discover/_field_data_with_fields_api.ts
+++ b/test/functional/apps/discover/_field_data_with_fields_api.ts
@@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const kibanaServer = getService('kibanaServer');
const toasts = getService('toasts');
const queryBar = getService('queryBar');
+ const browser = getService('browser');
const PageObjects = getPageObjects(['common', 'header', 'discover', 'visualize', 'timePicker']);
describe('discover tab with new fields API', function describeIndexTests() {
@@ -89,6 +90,28 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(message).to.contain(expectedError);
await toasts.dismissToast();
});
+
+ it('shows top-level object keys', async function () {
+ await queryBar.setQuery('election');
+ await queryBar.submitQuery();
+ const currentUrl = await browser.getCurrentUrl();
+ const [, hash] = currentUrl.split('#/');
+ await PageObjects.common.navigateToUrl(
+ 'discover',
+ hash.replace('columns:!()', 'columns:!(relatedContent)'),
+ { useActualUrl: true }
+ );
+ await retry.try(async function tryingForTime() {
+ expect(await PageObjects.discover.getDocHeader()).to.be('Time relatedContent');
+ });
+
+ const field = await PageObjects.discover.getDocTableField(1, 1);
+ expect(field).to.include.string('relatedContent.url:');
+
+ const marks = await PageObjects.discover.getMarks();
+ expect(marks.length).to.be(172);
+ expect(marks.indexOf('election')).to.be(0);
+ });
});
});
}
diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts
index d46976ddc15ae..4763a12c29329 100644
--- a/test/functional/page_objects/discover_page.ts
+++ b/test/functional/page_objects/discover_page.ts
@@ -201,11 +201,11 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider
return await row.getVisibleText();
}
- public async getDocTableField(index: number) {
- const field = await find.byCssSelector(
- `tr.kbnDocTable__row:nth-child(${index}) > [data-test-subj='docTableField']`
+ public async getDocTableField(index: number, cellIndex = 0) {
+ const fields = await find.allByCssSelector(
+ `tr.kbnDocTable__row:nth-child(${index}) [data-test-subj='docTableField']`
);
- return await field.getVisibleText();
+ return await fields[cellIndex].getVisibleText();
}
public async skipToEndOfDocTable() {