Ftr/tsfy doc table (#41710) (#41952)

* [services/doc_table] tsfy service and use parse dom to get rows

* [services/doc_table] do not pass table element as argument

* [services/doc_table] update service to minimize StaleElementReference cases

* [services/doc_table] add missing access modifier

* [services/doc_table] change getHeaderFields and fix return types
This commit is contained in:
Dmitry Lemeshko 2019-07-25 09:51:33 +02:00 committed by GitHub
parent b237a661a4
commit 2b4d037c06
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 219 additions and 173 deletions

View file

@ -46,13 +46,11 @@ export default function ({ getService, getPageObjects }) {
it('displays predessors - anchor - successors in right order ', async function () {
await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_TYPE, 'AU_x3-TaGFA8no6Qj999Z');
const table = await docTable.getTable();
const rows = await docTable.getBodyRows(table);
const actualRowsText = await Promise.all(rows.map(row => row.getVisibleText()));
const actualRowsText = await docTable.getRowsText();
const expectedRowsText = [
'Sep 18, 2019 @ 06:50:13.000000000\n-2',
'Sep 18, 2019 @ 06:50:12.999999999\n-3',
'Sep 19, 2015 @ 06:50:13.000100001\n1'
'Sep 18, 2019 @ 06:50:13.000000000-2',
'Sep 18, 2019 @ 06:50:12.999999999-3',
'Sep 19, 2015 @ 06:50:13.0001000011'
];
expect(actualRowsText).to.eql(expectedRowsText);
});
@ -61,19 +59,17 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_TYPE, 'AU_x3-TaGFA8no6Qjisd');
await PageObjects.context.clickPredecessorLoadMoreButton();
await PageObjects.context.clickSuccessorLoadMoreButton();
const table = await docTable.getTable();
const rows = await docTable.getBodyRows(table);
const actualRowsText = await Promise.all(rows.map(row => row.getVisibleText()));
const actualRowsText = await docTable.getRowsText();
const expectedRowsText = [
'Sep 22, 2019 @ 23:50:13.253123345\n5',
'Sep 18, 2019 @ 06:50:13.000000104\n4',
'Sep 18, 2019 @ 06:50:13.000000103\n2',
'Sep 18, 2019 @ 06:50:13.000000102\n1',
'Sep 18, 2019 @ 06:50:13.000000101\n0',
'Sep 18, 2019 @ 06:50:13.000000001\n-1',
'Sep 18, 2019 @ 06:50:13.000000000\n-2',
'Sep 18, 2019 @ 06:50:12.999999999\n-3',
'Sep 19, 2015 @ 06:50:13.000100001\n1'
'Sep 22, 2019 @ 23:50:13.2531233455',
'Sep 18, 2019 @ 06:50:13.0000001044',
'Sep 18, 2019 @ 06:50:13.0000001032',
'Sep 18, 2019 @ 06:50:13.0000001021',
'Sep 18, 2019 @ 06:50:13.0000001010',
'Sep 18, 2019 @ 06:50:13.000000001-1',
'Sep 18, 2019 @ 06:50:13.000000000-2',
'Sep 18, 2019 @ 06:50:12.999999999-3',
'Sep 19, 2015 @ 06:50:13.0001000011'
];
expect(actualRowsText).to.eql(expectedRowsText);

View file

