mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Typescriptify and shim kbn_tp_run_pipeline test plugin (#50645)
* Typscriptify and shim kbn_tp_run_pipeline test plugin * fix imports to not re-export ‘legacy’ from root of plugin
This commit is contained in:
parent
e8e517475a
commit
80879368a1
23 changed files with 593 additions and 276 deletions
|
@ -22,6 +22,6 @@ require('@kbn/test').runTestsCli([
|
|||
require.resolve('../test/functional/config.js'),
|
||||
require.resolve('../test/api_integration/config.js'),
|
||||
require.resolve('../test/plugin_functional/config.js'),
|
||||
require.resolve('../test/interpreter_functional/config.js'),
|
||||
require.resolve('../test/interpreter_functional/config.ts'),
|
||||
require.resolve('../test/ui_capabilities/newsfeed_err/config.ts'),
|
||||
]);
|
||||
|
|
|
@ -20,10 +20,6 @@
|
|||
import { PluginInitializerContext } from '../../../core/public';
|
||||
import { ExpressionsPublicPlugin } from './plugin';
|
||||
|
||||
export function plugin(initializerContext: PluginInitializerContext) {
|
||||
return new ExpressionsPublicPlugin(initializerContext);
|
||||
}
|
||||
|
||||
export { ExpressionsPublicPlugin as Plugin };
|
||||
|
||||
export * from './plugin';
|
||||
|
@ -31,3 +27,10 @@ export * from './types';
|
|||
export * from '../common';
|
||||
export { interpreterProvider, ExpressionInterpret } from './interpreter_provider';
|
||||
export { ExpressionRenderer, ExpressionRendererProps } from './expression_renderer';
|
||||
export { ExpressionDataHandler } from './execute';
|
||||
|
||||
export { RenderResult, ExpressionRenderHandler } from './render';
|
||||
|
||||
export function plugin(initializerContext: PluginInitializerContext) {
|
||||
return new ExpressionsPublicPlugin(initializerContext);
|
||||
}
|
||||
|
|
|
@ -30,15 +30,17 @@ interface RenderError {
|
|||
|
||||
export type IExpressionRendererExtraHandlers = Record<string, any>;
|
||||
|
||||
export type RenderResult = RenderId | RenderError;
|
||||
|
||||
export class ExpressionRenderHandler {
|
||||
render$: Observable<RenderId | RenderError>;
|
||||
render$: Observable<RenderResult>;
|
||||
update$: Observable<any>;
|
||||
events$: Observable<event>;
|
||||
|
||||
private element: HTMLElement;
|
||||
private destroyFn?: any;
|
||||
private renderCount: number = 0;
|
||||
private renderSubject: Rx.BehaviorSubject<RenderId | RenderError | null>;
|
||||
private renderSubject: Rx.BehaviorSubject<RenderResult | null>;
|
||||
private eventsSubject: Rx.Subject<unknown>;
|
||||
private updateSubject: Rx.Subject<unknown>;
|
||||
private handlers: IInterpreterRenderHandlers;
|
||||
|
@ -49,11 +51,11 @@ export class ExpressionRenderHandler {
|
|||
this.eventsSubject = new Rx.Subject();
|
||||
this.events$ = this.eventsSubject.asObservable().pipe(share());
|
||||
|
||||
this.renderSubject = new Rx.BehaviorSubject(null as RenderId | RenderError | null);
|
||||
this.renderSubject = new Rx.BehaviorSubject(null as RenderResult | null);
|
||||
this.render$ = this.renderSubject.asObservable().pipe(
|
||||
share(),
|
||||
filter(_ => _ !== null)
|
||||
) as Observable<RenderId | RenderError>;
|
||||
) as Observable<RenderResult>;
|
||||
|
||||
this.updateSubject = new Rx.Subject();
|
||||
this.update$ = this.updateSubject.asObservable().pipe(share());
|
||||
|
|
|
@ -254,7 +254,7 @@ module.exports = function (grunt) {
|
|||
cmd: NODE,
|
||||
args: [
|
||||
'scripts/functional_tests',
|
||||
'--config', 'test/interpreter_functional/config.js',
|
||||
'--config', 'test/interpreter_functional/config.ts',
|
||||
'--bail',
|
||||
'--debug',
|
||||
'--kibana-install-dir', KIBANA_INSTALL_DIR,
|
||||
|
|
|
@ -470,7 +470,10 @@ export async function BrowserProvider({ getService }: FtrProviderContext) {
|
|||
);
|
||||
}
|
||||
|
||||
public async executeAsync<R>(fn: string | ((...args: any[]) => R), ...args: any[]): Promise<R> {
|
||||
public async executeAsync<R>(
|
||||
fn: string | ((...args: any[]) => Promise<R>),
|
||||
...args: any[]
|
||||
): Promise<R> {
|
||||
return await driver.executeAsyncScript(
|
||||
fn,
|
||||
...cloneDeep<any>(args, arg => {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
This folder contains interpreter functional tests.
|
||||
|
||||
Add new test suites into the `test_suites` folder and reference them from the
|
||||
`config.js` file. These test suites work the same as regular functional test.
|
||||
`config.ts` file. These test suites work the same as regular functional test.
|
||||
|
||||
## Run the test
|
||||
|
||||
|
@ -11,17 +11,17 @@ To run these tests during development you can use the following commands:
|
|||
|
||||
```
|
||||
# Start the test server (can continue running)
|
||||
node scripts/functional_tests_server.js --config test/interpreter_functional/config.js
|
||||
node scripts/functional_tests_server.js --config test/interpreter_functional/config.ts
|
||||
|
||||
# Start a test run
|
||||
node scripts/functional_test_runner.js --config test/interpreter_functional/config.js
|
||||
node scripts/functional_test_runner.js --config test/interpreter_functional/config.ts
|
||||
```
|
||||
|
||||
# Writing tests
|
||||
|
||||
Look into test_suites/run_pipeline/basic.js for examples
|
||||
Look into test_suites/run_pipeline/basic.ts for examples
|
||||
|
||||
to update baseline screenshots and snapshots run with:
|
||||
```
|
||||
node scripts/functional_test_runner.js --config test/interpreter_functional/config.js --updateBaselines
|
||||
node scripts/functional_test_runner.js --config test/interpreter_functional/config.ts --updateBaselines
|
||||
```
|
|
@ -19,25 +19,26 @@
|
|||
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
|
||||
|
||||
export default async function ({ readConfigFile }) {
|
||||
export default async function({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const functionalConfig = await readConfigFile(require.resolve('../functional/config'));
|
||||
|
||||
// Find all folders in ./plugins since we treat all them as plugin folder
|
||||
const allFiles = fs.readdirSync(path.resolve(__dirname, 'plugins'));
|
||||
const plugins = allFiles.filter(file => fs.statSync(path.resolve(__dirname, 'plugins', file)).isDirectory());
|
||||
const plugins = allFiles.filter(file =>
|
||||
fs.statSync(path.resolve(__dirname, 'plugins', file)).isDirectory()
|
||||
);
|
||||
|
||||
return {
|
||||
testFiles: [
|
||||
require.resolve('./test_suites/run_pipeline'),
|
||||
],
|
||||
testFiles: [require.resolve('./test_suites/run_pipeline')],
|
||||
services: functionalConfig.get('services'),
|
||||
pageObjects: functionalConfig.get('pageObjects'),
|
||||
servers: functionalConfig.get('servers'),
|
||||
esTestCluster: functionalConfig.get('esTestCluster'),
|
||||
apps: functionalConfig.get('apps'),
|
||||
esArchiver: {
|
||||
directory: path.resolve(__dirname, '../es_archives')
|
||||
directory: path.resolve(__dirname, '../es_archives'),
|
||||
},
|
||||
snapshots: {
|
||||
directory: path.resolve(__dirname, 'snapshots'),
|
||||
|
@ -49,7 +50,9 @@ export default async function ({ readConfigFile }) {
|
|||
...functionalConfig.get('kbnTestServer'),
|
||||
serverArgs: [
|
||||
...functionalConfig.get('kbnTestServer.serverArgs'),
|
||||
...plugins.map(pluginDir => `--plugin-path=${path.resolve(__dirname, 'plugins', pluginDir)}`),
|
||||
...plugins.map(
|
||||
pluginDir => `--plugin-path=${path.resolve(__dirname, 'plugins', pluginDir)}`
|
||||
),
|
||||
],
|
||||
},
|
||||
};
|
|
@ -16,24 +16,34 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { Legacy } from 'kibana';
|
||||
import {
|
||||
ArrayOrItem,
|
||||
LegacyPluginApi,
|
||||
LegacyPluginSpec,
|
||||
LegacyPluginOptions,
|
||||
} from 'src/legacy/plugin_discovery/types';
|
||||
|
||||
export default function (kibana) {
|
||||
return new kibana.Plugin({
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function(kibana: LegacyPluginApi): ArrayOrItem<LegacyPluginSpec> {
|
||||
const pluginSpec: Partial<LegacyPluginOptions> = {
|
||||
id: 'kbn_tp_run_pipeline',
|
||||
uiExports: {
|
||||
app: {
|
||||
title: 'Run Pipeline',
|
||||
description: 'This is a sample plugin to test running pipeline expressions',
|
||||
main: 'plugins/kbn_tp_run_pipeline/app',
|
||||
}
|
||||
main: 'plugins/kbn_tp_run_pipeline/legacy',
|
||||
},
|
||||
},
|
||||
|
||||
init(server) {
|
||||
init(server: Legacy.Server) {
|
||||
// The following lines copy over some configuration variables from Kibana
|
||||
// to this plugin. This will be needed when embedding visualizations, so that e.g.
|
||||
// region map is able to get its configuration.
|
||||
server.injectUiAppVars('kbn_tp_run_pipeline', async () => {
|
||||
return await server.getInjectedUiAppVars('kibana');
|
||||
return server.getInjectedUiAppVars('kibana');
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
return new kibana.Plugin(pluginSpec);
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
|
||||
import { uiModules } from 'ui/modules';
|
||||
import chrome from 'ui/chrome';
|
||||
|
||||
import { RequestAdapter, DataAdapter } from 'ui/inspector/adapters';
|
||||
import { registries } from 'plugins/interpreter/registries';
|
||||
import { npStart } from 'ui/new_platform';
|
||||
|
||||
// This is required so some default styles and required scripts/Angular modules are loaded,
|
||||
// or the timezone setting is correctly applied.
|
||||
import 'ui/autoload/all';
|
||||
|
||||
// These are all the required uiExports you need to import in case you want to embed visualizations.
|
||||
import 'uiExports/visTypes';
|
||||
import 'uiExports/visResponseHandlers';
|
||||
import 'uiExports/visRequestHandlers';
|
||||
import 'uiExports/visEditorTypes';
|
||||
import 'uiExports/visualize';
|
||||
import 'uiExports/savedObjectTypes';
|
||||
import 'uiExports/search';
|
||||
import 'uiExports/interpreter';
|
||||
|
||||
import { Main } from './components/main';
|
||||
|
||||
const app = uiModules.get('apps/kbnRunPipelinePlugin', ['kibana']);
|
||||
|
||||
app.config($locationProvider => {
|
||||
$locationProvider.html5Mode({
|
||||
enabled: false,
|
||||
requireBase: false,
|
||||
rewriteLinks: false,
|
||||
});
|
||||
});
|
||||
app.config(stateManagementConfigProvider =>
|
||||
stateManagementConfigProvider.disable()
|
||||
);
|
||||
|
||||
function RootController($scope, $element) {
|
||||
const domNode = $element[0];
|
||||
|
||||
// render react to DOM
|
||||
render(<Main
|
||||
RequestAdapter={RequestAdapter}
|
||||
DataAdapter={DataAdapter}
|
||||
expressions={npStart.plugins.expressions}
|
||||
registries={registries}
|
||||
/>, domNode);
|
||||
|
||||
// unmount react on controller destroy
|
||||
$scope.$on('$destroy', () => {
|
||||
unmountComponentAtNode(domNode);
|
||||
});
|
||||
}
|
||||
|
||||
chrome.setRootController('kbnRunPipelinePlugin', RootController);
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {
|
||||
EuiPage,
|
||||
EuiPageBody,
|
||||
EuiPageContent,
|
||||
EuiPageContentHeader,
|
||||
} from '@elastic/eui';
|
||||
import { first } from 'rxjs/operators';
|
||||
|
||||
class Main extends React.Component {
|
||||
chartDiv = React.createRef();
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
expression: '',
|
||||
};
|
||||
|
||||
window.runPipeline = async (expression, context = {}, initialContext = {}) => {
|
||||
this.setState({ expression });
|
||||
const adapters = {
|
||||
requests: new props.RequestAdapter(),
|
||||
data: new props.DataAdapter(),
|
||||
};
|
||||
return await props.expressions.execute(expression, {
|
||||
inspectorAdapters: adapters,
|
||||
context,
|
||||
searchContext: initialContext,
|
||||
}).getData();
|
||||
};
|
||||
|
||||
let lastRenderHandler;
|
||||
window.renderPipelineResponse = async (context = {}) => {
|
||||
if (lastRenderHandler) {
|
||||
lastRenderHandler.destroy();
|
||||
}
|
||||
|
||||
lastRenderHandler = props.expressions.render(this.chartDiv, context);
|
||||
const renderResult = await lastRenderHandler.render$.pipe(first()).toPromise();
|
||||
|
||||
if (typeof renderResult === 'object' && renderResult.type === 'error') {
|
||||
return this.setState({ expression: 'Render error!\n\n' + JSON.stringify(renderResult.error) });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const pStyle = {
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '300px'
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiPage>
|
||||
<EuiPageBody>
|
||||
<EuiPageContent data-test-subj="pluginContent">
|
||||
<EuiPageContentHeader>
|
||||
runPipeline tests are running ...
|
||||
</EuiPageContentHeader>
|
||||
<div data-test-subj="pluginChart" ref={ref => this.chartDiv = ref} style={pStyle}/>
|
||||
<div>{this.state.expression}</div>
|
||||
</EuiPageContent>
|
||||
</EuiPageBody>
|
||||
</EuiPage>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { Main };
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
export * from './np_ready';
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { PluginInitializerContext } from 'src/core/public';
|
||||
import { npSetup, npStart } from 'ui/new_platform';
|
||||
|
||||
import { plugin } from './np_ready';
|
||||
|
||||
// This is required so some default styles and required scripts/Angular modules are loaded,
|
||||
// or the timezone setting is correctly applied.
|
||||
import 'ui/autoload/all';
|
||||
// Used to run esaggs queries
|
||||
import 'uiExports/fieldFormats';
|
||||
import 'uiExports/search';
|
||||
import 'uiExports/visRequestHandlers';
|
||||
import 'uiExports/visResponseHandlers';
|
||||
// Used for kibana_context function
|
||||
|
||||
import 'uiExports/savedObjectTypes';
|
||||
import 'uiExports/interpreter';
|
||||
|
||||
const pluginInstance = plugin({} as PluginInitializerContext);
|
||||
|
||||
export const setup = pluginInstance.setup(npSetup.core, npSetup.plugins);
|
||||
export const start = pluginInstance.start(npStart.core, npStart.plugins);
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { AppMountContext, AppMountParameters } from 'kibana/public';
|
||||
import { Main } from './components/main';
|
||||
|
||||
export const renderApp = (context: AppMountContext, { element }: AppMountParameters) => {
|
||||
render(<Main />, element);
|
||||
return () => unmountComponentAtNode(element);
|
||||
};
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiPage, EuiPageBody, EuiPageContent, EuiPageContentHeader } from '@elastic/eui';
|
||||
import { first } from 'rxjs/operators';
|
||||
import {
|
||||
RequestAdapter,
|
||||
DataAdapter,
|
||||
} from '../../../../../../../../src/plugins/inspector/public/adapters';
|
||||
import {
|
||||
Adapters,
|
||||
Context,
|
||||
ExpressionRenderHandler,
|
||||
ExpressionDataHandler,
|
||||
RenderResult,
|
||||
} from '../../types';
|
||||
import { getExpressions } from '../../services';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
runPipeline: (
|
||||
expressions: string,
|
||||
context?: Context,
|
||||
initialContext?: Context
|
||||
) => ReturnType<ExpressionDataHandler['getData']>;
|
||||
renderPipelineResponse: (context?: Context) => Promise<RenderResult>;
|
||||
}
|
||||
}
|
||||
|
||||
interface State {
|
||||
expression: string;
|
||||
}
|
||||
|
||||
class Main extends React.Component<{}, State> {
|
||||
chartRef = React.createRef<HTMLDivElement>();
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
expression: '',
|
||||
};
|
||||
|
||||
window.runPipeline = async (
|
||||
expression: string,
|
||||
context: Context = {},
|
||||
initialContext: Context = {}
|
||||
) => {
|
||||
this.setState({ expression });
|
||||
const adapters: Adapters = {
|
||||
requests: new RequestAdapter(),
|
||||
data: new DataAdapter(),
|
||||
};
|
||||
return getExpressions()
|
||||
.execute(expression, {
|
||||
inspectorAdapters: adapters,
|
||||
context,
|
||||
// TODO: naming / typing is confusing and doesn't match here
|
||||
// searchContext is also a way to set initialContext and Context can't be set to SearchContext
|
||||
searchContext: initialContext as any,
|
||||
})
|
||||
.getData();
|
||||
};
|
||||
|
||||
let lastRenderHandler: ExpressionRenderHandler;
|
||||
window.renderPipelineResponse = async (context = {}) => {
|
||||
if (lastRenderHandler) {
|
||||
lastRenderHandler.destroy();
|
||||
}
|
||||
|
||||
lastRenderHandler = getExpressions().render(this.chartRef.current!, context);
|
||||
const renderResult = await lastRenderHandler.render$.pipe(first()).toPromise();
|
||||
|
||||
if (typeof renderResult === 'object' && renderResult.type === 'error') {
|
||||
this.setState({
|
||||
expression: 'Render error!\n\n' + JSON.stringify(renderResult.error),
|
||||
});
|
||||
}
|
||||
|
||||
return renderResult;
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const pStyle = {
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '300px',
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiPage>
|
||||
<EuiPageBody>
|
||||
<EuiPageContent data-test-subj="pluginContent">
|
||||
<EuiPageContentHeader>runPipeline tests are running ...</EuiPageContentHeader>
|
||||
<div data-test-subj="pluginChart" ref={this.chartRef} style={pStyle} />
|
||||
<div>{this.state.expression}</div>
|
||||
</EuiPageContent>
|
||||
</EuiPageBody>
|
||||
</EuiPage>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { Main };
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { PluginInitializer, PluginInitializerContext } from 'src/core/public';
|
||||
import { Plugin, StartDeps } from './plugin';
|
||||
export { StartDeps };
|
||||
|
||||
export const plugin: PluginInitializer<void, void, {}, StartDeps> = (
|
||||
initializerContext: PluginInitializerContext
|
||||
) => {
|
||||
return new Plugin(initializerContext);
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { CoreSetup, CoreStart, PluginInitializerContext } from 'src/core/public';
|
||||
import { ExpressionsStart } from './types';
|
||||
import { setExpressions } from './services';
|
||||
|
||||
export interface StartDeps {
|
||||
expressions: ExpressionsStart;
|
||||
}
|
||||
|
||||
export class Plugin {
|
||||
constructor(initializerContext: PluginInitializerContext) {}
|
||||
|
||||
public setup({ application }: CoreSetup) {
|
||||
application.register({
|
||||
id: 'kbn_tp_run_pipeline',
|
||||
title: 'Run Pipeline',
|
||||
async mount(context, params) {
|
||||
const { renderApp } = await import('./app/app');
|
||||
return renderApp(context, params);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public start(start: CoreStart, { expressions }: StartDeps) {
|
||||
setExpressions(expressions);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { createGetterSetter } from '../../../../../../src/plugins/kibana_utils/public/core';
|
||||
import { ExpressionsStart } from './types';
|
||||
|
||||
export const [getExpressions, setExpressions] = createGetterSetter<ExpressionsStart>('Expressions');
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
ExpressionsStart,
|
||||
Context,
|
||||
ExpressionRenderHandler,
|
||||
ExpressionDataHandler,
|
||||
RenderResult,
|
||||
} from 'src/plugins/expressions/public';
|
||||
|
||||
import { Adapters } from 'src/plugins/inspector/public';
|
||||
|
||||
export {
|
||||
ExpressionsStart,
|
||||
Context,
|
||||
ExpressionRenderHandler,
|
||||
ExpressionDataHandler,
|
||||
RenderResult,
|
||||
Adapters,
|
||||
};
|
|
@ -18,13 +18,16 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { expectExpressionProvider } from './helpers';
|
||||
import { ExpectExpression, expectExpressionProvider } from './helpers';
|
||||
import { FtrProviderContext } from '../../../functional/ftr_provider_context';
|
||||
|
||||
// this file showcases how to use testing utilities defined in helpers.js together with the kbn_tp_run_pipeline
|
||||
// this file showcases how to use testing utilities defined in helpers.ts together with the kbn_tp_run_pipeline
|
||||
// test plugin to write autmated tests for interprete
|
||||
export default function ({ getService, updateBaselines }) {
|
||||
|
||||
let expectExpression;
|
||||
export default function({
|
||||
getService,
|
||||
updateBaselines,
|
||||
}: FtrProviderContext & { updateBaselines: boolean }) {
|
||||
let expectExpression: ExpectExpression;
|
||||
describe('basic visualize loader pipeline expression tests', () => {
|
||||
before(() => {
|
||||
expectExpression = expectExpressionProvider({ getService, updateBaselines });
|
||||
|
@ -39,7 +42,12 @@ export default function ({ getService, updateBaselines }) {
|
|||
});
|
||||
|
||||
it('correctly sets timeRange', async () => {
|
||||
const result = await expectExpression('correctly_sets_timerange', 'kibana', {}, { timeRange: 'test' }).getResponse();
|
||||
const result = await expectExpression(
|
||||
'correctly_sets_timerange',
|
||||
'kibana',
|
||||
{},
|
||||
{ timeRange: 'test' }
|
||||
).getResponse();
|
||||
expect(result).to.have.property('timeRange', 'test');
|
||||
});
|
||||
});
|
||||
|
@ -60,30 +68,32 @@ export default function ({ getService, updateBaselines }) {
|
|||
|
||||
// we can also do snapshot comparison of result of our expression
|
||||
// to update the snapshots run the tests with --updateBaselines
|
||||
it ('runs the expression and compares final output', async () => {
|
||||
it('runs the expression and compares final output', async () => {
|
||||
await expectExpression('final_output_test', expression).toMatchSnapshot();
|
||||
});
|
||||
|
||||
// its also possible to check snapshot at every step of expression (after execution of each function)
|
||||
it ('runs the expression and compares output at every step', async () => {
|
||||
it('runs the expression and compares output at every step', async () => {
|
||||
await expectExpression('step_output_test', expression).steps.toMatchSnapshot();
|
||||
});
|
||||
|
||||
// and we can do screenshot comparison of the rendered output of expression (if expression returns renderable)
|
||||
it ('runs the expression and compares screenshots', async () => {
|
||||
it('runs the expression and compares screenshots', async () => {
|
||||
await expectExpression('final_screenshot_test', expression).toMatchScreenshot();
|
||||
});
|
||||
|
||||
// it is also possible to combine different checks
|
||||
it ('runs the expression and combines different checks', async () => {
|
||||
await (await expectExpression('combined_test', expression).steps.toMatchSnapshot()).toMatchScreenshot();
|
||||
it('runs the expression and combines different checks', async () => {
|
||||
await (
|
||||
await expectExpression('combined_test', expression).steps.toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
// if we want to do multiple different tests using the same data, or reusing a part of expression its
|
||||
// possible to retrieve the intermediate result and reuse it in later expressions
|
||||
describe('reusing partial results', () => {
|
||||
it ('does some screenshot comparisons', async () => {
|
||||
it('does some screenshot comparisons', async () => {
|
||||
const expression = `kibana | kibana_context | esaggs index='logstash-*' aggConfigs='[
|
||||
{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},
|
||||
{"id":"2","enabled":true,"type":"terms","schema":"segment","params":
|
||||
|
@ -93,17 +103,20 @@ export default function ({ getService, updateBaselines }) {
|
|||
const context = await expectExpression('partial_test', expression).getResponse();
|
||||
|
||||
// we reuse that response to render 3 different charts and compare screenshots with baselines
|
||||
const tagCloudExpr =
|
||||
`tagcloud metric={visdimension 1 format="number"} bucket={visdimension 0}`;
|
||||
await (await expectExpression('partial_test_1', tagCloudExpr, context).toMatchSnapshot()).toMatchScreenshot();
|
||||
const tagCloudExpr = `tagcloud metric={visdimension 1 format="number"} bucket={visdimension 0}`;
|
||||
await (
|
||||
await expectExpression('partial_test_1', tagCloudExpr, context).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
|
||||
const metricExpr =
|
||||
`metricVis metric={visdimension 1 format="number"} bucket={visdimension 0}`;
|
||||
await (await expectExpression('partial_test_2', metricExpr, context).toMatchSnapshot()).toMatchScreenshot();
|
||||
const metricExpr = `metricVis metric={visdimension 1 format="number"} bucket={visdimension 0}`;
|
||||
await (
|
||||
await expectExpression('partial_test_2', metricExpr, context).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
|
||||
const regionMapExpr =
|
||||
`regionmap visConfig='{"metric":{"accessor":1,"format":{"id":"number"}},"bucket":{"accessor":0}}'`;
|
||||
await (await expectExpression('partial_test_3', regionMapExpr, context).toMatchSnapshot()).toMatchScreenshot();
|
||||
const regionMapExpr = `regionmap visConfig='{"metric":{"accessor":1,"format":{"id":"number"}},"bucket":{"accessor":0}}'`;
|
||||
await (
|
||||
await expectExpression('partial_test_3', regionMapExpr, context).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -18,14 +18,45 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../functional/ftr_provider_context';
|
||||
import {
|
||||
ExpressionDataHandler,
|
||||
RenderResult,
|
||||
Context,
|
||||
} from '../../plugins/kbn_tp_run_pipeline/public/np_ready/types';
|
||||
|
||||
type UnWrapPromise<T> = T extends Promise<infer U> ? U : T;
|
||||
export type ExpressionResult = UnWrapPromise<ReturnType<ExpressionDataHandler['getData']>>;
|
||||
|
||||
export type ExpectExpression = (
|
||||
name: string,
|
||||
expression: string,
|
||||
context?: Context,
|
||||
initialContext?: Context
|
||||
) => ExpectExpressionHandler;
|
||||
|
||||
export interface ExpectExpressionHandler {
|
||||
toReturn: (expectedResult: ExpressionResult) => Promise<void>;
|
||||
getResponse: () => Promise<ExpressionResult>;
|
||||
runExpression: (step?: string, stepContext?: Context) => Promise<ExpressionResult>;
|
||||
steps: {
|
||||
toMatchSnapshot: () => Promise<ExpectExpressionHandler>;
|
||||
};
|
||||
toMatchSnapshot: () => Promise<ExpectExpressionHandler>;
|
||||
toMatchScreenshot: () => Promise<ExpectExpressionHandler>;
|
||||
}
|
||||
|
||||
// helper for testing interpreter expressions
|
||||
export const expectExpressionProvider = ({ getService, updateBaselines }) => {
|
||||
export function expectExpressionProvider({
|
||||
getService,
|
||||
updateBaselines,
|
||||
}: Pick<FtrProviderContext, 'getService'> & { updateBaselines: boolean }): ExpectExpression {
|
||||
const browser = getService('browser');
|
||||
const screenshot = getService('screenshots');
|
||||
const snapshots = getService('snapshots');
|
||||
const log = getService('log');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
/**
|
||||
* returns a handler object to test a given expression
|
||||
* @name: name of the test
|
||||
|
@ -34,20 +65,25 @@ export const expectExpressionProvider = ({ getService, updateBaselines }) => {
|
|||
* @initialContext: initialContext provided to the expression
|
||||
* @returns handler object
|
||||
*/
|
||||
return (name, expression, context = {}, initialContext = {}) => {
|
||||
return (
|
||||
name: string,
|
||||
expression: string,
|
||||
context: Context = {},
|
||||
initialContext: Context = {}
|
||||
): ExpectExpressionHandler => {
|
||||
log.debug(`executing expression ${expression}`);
|
||||
const steps = expression.split('|'); // todo: we should actually use interpreter parser and get the ast
|
||||
let responsePromise;
|
||||
let responsePromise: Promise<ExpressionResult>;
|
||||
|
||||
const handler = {
|
||||
const handler: ExpectExpressionHandler = {
|
||||
/**
|
||||
* checks if provided object matches expression result
|
||||
* @param result: expected expression result
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
toReturn: async result => {
|
||||
toReturn: async (expectedResult: ExpressionResult) => {
|
||||
const pipelineResponse = await handler.getResponse();
|
||||
expect(pipelineResponse).to.eql(result);
|
||||
expect(pipelineResponse).to.eql(expectedResult);
|
||||
},
|
||||
/**
|
||||
* returns expression response
|
||||
|
@ -63,16 +99,31 @@ export const expectExpressionProvider = ({ getService, updateBaselines }) => {
|
|||
* @param stepContext: context to provide to expression
|
||||
* @returns {Promise<*>} result of running expression
|
||||
*/
|
||||
runExpression: async (step, stepContext) => {
|
||||
runExpression: async (
|
||||
step: string = expression,
|
||||
stepContext: Context = context
|
||||
): Promise<ExpressionResult> => {
|
||||
log.debug(`running expression ${step || expression}`);
|
||||
const promise = browser.executeAsync((expression, context, initialContext, done) => {
|
||||
if (!context) context = {};
|
||||
if (!context.type) context.type = 'null';
|
||||
window.runPipeline(expression, context, initialContext).then(result => {
|
||||
done(result);
|
||||
});
|
||||
}, step || expression, stepContext || context, initialContext);
|
||||
return await promise;
|
||||
return browser.executeAsync<ExpressionResult>(
|
||||
(
|
||||
_expression: string,
|
||||
_currentContext: Context & { type: string },
|
||||
_initialContext: Context,
|
||||
done: (expressionResult: ExpressionResult) => void
|
||||
) => {
|
||||
if (!_currentContext) _currentContext = { type: 'null' };
|
||||
if (!_currentContext.type) _currentContext.type = 'null';
|
||||
return window
|
||||
.runPipeline(_expression, _currentContext, _initialContext)
|
||||
.then(expressionResult => {
|
||||
done(expressionResult);
|
||||
return expressionResult;
|
||||
});
|
||||
},
|
||||
step,
|
||||
stepContext,
|
||||
initialContext
|
||||
);
|
||||
},
|
||||
steps: {
|
||||
/**
|
||||
|
@ -80,17 +131,19 @@ export const expectExpressionProvider = ({ getService, updateBaselines }) => {
|
|||
* @returns {Promise<void>}
|
||||
*/
|
||||
toMatchSnapshot: async () => {
|
||||
let lastResponse;
|
||||
let lastResponse: ExpressionResult;
|
||||
for (let i = 0; i < steps.length; i++) {
|
||||
const step = steps[i];
|
||||
lastResponse = await handler.runExpression(step, lastResponse);
|
||||
const diff = await snapshots.compareAgainstBaseline(name + i, toSerializable(lastResponse), updateBaselines);
|
||||
lastResponse = await handler.runExpression(step, lastResponse!);
|
||||
const diff = await snapshots.compareAgainstBaseline(
|
||||
name + i,
|
||||
toSerializable(lastResponse!),
|
||||
updateBaselines
|
||||
);
|
||||
expect(diff).to.be.lessThan(0.05);
|
||||
}
|
||||
if (!responsePromise) {
|
||||
responsePromise = new Promise(resolve => {
|
||||
resolve(lastResponse);
|
||||
});
|
||||
responsePromise = Promise.resolve(lastResponse!);
|
||||
}
|
||||
return handler;
|
||||
},
|
||||
|
@ -101,7 +154,11 @@ export const expectExpressionProvider = ({ getService, updateBaselines }) => {
|
|||
*/
|
||||
toMatchSnapshot: async () => {
|
||||
const pipelineResponse = await handler.getResponse();
|
||||
await snapshots.compareAgainstBaseline(name, toSerializable(pipelineResponse), updateBaselines);
|
||||
await snapshots.compareAgainstBaseline(
|
||||
name,
|
||||
toSerializable(pipelineResponse),
|
||||
updateBaselines
|
||||
);
|
||||
return handler;
|
||||
},
|
||||
/**
|
||||
|
@ -111,24 +168,31 @@ export const expectExpressionProvider = ({ getService, updateBaselines }) => {
|
|||
toMatchScreenshot: async () => {
|
||||
const pipelineResponse = await handler.getResponse();
|
||||
log.debug('starting to render');
|
||||
const result = await browser.executeAsync((context, done) => {
|
||||
window.renderPipelineResponse(context).then(result => {
|
||||
done(result);
|
||||
});
|
||||
}, pipelineResponse);
|
||||
const result = await browser.executeAsync<RenderResult>(
|
||||
(_context: ExpressionResult, done: (renderResult: RenderResult) => void) =>
|
||||
window.renderPipelineResponse(_context).then(renderResult => {
|
||||
done(renderResult);
|
||||
return renderResult;
|
||||
}),
|
||||
pipelineResponse
|
||||
);
|
||||
log.debug('response of rendering: ', result);
|
||||
|
||||
const chartEl = await testSubjects.find('pluginChart');
|
||||
const percentDifference = await screenshot.compareAgainstBaseline(name, updateBaselines, chartEl);
|
||||
const percentDifference = await screenshot.compareAgainstBaseline(
|
||||
name,
|
||||
updateBaselines,
|
||||
chartEl
|
||||
);
|
||||
expect(percentDifference).to.be.lessThan(0.1);
|
||||
return handler;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return handler;
|
||||
};
|
||||
|
||||
function toSerializable(response) {
|
||||
function toSerializable(response: ExpressionResult) {
|
||||
if (response.error) {
|
||||
// in case of error, pass through only message to the snapshot
|
||||
// as error could be expected and stack trace shouldn't be part of the snapshot
|
||||
|
@ -136,4 +200,4 @@ export const expectExpressionProvider = ({ getService, updateBaselines }) => {
|
|||
}
|
||||
return response;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -17,7 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export default function ({ getService, getPageObjects, loadTestFile }) {
|
||||
import { FtrProviderContext } from '../../../functional/ftr_provider_context';
|
||||
|
||||
export default function({ getService, getPageObjects, loadTestFile }: FtrProviderContext) {
|
||||
const browser = getService('browser');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
@ -25,13 +27,16 @@ export default function ({ getService, getPageObjects, loadTestFile }) {
|
|||
const testSubjects = getService('testSubjects');
|
||||
const PageObjects = getPageObjects(['common', 'header']);
|
||||
|
||||
describe('runPipeline', function () {
|
||||
describe('runPipeline', function() {
|
||||
this.tags(['skipFirefox']);
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.loadIfNeeded('../functional/fixtures/es_archiver/logstash_functional');
|
||||
await esArchiver.load('../functional/fixtures/es_archiver/visualize_embedding');
|
||||
await kibanaServer.uiSettings.replace({ 'dateFormat:tz': 'Australia/North', 'defaultIndex': 'logstash-*' });
|
||||
await kibanaServer.uiSettings.replace({
|
||||
'dateFormat:tz': 'Australia/North',
|
||||
defaultIndex: 'logstash-*',
|
||||
});
|
||||
await browser.setWindowSize(1300, 900);
|
||||
await PageObjects.common.navigateToApp('settings');
|
||||
await appsMenu.clickLink('Run Pipeline');
|
|
@ -17,18 +17,21 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { expectExpressionProvider } from './helpers';
|
||||
import { ExpectExpression, expectExpressionProvider, ExpressionResult } from './helpers';
|
||||
import { FtrProviderContext } from '../../../functional/ftr_provider_context';
|
||||
|
||||
export default function ({ getService, updateBaselines }) {
|
||||
|
||||
let expectExpression;
|
||||
export default function({
|
||||
getService,
|
||||
updateBaselines,
|
||||
}: FtrProviderContext & { updateBaselines: boolean }) {
|
||||
let expectExpression: ExpectExpression;
|
||||
describe('metricVis pipeline expression tests', () => {
|
||||
before(() => {
|
||||
expectExpression = expectExpressionProvider({ getService, updateBaselines });
|
||||
});
|
||||
|
||||
describe('correctly renders metric', () => {
|
||||
let dataContext;
|
||||
let dataContext: ExpressionResult;
|
||||
before(async () => {
|
||||
const expression = `kibana | kibana_context | esaggs index='logstash-*' aggConfigs='[
|
||||
{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},
|
||||
|
@ -44,27 +47,46 @@ export default function ({ getService, updateBaselines }) {
|
|||
|
||||
it('with invalid data', async () => {
|
||||
const expression = 'metricVis metric={visdimension 0}';
|
||||
await (await expectExpression('metric_invalid_data', expression).toMatchSnapshot()).toMatchScreenshot();
|
||||
await (
|
||||
await expectExpression('metric_invalid_data', expression).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
|
||||
it('with single metric data', async () => {
|
||||
const expression = 'metricVis metric={visdimension 0}';
|
||||
await (await expectExpression('metric_single_metric_data', expression, dataContext).toMatchSnapshot()).toMatchScreenshot();
|
||||
await (
|
||||
await expectExpression(
|
||||
'metric_single_metric_data',
|
||||
expression,
|
||||
dataContext
|
||||
).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
|
||||
it('with multiple metric data', async () => {
|
||||
const expression = 'metricVis metric={visdimension 0} metric={visdimension 1}';
|
||||
await (await expectExpression('metric_multi_metric_data', expression, dataContext).toMatchSnapshot()).toMatchScreenshot();
|
||||
await (
|
||||
await expectExpression(
|
||||
'metric_multi_metric_data',
|
||||
expression,
|
||||
dataContext
|
||||
).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
|
||||
it('with metric and bucket data', async () => {
|
||||
const expression = 'metricVis metric={visdimension 0} bucket={visdimension 2}';
|
||||
await (await expectExpression('metric_all_data', expression, dataContext).toMatchSnapshot()).toMatchScreenshot();
|
||||
await (
|
||||
await expectExpression('metric_all_data', expression, dataContext).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
|
||||
it('with percentage option', async () => {
|
||||
const expression = 'metricVis metric={visdimension 0} percentage=true colorRange={range from=0 to=1000}';
|
||||
await (await expectExpression('metric_percentage', expression, dataContext).toMatchSnapshot()).toMatchScreenshot();
|
||||
const expression =
|
||||
'metricVis metric={visdimension 0} percentage=true colorRange={range from=0 to=1000}';
|
||||
await (
|
||||
await expectExpression('metric_percentage', expression, dataContext).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -17,18 +17,21 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { expectExpressionProvider } from './helpers';
|
||||
import { ExpectExpression, expectExpressionProvider, ExpressionResult } from './helpers';
|
||||
import { FtrProviderContext } from '../../../functional/ftr_provider_context';
|
||||
|
||||
export default function ({ getService, updateBaselines }) {
|
||||
|
||||
let expectExpression;
|
||||
export default function({
|
||||
getService,
|
||||
updateBaselines,
|
||||
}: FtrProviderContext & { updateBaselines: boolean }) {
|
||||
let expectExpression: ExpectExpression;
|
||||
describe('tag cloud pipeline expression tests', () => {
|
||||
before(() => {
|
||||
expectExpression = expectExpressionProvider({ getService, updateBaselines });
|
||||
});
|
||||
|
||||
describe('correctly renders tagcloud', () => {
|
||||
let dataContext;
|
||||
let dataContext: ExpressionResult;
|
||||
before(async () => {
|
||||
const expression = `kibana | kibana_context | esaggs index='logstash-*' aggConfigs='[
|
||||
{"id":"1","enabled":true,"type":"count","schema":"metric","params":{}},
|
||||
|
@ -41,27 +44,39 @@ export default function ({ getService, updateBaselines }) {
|
|||
|
||||
it('with invalid data', async () => {
|
||||
const expression = 'tagcloud metric={visdimension 0}';
|
||||
await (await expectExpression('tagcloud_invalid_data', expression).toMatchSnapshot()).toMatchScreenshot();
|
||||
await (
|
||||
await expectExpression('tagcloud_invalid_data', expression).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
|
||||
it('with just metric data', async () => {
|
||||
const expression = 'tagcloud metric={visdimension 0}';
|
||||
await (await expectExpression('tagcloud_metric_data', expression, dataContext).toMatchSnapshot()).toMatchScreenshot();
|
||||
await (
|
||||
await expectExpression('tagcloud_metric_data', expression, dataContext).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
|
||||
it('with metric and bucket data', async () => {
|
||||
const expression = 'tagcloud metric={visdimension 0} bucket={visdimension 1}';
|
||||
await (await expectExpression('tagcloud_all_data', expression, dataContext).toMatchSnapshot()).toMatchScreenshot();
|
||||
await (
|
||||
await expectExpression('tagcloud_all_data', expression, dataContext).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
|
||||
it('with font size options', async () => {
|
||||
const expression = 'tagcloud metric={visdimension 0} bucket={visdimension 1} minFontSize=20 maxFontSize=40';
|
||||
await (await expectExpression('tagcloud_fontsize', expression, dataContext).toMatchSnapshot()).toMatchScreenshot();
|
||||
const expression =
|
||||
'tagcloud metric={visdimension 0} bucket={visdimension 1} minFontSize=20 maxFontSize=40';
|
||||
await (
|
||||
await expectExpression('tagcloud_fontsize', expression, dataContext).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
|
||||
it('with scale and orientation options', async () => {
|
||||
const expression = 'tagcloud metric={visdimension 0} bucket={visdimension 1} scale="log" orientation="multiple"';
|
||||
await (await expectExpression('tagcloud_options', expression, dataContext).toMatchSnapshot()).toMatchScreenshot();
|
||||
const expression =
|
||||
'tagcloud metric={visdimension 0} bucket={visdimension 1} scale="log" orientation="multiple"';
|
||||
await (
|
||||
await expectExpression('tagcloud_options', expression, dataContext).toMatchSnapshot()
|
||||
).toMatchScreenshot();
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue