Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New scripted field tests #9242

Merged
merged 12 commits into from
Dec 20, 2016
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ <h5 ng-show="!field.details.error">Quick Count <kbn-info info="Top 5 values base
<div>
<span ng-show="field.filterable" class="pull-right">
<i aria-hidden="true" class="fa fa-search-minus pull-right discover-field-details-filter"
ng-click="updateFilterInQuery(field, bucket.value, '-')"></i>
ng-click="updateFilterInQuery(field, bucket.value, '-')" data-test-subj="minus-{{::field.name}}-{{::bucket.display}}"></i>
<i aria-hidden="true" class="fa fa-search-plus pull-right discover-field-details-filter"
ng-click="updateFilterInQuery(field, bucket.value, '+')"></i>
ng-click="updateFilterInQuery(field, bucket.value, '+')" data-test-subj="plus-{{::field.name}}-{{::bucket.display}}"></i>
</span>
<div css-truncate css-truncate-expandable="true" class="discover-field-details-value" title="{{::bucket.display}}">
{{::bucket.display}} <i ng-show="bucket.display === ''">Empty string</i>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@

<!-- tab list -->
<ul class="nav nav-tabs">
<li class="kbn-management-tab" ng-class="{ active: state.tab === editSection.index }" ng-repeat="editSection in editSections">
<a ng-click="changeTab(editSection)">
<li class="kbn-management-tab" ng-class="{ active: state.tab === editSection.index }" ng-repeat="editSection in editSections" data-test-subj="li-{{ editSection.index }}">
<a ng-click="changeTab(editSection)" data-test-subj="tab-{{ editSection.index }}" >
{{ editSection.title }}
<small>({{ editSection.count }})</small>
</a>
Expand Down
8 changes: 4 additions & 4 deletions src/ui/public/filter_bar/filter_bar.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@
<span ng-if="!filter.meta.alias">"{{ filter.meta.value }}"</span>
</div>
<div class="filter-actions">
<a class="action filter-toggle" ng-click="toggleFilter(filter)">
<a class="action filter-toggle" ng-click="toggleFilter(filter)" data-test-subj="disableFilter-{{ filter.meta.key }}">
<i ng-show="filter.meta.disabled" class="fa fa-fw fa-square-o disabled"></i>
<i ng-hide="filter.meta.disabled" class="fa fa-fw fa-check-square-o enabled"></i>
</a>
<a class="action filter-pin" ng-click="pinFilter(filter)">
<a class="action filter-pin" ng-click="pinFilter(filter)" data-test-subj="pinFilter-{{ filter.meta.key }}">
<i ng-show="filter.$state.store == 'globalState'" class="fa fa-fw fa-thumb-tack pinned"></i>
<i ng-hide="filter.$state.store == 'globalState'" class="fa fa-fw fa-thumb-tack fa-rotate-270 unpinned"></i>
</a>
<a class="action filter-invert" ng-click="invertFilter(filter)">
<a class="action filter-invert" ng-click="invertFilter(filter)" data-test-subj="invertFilter-{{ filter.meta.key }}">
<i ng-show="filter.meta.negate" class="fa fa-fw fa-search-plus negative"></i>
<i ng-hide="filter.meta.negate" class="fa fa-fw fa-search-minus positive"></i>
</a>
<a class="action filter-remove" ng-click="removeFilter(filter)">
<i class="fa fa-fw fa-trash"></i>
<i class="fa fa-fw fa-trash" data-test-subj="removeFilter-{{ filter.meta.key }}"></i>
</a>
<a class="action filter-edit" ng-click="startEditingFilter(filter)">
<i class="fa fa-fw fa-edit"></i>
Expand Down
232 changes: 232 additions & 0 deletions test/functional/apps/management/_scripted_fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
// Tests for 3 scripted fields;
// 1. Lucene expression (number type)
// 2. Painless (number type)
// 3. Painless (string type)
//
// Each of these scripted fields has 4 tests (12 tests total);
// 1. Create scripted field
// 2. See the expected value of the scripted field in Discover doc view
// 3. Filter in Discover by the scripted field
// 4. Visualize with aggregation on the scripted field by clicking discover.clickFieldListItemVisualize

import expect from 'expect.js';

import {
bdd,
scenarioManager,
esClient
} from '../../../support';

import PageObjects from '../../../support/page_objects';