@ -45,40 +45,26 @@ export default function ({ getService, getPageObjects }) {
});
it('should open the context view with the selected document as anchor', async function () {
const discoverDocTable = await docTable.getTable();
const firstRow = (await docTable.getBodyRows(discoverDocTable))[0];
// get the timestamp of the first row
const firstTimestamp = await (await docTable.getFields(firstRow))[0]
.getVisibleText();
const firstTimestamp = (await docTable.getFields())[0][0];
// navigate to the context view
await (await docTable.getRowExpandToggle(firstRow)).click();
const firstDetailsRow = (await docTable.getDetailsRows(discoverDocTable))[0];
await (await docTable.getRowActions(firstDetailsRow))[0].click();
await docTable.clickRowToggle({ rowIndex: 0 });
await (await docTable.getRowActions({ rowIndex: 0 }))[0].click();
// check the anchor timestamp in the context view
await retry.try(async () => {
const contextDocTable = await docTable.getTable();
const anchorRow = await docTable.getAnchorRow(contextDocTable);
const anchorTimestamp = await (await docTable.getFields(anchorRow))[0]
.getVisibleText();
const anchorTimestamp = (await docTable.getFields({ isAnchorRow: true }))[0][0];
expect(anchorTimestamp).to.equal(firstTimestamp);
});
});
it('should open the context view with the same columns', async function () {
const table = await docTable.getTable();
await retry.try(async () => {
const headerFields = await docTable.getHeaderFields(table);
const columnNames = await Promise.all(headerFields.map((headerField) => (
headerField.getVisibleText()
)));
expect(columnNames).to.eql([
'Time',
...TEST_COLUMN_NAMES,
]);
});
const columnNames = await docTable.getHeaderFields();
expect(columnNames).to.eql([
'Time',
...TEST_COLUMN_NAMES,
]);
});
it('should open the context view with the filters disabled', async function () {

View file

@ -29,6 +29,8 @@ const TEST_COLUMN_NAMES = ['extension', 'geo.src'];
export default function ({ getService, getPageObjects }) {
const docTable = getService('docTable');
const filterBar = getService('filterBar');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'context']);
describe('context filters', function contextSize() {
@ -38,47 +40,40 @@ export default function ({ getService, getPageObjects }) {
});
});
// FLAKY: https://github.com/elastic/kibana/issues/39927
it.skip('should be addable via expanded doc table rows', async function () {
const table = await docTable.getTable();
const anchorRow = await docTable.getAnchorRow(table);
it('should be addable via expanded doc table rows', async function () {
await docTable.toggleRowExpanded({ isAnchorRow: true });
await docTable.toggleRowExpanded(anchorRow);
const anchorDetailsRow = await docTable.getAnchorDetailsRow(table);
const anchorDetailsRow = await docTable.getAnchorDetailsRow();
await docTable.addInclusiveFilter(anchorDetailsRow, TEST_ANCHOR_FILTER_FIELD);
await PageObjects.context.waitUntilContextLoadingHasFinished();
await docTable.toggleRowExpanded(anchorRow);
await docTable.toggleRowExpanded({ isAnchorRow: true });
expect(await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, true)).to.be(true);
const rows = await docTable.getBodyRows(table);
const hasOnlyFilteredRows = (
await Promise.all(rows.map(
async (row) => await (await docTable.getFields(row))[2].getVisibleText()
))
).every((fieldContent) => fieldContent === TEST_ANCHOR_FILTER_VALUE);
expect(hasOnlyFilteredRows).to.be(true);
await retry.try(async () => {
expect(await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, true)).to.be(true);
const fields = await docTable.getFields();
const hasOnlyFilteredRows = fields
.map(row => row[2])
.every((fieldContent) => fieldContent === TEST_ANCHOR_FILTER_VALUE);
expect(hasOnlyFilteredRows).to.be(true);
});
});
it('should be toggleable via the filter bar', async function () {
const table = await docTable.getTable();
await filterBar.addFilter(TEST_ANCHOR_FILTER_FIELD, 'IS', TEST_ANCHOR_FILTER_VALUE);
await PageObjects.context.waitUntilContextLoadingHasFinished();
// disable filter
await filterBar.toggleFilterEnabled(TEST_ANCHOR_FILTER_FIELD);
await PageObjects.context.waitUntilContextLoadingHasFinished();
expect(await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, false)).to.be(true);
const rows = await docTable.getBodyRows(table);
const hasOnlyFilteredRows = (
await Promise.all(rows.map(
async (row) => await (await docTable.getFields(row))[2].getVisibleText()
))
).every((fieldContent) => fieldContent === TEST_ANCHOR_FILTER_VALUE);
expect(hasOnlyFilteredRows).to.be(false);
retry.try(async () => {
expect(await filterBar.hasFilter(TEST_ANCHOR_FILTER_FIELD, TEST_ANCHOR_FILTER_VALUE, false)).to.be(true);
const fields = await docTable.getFields();
const hasOnlyFilteredRows = fields
.map(row => row[2])
.every((fieldContent) => fieldContent === TEST_ANCHOR_FILTER_VALUE);
expect(hasOnlyFilteredRows).to.be(false);
});
});
});
}

View file

