Add query enhancements opt-in switch to query bar (#17232)

Makes our language updates more visible to users and removes mentions of Kuery as a separate language. Users still get the old lucene experience by default, but have the option to opt-in to "experimental query features" directly in the query bar. Goal is to get more feedback by making these new features more prominent and less of a jump from lucene.
This commit is contained in:
Matt Bargar 2018-03-22 15:47:52 -04:00 committed by GitHub
parent d20b047481
commit aeaf57dd97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 208 additions and 217 deletions

View file

@ -1,20 +1,26 @@
[[kuery-query]]
=== Kuery
=== Kibana Query Language Enhancements
experimental[This functionality is experimental and may be changed or removed completely in a future release.]
[NOTE]
============
Breaking changes were made to Kuery's experimental syntax in 6.3. Read on for details of the new syntax.
In 6.0 we introduced an experimental query language called Kuery. We've taken what we learned from that experiment
and applied it to the standard Kibana query language. As a result, Kuery is no longer available as a standalone
option. Saved searches using Kuery will automatically be opted in to using the language enhancements described on
this page. However, some breaking changes have been made to the query syntax, so read on for the full details on
what's new.
============
Kuery is a new query language built specifically for Kibana. It aims to simplify the search experience in Kibana
and enable the creation of helpful features like auto-complete, seamless migration of saved searches, additional
query types, and more. Kuery is a basic experience today but we're hard at work building these additional features on
top of the foundation Kuery provides.
Starting in 6.3, you can choose to opt-in to a number of exciting experimental query language enhancements under the
options menu in the query bar. Currently, opting in will enable autocomplete functionality, scripted field support,
and a simplified, easier to use syntax. We're hard at work building even more features for you to try out. Take
these features for a spin and let us know what you think!
If you're familiar with Kibana's old lucene query syntax, you should feel right at home with Kuery. Both languages
are very similar, but there are some differences we'll note along the way.
==== New Simplified Syntax
If you're familiar with Kibana's old lucene query syntax, you should feel right at home with the new syntax. The basics
stay the same, we've simply refined things to make the query language easier to use. Read about the changes below.
`response:200` will match documents where the response field matches the value 200.
@ -24,8 +30,8 @@ the message field's configured analyzer and will match documents that contain th
they appear. This means documents with "quick brown fox" will match, but so will "quick fox brown". Remember to use quotes if you want
to search for a phrase.
Unlike lucene, Kuery will not split on whitespace. Multiple search terms must be separated by explicit
boolean operators. Note that boolean operators in Kuery are not case sensitive.
The query parser will no longer split on whitespace. Multiple search terms must be separated by explicit
boolean operators. Note that boolean operators are not case sensitive.
`response:200 extension:php` in lucene would become `response:200 and extension:php`.
This will match documents where response matches 200 and extension matches php.
@ -55,9 +61,9 @@ Entire groups can also be inverted.
`response:200 and not (extension:php or extension:css)`
Ranges in Kuery are similar to lucene with a small syntactical difference.
Ranges are similar to lucene with a small syntactical difference.
Instead of `bytes:>1000`, Kuery omits the colon: `bytes > 1000`.
Instead of `bytes:>1000`, we omit the colon: `bytes > 1000`.
`>, >=, <, <=` are all valid range operators.

View file

@ -1,10 +1,11 @@
[[search]]
== Searching Your Data
You can search the indices that match the current index pattern by entering
your search criteria in the Query bar. You can use the Lucene
https://lucene.apache.org/core/2_9_4/queryparsersyntax.html[
query syntax], the full JSON-based {ref}/query-dsl.html[Elasticsearch
Query DSL] or Kuery, an experimental new query language built specifically for Kibana.
your search criteria in the Query bar. You can use Kibana's standard query language
(based on Lucene https://lucene.apache.org/core/2_9_4/queryparsersyntax.html[query syntax])
or the full JSON-based {ref}/query-dsl.html[Elasticsearch Query DSL]. Autocomplete
and a simplified query syntax are available for the Kibana query language as experimental
features which you can opt-in to under the options menu in the Query Bar.
When you submit a search request, the histogram, Documents table, and Fields
list are updated to reflect the search results. The total number of hits
@ -21,15 +22,15 @@ the request to Elasticsearch.
[NOTE]
===========
By default, Kibana will accept either the Lucene query syntax or the
Elasticsearch Query DSL in the Query bar. In order to use the new Kuery
language you must enable language switching in *Management > Advanced Settings*
via the `search:queryLanguage:switcher:enable` option. You can also change the
default language with the `search:queryLanguage` setting.
You can opt-in to our experimental query features by default by changing `search:queryLanguage`
to `kuery` under Advanced Settings.
===========
[[lucene-query]]
=== Lucene Query Syntax
Kibana's query language has historically been based on the Lucene query syntax. The following
are some tips that can help get you started.
* To perform a free text search, simply enter a text string. For example, if
you're searching web server logs, you could enter `safari` to search all
fields for the term `safari`.

View file

@ -24,7 +24,6 @@ compatible with other configuration settings. Deleting a custom setting removes
`query:queryString:options`:: Options for the Lucene query string parser.
`query:allowLeadingWildcards`:: When set, * is allowed as the first character in a query clause. Currently only applies when experimental query features are enabled in the query bar. To disallow leading wildcards in basic lucene queries, use query:queryString:options.
`search:queryLanguage`:: Default is `lucene`. Query language used by the query bar. Choose between the lucene query syntax and kuery, an experimental new language built specifically for Kibana.
`search:queryLanguage:switcher:enable`:: Show or hide the query language switcher in the query bar.
`sort:options`:: Options for the Elasticsearch {ref}/search-request-sort.html[sort] parameter.
`dateFormat`:: The format to use for displaying pretty-formatted dates.
`dateFormat:tz`:: The timezone that Kibana uses. The default value of `Browser` uses the timezone detected by the browser.

View file

@ -2764,7 +2764,7 @@ main {
*/
.kuiLocalSearchAssistedInput__assistance {
position: absolute;
right: 12px;
right: 6px;
top: 50%;
/* 1 */
z-index: 2;

View file

@ -44,7 +44,7 @@
*/
.kuiLocalSearchAssistedInput__assistance {
position: absolute;
right: $kuiFormControlHorizontalPadding;
right: $kuiFormControlHorizontalPadding/2;
top: 50%; /* 1 */
z-index: 2;
transform: translateY(-50%); /* 1 */

View file

@ -54,7 +54,7 @@ app.directive('dashboardApp', function ($injector) {
return {
restrict: 'E',
controllerAs: 'dashboardApp',
controller: function ($scope, $rootScope, $route, $routeParams, $location, getAppState, $compile, dashboardConfig) {
controller: function ($scope, $rootScope, $route, $routeParams, $location, getAppState, $compile, dashboardConfig, localStorage) {
const filterManager = Private(FilterManagerProvider);
const filterBar = Private(FilterBarQueryFilterProvider);
const docTitle = Private(DocTitleProvider);
@ -121,7 +121,10 @@ app.directive('dashboardApp', function ($injector) {
});
dashboardStateManager.applyFilters(
dashboardStateManager.getQuery() || { query: '', language: config.get('search:queryLanguage') },
dashboardStateManager.getQuery() || {
query: '',
language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage')
},
filterBar.getFilters()
);
@ -170,11 +173,6 @@ app.directive('dashboardApp', function ($injector) {
};
$scope.updateQueryAndFetch = function (query) {
// reset state if language changes
if ($scope.model.query.language && $scope.model.query.language !== query.language) {
filterBar.removeAll();
dashboardStateManager.getAppState().$newFilters = [];
}
$scope.model.query = migrateLegacyQuery(query);
dashboardStateManager.applyFilters($scope.model.query, filterBar.getFilters());
$scope.refresh();

View file

@ -122,6 +122,7 @@ function discoverController(
courier,
kbnUrl,
timefilter,
localStorage,
) {
const Vis = Private(VisProvider);
@ -262,7 +263,10 @@ function discoverController(
function getStateDefaults() {
return {
query: $scope.searchSource.get('query') || { query: '', language: config.get('search:queryLanguage') },
query: $scope.searchSource.get('query') || {
query: '',
language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage')
},
sort: getSort.array(savedSearch.sort, $scope.indexPattern, config.get('discover:sort:defaultOrder')),
columns: savedSearch.columns.length > 0 ? savedSearch.columns : config.get('defaultColumns').slice(),
index: $scope.indexPattern.id,
@ -461,10 +465,6 @@ function discoverController(
};
$scope.updateQueryAndFetch = function (query) {
// reset state if language changes
if ($state.query.language && $state.query.language !== query.language) {
$state.filters = [];
}
$state.query = migrateLegacyQuery(query);
$scope.fetch();
};

View file

@ -11,7 +11,6 @@ describe('Settings', function () {
it('should return a space delimited lower-case string with no special characters', function () {
expect(getAriaName('xPack:defaultAdminEmail')).to.be('x pack default admin email');
expect(getAriaName('search:queryLanguage:switcher:enable')).to.be('search query language switcher enable');
expect(getAriaName('doc_table:highlight')).to.be('doc table highlight');
expect(getAriaName('foo')).to.be('foo');
});

View file

@ -78,7 +78,7 @@ uiModules
};
});
function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courier, Private, Promise, config, kbnBaseUrl) {
function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courier, Private, Promise, config, kbnBaseUrl, localStorage) {
const docTitle = Private(DocTitleProvider);
const queryFilter = Private(FilterBarQueryFilterProvider);
@ -144,7 +144,10 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie
const stateDefaults = {
uiState: savedVis.uiStateJSON ? JSON.parse(savedVis.uiStateJSON) : {},
linked: !!savedVis.savedSearchId,
query: searchSource.getOwn('query') || { query: '', language: config.get('search:queryLanguage') },
query: searchSource.getOwn('query') || {
query: '',
language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage')
},
filters: searchSource.getOwn('filter') || [],
vis: savedVisState
};
@ -234,11 +237,6 @@ function VisEditor($scope, $route, timefilter, AppState, $window, kbnUrl, courie
}
$scope.updateQueryAndFetch = function (query) {
// reset state if language changes
if ($state.query.language && $state.query.language !== query.language) {
$state.filters = [];
$state.$newFilters = [];
}
$state.query = migrateLegacyQuery(query);
$scope.fetch();
};

View file

@ -29,10 +29,6 @@ export function getUiSettingDefaults() {
type: 'select',
options: ['lucene', 'kuery']
},
'search:queryLanguage:switcher:enable': {
value: false,
description: 'Show or hide the query language switcher in the query bar'
},
'sort:options': {
value: '{ "unmapped_type": "boolean" }',
description: '<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html" target="_blank" rel="noopener noreferrer">Options</a> for the Elasticsearch sort parameter',

View file

@ -14,12 +14,10 @@
role="search"
>
<!-- Lucene input -->
<div
class="kuiLocalSearchAssistedInput"
ng-if="queryBar.localQuery.language === 'lucene'"
>
<div class="kuiLocalSearchAssistedInput">
<!-- Lucene input -->
<input
ng-if="queryBar.localQuery.language === 'lucene'"
parse-query
input-focus
disable-input-focus="queryBar.disableAutoFocus"
@ -30,31 +28,14 @@
aria-label="Search input"
aria-describedby="discoverLuceneSyntaxHint"
type="text"
class="kuiLocalSearchInput kuiLocalSearchInput--lucene"
class="kuiLocalSearchInput"
ng-class="{'kuiLocalSearchInput-isInvalid': queryBarForm.$invalid}"
data-test-subj="queryInput"
>
<div class="kuiLocalSearchAssistedInput__assistance">
<p class="kuiText">
<a
id="discoverLuceneSyntaxHint"
class="kuiLink"
documentation-href="query.luceneQuerySyntax"
target="_blank"
rel="noopener noreferrer"
>
Uses lucene query syntax
</a>
</p>
</div>
</div>
<!-- kuery input -->
<div
class="kuiLocalSearchAssistedInput"
ng-if="queryBar.localQuery.language === 'kuery'"
>
<!-- kuery input -->
<input
ng-if="queryBar.localQuery.language === 'kuery'"
ng-model="queryBar.localQuery.query"
ng-model-options="{ debounce: 100 }"
ng-trim="false"
@ -69,35 +50,18 @@
aria-label="Search input"
aria-describedby="discoverKuerySyntaxHint"
type="text"
class="kuiLocalSearchInput kuiLocalSearchInput--kuery"
class="kuiLocalSearchInput"
ng-class="{'kuiLocalSearchInput-isInvalid': queryBarForm.$invalid}"
data-test-subj="queryInput"
/>
<div class="kuiLocalSearchAssistedInput__assistance">
<p class="kuiText">
<a
id="discoverKuerySyntaxHint"
class="kuiLink"
documentation-href="query.kueryQuerySyntax"
target="_blank"
rel="noopener noreferrer"
>
Uses kuery syntax
</a>
</p>
<query-popover
language="queryBar.localQuery.language"
on-select-language="queryBar.selectLanguage($language)"
></query-popover>
</div>
</div>
<select
class="kuiLocalSearchSelect"
ng-options="option for option in queryBar.availableQueryLanguages"
ng-model="queryBar.localQuery.language"
ng-change="queryBar.selectLanguage()"
ng-if="queryBar.showLanguageSwitcher"
data-test-subj="queryBarLanguageSwitcher"
>
</select>
<button
type="submit"
aria-label="Search"

View file

@ -3,11 +3,10 @@ import { uiModules } from 'ui/modules';
import { callAfterBindingsWorkaround } from 'ui/compat';
import template from './query_bar.html';
import suggestionTemplate from './suggestion.html';
import { queryLanguages } from '../lib/queryLanguages';
import { getSuggestionsProvider } from '../../kuery';
import './suggestion.less';
import '../../directives/documentation_href';
import '../../directives/match_pairs';
import './query_popover';
const module = uiModules.get('kibana');
@ -28,8 +27,6 @@ module.directive('queryBar', function () {
controller: callAfterBindingsWorkaround(function ($scope, $element, $http, $timeout, config, PersistedLog, indexPatterns) {
this.appName = this.appName || 'global';
this.availableQueryLanguages = queryLanguages;
this.showLanguageSwitcher = config.get('search:queryLanguage:switcher:enable');
this.getIndexPatterns = () => {
if (compact(this.indexPatterns).length) return Promise.resolve(this.indexPatterns);
@ -44,7 +41,8 @@ module.directive('queryBar', function () {
this.suggestions = [];
};
this.selectLanguage = () => {
this.selectLanguage = (language) => {
this.localQuery.language = language;
this.localQuery.query = '';
this.submit();
};

View file

@ -0,0 +1,133 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { uiModules } from 'ui/modules';
import { documentationLinks } from '../../documentation_links/documentation_links';
import {
EuiPopover,
EuiButtonEmpty,
EuiForm,
EuiFormRow,
EuiSwitch,
EuiLink,
EuiText,
EuiSpacer,
EuiHorizontalRule,
EuiPopoverTitle,
} from '@elastic/eui';
const luceneQuerySyntaxDocs = documentationLinks.query.luceneQuerySyntax;
const kueryQuerySyntaxDocs = documentationLinks.query.kueryQuerySyntax;
const module = uiModules.get('app/kibana', ['react']);
module.directive('queryPopover', function (localStorage) {
return {
restrict: 'E',
scope: {
language: '<',
onSelectLanguage: '&',
},
link: function ($scope, $element) {
$scope.isPopoverOpen = false;
function togglePopover() {
$scope.$evalAsync(() => {
$scope.isPopoverOpen = !$scope.isPopoverOpen;
});
}
function closePopover() {
$scope.$evalAsync(() => {
$scope.isPopoverOpen = false;
});
}
function onSwitchChange() {
$scope.$evalAsync(() => {
const newLanguage = $scope.language === 'lucene' ? 'kuery' : 'lucene';
localStorage.set('kibana.userQueryLanguage', newLanguage);
$scope.onSelectLanguage({ $language: newLanguage });
});
}
function render() {
const button = (
<EuiButtonEmpty
size="xs"
onClick={togglePopover}
>
Options
</EuiButtonEmpty>
);
const popover = (
<EuiPopover
id="popover"
ownFocus
anchorPosition="downRight"
button={button}
isOpen={$scope.isPopoverOpen}
closePopover={closePopover}
withTitle
>
<EuiPopoverTitle>Syntax options</EuiPopoverTitle>
<div style={{ width: '350px' }}>
<EuiText>
<p>
Our experimental autocomplete and simple syntax features can help you create your queries. Just start
typing and youll see matches related to your data.
See docs {(
<EuiLink
href={kueryQuerySyntaxDocs}
target="_blank"
>
here
</EuiLink>
)}.
</p>
</EuiText>
<EuiSpacer size="m" />
<EuiForm>
<EuiFormRow>
<EuiSwitch
id="queryEnhancementOptIn"
name="popswitch"
label="Turn on query features"
checked={$scope.language === 'kuery'}
onChange={onSwitchChange}
/>
</EuiFormRow>
</EuiForm>
<EuiHorizontalRule margin="s" />
<EuiText size="xs">
<p>
Not ready yet? Find our lucene docs {(
<EuiLink
href={luceneQuerySyntaxDocs}
target="_blank"
>
here
</EuiLink>
)}.
</p>
</EuiText>
</div>
</EuiPopover>
);
ReactDOM.render(popover, $element[0]);
}
$scope.$watch('isPopoverOpen', render);
$scope.$watch('language', render);
}
};
});

View file

@ -1,4 +0,0 @@
export const queryLanguages = [
'lucene',
'kuery',
];

View file

@ -3,10 +3,6 @@
* won't overlap if the user increases their default browser font size
* This is sized for the 'Uses lucene query syntax' link
*/
.kuiLocalSearchInput--lucene {
padding-right: 13em; /* 1 */
}
.kuiLocalSearchInput--kuery {
padding-right: 10em; /* 1 */
.kuiLocalSearchInput {
padding-right: 6em; /* 1 */
}

View file

@ -6,7 +6,6 @@ export default function ({ getService, getPageObjects }) {
const esArchiver = getService('esArchiver');
const remote = getService('remote');
const kibanaServer = getService('kibanaServer');
const queryBar = getService('queryBar');
const filterBar = getService('filterBar');
const PageObjects = getPageObjects(['common', 'discover', 'header']);
const defaultSettings = {
@ -235,81 +234,6 @@ export default function ({ getService, getPageObjects }) {
});
});
describe('query language switching', function () {
after(async function () {
await kibanaServer.uiSettings.replace(defaultSettings);
log.debug('discover');
await PageObjects.common.navigateToApp('discover');
});
it('should not show a language switcher by default', async function () {
const languageSwitcherExists = await queryBar.hasLanguageSwitcher();
expect(languageSwitcherExists).to.be(false);
});
it('should show a language switcher after it has been enabled in the advanced settings', async function () {
await kibanaServer.uiSettings.update({
'search:queryLanguage:switcher:enable': true
});
await PageObjects.common.navigateToApp('discover');
const languageSwitcherExists = await queryBar.hasLanguageSwitcher();
expect(languageSwitcherExists).to.be(true);
});
it('should use lucene by default', async function () {
const currentLanguage = await queryBar.getCurrentLanguage();
expect(currentLanguage).to.be('lucene');
});
it('should allow changing the default language in advanced settings', async function () {
await kibanaServer.uiSettings.update({
'search:queryLanguage': 'kuery'
});
await PageObjects.common.navigateToApp('discover');
const languageSwitcherExists = await queryBar.hasLanguageSwitcher();
expect(languageSwitcherExists).to.be(true);
const currentLanguage = await queryBar.getCurrentLanguage();
expect(currentLanguage).to.be('kuery');
});
it('should reset the query and filters when the language is switched', async function () {
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
await PageObjects.discover.clickFieldListItem('response');
await PageObjects.discover.clickFieldListPlusFilter('response', 200);
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.query('php');
await PageObjects.header.waitUntilLoadingHasFinished();
let queryString = await queryBar.getQueryString();
expect(queryString).to.not.be.empty();
await queryBar.setLanguage('lucene');
await PageObjects.header.waitUntilLoadingHasFinished();
queryString = await queryBar.getQueryString();
expect(queryString).to.be.empty();
expect(await filterBar.hasFilter('response', 200)).to.be(false);
await PageObjects.discover.clickFieldListPlusFilter('response', 200);
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.query('php');
queryString = await queryBar.getQueryString();
await PageObjects.header.waitUntilLoadingHasFinished();
expect(queryString).to.not.be.empty();
expect(await filterBar.hasFilter('response', 200)).to.be(true);
await queryBar.setLanguage('kuery');
await PageObjects.header.waitUntilLoadingHasFinished();
queryString = await queryBar.getQueryString();
expect(queryString).to.be.empty();
expect(await filterBar.hasFilter('response', 200)).to.be(false);
});
});
describe('data-shared-item', function () {
it('should have correct data-shared-item title and description', async () => {
const expected = {

View file

@ -94,7 +94,7 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.visualize.waitForVisualization();
await PageObjects.visualize.toggleSpyPanel();
await PageObjects.settings.setPageSize('All');
await PageObjects.visualize.setSpyPanelPageSize('All');
const data = await PageObjects.visualize.getDataTableData();
await log.debug('getDataTableData = ' + data.split('\n'));
await log.debug('data=' + data);
@ -158,7 +158,7 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.visualize.waitForVisualization();
await PageObjects.visualize.toggleSpyPanel();
await PageObjects.settings.setPageSize('All');
await PageObjects.visualize.setSpyPanelPageSize('All');
const data = await PageObjects.visualize.getDataTableData();
await log.debug('getDataTableData = ' + data.split('\n'));
await log.debug('data=' + data);
@ -222,7 +222,7 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.visualize.waitForVisualization();
await PageObjects.visualize.toggleSpyPanel();
await PageObjects.settings.setPageSize('All');
await PageObjects.visualize.setSpyPanelPageSize('All');
const data = await PageObjects.visualize.getDataTableData();
await log.debug('getDataTableData = ' + data.split('\n'));
await log.debug('data=' + data);
@ -286,7 +286,7 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.visualize.waitForVisualization();
await PageObjects.visualize.toggleSpyPanel();
await PageObjects.settings.setPageSize('All');
await PageObjects.visualize.setSpyPanelPageSize('All');
const data = await PageObjects.visualize.getDataTableData();
await log.debug('getDataTableData = ' + data.split('\n'));
await log.debug('data=' + data);

View file

@ -178,7 +178,7 @@ export default function ({ getService, getPageObjects }) {
return PageObjects.visualize.toggleSpyPanel()
.then(function setPageSize() {
return PageObjects.settings.setPageSize('All');
return PageObjects.visualize.setSpyPanelPageSize('All');
})
.then(function getDataTableData() {
return PageObjects.visualize.getDataTableData();

View file

@ -103,7 +103,7 @@ export default function ({ getService, getPageObjects }) {
return PageObjects.visualize.toggleSpyPanel()
.then(function () {
return PageObjects.settings.setPageSize('All');
return PageObjects.visualize.setSpyPanelPageSize('All');
})
.then(function getDataTableData() {
return PageObjects.visualize.getDataTableData();

View file

@ -142,7 +142,7 @@ export default function ({ getService, getPageObjects }) {
return PageObjects.visualize.toggleSpyPanel()
.then(function () {
return PageObjects.settings.setPageSize('All');
return PageObjects.visualize.setSpyPanelPageSize('All');
})
.then(function getDataTableData() {
return PageObjects.visualize.getDataTableData();

View file

@ -114,7 +114,7 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.visualize.clickMapZoomOut();
await PageObjects.visualize.openSpyPanel();
await PageObjects.settings.setPageSize('All');
await PageObjects.visualize.setSpyPanelPageSize('All');
await PageObjects.visualize.selectTableInSpyPaneSelect();
const actualTableData = await PageObjects.visualize.getDataTableData();
compareTableData(expectedTableData, actualTableData.trim().split('\n'));

View file

@ -308,6 +308,12 @@ export function VisualizePageProvider({ getService, getPageObjects }) {
await testSubjects.click('spyToggleButton');
}
async setSpyPanelPageSize(size) {
await remote.setFindTimeout(defaultFindTimeout)
.findByCssSelector(`[data-test-subj="paginateControlsPageSizeSelect"] option[label="${size}"]`)
.click();
}
async getMetric() {
const metricElement = await find.byCssSelector('div[ng-controller="KbnMetricVisController"]');
return await metricElement.getVisibleText();

View file

@ -1,6 +1,5 @@
export function QueryBarProvider({ getService }) {
const testSubjects = getService('testSubjects');
const find = getService('find');
class QueryBar {
@ -9,28 +8,6 @@ export function QueryBarProvider({ getService }) {
return await queryInput.getProperty('value');
}
async hasLanguageSwitcher() {
return await testSubjects.exists('queryBarLanguageSwitcher');
}
async getLanguageSwitcher() {
return await testSubjects.find('queryBarLanguageSwitcher');
}
async getCurrentLanguage() {
const languageSwitcher = await this.getLanguageSwitcher();
const selectedOption = await languageSwitcher.findByCssSelector('option[selected="selected"]');
return await selectedOption.getVisibleText();
}
async setLanguage(language) {
const languageSwitcher = await this.getLanguageSwitcher();
await languageSwitcher.click();
const requestedOption = await find.byCssSelector(`option[label="${language}"]`);
await requestedOption.click();
}
}
return new QueryBar();