bdd.describe('creating and using Lucence expression scripted fields', function describeIndexTests() {

const scriptedExpressionFieldName = 'ram_expr1';

bdd.it('should create scripted field', async function () {
// delete .kibana index and then wait for Kibana to re-create it
await esClient.deleteAndUpdateConfigDoc({'dateFormat:tz':'UTC'});
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaIndicies();
await PageObjects.settings.createIndexPattern();
await PageObjects.settings.clickScriptedFieldsTab();
await PageObjects.common.debug('add scripted field');
await PageObjects.settings
.addScriptedField(scriptedExpressionFieldName,
'expression', 'number', null, '1', 'doc[\'machine.ram\'].value / (1024 * 1024 * 1024)'
);
await PageObjects.common.try(async function() {
expect(await PageObjects.settings.getScriptedFieldsTabCount()).to.be('1');
});
});

bdd.it('should see scripted field value in Discover', async function () {
const fromTime = '2015-09-17 06:31:44.000';
const toTime = '2015-09-18 18:31:44.000';
await PageObjects.common.navigateToApp('discover');
await PageObjects.common.debug('setAbsoluteRange (' + fromTime + ') to (' + toTime + ')');
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.discover.clickFieldListItem(scriptedExpressionFieldName);
await PageObjects.common.try(async function() {
await PageObjects.discover.clickFieldListItemAdd(scriptedExpressionFieldName);
});
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.common.try(async function() {
const rowData = await PageObjects.discover.getDocTableIndex(1);
expect(rowData).to.be('September 18th 2015, 18:20:57.916 18');
});
});

bdd.it('should filter by scripted field value in Discover', async function () {
await PageObjects.discover.clickFieldListItem(scriptedExpressionFieldName);
await PageObjects.common.debug('filter by the first value (14) in the expanded scripted field list');
await PageObjects.discover.clickFieldListPlusFilter(scriptedExpressionFieldName, '14');
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.common.try(async function() {
expect(await PageObjects.discover.getHitCount()).to.be('31');
});
});

bdd.it('should visualize scripted field in vertical bar chart', async function () {
const expectedChartValues = [ '14 31', '10 29', '7 24', '11 24', '12 23',
'20 23', '19 21', '6 20', '17 20', '30 20', '13 19', '18 18', '16 17', '5 16',
'8 16', '15 14', '3 13', '2 12', '9 10', '4 9'
];
await PageObjects.discover.removeAllFilters();
await PageObjects.discover.clickFieldListItem(scriptedExpressionFieldName);
await PageObjects.discover.clickFieldListItemVisualize(scriptedExpressionFieldName);
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.visualize.collapseChart();
await PageObjects.settings.setPageSize('All');
var data = await PageObjects.visualize.getDataTableData();
await PageObjects.common.debug('getDataTableData = ' + data.split('\n'));
await PageObjects.common.debug('data=' + data);
await PageObjects.common.debug('data.length=' + data.length);
await PageObjects.common.saveScreenshot('Visualize-vertical-bar-chart');
expect(data.trim().split('\n')).to.eql(expectedChartValues);
});

});

bdd.describe('creating and using Painless numeric scripted fields', function describeIndexTests() {

const scriptedExpressionFieldName = 'ram_expr1';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused const

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

const scriptedPainlessFieldName = 'ram_Pain1';

bdd.it('should create scripted field', async function () {
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaIndicies();
await PageObjects.settings.clickScriptedFieldsTab();
await PageObjects.common.debug('add scripted field');
await PageObjects.settings
.addScriptedField(scriptedPainlessFieldName, 'painless', 'number', null, '1', 'doc[\'machine.ram\'].value / (1024 * 1024 * 1024)');
await PageObjects.common.try(async function() {
expect(await PageObjects.settings.getScriptedFieldsTabCount()).to.be('2');
});
});

bdd.it('should see scripted field value in Discover', async function () {
const fromTime = '2015-09-17 06:31:44.000';
const toTime = '2015-09-18 18:31:44.000';
await PageObjects.common.navigateToApp('discover');
await PageObjects.common.debug('setAbsoluteRange (' + fromTime + ') to (' + toTime + ')');
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName);
await PageObjects.common.try(async function() {
await PageObjects.discover.clickFieldListItemAdd(scriptedPainlessFieldName);
});
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.common.try(async function() {
const rowData = await PageObjects.discover.getDocTableIndex(1);
expect(rowData).to.be('September 18th 2015, 18:20:57.916 18');
});
});

bdd.it('should filter by scripted field value in Discover', async function () {
await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName);
await PageObjects.common.debug('filter by the first value (14) in the expanded scripted field list');
await PageObjects.discover.clickFieldListPlusFilter(scriptedPainlessFieldName, '14');
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.common.try(async function() {
expect(await PageObjects.discover.getHitCount()).to.be('31');
});
});

bdd.it('should visualize scripted field in vertical bar chart', async function () {
const expectedChartValues = [ '14 31', '10 29', '7 24', '11 24', '12 23',
'20 23', '19 21', '6 20', '17 20', '30 20', '13 19', '18 18', '16 17', '5 16',
'8 16', '15 14', '3 13', '2 12', '9 10', '4 9'
];
await PageObjects.discover.removeAllFilters();
await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName);
await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName);
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.visualize.collapseChart();
await PageObjects.settings.setPageSize('All');
var data = await PageObjects.visualize.getDataTableData();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All vars should be updated to const or let

