Move EuiComboBox functional test utility functions into own service (#21219)

* Move EuiComboBox utility functions into its own service

* remove old functions from visualize page object

* use waitForDeletedByClassName instead of retry and exists to ensure no longer loading

* wait for options loading when getting options list
This commit is contained in:
Nathan Reese 2018-07-30 16:00:30 -06:00 committed by GitHub
parent 8399f8b5d7
commit 3b74158b40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 173 additions and 125 deletions

View file

@ -24,6 +24,7 @@ export default function ({ getService, getPageObjects }) {
const PageObjects = getPageObjects(['common', 'visualize', 'header']);
const testSubjects = getService('testSubjects');
const find = getService('find');
const comboBox = getService('comboBox');
const FIELD_NAME = 'machine.os.raw';
@ -36,8 +37,8 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.header.setAbsoluteRange('2017-01-01', '2017-01-02');
await PageObjects.visualize.clickVisEditorTab('controls');
await PageObjects.visualize.addInputControl();
await PageObjects.visualize.setComboBox('indexPatternSelect-0', 'logstash');
await PageObjects.visualize.setComboBox('fieldSelect-0', FIELD_NAME);
await comboBox.set('indexPatternSelect-0', 'logstash');
await comboBox.set('fieldSelect-0', FIELD_NAME);
await PageObjects.visualize.clickGo();
await PageObjects.header.waitUntilLoadingHasFinished();
});
@ -51,7 +52,7 @@ export default function ({ getService, getPageObjects }) {
describe('updateFiltersOnChange is false', () => {
it('should contain dropdown with terms aggregation results as options', async () => {
const menu = await PageObjects.visualize.getComboBoxOptions('listControlSelect0');
const menu = await comboBox.getOptionsList('listControlSelect0');
expect(menu.trim().split('\n').join()).to.equal('ios,osx,win 7,win 8,win xp');
});
@ -65,9 +66,9 @@ export default function ({ getService, getPageObjects }) {
});
it('should stage filter when item selected but not create filter pill', async () => {
await PageObjects.visualize.setComboBox('listControlSelect0', 'ios');
await comboBox.set('listControlSelect0', 'ios');
const selectedOptions = await PageObjects.visualize.getComboBoxSelectedOptions('listControlSelect0');
const selectedOptions = await comboBox.getComboBoxSelectedOptions('listControlSelect0');
expect(selectedOptions[0].trim()).to.equal('ios');
const hasFilter = await filterBar.hasFilter(FIELD_NAME, 'ios');
@ -82,8 +83,8 @@ export default function ({ getService, getPageObjects }) {
});
it('should replace existing filter pill(s) when new item is selected', async () => {
await PageObjects.visualize.clearComboBox('listControlSelect0');
await PageObjects.visualize.setComboBox('listControlSelect0', 'osx');
await comboBox.clear('listControlSelect0');
await comboBox.set('listControlSelect0', 'osx');
await PageObjects.visualize.inputControlSubmit();
await PageObjects.common.sleep(1000);
@ -97,18 +98,18 @@ export default function ({ getService, getPageObjects }) {
await filterBar.removeFilter(FIELD_NAME);
await PageObjects.common.sleep(500); // give time for filter to be removed and event handlers to fire
const hasValue = await PageObjects.visualize.doesComboBoxHaveSelectedOptions('listControlSelect0');
const hasValue = await comboBox.doesComboBoxHaveSelectedOptions('listControlSelect0');
expect(hasValue).to.equal(false);
});
it('should clear form when Clear button is clicked but not remove filter pill', async () => {
await PageObjects.visualize.setComboBox('listControlSelect0', 'ios');
await comboBox.set('listControlSelect0', 'ios');
await PageObjects.visualize.inputControlSubmit();
const hasFilterBeforeClearBtnClicked = await filterBar.hasFilter(FIELD_NAME, 'ios');
expect(hasFilterBeforeClearBtnClicked).to.equal(true);
await PageObjects.visualize.inputControlClear();
const hasValue = await PageObjects.visualize.doesComboBoxHaveSelectedOptions('listControlSelect0');
const hasValue = await comboBox.doesComboBoxHaveSelectedOptions('listControlSelect0');
expect(hasValue).to.equal(false);
const hasFilterAfterClearBtnClicked = await filterBar.hasFilter(FIELD_NAME, 'ios');
@ -149,9 +150,9 @@ export default function ({ getService, getPageObjects }) {
});
it('should add filter pill when item selected', async () => {
await PageObjects.visualize.setComboBox('listControlSelect0', 'ios');
await comboBox.set('listControlSelect0', 'ios');
const selectedOptions = await PageObjects.visualize.getComboBoxSelectedOptions('listControlSelect0');
const selectedOptions = await comboBox.getComboBoxSelectedOptions('listControlSelect0');
expect(selectedOptions[0].trim()).to.equal('ios');
const hasFilter = await filterBar.hasFilter(FIELD_NAME, 'ios');
@ -177,7 +178,7 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.header.waitUntilLoadingHasFinished();
// Expect control to have values for selected time filter
const menu = await PageObjects.visualize.getComboBoxOptions('listControlSelect0');
const menu = await comboBox.getOptionsList('listControlSelect0');
expect(menu.trim().split('\n').join()).to.equal('osx,win 7,win 8,win xp');
});
});
@ -189,37 +190,37 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.visualize.clickVisEditorTab('controls');
await PageObjects.visualize.addInputControl();
await PageObjects.visualize.setComboBox('indexPatternSelect-0', 'logstash');
await PageObjects.visualize.setComboBox('fieldSelect-0', 'geo.src');
await comboBox.set('indexPatternSelect-0', 'logstash');
await comboBox.set('fieldSelect-0', 'geo.src');
await PageObjects.visualize.clickGo();
await PageObjects.header.waitUntilLoadingHasFinished();
});
it('should fetch new options when string field is filtered', async () => {
const initialOptions = await PageObjects.visualize.getComboBoxOptions('listControlSelect0');
const initialOptions = await comboBox.getOptionsList('listControlSelect0');
expect(initialOptions.trim().split('\n').join()).to.equal('BD,BR,CN,ID,IN,JP,NG,PK,RU,US');
await PageObjects.visualize.filterComboBoxOptions('listControlSelect0', 'R');
await comboBox.filterOptionsList('listControlSelect0', 'R');
await PageObjects.header.waitUntilLoadingHasFinished();
const updatedOptions = await PageObjects.visualize.getComboBoxOptions('listControlSelect0');
const updatedOptions = await comboBox.getOptionsList('listControlSelect0');
expect(updatedOptions.trim().split('\n').join()).to.equal('AR,BR,FR,GR,IR,KR,RO,RU,RW,TR');
});
it('should not fetch new options when non-string is filtered', async () => {
await PageObjects.visualize.setComboBox('fieldSelect-0', 'clientip');
await comboBox.set('fieldSelect-0', 'clientip');
await PageObjects.visualize.clickGo();
await PageObjects.header.waitUntilLoadingHasFinished();
const initialOptions = await PageObjects.visualize.getComboBoxOptions('listControlSelect0');
const initialOptions = await comboBox.getOptionsList('listControlSelect0');
expect(initialOptions.trim().split('\n').join()).to.equal(
'135.206.117.161,177.194.175.66,18.55.141.62,243.158.217.196,32.146.206.24');
await PageObjects.visualize.filterComboBoxOptions('listControlSelect0', '17');
await comboBox.filterOptionsList('listControlSelect0', '17');
await PageObjects.header.waitUntilLoadingHasFinished();
const updatedOptions = await PageObjects.visualize.getComboBoxOptions('listControlSelect0');
const updatedOptions = await comboBox.getOptionsList('listControlSelect0');
expect(updatedOptions.trim().split('\n').join()).to.equal('135.206.117.161,177.194.175.66,243.158.217.196');
});
});
@ -232,12 +233,12 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.visualize.clickVisEditorTab('controls');
await PageObjects.visualize.addInputControl();
await PageObjects.visualize.setComboBox('indexPatternSelect-0', 'logstash');
await PageObjects.visualize.setComboBox('fieldSelect-0', 'geo.src');
await comboBox.set('indexPatternSelect-0', 'logstash');
await comboBox.set('fieldSelect-0', 'geo.src');
await PageObjects.visualize.addInputControl();
await PageObjects.visualize.setComboBox('indexPatternSelect-1', 'logstash');
await PageObjects.visualize.setComboBox('fieldSelect-1', 'clientip');
await comboBox.set('indexPatternSelect-1', 'logstash');
await comboBox.set('fieldSelect-1', 'clientip');
await PageObjects.visualize.setSelectByOptionText('parentSelect-1', 'geo.src');
await PageObjects.visualize.clickGo();
@ -245,7 +246,7 @@ export default function ({ getService, getPageObjects }) {
});
it('should disable child control when parent control is not set', async () => {
const parentControlMenu = await PageObjects.visualize.getComboBoxOptions('listControlSelect0');
const parentControlMenu = await comboBox.getOptionsList('listControlSelect0');
expect(parentControlMenu.trim().split('\n').join()).to.equal('BD,BR,CN,ID,IN,JP,NG,PK,RU,US');
const childControlInput = await find.byCssSelector('[data-test-subj="inputControl1"] input');
@ -254,14 +255,14 @@ export default function ({ getService, getPageObjects }) {
});
it('should filter child control options by parent control value', async () => {
await PageObjects.visualize.setComboBox('listControlSelect0', 'BR');
await comboBox.set('listControlSelect0', 'BR');
const childControlMenu = await PageObjects.visualize.getComboBoxOptions('listControlSelect1');
const childControlMenu = await comboBox.getOptionsList('listControlSelect1');
expect(childControlMenu.trim().split('\n').join()).to.equal('14.61.182.136,3.174.21.181,6.183.121.70,71.241.97.89,9.69.255.135');
});
it('should create a seperate filter pill for parent control and child control', async () => {
await PageObjects.visualize.setComboBox('listControlSelect1', '14.61.182.136');
await comboBox.set('listControlSelect1', '14.61.182.136');
await PageObjects.visualize.inputControlSubmit();
@ -273,7 +274,7 @@ export default function ({ getService, getPageObjects }) {
});
it('should clear child control dropdown when parent control value is removed', async () => {
await PageObjects.visualize.clearComboBox('listControlSelect0');
await comboBox.clear('listControlSelect0');
await PageObjects.common.sleep(500); // give time for filter to be removed and event handlers to fire
const childControlInput = await find.byCssSelector('[data-test-subj="inputControl1"] input');
@ -287,7 +288,7 @@ export default function ({ getService, getPageObjects }) {
await filterBar.removeFilter('geo.src');
await PageObjects.common.sleep(500); // give time for filter to be removed and event handlers to fire
const hasValue = await PageObjects.visualize.doesComboBoxHaveSelectedOptions('listControlSelect0');
const hasValue = await comboBox.doesComboBoxHaveSelectedOptions('listControlSelect0');
expect(hasValue).to.equal(false);
});
});

View file

@ -49,6 +49,7 @@ import {
DashboardAddPanelProvider,
DashboardPanelActionsProvider,
FlyoutProvider,
ComboBoxProvider,
VisualizationProvider,
} from './services';
@ -104,6 +105,7 @@ export default async function ({ readConfigFile }) {
dashboardAddPanel: DashboardAddPanelProvider,
dashboardPanelActions: DashboardPanelActionsProvider,
flyout: FlyoutProvider,
comboBox: ComboBoxProvider,
visualization: VisualizationProvider,
},
servers: commonConfig.get('servers'),

View file

@ -27,7 +27,8 @@ export function SettingsPageProvider({ getService, getPageObjects }) {
const config = getService('config');
const defaultFindTimeout = config.get('timeouts.find');
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['header', 'common', 'visualize']);
const comboBox = getService('comboBox');
const PageObjects = getPageObjects(['header', 'common']);
class SettingsPage {
async clickNavigation() {
@ -534,7 +535,7 @@ export function SettingsPageProvider({ getService, getPageObjects }) {
await this.setScriptedFieldScript(script);
await this.openScriptedFieldHelp('testTab');
if (additionalField) {
await PageObjects.visualize.setComboBox('additionalFieldsSelect', additionalField);
await comboBox.set('additionalFieldsSelect', additionalField);
await testSubjects.click('runScriptButton');
}
let scriptResults;

View file

@ -24,6 +24,7 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }) {
const retry = getService('retry');
const log = getService('log');
const testSubjects = getService('testSubjects');
const comboBox = getService('comboBox');
const PageObjects = getPageObjects(['common', 'header', 'visualize']);
class VisualBuilderPage {
@ -154,7 +155,7 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }) {
async selectAggType(value, nth = 0) {
const elements = await testSubjects.findAll('aggSelector');
await PageObjects.visualize.setComboBoxElement(elements[nth], value);
await comboBox.setElement(elements[nth], value);
return await PageObjects.header.waitUntilLoadingHasFinished();
}
@ -169,14 +170,13 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }) {
const varNameInput = await elements[nth].findByCssSelector('.vis_editor__calc_vars-name input');
await varNameInput.type(name);
const metricSelectWrapper = await elements[nth].findByCssSelector('.vis_editor__calc_vars-var');
await PageObjects.visualize.setComboBoxElement(metricSelectWrapper, metric);
await comboBox.setElement(metricSelectWrapper, metric);
return await PageObjects.header.waitUntilLoadingHasFinished();
}
async selectGroupByField(fieldName) {
const element = await testSubjects.find('groupByField');
await PageObjects.visualize.setComboBoxElement(element, fieldName);
await comboBox.set('groupByField', fieldName);
}
async setLabelValue(value) {

View file

@ -247,93 +247,6 @@ export function VisualizePageProvider({ getService, getPageObjects }) {
await input.type(timeString);
}
async setComboBox(comboBoxSelector, value) {
const comboBox = await testSubjects.find(comboBoxSelector);
await this.setComboBoxElement(comboBox, value);
await PageObjects.common.sleep(1000);
}
async setComboBoxElement(element, value) {
const input = await element.findByTagName('input');
await input.clearValue();
await input.type(value);
await PageObjects.common.sleep(500);
await find.clickByCssSelector('.euiComboBoxOption');
await this.closeComboBoxOptionsList(element);
}
async filterComboBoxOptions(comboBoxSelector, value) {
const comboBox = await testSubjects.find(comboBoxSelector);
const input = await comboBox.findByTagName('input');
await input.clearValue();
await input.type(value);
await PageObjects.common.sleep(500);
await this.closeComboBoxOptionsList(comboBox);
}
async getComboBoxOptions(comboBoxSelector) {
await testSubjects.click(comboBoxSelector);
const menu = await retry.try(
async () => await testSubjects.find('comboBoxOptionsList'));
const optionsText = await menu.getVisibleText();
const comboBox = await testSubjects.find(comboBoxSelector);
await this.closeComboBoxOptionsList(comboBox);
return optionsText;
}
async doesComboBoxHaveSelectedOptions(comboBoxSelector) {
const comboBox = await testSubjects.find(comboBoxSelector);
const selectedOptions = await comboBox.findAllByClassName('euiComboBoxPill');
return selectedOptions > 0;
}
async getComboBoxSelectedOptions(comboBoxSelector) {
const comboBox = await testSubjects.find(comboBoxSelector);
const selectedOptions = await comboBox.findAllByClassName('euiComboBoxPill');
if (selectedOptions.length === 0) {
return [];
}
const getOptionValuePromises = selectedOptions.map(async (optionElement) => {
return await optionElement.getVisibleText();
});
return await Promise.all(getOptionValuePromises);
}
async clearComboBox(comboBoxSelector) {
log.debug(`clearComboBox for comboBoxSelector:${comboBoxSelector}`);
const comboBox = await testSubjects.find(comboBoxSelector);
await retry.try(async () => {
const clearButtonExists = await this.doesComboBoxClearButtonExist(comboBox);
if (!clearButtonExists) {
log.debug('Unable to clear comboBox, comboBoxClearButton does not exist');
return;
}
const clearBtn = await comboBox.findByCssSelector('[data-test-subj="comboBoxClearButton"]');
await clearBtn.click();
const clearButtonStillExists = await this.doesComboBoxClearButtonExist(comboBox);
if (clearButtonStillExists) {
throw new Error('Failed to clear comboBox');
}
});
await this.closeComboBoxOptionsList(comboBox);
}
async doesComboBoxClearButtonExist(comboBoxElement) {
return await find.exists(
async () => await comboBoxElement.findByCssSelector('[data-test-subj="comboBoxClearButton"]'));
}
async closeComboBoxOptionsList(comboBoxElement) {
const isOptionsListOpen = await testSubjects.exists('comboBoxOptionsList');
if (isOptionsListOpen) {
const closeBtn = await comboBoxElement.findByCssSelector('[data-test-subj="comboBoxToggleListButton"]');
await closeBtn.click();
}
}
async addInputControl() {
await testSubjects.click('inputControlEditorAddBtn');
await PageObjects.header.waitUntilLoadingHasFinished();

View file

@ -0,0 +1,130 @@
/*
* 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 ComboBoxProvider({ getService }) {
const testSubjects = getService('testSubjects');
const find = getService('find');
const log = getService('log');
const retry = getService('retry');
// wrapper around EuiComboBox interactions
class ComboBox {
async set(comboBoxSelector, value) {
log.debug(`comboBox.set, comboBoxSelector: ${comboBoxSelector}`);
const comboBox = await testSubjects.find(comboBoxSelector);
await this.setElement(comboBox, value);
}
async setElement(comboBoxElement, value) {
log.debug(`comboBox.setElement, value: ${value}`);
await this._filterOptionsList(comboBoxElement, value);
await find.clickByCssSelector('.euiComboBoxOption');
await this.closeOptionsList(comboBoxElement);
}
async filterOptionsList(comboBoxSelector, filterValue) {
log.debug(`comboBox.filterOptionsList, comboBoxSelector: ${comboBoxSelector}, filter: ${filterValue}`);
const comboBox = await testSubjects.find(comboBoxSelector);
await this._filterOptionsList(comboBox, filterValue);
await this.closeOptionsList(comboBox);
}
async _filterOptionsList(comboBoxElement, filterValue) {
const input = await comboBoxElement.findByTagName('input');
await input.clearValue();
await input.type(filterValue);
await this._waitForOptionsListLoading(comboBoxElement);
}
async _waitForOptionsListLoading(comboBoxElement) {
await comboBoxElement.waitForDeletedByClassName('euiLoadingSpinner');
}
async getOptionsList(comboBoxSelector) {
log.debug(`comboBox.getOptionsList, comboBoxSelector: ${comboBoxSelector}`);
const comboBox = await testSubjects.find(comboBoxSelector);
await testSubjects.click(comboBoxSelector);
await this._waitForOptionsListLoading(comboBox);
const menu = await retry.try(
async () => await testSubjects.find('comboBoxOptionsList'));
const optionsText = await menu.getVisibleText();
await this.closeOptionsList(comboBox);
return optionsText;
}
async doesComboBoxHaveSelectedOptions(comboBoxSelector) {
log.debug(`comboBox.doesComboBoxHaveSelectedOptions, comboBoxSelector: ${comboBoxSelector}`);
const comboBox = await testSubjects.find(comboBoxSelector);
const selectedOptions = await comboBox.findAllByClassName('euiComboBoxPill');
return selectedOptions > 0;
}
async getComboBoxSelectedOptions(comboBoxSelector) {
log.debug(`comboBox.getComboBoxSelectedOptions, comboBoxSelector: ${comboBoxSelector}`);
const comboBox = await testSubjects.find(comboBoxSelector);
const selectedOptions = await comboBox.findAllByClassName('euiComboBoxPill');
if (selectedOptions.length === 0) {
return [];
}
const getOptionValuePromises = selectedOptions.map(async (optionElement) => {
return await optionElement.getVisibleText();
});
return await Promise.all(getOptionValuePromises);
}
async clear(comboBoxSelector) {
log.debug(`comboBox.clear, comboBoxSelector:${comboBoxSelector}`);
const comboBox = await testSubjects.find(comboBoxSelector);
await retry.try(async () => {
const clearButtonExists = await this.doesClearButtonExist(comboBox);
if (!clearButtonExists) {
log.debug('Unable to clear comboBox, comboBoxClearButton does not exist');
return;
}
const clearBtn = await comboBox.findByCssSelector('[data-test-subj="comboBoxClearButton"]');
await clearBtn.click();
const clearButtonStillExists = await this.doesClearButtonExist(comboBox);
if (clearButtonStillExists) {
throw new Error('Failed to clear comboBox');
}
});
await this.closeOptionsList(comboBox);
}
async doesClearButtonExist(comboBoxElement) {
return await find.exists(
async () => await comboBoxElement.findByCssSelector('[data-test-subj="comboBoxClearButton"]'));
}
async closeOptionsList(comboBoxElement) {
const isOptionsListOpen = await testSubjects.exists('comboBoxOptionsList');
if (isOptionsListOpen) {
const closeBtn = await comboBoxElement.findByCssSelector('[data-test-subj="comboBoxToggleListButton"]');
await closeBtn.click();
}
}
}
return new ComboBox();
}

View file

@ -27,6 +27,7 @@ export { ScreenshotsProvider } from './screenshots';
export { FailureDebuggingProvider } from './failure_debugging';
export { VisualizeListingTableProvider } from './visualize_listing_table';
export { FlyoutProvider } from './flyout';
export { ComboBoxProvider } from './combo_box';
export * from './dashboard';
export * from './visualize';