diff --git a/docs/release-notes.asciidoc b/docs/release-notes.asciidoc index a8f203155445a..5f5e6b4098603 100644 --- a/docs/release-notes.asciidoc +++ b/docs/release-notes.asciidoc @@ -14,6 +14,7 @@ This section summarizes the changes in each release. * <> -- +include::release-notes/5.2.1.asciidoc[] include::release-notes/5.2.0.asciidoc[] include::release-notes/5.1.2.asciidoc[] include::release-notes/5.1.1.asciidoc[] diff --git a/docs/release-notes/5.2.1.asciidoc b/docs/release-notes/5.2.1.asciidoc new file mode 100644 index 0000000000000..87d78a8493359 --- /dev/null +++ b/docs/release-notes/5.2.1.asciidoc @@ -0,0 +1,27 @@ +[[release-notes-5.2.1]] +== 5.2.1 Release Notes + +Also see <>. + +[float] +[[security-5.2.1]] +=== Security fix +When previous versions of Kibana 5 are configured for SSL client access, file +descriptors will fail to be cleaned up after certain requests and will +accumulate over time until the process crashes. Requests that are canceled +before data is sent can also crash the process. + +{security}[ESA-2017-02] ({pull}10225[#10225]) + +[float] +[[bug-5.2.1]] +=== Bug fixes +Core:: +* Bump Node.js to version 6.9.5. This was a low severity security release for Node.js, which has minimal impact to Kibana, but is still worth upgrading. {pull}10135[#10135] +Discover:: +* Prevented a background action that was causing unnecessary CPU cycles {pull}10036[#10036] +Management:: +* Delete button for color formatters no longer overlaps format dropdown {issue}8864[#8864] +Visualize:: +* Fixed regression where certain visualizations were being limited to 25 series {issue}10132[#10132] +* Fixed typo on a tag cloud warning message {pull}10092[#10092] +* Fixed a bug where data table visualizations would incorrectly appear empty in certain circumstances {issue}9757[#9757] diff --git a/src/core_plugins/kibana/public/dashboard/dashboard.js b/src/core_plugins/kibana/public/dashboard/dashboard.js index 8442c627292eb..02e189f55c9ae 100644 --- a/src/core_plugins/kibana/public/dashboard/dashboard.js +++ b/src/core_plugins/kibana/public/dashboard/dashboard.js @@ -12,6 +12,7 @@ import FilterBarQueryFilterProvider from 'ui/filter_bar/query_filter'; import DocTitleProvider from 'ui/doc_title'; import { getTopNavConfig } from './top_nav/get_top_nav_config'; import { DashboardConstants } from './dashboard_constants'; +import { VisualizeConstants } from 'plugins/kibana/visualize/visualize_constants'; import UtilsBrushEventProvider from 'ui/utils/brush_event'; import FilterBarFilterBarClickHandlerProvider from 'ui/filter_bar/filter_bar_click_handler'; import { DashboardState } from './dashboard_state'; @@ -212,7 +213,8 @@ app.directive('dashboardApp', function (Notifier, courier, AppState, timefilter, } const addNewVis = function addNewVis() { - kbnUrl.change(`/visualize?${DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM}`); + kbnUrl.change( + `${VisualizeConstants.WIZARD_STEP_1_PAGE_PATH}?${DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM}`); }; // Setup configurable values for config directive, after objects are initialized diff --git a/src/ui/public/agg_types/__tests__/buckets/terms.js b/src/ui/public/agg_types/__tests__/buckets/terms.js index d5fd937b0b3d8..2cfc18b8d49a7 100644 --- a/src/ui/public/agg_types/__tests__/buckets/terms.js +++ b/src/ui/public/agg_types/__tests__/buckets/terms.js @@ -7,7 +7,7 @@ describe('Terms Agg', function () { let $rootScope; - function init({ responseValueAggs = [] }) { + function init({ responseValueAggs = [], aggParams = {} }) { ngMock.module('kibana'); ngMock.inject(function (Private, $controller, _$rootScope_) { const terms = Private(AggTypesIndexProvider).byName.terms; @@ -16,7 +16,7 @@ describe('Terms Agg', function () { $rootScope = _$rootScope_; $rootScope.agg = { id: 'test', - params: {}, + params: aggParams, type: terms, vis: { aggs: [] @@ -152,5 +152,60 @@ describe('Terms Agg', function () { it('displays a metric editor if "custom metric" is selected'); it('saves the "custom metric" to state and refreshes from it'); it('invalidates the form if the metric agg form is not complete'); + + describe('convert import/export from old format', function () { + + it('it doesnt do anything with string type', function () { + init({ + aggParams: { + include: '404', + exclude: '400', + } + }); + + const aggConfig = $rootScope.agg; + const includeArg = $rootScope.agg.type.params.byName.include; + const excludeArg = $rootScope.agg.type.params.byName.exclude; + + expect(includeArg.serialize(aggConfig.params.include)).to.equal('404'); + expect(excludeArg.serialize(aggConfig.params.exclude)).to.equal('400'); + + const output = { params: {} }; + + includeArg.write(aggConfig, output); + excludeArg.write(aggConfig, output); + + expect(output.params.include).to.equal('404'); + expect(output.params.exclude).to.equal('400'); + }); + + it('converts object to string type', function () { + init({ + aggParams: { + include: { + pattern: '404' + }, exclude: { + pattern: '400' + }, + } + }); + + const aggConfig = $rootScope.agg; + const includeArg = $rootScope.agg.type.params.byName.include; + const excludeArg = $rootScope.agg.type.params.byName.exclude; + + expect(includeArg.serialize(aggConfig.params.include)).to.equal('404'); + expect(excludeArg.serialize(aggConfig.params.exclude)).to.equal('400'); + + const output = { params: {} }; + + includeArg.write(aggConfig, output); + excludeArg.write(aggConfig, output); + + expect(output.params.include).to.equal('404'); + expect(output.params.exclude).to.equal('400'); + }); + + }); }); }); diff --git a/src/ui/public/agg_types/buckets/terms.js b/src/ui/public/agg_types/buckets/terms.js index abb25ccb9c026..c024e2e4e4f5c 100644 --- a/src/ui/public/agg_types/buckets/terms.js +++ b/src/ui/public/agg_types/buckets/terms.js @@ -33,6 +33,21 @@ export default function TermsAggDefinition(Private) { }; } + const migrateIncludeExcludeFormat = { + serialize: function (value) { + if (!value || _.isString(value)) return value; + else return value.pattern; + }, + write: function (aggConfig, output) { + const value = aggConfig.params[this.name]; + if (_.isObject(value)) { + output.params[this.name] = value.pattern; + } else if (value) { + output.params[this.name] = value; + } + } + }; + return new BucketAggType({ name: 'terms', title: 'Terms', @@ -48,15 +63,17 @@ export default function TermsAggDefinition(Private) { }, { name: 'exclude', - type: 'regex', + type: 'string', advanced: true, - disabled: isNotType('string') + disabled: isNotType('string'), + ...migrateIncludeExcludeFormat }, { name: 'include', - type: 'regex', + type: 'string', advanced: true, - disabled: isNotType('string') + disabled: isNotType('string'), + ...migrateIncludeExcludeFormat }, { name: 'size', diff --git a/src/ui/public/parse_query/lib/to_user.js b/src/ui/public/parse_query/lib/to_user.js index 4372c9609e4f4..a47b0db198813 100644 --- a/src/ui/public/parse_query/lib/to_user.js +++ b/src/ui/public/parse_query/lib/to_user.js @@ -12,5 +12,8 @@ export default function toUser(text) { if (text.query_string) return toUser(text.query_string.query); return angular.toJson(text); } + if (text === '*') { + return ''; + } return '' + text; } diff --git a/src/ui/public/vis_maps/__tests__/tile_maps/markers.js b/src/ui/public/vis_maps/__tests__/tile_maps/markers.js index 8b345b17d7077..27bebc34d8fe9 100644 --- a/src/ui/public/vis_maps/__tests__/tile_maps/markers.js +++ b/src/ui/public/vis_maps/__tests__/tile_maps/markers.js @@ -42,13 +42,14 @@ describe('tilemaptest - Marker Tests', function () { let mapData; let markerLayer; - function createMarker(MarkerClass, geoJson) { + function createMarker(MarkerClass, geoJson, tooltipFormatter) { mapData = _.assign({}, geoJsonData.geoJson, geoJson || {}); mapData.properties.allmin = mapData.properties.min; mapData.properties.allmax = mapData.properties.max; return new MarkerClass(mockMap, mapData, { - valueFormatter: geoJsonData.valueFormatter + valueFormatter: geoJsonData.valueFormatter, + tooltipFormatter: tooltipFormatter || null }); } @@ -143,15 +144,14 @@ describe('tilemaptest - Marker Tests', function () { describe('showTooltip', function () { it('should use the tooltip formatter', function () { - let content; const sample = _.sample(mapData.features); + markerLayer = createMarker(MarkerClass, null, Function.prototype);//create marker with tooltip + markerLayer._attr.addTooltip = true; const stub = sinon.stub(markerLayer, '_tooltipFormatter', function (val) { return; }); - markerLayer._showTooltip(sample); - expect(stub.callCount).to.equal(1); expect(stub.firstCall.calledWith(sample)).to.be(true); }); diff --git a/src/ui/public/vis_maps/visualizations/_map.js b/src/ui/public/vis_maps/visualizations/_map.js index e61b0457887ee..f77279dec63c5 100644 --- a/src/ui/public/vis_maps/visualizations/_map.js +++ b/src/ui/public/vis_maps/visualizations/_map.js @@ -38,7 +38,7 @@ export default function MapFactory(Private, tilemapSettings) { this._events = _.get(params, 'events'); this._markerType = markerTypes[params.markerType] ? params.markerType : defaultMarkerType; this._valueFormatter = params.valueFormatter || _.identity; - this._tooltipFormatter = params.tooltipFormatter || _.identity; + this._tooltipFormatter = params.tooltipFormatter; this._geoJson = _.get(this._chartData, 'geoJson'); this._attr = params.attr || {}; diff --git a/src/ui/public/vis_maps/visualizations/marker_types/base_marker.js b/src/ui/public/vis_maps/visualizations/marker_types/base_marker.js index 5f330006ae58f..6154019f51cc6 100644 --- a/src/ui/public/vis_maps/visualizations/marker_types/base_marker.js +++ b/src/ui/public/vis_maps/visualizations/marker_types/base_marker.js @@ -17,7 +17,7 @@ export default function MarkerFactory() { this.geoJson = geoJson; this.popups = []; - this._tooltipFormatter = params.tooltipFormatter || _.identity; + this._tooltipFormatter = params.tooltipFormatter || null; this._valueFormatter = params.valueFormatter || _.identity; this._attr = params.attr || {}; @@ -218,7 +218,11 @@ export default function MarkerFactory() { * @return undefined */ _showTooltip(feature, latLng) { - if (!this.map) return; + const hasMap = !!this.map; + const hasTooltip = !!this._attr.addTooltip; + if (!hasMap || !hasTooltip) { + return; + } const lat = _.get(feature, 'geometry.coordinates.1'); const lng = _.get(feature, 'geometry.coordinates.0'); latLng = latLng || L.latLng(lat, lng); diff --git a/src/ui/public/vis_maps/visualizations/tile_map.js b/src/ui/public/vis_maps/visualizations/tile_map.js index f9e6ea11b66f6..1c423d6fee24a 100644 --- a/src/ui/public/vis_maps/visualizations/tile_map.js +++ b/src/ui/public/vis_maps/visualizations/tile_map.js @@ -98,12 +98,13 @@ export default function TileMapFactory(Private) { const params = _.assign({}, _.get(this._chartData, 'geoAgg.vis.params'), uiStateParams); + const tooltipFormatter = this.handler.visConfig.get('addTooltip') ? this.tooltipFormatter : null; const map = new TileMapMap(container, this._chartData, { center: params.mapCenter, zoom: params.mapZoom, events: this.events, markerType: this.handler.visConfig.get('mapType'), - tooltipFormatter: this.tooltipFormatter, + tooltipFormatter: tooltipFormatter, valueFormatter: this.valueFormatter, attr: this.handler.visConfig._values }); diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index 3a3b81f5a8b93..33756a28009e5 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -56,13 +56,13 @@ bdd.describe('creating and using Lucence expression scripted fields', function d 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.header.waitUntilLoadingHasFinished(); 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { const rowData = await PageObjects.discover.getDocTableIndex(1); @@ -75,7 +75,7 @@ bdd.describe('creating and using Lucence expression scripted fields', function d 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { expect(await PageObjects.discover.getHitCount()).to.be('31'); @@ -90,7 +90,7 @@ bdd.describe('creating and using Lucence expression scripted fields', function d await PageObjects.discover.removeAllFilters(); await PageObjects.discover.clickFieldListItem(scriptedExpressionFieldName); await PageObjects.discover.clickFieldListItemVisualize(scriptedExpressionFieldName); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.visualize.collapseChart(); await PageObjects.settings.setPageSize('All'); @@ -127,13 +127,13 @@ bdd.describe('creating and using Painless numeric scripted fields', function des 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.header.waitUntilLoadingHasFinished(); 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { const rowData = await PageObjects.discover.getDocTableIndex(1); @@ -145,7 +145,7 @@ bdd.describe('creating and using Painless numeric scripted fields', function des 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { expect(await PageObjects.discover.getHitCount()).to.be('31'); @@ -160,7 +160,7 @@ bdd.describe('creating and using Painless numeric scripted fields', function des await PageObjects.discover.removeAllFilters(); await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName); await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.visualize.collapseChart(); await PageObjects.settings.setPageSize('All'); @@ -198,13 +198,13 @@ bdd.describe('creating and using Painless string scripted fields', function desc 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.header.waitUntilLoadingHasFinished(); 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { const rowData = await PageObjects.discover.getDocTableIndex(1); @@ -217,7 +217,7 @@ bdd.describe('creating and using Painless string scripted fields', function desc 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { expect(await PageObjects.discover.getHitCount()).to.be('27'); @@ -228,7 +228,7 @@ bdd.describe('creating and using Painless string scripted fields', function desc 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.visualize.collapseChart(); await PageObjects.settings.setPageSize('All'); @@ -266,13 +266,13 @@ bdd.describe('creating and using Painless boolean scripted fields', function des 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.header.waitUntilLoadingHasFinished(); 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { const rowData = await PageObjects.discover.getDocTableIndex(1); @@ -285,7 +285,7 @@ bdd.describe('creating and using Painless boolean scripted fields', function des await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName2); await PageObjects.common.debug('filter by "true" in the expanded scripted field list'); await PageObjects.discover.clickFieldListPlusFilter(scriptedPainlessFieldName2, 'true'); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { expect(await PageObjects.discover.getHitCount()).to.be('359'); @@ -296,7 +296,7 @@ bdd.describe('creating and using Painless boolean scripted fields', function des 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.visualize.collapseChart(); await PageObjects.settings.setPageSize('All'); @@ -335,13 +335,13 @@ bdd.describe('creating and using Painless date scripted fields', function descri 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.header.waitUntilLoadingHasFinished(); 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { const rowData = await PageObjects.discover.getDocTableIndex(1); @@ -353,7 +353,7 @@ bdd.describe('creating and using Painless date scripted fields', function descri await PageObjects.discover.clickFieldListItem(scriptedPainlessFieldName2); await PageObjects.common.debug('filter by "2015-09-17 23:00" in the expanded scripted field list'); await PageObjects.discover.clickFieldListPlusFilter(scriptedPainlessFieldName2, '2015-09-17 23:00'); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.common.try(async function() { expect(await PageObjects.discover.getHitCount()).to.be('1'); @@ -364,7 +364,7 @@ bdd.describe('creating and using Painless date scripted fields', function descri 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.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); await PageObjects.visualize.collapseChart(); await PageObjects.settings.setPageSize('All'); diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js index fa1593c2d9ff1..54cf8311a1c0a 100644 --- a/test/functional/apps/visualize/_area_chart.js +++ b/test/functional/apps/visualize/_area_chart.js @@ -53,9 +53,9 @@ bdd.describe('visualize app', function describeIndexTests() { .then(function clickGo() { return PageObjects.visualize.clickGo(); }) - .then(function isGlobalLoadingIndicatorHidden() { + .then(function waitUntilLoadingHasFinished() { PageObjects.common.debug('Waiting...'); - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); }); diff --git a/test/functional/apps/visualize/_data_table.js b/test/functional/apps/visualize/_data_table.js index 07d1bd274fb06..bbb632f9a18ab 100644 --- a/test/functional/apps/visualize/_data_table.js +++ b/test/functional/apps/visualize/_data_table.js @@ -47,7 +47,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.clickGo(); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); }); diff --git a/test/functional/apps/visualize/_heatmap_chart.js b/test/functional/apps/visualize/_heatmap_chart.js index cd4bd06d111a3..608d03a2fc59f 100644 --- a/test/functional/apps/visualize/_heatmap_chart.js +++ b/test/functional/apps/visualize/_heatmap_chart.js @@ -43,7 +43,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.clickGo(); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }) .then(function waitForVisualization() { return PageObjects.visualize.waitForVisualization(); @@ -66,7 +66,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.loadSavedVisualization(vizName1); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }) .then(function waitForVisualization() { return PageObjects.visualize.waitForVisualization(); diff --git a/test/functional/apps/visualize/_line_chart.js b/test/functional/apps/visualize/_line_chart.js index db324e28a5b0b..8375545097a15 100644 --- a/test/functional/apps/visualize/_line_chart.js +++ b/test/functional/apps/visualize/_line_chart.js @@ -46,7 +46,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.clickGo(); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); }); diff --git a/test/functional/apps/visualize/_pie_chart.js b/test/functional/apps/visualize/_pie_chart.js index 7636062cdb162..6142a8f1fd84b 100644 --- a/test/functional/apps/visualize/_pie_chart.js +++ b/test/functional/apps/visualize/_pie_chart.js @@ -39,7 +39,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.selectField('memory'); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }) .then(function sleep() { return PageObjects.common.sleep(1003); @@ -53,7 +53,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.clickGo(); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); }); diff --git a/test/functional/apps/visualize/_tile_map.js b/test/functional/apps/visualize/_tile_map.js index 610cb88f4b480..02ff017d10d23 100644 --- a/test/functional/apps/visualize/_tile_map.js +++ b/test/functional/apps/visualize/_tile_map.js @@ -45,7 +45,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.clickGo(); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); }); diff --git a/test/functional/apps/visualize/_vertical_bar_chart.js b/test/functional/apps/visualize/_vertical_bar_chart.js index 047ea2ecbece2..a6cfbdf6c57fc 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart.js +++ b/test/functional/apps/visualize/_vertical_bar_chart.js @@ -43,7 +43,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.clickGo(); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }) .then(function waitForVisualization() { return PageObjects.visualize.waitForVisualization(); @@ -66,7 +66,7 @@ bdd.describe('visualize app', function describeIndexTests() { return PageObjects.visualize.loadSavedVisualization(vizName1); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }) .then(function waitForVisualization() { return PageObjects.visualize.waitForVisualization(); diff --git a/test/support/page_objects/common.js b/test/support/page_objects/common.js index 6d0e4204ddcf2..0310375cd3981 100644 --- a/test/support/page_objects/common.js +++ b/test/support/page_objects/common.js @@ -299,11 +299,20 @@ export default class Common { return exists; } - findTestSubject(selector) { + findTestSubject(selector, timeout = defaultFindTimeout) { this.debug('in findTestSubject: ' + testSubjSelector(selector)); + let originalFindTimeout = null; return this.remote - .setFindTimeout(defaultFindTimeout) - .findDisplayedByCssSelector(testSubjSelector(selector)); + .getFindTimeout() + .then((findTimeout) => originalFindTimeout = findTimeout) + .setFindTimeout(timeout) + .findDisplayedByCssSelector(testSubjSelector(selector)) + .then( + (result) => this.remote.setFindTimeout(originalFindTimeout) + .finally(() => result), + (error) => this.remote.setFindTimeout(originalFindTimeout) + .finally(() => { throw error; }), + ); } async findAllTestSubjects(selector) { diff --git a/test/support/page_objects/dashboard_page.js b/test/support/page_objects/dashboard_page.js index ff4782f57cdd3..9b5df5383f5cd 100644 --- a/test/support/page_objects/dashboard_page.js +++ b/test/support/page_objects/dashboard_page.js @@ -133,7 +133,7 @@ export default class DashboardPage { async saveDashboard(dashName, storeTimeWithDash) { await PageObjects.common.findTestSubject('dashboardSaveButton').click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.common.sleep(1000); PageObjects.common.debug('entering new title'); @@ -143,7 +143,7 @@ export default class DashboardPage { await this.storeTimeWithDashboard(storeTimeWithDash); } - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.common.sleep(1000); await PageObjects.common.try(() => { @@ -151,7 +151,7 @@ export default class DashboardPage { return this.findTimeout.findByCssSelector('.btn-primary').click(); }); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); // verify that green message at the top of the page. // it's only there for about 5 seconds @@ -179,10 +179,10 @@ export default class DashboardPage { await searchBox.click(); await searchBox.type(dashName.replace('-',' ')); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.common.sleep(1000); await this.clickDashboardByLinkText(dashName); - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); } getPanelTitles() { diff --git a/test/support/page_objects/discover_page.js b/test/support/page_objects/discover_page.js index a6cfdd957f99c..71d63da1c9007 100644 --- a/test/support/page_objects/discover_page.js +++ b/test/support/page_objects/discover_page.js @@ -52,7 +52,7 @@ export default class DiscoverPage { this.findTimeout.findByLinkText(searchName).click(); }) .then(() => { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); } @@ -81,7 +81,7 @@ export default class DiscoverPage { let yAxisLabel = 0; let yAxisHeight; - return PageObjects.header.isGlobalLoadingIndicatorHidden() + return PageObjects.header.waitUntilLoadingHasFinished() .then(() => { return this.findTimeout .findByCssSelector('div.y-axis-div-wrapper > div > svg > g > g:last-of-type'); @@ -167,12 +167,12 @@ export default class DiscoverPage { .click(); }) .then(() => { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); } getHitCount() { - return PageObjects.header.isGlobalLoadingIndicatorHidden() + return PageObjects.header.waitUntilLoadingHasFinished() .then(() => { return PageObjects.common.findTestSubject('discoverQueryHits') .getVisibleText(); @@ -190,7 +190,7 @@ export default class DiscoverPage { .click(); }) .then(() => { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); } diff --git a/test/support/page_objects/header_page.js b/test/support/page_objects/header_page.js index b5469e5ddba6e..341519e0bec62 100644 --- a/test/support/page_objects/header_page.js +++ b/test/support/page_objects/header_page.js @@ -100,7 +100,7 @@ export default class HeaderPage { .findByClassName('kbn-timepicker-go') .click() .then(function () { - return self.isGlobalLoadingIndicatorHidden(); + return self.waitUntilLoadingHasFinished(); }); } @@ -123,7 +123,7 @@ export default class HeaderPage { return this.clickGoButton(); }) .then(() => { - return this.isGlobalLoadingIndicatorHidden(); + return this.waitUntilLoadingHasFinished(); }); } @@ -144,6 +144,23 @@ export default class HeaderPage { .click(); } + async waitUntilLoadingHasFinished() { + try { + await this.isGlobalLoadingIndicatorVisible(); + } catch (exception) { + if (exception.name === 'ElementNotVisible') { + // selenium might just have been too slow to catch it + } else { + throw exception; + } + } + await this.isGlobalLoadingIndicatorHidden(); + } + + isGlobalLoadingIndicatorVisible() { + return PageObjects.common.findTestSubject('globalLoadingIndicator', defaultFindTimeout / 5); + } + isGlobalLoadingIndicatorHidden() { return this.remote.setFindTimeout(defaultFindTimeout * 10) .findByCssSelector('[data-test-subj="globalLoadingIndicator"].ng-hide'); diff --git a/test/support/page_objects/settings_page.js b/test/support/page_objects/settings_page.js index db8f7dfc38e50..7f5a1e02251bf 100644 --- a/test/support/page_objects/settings_page.js +++ b/test/support/page_objects/settings_page.js @@ -39,13 +39,13 @@ export default class SettingsPage { async setAdvancedSettings(propertyName, propertyValue) { const self = this; await PageObjects.common.findTestSubject('advancedSetting-' + propertyName + '-editButton').click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.common.sleep(1000); await this.remote.setFindTimeout(defaultFindTimeout) .findByCssSelector('option[label="' + propertyValue + '"]').click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.common.findTestSubject('advancedSetting-' + propertyName + '-saveButton').click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); } async navigateTo() { @@ -79,7 +79,7 @@ export default class SettingsPage { (await this.getTimeFieldNameField()).click(); // close dropdown, keep focus (await this.getTimeFieldNameField()).click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.common.try(async () => { (await this.getTimeFieldOption(selection)).click(); const selected = (await this.getTimeFieldOption(selection)).isSelected(); @@ -100,7 +100,7 @@ export default class SettingsPage { async clickDefaultIndexButton() { await this.remote.setFindTimeout(defaultFindTimeout) .findByCssSelector('button.btn.btn-success.ng-scope').click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); } async clickDeletePattern() { @@ -133,7 +133,7 @@ export default class SettingsPage { if (chartString === columnName) { return chart.click() .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); } }); @@ -212,7 +212,7 @@ export default class SettingsPage { .findByCssSelector('ul.pagination-other-pages-list.pagination-sm.ng-scope li.ng-scope:nth-child(' + (pageNum + 1) + ') a.ng-binding') .click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); } async openControlsRow(row) { @@ -232,7 +232,7 @@ export default class SettingsPage { await this.remote.setFindTimeout(defaultFindTimeout) .findByCssSelector('button.btn.btn-default[aria-label="Plus"]') .click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); } getPopularity() { @@ -245,21 +245,21 @@ export default class SettingsPage { await this.remote.setFindTimeout(defaultFindTimeout) .findByCssSelector('button.btn.btn-primary[aria-label="Cancel"]') .click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); } async controlChangeSave() { await this.remote.setFindTimeout(defaultFindTimeout) .findByCssSelector('button.btn.btn-success.ng-binding[aria-label="Update Field"]') .click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); } async setPageSize(size) { await this.remote.setFindTimeout(defaultFindTimeout) .findByCssSelector('form.form-inline.pagination-size.ng-scope.ng-pristine.ng-valid div.form-group option[label="' + size + '"]') .click(); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); } async createIndexPattern() { @@ -269,7 +269,7 @@ export default class SettingsPage { await this.selectTimeFieldOption('@timestamp'); await this.getCreateButton().click(); }); - await PageObjects.header.isGlobalLoadingIndicatorHidden(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.common.try(async () => { const currentUrl = await this.remote.getCurrentUrl(); PageObjects.common.log('currentUrl', currentUrl); diff --git a/test/support/page_objects/visualize_page.js b/test/support/page_objects/visualize_page.js index 263de4eea6b83..e74fc8d107a97 100644 --- a/test/support/page_objects/visualize_page.js +++ b/test/support/page_objects/visualize_page.js @@ -292,7 +292,7 @@ export default class VisualizePage { .findByCssSelector('.btn-success') .click() .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); } @@ -316,7 +316,7 @@ export default class VisualizePage { .click(); }) .then(function () { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }) // verify that green message at the top of the page. // it's only there for about 5 seconds @@ -712,7 +712,7 @@ export default class VisualizePage { return PageObjects.common.sleep(1000); }) .then(() => { - return PageObjects.header.isGlobalLoadingIndicatorHidden(); + return PageObjects.header.waitUntilLoadingHasFinished(); }); }