await PageObjects.common.debug('getDataTableData = ' + data.split('\n'));
await PageObjects.common.debug('data=' + data);
await PageObjects.common.debug('data.length=' + data.length);
await PageObjects.common.saveScreenshot('Visualize-vertical-bar-chart');
expect(data.trim().split('\n')).to.eql(expectedChartValues);
});

});

bdd.describe('creating and using Painless string scripted fields', function describeIndexTests() {

const scriptedPainlessFieldName2 = 'painString';

bdd.it('should create scripted field', async function () {
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaIndicies();
await PageObjects.settings.clickScriptedFieldsTab();
await PageObjects.common.debug('add scripted field');
await PageObjects.settings
.addScriptedField(scriptedPainlessFieldName2, 'painless', 'string', null, '1',
'if (doc[\'response.raw\'].value == \'200\') { return \'good\'} else { return \'bad\'}');
await PageObjects.common.try(async function() {
expect(await PageObjects.settings.getScriptedFieldsTabCount()).to.be('3');
});
});

bdd.it('should see scripted field value in Discover', async function () {
const fromTime = '2015-09-17 06:31:44.000';
const toTime = '2015-09-18 18:31:44.000';
await PageObjects.common.navigateToApp('discover');
await PageObjects.common.debug('setAbsoluteRange (' + fromTime + ') to (' + toTime + ')');
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName2);
await PageObjects.common.try(async function() {
await PageObjects.discover.clickFieldListItemAdd(scriptedPainlessFieldName2);
});
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.common.try(async function() {
const rowData = await PageObjects.discover.getDocTableIndex(1);
expect(rowData).to.be('September 18th 2015, 18:20:57.916 good');

});
});

bdd.it('should filter by expression scripted field value in Discover', async function () {
await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName2);
await PageObjects.common.debug('filter by "bad" in the expanded scripted field list');
await PageObjects.discover.clickFieldListPlusFilter(scriptedPainlessFieldName2, 'bad');
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.common.try(async function() {
expect(await PageObjects.discover.getHitCount()).to.be('27');
});
await PageObjects.discover.removeAllFilters();
});

bdd.it('should visualize scripted field in vertical bar chart', async function () {
await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName2);
await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName2);
await PageObjects.header.isGlobalLoadingIndicatorHidden();
await PageObjects.visualize.waitForVisualization();
await PageObjects.visualize.collapseChart();
await PageObjects.settings.setPageSize('All');
var data = await PageObjects.visualize.getDataTableData();
await PageObjects.common.debug('getDataTableData = ' + data.split('\n'));
await PageObjects.common.debug('data=' + data);
await PageObjects.common.debug('data.length=' + data.length);
expect(data.trim().split('\n')).to.eql([ 'good 359', 'bad 27' ]);
});



});
1 change: 1 addition & 0 deletions test/functional/apps/management/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ bdd.describe('settings app', function () {
require('./_index_pattern_results_sort');
require('./_index_pattern_popularity');
require('./_kibana_settings');
require('./_scripted_fields');
});
51 changes: 51 additions & 0 deletions test/support/page_objects/discover_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,55 @@ export default class DiscoverPage {
.catch(() => false);
}

clickFieldListItem(field) {
return this.findTimeout
.findByCssSelector('li[attr-field="' + field + '"]').click();
}

clickFieldListItemAdd(field) {
return this.findTimeout
.findByCssSelector('li[attr-field="' + field + '"] > div > button').click();
}

clickFieldListItemVisualize(field) {
return this.findTimeout
.findByCssSelector('li[attr-field="' + field + '"] > a').click();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the method above feel a little too generic, I'd worry about them breaking if we add another link or button. Maybe add data-test-subj attributes for these too?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't fix this. Yes, I agree we need a lot more data-test-subjs. I'd like to get these tests in and have another PR for adding data-test-subjs and using them in the tests.


clickFieldListPlusFilter(field, value) {
// this method requires the field details to be open from clickFieldListItem()
return PageObjects.common.findTestSubject('plus-' + field + '-' + value)
.click();
}

clickFieldListMinusFilter(field, value) {
// this method requires the field details to be open from clickFieldListItem()
return PageObjects.common.findTestSubject('minus-' + field + '-' + value)
.click();
}

// this doesn't work yet. Seems like we have to mouse over first to get it to appear?
removeFilter(field) {
return PageObjects.common.findTestSubject('removeFilter-' + field)
.click();
}

// this doesn't work yet. Seems like we have to mouse over first to get it to appear?
disableFilter(field) {
return PageObjects.common.findTestSubject('disableFilter-' + field)
.click();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just remove these if they don't work?


removeAllFilters() {
return this.findTimeout
.findByCssSelector('a[ng-click="showFilterActions = !showFilterActions"]')
.click()
.then(() => {
return this.findTimeout
.findByCssSelector('a[ng-click="removeAll()"]')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't rely on ng-click values, these could very easily change in the future.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to get these tests in and have another PR for adding data-test-subjs and using them in the tests.

.click();
});
}


}
Loading