@ -42,9 +42,8 @@ export default function ({ getService, getPageObjects }) {
it('should default to the `context:defaultSize` setting', async function () {
await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_TYPE, TEST_ANCHOR_ID);
const table = await docTable.getTable();
await retry.try(async function () {
expect(await docTable.getBodyRows(table)).to.have.length(2 * TEST_DEFAULT_CONTEXT_SIZE + 1);
expect(await docTable.getRowsText()).to.have.length(2 * TEST_DEFAULT_CONTEXT_SIZE + 1);
});
await retry.try(async function () {
const predecessorCountPicker = await PageObjects.context.getPredecessorCountPicker();
@ -58,12 +57,10 @@ export default function ({ getService, getPageObjects }) {
it('should increase according to the `context:step` setting when clicking the `load newer` button', async function () {
await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_TYPE, TEST_ANCHOR_ID);
const table = await docTable.getTable();
await PageObjects.context.clickPredecessorLoadMoreButton();
await retry.try(async function () {
expect(await docTable.getBodyRows(table)).to.have.length(
expect(await docTable.getRowsText()).to.have.length(
2 * TEST_DEFAULT_CONTEXT_SIZE + TEST_STEP_SIZE + 1
);
});
@ -71,12 +68,10 @@ export default function ({ getService, getPageObjects }) {
it('should increase according to the `context:step` setting when clicking the `load older` button', async function () {
await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, TEST_ANCHOR_TYPE, TEST_ANCHOR_ID);
const table = await docTable.getTable();
await PageObjects.context.clickSuccessorLoadMoreButton();
await retry.try(async function () {
expect(await docTable.getBodyRows(table)).to.have.length(
expect(await docTable.getRowsText()).to.have.length(
2 * TEST_DEFAULT_CONTEXT_SIZE + TEST_STEP_SIZE + 1
);
});

View file

@ -46,13 +46,9 @@ export default function ({ getService, getPageObjects }) {
});
it('should open the doc view of the selected document', async function () {
const discoverDocTable = await docTable.getTable();
const firstRow = (await docTable.getBodyRows(discoverDocTable))[0];
// navigate to the doc view
await (await docTable.getRowExpandToggle(firstRow)).click();
const firstDetailsRow = (await docTable.getDetailsRows(discoverDocTable))[0];
await (await docTable.getRowActions(firstDetailsRow))[1].click();
await docTable.clickRowToggle({ rowIndex: 0 });
await (await docTable.getRowActions({ rowIndex: 0 }))[1].click();
const hasDocHit = await testSubjects.exists('doc-hit');
expect(hasDocHit).to.be(true);

View file

@ -1,91 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export function DocTableProvider({ getService, getPageObjects }) {
const testSubjects = getService('testSubjects');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'header']);
class DocTable {
async getTable() {
return await testSubjects.find('docTable');
}
async getBodyRows(table) {
return await table.findAllByCssSelector('[data-test-subj~="docTableRow"]');
}
async getAnchorRow(table) {
return await table.findByCssSelector('[data-test-subj~="docTableAnchorRow"]');
}
async getAnchorDetailsRow(table) {
return await table.findByCssSelector('[data-test-subj~="docTableAnchorRow"] + [data-test-subj~="docTableDetailsRow"]');
}
async getRowExpandToggle(row) {
return await row.findByCssSelector('[data-test-subj~="docTableExpandToggleColumn"]');
}
async getDetailsRows(table) {
return await table.findAllByCssSelector('[data-test-subj~="docTableRow"] + [data-test-subj~="docTableDetailsRow"]');
}
async getRowActions(row) {
return await row.findAllByCssSelector('[data-test-subj~="docTableRowAction"]');
}
async getFields(row) {
return await row.findAllByCssSelector('[data-test-subj~="docTableField"]');
}
async getHeaderFields(table) {
return await table.findAllByCssSelector('[data-test-subj~="docTableHeaderField"]');
}
async getTableDocViewRow(detailsRow, fieldName) {
return await detailsRow.findByCssSelector(`[data-test-subj~="tableDocViewRow-${fieldName}"]`);
}
async getAddInclusiveFilterButton(tableDocViewRow) {
return await tableDocViewRow.findByCssSelector(`[data-test-subj~="addInclusiveFilterButton"]`);
}
async addInclusiveFilter(detailsRow, fieldName) {
const tableDocViewRow = await this.getTableDocViewRow(detailsRow, fieldName);
const addInclusiveFilterButton = await this.getAddInclusiveFilterButton(tableDocViewRow);
await addInclusiveFilterButton.click();
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}
async toggleRowExpanded(row) {
const rowExpandToggle = await this.getRowExpandToggle(row);
await rowExpandToggle.click();
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
const detailsRow = await row.findByXpath('./following-sibling::*[@data-test-subj="docTableDetailsRow"]');
return await retry.try(async () => {
return detailsRow.findByCssSelector('[data-test-subj~="docViewer"]');
});
}
}
return new DocTable();
}

View file

@ -0,0 +1,169 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { FtrProviderContext } from '../ftr_provider_context';
import { WebElementWrapper } from './lib/web_element_wrapper';
export function DocTableProvider({ getService, getPageObjects }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
const retry = getService('retry');
const PageObjects = getPageObjects(['common', 'header']);
interface SelectOptions {
isAnchorRow: boolean;
rowIndex: number;
}
class DocTable {
public async getTable() {
return await testSubjects.find('docTable');
}
public async getRowsText(): Promise<string[]> {
const table = await this.getTable();
const $ = await table.parseDomContent();
return $('[data-test-subj~="docTableRow"]')
.toArray()
.map((row: any) =>
$(row)
.text()
.trim()
);
}
public async getBodyRows(): Promise<WebElementWrapper[]> {
const table = await this.getTable();
return await table.findAllByCssSelector('[data-test-subj~="docTableRow"]');
}
public async getAnchorRow(): Promise<WebElementWrapper> {
const table = await this.getTable();
return await table.findByCssSelector('[data-test-subj~="docTableAnchorRow"]');
}
public async getRow(options: SelectOptions): Promise<WebElementWrapper> {
return options.isAnchorRow
? await this.getAnchorRow()
: (await this.getBodyRows())[options.rowIndex];
}
public async getAnchorDetailsRow(): Promise<WebElementWrapper> {
const table = await this.getTable();
return await table.findByCssSelector(
'[data-test-subj~="docTableAnchorRow"] + [data-test-subj~="docTableDetailsRow"]'
);
}
public async clickRowToggle(
options: SelectOptions = { isAnchorRow: false, rowIndex: 0 }
): Promise<void> {
const row = await this.getRow(options);
const toggle = await row.findByCssSelector('[data-test-subj~="docTableExpandToggleColumn"]');
await toggle.click();
}
public async getDetailsRows(): Promise<WebElementWrapper[]> {
const table = await this.getTable();
return await table.findAllByCssSelector(
'[data-test-subj~="docTableRow"] + [data-test-subj~="docTableDetailsRow"]'
);
}
public async getRowActions(
options: SelectOptions = { isAnchorRow: false, rowIndex: 0 }
): Promise<WebElementWrapper[]> {
const detailsRow = options.isAnchorRow
? await this.getAnchorDetailsRow()
: (await this.getDetailsRows())[options.rowIndex];
return await detailsRow.findAllByCssSelector('[data-test-subj~="docTableRowAction"]');
}
public async getFields(
options: { isAnchorRow: boolean } = { isAnchorRow: false }
): Promise<string[][]> {
const table = await this.getTable();
const $ = await table.parseDomContent();
const rowLocator = options.isAnchorRow
? '[data-test-subj~="docTableAnchorRow"]'
: '[data-test-subj~="docTableRow"]';
const rows = $(rowLocator).toArray();
const fields = rows.map((row: any) =>
$(row)
.find('[data-test-subj~="docTableField"]')
.toArray()
.map((field: any) => $(field).text())
);
return fields;
}
public async getHeaderFields(): Promise<string[]> {
const table = await this.getTable();
const $ = await table.parseDomContent();
return $('[data-test-subj~="docTableHeaderField"]')
.toArray()
.map((field: any) =>
$(field)
.text()
.trim()
);
}
public async getTableDocViewRow(
detailsRow: WebElementWrapper,
fieldName: WebElementWrapper
): Promise<WebElementWrapper> {
return await detailsRow.findByCssSelector(`[data-test-subj~="tableDocViewRow-${fieldName}"]`);
}
public async getAddInclusiveFilterButton(
tableDocViewRow: WebElementWrapper
): Promise<WebElementWrapper> {
return await tableDocViewRow.findByCssSelector(
`[data-test-subj~="addInclusiveFilterButton"]`
);
}
public async addInclusiveFilter(
detailsRow: WebElementWrapper,
fieldName: WebElementWrapper
): Promise<void> {
const tableDocViewRow = await this.getTableDocViewRow(detailsRow, fieldName);
const addInclusiveFilterButton = await this.getAddInclusiveFilterButton(tableDocViewRow);
await addInclusiveFilterButton.click();
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}
public async toggleRowExpanded(
options: SelectOptions = { isAnchorRow: false, rowIndex: 0 }
): Promise<WebElementWrapper> {
await this.clickRowToggle(options);
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
return await retry.try(async () => {
const row = options.isAnchorRow
? await this.getAnchorRow()
: (await this.getBodyRows())[options.rowIndex];
const detailsRow = await row.findByXpath(
'./following-sibling::*[@data-test-subj="docTableDetailsRow"]'
);
return detailsRow.findByCssSelector('[data-test-subj~="docViewer"]');
});
}
}
return new DocTable();
}