Skip to content

Commit

Permalink
[ftr] migrate "filterBar" service to FtrService class (elastic#100601)
Browse files Browse the repository at this point in the history
Co-authored-by: spalger <spalger@users.noreply.github.com>
  • Loading branch information
2 people authored and ecezalp committed May 26, 2021
1 parent 7f65952 commit 2003ed0
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 179 deletions.
350 changes: 173 additions & 177 deletions test/functional/services/filter_bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,200 +7,196 @@
*/

import classNames from 'classnames';
import { FtrProviderContext } from '../ftr_provider_context';

export function FilterBarProvider({ getService, getPageObjects }: FtrProviderContext) {
const comboBox = getService('comboBox');
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['common', 'header']);

class FilterBar {
/**
* Checks if specified filter exists
*
* @param key field name
* @param value filter value
* @param enabled filter status
* @param pinned filter pinned status
* @param negated filter including or excluding value
*/
public async hasFilter(
key: string,
value: string,
enabled: boolean = true,
pinned: boolean = false,
negated: boolean = false
): Promise<boolean> {
const filterActivationState = enabled ? 'enabled' : 'disabled';
const filterPinnedState = pinned ? 'pinned' : 'unpinned';
const filterNegatedState = negated ? 'filter-negated' : '';
return testSubjects.exists(
classNames(
'filter',
`filter-${filterActivationState}`,
key !== '' && `filter-key-${key}`,
value !== '' && `filter-value-${value}`,
`filter-${filterPinnedState}`,
filterNegatedState
),
{
allowHidden: true,
}
);
}
import { FtrService } from '../ftr_provider_context';

export class FilterBarService extends FtrService {
private readonly comboBox = this.ctx.getService('comboBox');
private readonly testSubjects = this.ctx.getService('testSubjects');
private readonly PageObjects = this.ctx.getPageObjects(['common', 'header']);

/**
* Checks if specified filter exists
*
* @param key field name
* @param value filter value
* @param enabled filter status
* @param pinned filter pinned status
* @param negated filter including or excluding value
*/
public async hasFilter(
key: string,
value: string,
enabled: boolean = true,
pinned: boolean = false,
negated: boolean = false
): Promise<boolean> {
const filterActivationState = enabled ? 'enabled' : 'disabled';
const filterPinnedState = pinned ? 'pinned' : 'unpinned';
const filterNegatedState = negated ? 'filter-negated' : '';
return this.testSubjects.exists(
classNames(
'filter',
`filter-${filterActivationState}`,
key !== '' && `filter-key-${key}`,
value !== '' && `filter-value-${value}`,
`filter-${filterPinnedState}`,
filterNegatedState
),
{
allowHidden: true,
}
);
}

/**
* Removes specified filter
*
* @param key field name
*/
public async removeFilter(key: string): Promise<void> {
await testSubjects.click(`~filter & ~filter-key-${key}`);
await testSubjects.click(`deleteFilter`);
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}
/**
* Removes specified filter
*
* @param key field name
*/
public async removeFilter(key: string): Promise<void> {
await this.testSubjects.click(`~filter & ~filter-key-${key}`);
await this.testSubjects.click(`deleteFilter`);
await this.PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}

/**
* Removes all filters
*/
public async removeAllFilters(): Promise<void> {
await testSubjects.click('showFilterActions');
await testSubjects.click('removeAllFilters');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.common.waitUntilUrlIncludes('filters:!()');
}
/**
* Removes all filters
*/
public async removeAllFilters(): Promise<void> {
await this.testSubjects.click('showFilterActions');
await this.testSubjects.click('removeAllFilters');
await this.PageObjects.header.waitUntilLoadingHasFinished();
await this.PageObjects.common.waitUntilUrlIncludes('filters:!()');
}

/**
* Changes filter active status
*
* @param key field name
*/
public async toggleFilterEnabled(key: string): Promise<void> {
await testSubjects.click(`~filter & ~filter-key-${key}`);
await testSubjects.click(`disableFilter`);
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}
/**
* Changes filter active status
*
* @param key field name
*/
public async toggleFilterEnabled(key: string): Promise<void> {
await this.testSubjects.click(`~filter & ~filter-key-${key}`);
await this.testSubjects.click(`disableFilter`);
await this.PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}

public async toggleFilterPinned(key: string): Promise<void> {
await testSubjects.click(`~filter & ~filter-key-${key}`);
await testSubjects.click(`pinFilter`);
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}
public async toggleFilterPinned(key: string): Promise<void> {
await this.testSubjects.click(`~filter & ~filter-key-${key}`);
await this.testSubjects.click(`pinFilter`);
await this.PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}

public async isFilterPinned(key: string): Promise<boolean> {
const filter = await testSubjects.find(`~filter & ~filter-key-${key}`);
return (await filter.getAttribute('data-test-subj')).includes('filter-pinned');
}
public async isFilterPinned(key: string): Promise<boolean> {
const filter = await this.testSubjects.find(`~filter & ~filter-key-${key}`);
return (await filter.getAttribute('data-test-subj')).includes('filter-pinned');
}

public async getFilterCount(): Promise<number> {
const filters = await testSubjects.findAll('~filter');
return filters.length;
}
public async getFilterCount(): Promise<number> {
const filters = await this.testSubjects.findAll('~filter');
return filters.length;
}

/**
* Adds a filter to the filter bar.
*
* @param {string} field The name of the field the filter should be applied for.
* @param {string} operator A valid operator for that fields, e.g. "is one of", "is", "exists", etc.
* @param {string[]|string} values The remaining parameters are the values passed into the individual
* value input fields, i.e. the third parameter into the first input field, the fourth into the second, etc.
* Each value itself can be an array, in case you want to enter multiple values into one field (e.g. for "is one of"):
* @example
* // Add a plain single value
* filterBar.addFilter('country', 'is', 'NL');
* // Add an exists filter
* filterBar.addFilter('country', 'exists');
* // Add a range filter for a numeric field
* filterBar.addFilter('bytes', 'is between', '500', '1000');
* // Add a filter containing multiple values
* filterBar.addFilter('extension', 'is one of', ['jpg', 'png']);
*/
public async addFilter(field: string, operator: string, ...values: any): Promise<void> {
await testSubjects.click('addFilter');
await comboBox.set('filterFieldSuggestionList', field);
await comboBox.set('filterOperatorList', operator);
const params = await testSubjects.find('filterParams');
const paramsComboBoxes = await params.findAllByCssSelector(
'[data-test-subj~="filterParamsComboBox"]',
1000
);
const paramFields = await params.findAllByTagName('input', 1000);
for (let i = 0; i < values.length; i++) {
let fieldValues = values[i];
if (!Array.isArray(fieldValues)) {
fieldValues = [fieldValues];
}
/**
* Adds a filter to the filter bar.
*
* @param {string} field The name of the field the filter should be applied for.
* @param {string} operator A valid operator for that fields, e.g. "is one of", "is", "exists", etc.
* @param {string[]|string} values The remaining parameters are the values passed into the individual
* value input fields, i.e. the third parameter into the first input field, the fourth into the second, etc.
* Each value itself can be an array, in case you want to enter multiple values into one field (e.g. for "is one of"):
* @example
* // Add a plain single value
* filterBar.addFilter('country', 'is', 'NL');
* // Add an exists filter
* filterBar.addFilter('country', 'exists');
* // Add a range filter for a numeric field
* filterBar.addFilter('bytes', 'is between', '500', '1000');
* // Add a filter containing multiple values
* filterBar.addFilter('extension', 'is one of', ['jpg', 'png']);
*/
public async addFilter(field: string, operator: string, ...values: any): Promise<void> {
await this.testSubjects.click('addFilter');
await this.comboBox.set('filterFieldSuggestionList', field);
await this.comboBox.set('filterOperatorList', operator);
const params = await this.testSubjects.find('filterParams');
const paramsComboBoxes = await params.findAllByCssSelector(
'[data-test-subj~="filterParamsComboBox"]',
1000
);
const paramFields = await params.findAllByTagName('input', 1000);
for (let i = 0; i < values.length; i++) {
let fieldValues = values[i];
if (!Array.isArray(fieldValues)) {
fieldValues = [fieldValues];
}

if (paramsComboBoxes && paramsComboBoxes.length > 0) {
for (let j = 0; j < fieldValues.length; j++) {
await comboBox.setElement(paramsComboBoxes[i], fieldValues[j]);
}
} else if (paramFields && paramFields.length > 0) {
for (let j = 0; j < fieldValues.length; j++) {
await paramFields[i].type(fieldValues[j]);
}
if (paramsComboBoxes && paramsComboBoxes.length > 0) {
for (let j = 0; j < fieldValues.length; j++) {
await this.comboBox.setElement(paramsComboBoxes[i], fieldValues[j]);
}
} else if (paramFields && paramFields.length > 0) {
for (let j = 0; j < fieldValues.length; j++) {
await paramFields[i].type(fieldValues[j]);
}
}
await testSubjects.click('saveFilter');
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}

/**
* Activates filter editing
* @param key field name
* @param value field value
*/
public async clickEditFilter(key: string, value: string): Promise<void> {
await testSubjects.click(`~filter & ~filter-key-${key} & ~filter-value-${value}`);
await testSubjects.click(`editFilter`);
await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}
await this.testSubjects.click('saveFilter');
await this.PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}

/**
* Returns available phrases in the filter
*/
public async getFilterEditorSelectedPhrases(): Promise<string[]> {
return await comboBox.getComboBoxSelectedOptions('~filterParamsComboBox');
}
/**
* Activates filter editing
* @param key field name
* @param value field value
*/
public async clickEditFilter(key: string, value: string): Promise<void> {
await this.testSubjects.click(`~filter & ~filter-key-${key} & ~filter-value-${value}`);
await this.testSubjects.click(`editFilter`);
await this.PageObjects.header.awaitGlobalLoadingIndicatorHidden();
}

/**
* Returns available fields in the filter
*/
public async getFilterEditorFields(): Promise<string[]> {
const optionsString = await comboBox.getOptionsList('filterFieldSuggestionList');
return optionsString.split('\n');
}
/**
* Returns available phrases in the filter
*/
public async getFilterEditorSelectedPhrases(): Promise<string[]> {
return await this.comboBox.getComboBoxSelectedOptions('~filterParamsComboBox');
}

/**
* Closes field editor modal window
*/
public async ensureFieldEditorModalIsClosed(): Promise<void> {
const cancelSaveFilterModalButtonExists = await testSubjects.exists('cancelSaveFilter');
if (cancelSaveFilterModalButtonExists) {
await testSubjects.click('cancelSaveFilter');
}
await testSubjects.waitForDeleted('cancelSaveFilter');
}
/**
* Returns available fields in the filter
*/
public async getFilterEditorFields(): Promise<string[]> {
const optionsString = await this.comboBox.getOptionsList('filterFieldSuggestionList');
return optionsString.split('\n');
}

/**
* Returns comma-separated list of index patterns
*/
public async getIndexPatterns(): Promise<string> {
await testSubjects.click('addFilter');
const indexPatterns = await comboBox.getOptionsList('filterIndexPatternsSelect');
await this.ensureFieldEditorModalIsClosed();
return indexPatterns.trim().split('\n').join(',');
/**
* Closes field editor modal window
*/
public async ensureFieldEditorModalIsClosed(): Promise<void> {
const cancelSaveFilterModalButtonExists = await this.testSubjects.exists('cancelSaveFilter');
if (cancelSaveFilterModalButtonExists) {
await this.testSubjects.click('cancelSaveFilter');
}
await this.testSubjects.waitForDeleted('cancelSaveFilter');
}

/**
* Adds new index pattern filter
* @param indexPatternTitle
*/
public async selectIndexPattern(indexPatternTitle: string): Promise<void> {
await testSubjects.click('addFilter');
await comboBox.set('filterIndexPatternsSelect', indexPatternTitle);
}
/**
* Returns comma-separated list of index patterns
*/
public async getIndexPatterns(): Promise<string> {
await this.testSubjects.click('addFilter');
const indexPatterns = await this.comboBox.getOptionsList('filterIndexPatternsSelect');
await this.ensureFieldEditorModalIsClosed();
return indexPatterns.trim().split('\n').join(',');
}

return new FilterBar();
/**
* Adds new index pattern filter
* @param indexPatternTitle
*/
public async selectIndexPattern(indexPatternTitle: string): Promise<void> {
await this.testSubjects.click('addFilter');
await this.comboBox.set('filterIndexPatternsSelect', indexPatternTitle);
}
}
4 changes: 2 additions & 2 deletions test/functional/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from './dashboard';
import { DocTableProvider } from './doc_table';
import { EmbeddingProvider } from './embedding';
import { FilterBarProvider } from './filter_bar';
import { FilterBarService } from './filter_bar';
import { FlyoutProvider } from './flyout';
import { GlobalNavProvider } from './global_nav';
import { InspectorProvider } from './inspector';
Expand All @@ -53,7 +53,7 @@ export const services = {
...commonServiceProviders,

__webdriver__: RemoteProvider,
filterBar: FilterBarProvider,
filterBar: FilterBarService,
queryBar: QueryBarProvider,
find: FindProvider,
testSubjects: TestSubjectsProvider,
Expand Down

0 comments on commit 2003ed0

Please sign in to comment.